| // Copyright 2018 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef COMPONENTS_HEAP_PROFILING_CLIENT_CONNECTION_MANAGER_H_ | 
 | #define COMPONENTS_HEAP_PROFILING_CLIENT_CONNECTION_MANAGER_H_ | 
 |  | 
 | #include <unordered_set> | 
 |  | 
 | #include "base/gtest_prod_util.h" | 
 | #include "base/macros.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "content/public/browser/browser_child_process_observer.h" | 
 | #include "content/public/browser/child_process_data.h" | 
 | #include "content/public/browser/notification_observer.h" | 
 | #include "content/public/browser/notification_registrar.h" | 
 |  | 
 | namespace content { | 
 | class RenderProcessHost; | 
 | }  // namespace content | 
 |  | 
 | namespace heap_profiling { | 
 |  | 
 | class Controller; | 
 | enum class Mode; | 
 |  | 
 | // This class is responsible for connecting HeapProfilingClients to the | 
 | // HeapProfilingService. | 
 | //   * It registers itself as a content::NotificationObserver to listen for the | 
 | //     creation of the renderer processes. | 
 | //   * It registers itself as a content::BrowserChildProcessObserver to listen | 
 | //     for the creation of non-renderer processes. | 
 | // When a new process is created, it checks the current |Mode| to see whether | 
 | // the process should be profiled. If so, it grabs the HeapProfilingClient from | 
 | // the newly created process and connects it to the HeapProfilingService. | 
 | // | 
 | // This class is intended to be used from the browser/privileged process of the | 
 | // embedder. | 
 | // | 
 | // This class must be constructed/accessed/destroyed from the UI thread. | 
 | // | 
 | // This class can be subclassed for exactly one reason: to allow embedders to | 
 | // override AllowedToProfileRenderer in order to prevent incognito renderers | 
 | // from being profiled. | 
 | class ClientConnectionManager : public content::BrowserChildProcessObserver, | 
 |                                 content::NotificationObserver { | 
 |  public: | 
 |   // The owner of this instance must guarantee that |controller_| outlives this | 
 |   // class. | 
 |   // |controller| must be bound to the IO thread. | 
 |   ClientConnectionManager(base::WeakPtr<Controller> controller, Mode mode); | 
 |   ~ClientConnectionManager() override; | 
 |  | 
 |   // Start must be called immediately after the constructor. The only reason | 
 |   // that this is not a part of the constructor is to allow tests to skip this | 
 |   // step. | 
 |   void Start(); | 
 |  | 
 |   Mode GetMode(); | 
 |  | 
 |   // In additional to profiling |pid|, this will change the Mode to kManual. | 
 |   // From here on out, the caller must manually specify processes to be | 
 |   // profiled. | 
 |   void StartProfilingProcess(base::ProcessId pid); | 
 |  | 
 |   virtual bool AllowedToProfileRenderer(content::RenderProcessHost* host); | 
 |  | 
 |  private: | 
 |   FRIEND_TEST_ALL_PREFIXES(ChromeClientConnectionManager, | 
 |                            ShouldProfileNewRenderer); | 
 |  | 
 |   // Exists for testing only. | 
 |   void SetModeForTesting(Mode mode); | 
 |  | 
 |   // New processes will be profiled as they are created. Existing processes msut | 
 |   // be manually checked upon creation. | 
 |   void StartProfilingExistingProcessesIfNecessary(); | 
 |  | 
 |   // BrowserChildProcessObserver | 
 |   // Observe connection of non-renderer child processes. | 
 |   void BrowserChildProcessLaunchedAndConnected( | 
 |       const content::ChildProcessData& data) override; | 
 |  | 
 |   void StartProfilingNonRendererChild(const content::ChildProcessData& data); | 
 |  | 
 |   // NotificationObserver | 
 |   // Observe connection of renderer child processes. | 
 |   void Observe(int type, | 
 |                const content::NotificationSource& source, | 
 |                const content::NotificationDetails& details) override; | 
 |  | 
 |   bool ShouldProfileNewRenderer(content::RenderProcessHost* renderer); | 
 |  | 
 |   void StartProfilingRenderer(content::RenderProcessHost* renderer); | 
 |  | 
 |   // The owner of this instance must guarantee that |controller_| outlives this | 
 |   // class. | 
 |   // |controller_| must be bound to the IO thread. | 
 |   base::WeakPtr<Controller> controller_; | 
 |  | 
 |   Mode mode_; | 
 |   content::NotificationRegistrar registrar_; | 
 |  | 
 |   // This is used to identify the currently profiled renderers. Elements should | 
 |   // only be accessed on the UI thread and their values should be considered | 
 |   // opaque. | 
 |   // | 
 |   // Semantically, the elements must be something that identifies which | 
 |   // specific RenderProcess is being profiled. When the underlying RenderProcess | 
 |   // goes away, the element must be removed. The RenderProcessHost | 
 |   // pointer and the NOTIFICATION_RENDERER_PROCESS_CREATED notification can be | 
 |   // used to provide these semantics. | 
 |   // | 
 |   // This variable represents renderers that have been instructed to start | 
 |   // profiling - it does not reflect whether a renderer is currently still being | 
 |   // profiled. That information is only known by the profiling service, and for | 
 |   // simplicity, it's easier to just track this variable in this process. | 
 |   std::unordered_set<void*> profiled_renderers_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(ClientConnectionManager); | 
 | }; | 
 |  | 
 | }  // namespace heap_profiling | 
 |  | 
 | #endif  // COMPONENTS_HEAP_PROFILING_CLIENT_CONNECTION_MANAGER_H_ |