Index: content/browser/memory/memory_coordinator_impl.h |
diff --git a/content/browser/memory/memory_coordinator_impl.h b/content/browser/memory/memory_coordinator_impl.h |
index 014bb5280245d41d88032e40b29e5aacc5c099a4..d95ab53af30862bd2f45a39937c59f4b84bfda28 100644 |
--- a/content/browser/memory/memory_coordinator_impl.h |
+++ b/content/browser/memory/memory_coordinator_impl.h |
@@ -6,44 +6,79 @@ |
#define CONTENT_BROWSER_MEMORY_MEMORY_COORDINATOR_IMPL_H_ |
#include "base/callback.h" |
+#include "base/memory/memory_coordinator_client.h" |
+#include "base/memory/memory_pressure_monitor.h" |
#include "base/memory/singleton.h" |
#include "base/single_thread_task_runner.h" |
#include "base/threading/non_thread_safe.h" |
#include "base/time/time.h" |
-#include "content/browser/memory/memory_coordinator.h" |
+#include "content/common/content_export.h" |
+#include "content/common/memory_coordinator.mojom.h" |
+#include "content/public/browser/memory_coordinator_delegate.h" |
#include "content/public/browser/notification_observer.h" |
#include "content/public/browser/notification_registrar.h" |
namespace content { |
-class MemoryMonitor; |
+// NOTE: Memory coordinator is under development and not fully working. |
+// TODO(bashi): Add content::MemoryCoordinator which is a pure virtual |
+// interface to expose APIs outside content/. |
+ |
+class MemoryCoordinatorHandleImpl; |
class MemoryCoordinatorImplTest; |
+class MemoryMonitor; |
class MemoryStateUpdater; |
struct MemoryCoordinatorSingletonTraits; |
// MemoryCoordinatorImpl is an implementation of MemoryCoordinator. |
// The current implementation uses MemoryStateUpdater to update the global |
// memory state. See comments in MemoryStateUpdater for details. |
-class CONTENT_EXPORT MemoryCoordinatorImpl : public MemoryCoordinator, |
- public NotificationObserver, |
+class CONTENT_EXPORT MemoryCoordinatorImpl : public NotificationObserver, |
public base::NonThreadSafe { |
public: |
using MemoryState = base::MemoryState; |
+ static MemoryCoordinatorImpl* GetInstance(); |
+ |
MemoryCoordinatorImpl(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
std::unique_ptr<MemoryMonitor> monitor); |
~MemoryCoordinatorImpl() override; |
MemoryMonitor* memory_monitor() { return memory_monitor_.get(); } |
- MemoryStateUpdater* state_updater() { return state_updater_.get(); } |
- // MemoryCoordinator implementations: |
- void Start() override; |
- void OnChildAdded(int render_process_id) override; |
+ // Starts monitoring memory usage. After calling this method, memory |
+ // coordinator will start dispatching state changes. |
+ void Start(); |
+ |
+ // Creates a handle to the provided child process. |
+ void CreateHandle(int render_process_id, |
+ mojom::MemoryCoordinatorHandleRequest request); |
+ |
+ // Dispatches a memory state change to the provided process. Returns true if |
+ // the process is tracked by this coordinator and successfully dispatches, |
+ // returns false otherwise. |
+ bool SetChildMemoryState( |
+ int render_process_id, mojom::MemoryState memory_state); |
- MemoryState GetGlobalMemoryState() const override; |
- MemoryState GetCurrentMemoryState() const override; |
- void SetCurrentMemoryStateForTesting(MemoryState memory_state) override; |
+ // Returns the memory state of the specified render process. Returns UNKNOWN |
+ // if the process is not tracked by this coordinator. |
+ mojom::MemoryState GetChildMemoryState(int render_process_id) const; |
+ |
+ // Records memory pressure notifications. Called by MemoryPressureMonitor. |
+ // TODO(bashi): Remove this when MemoryPressureMonitor is retired. |
+ void RecordMemoryPressure( |
+ base::MemoryPressureMonitor::MemoryPressureLevel level); |
+ |
+ // Returns the global memory state. |
+ virtual MemoryState GetGlobalMemoryState() const; |
+ |
+ // Returns the browser's current memory state. Note that the current state |
+ // could be different from the global memory state as the browser won't be |
+ // suspended. |
+ MemoryState GetCurrentMemoryState() const; |
+ |
+ // Sets the global memory state for testing. |
+ void SetCurrentMemoryStateForTesting(MemoryState memory_state); |
// NotificationObserver implementation: |
void Observe(int type, |
@@ -61,13 +96,66 @@ class CONTENT_EXPORT MemoryCoordinatorImpl : public MemoryCoordinator, |
// the state is actually changed. |
bool ChangeStateIfNeeded(MemoryState prev_state, MemoryState next_state); |
+ protected: |
+ // Adds the given ChildMemoryCoordinator as a child of this coordinator. |
+ void AddChildForTesting(int dummy_render_process_id, |
+ mojom::ChildMemoryCoordinatorPtr child); |
+ |
+ // Callback invoked by mojo when the child connection goes down. Exposed |
+ // for testing. |
+ void OnConnectionError(int render_process_id); |
+ |
+ // Returns true when a given renderer can be suspended. |
+ bool CanSuspendRenderer(int render_process_id); |
+ |
+ // Stores information about any known child processes. |
+ struct ChildInfo { |
+ // This object must be compatible with STL containers. |
+ ChildInfo(); |
+ ChildInfo(const ChildInfo& rhs); |
+ ~ChildInfo(); |
+ |
+ mojom::MemoryState memory_state; |
+ bool is_visible = false; |
+ std::unique_ptr<MemoryCoordinatorHandleImpl> handle; |
+ }; |
+ |
+ // A map from process ID (RenderProcessHost::GetID()) to child process info. |
+ using ChildInfoMap = std::map<int, ChildInfo>; |
+ |
+ ChildInfoMap& children() { return children_; } |
+ |
private: |
+#if !defined(OS_MACOSX) |
+ FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplBrowserTest, HandleAdded); |
+ FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplBrowserTest, |
+ CanSuspendRenderer); |
+ FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorWithServiceWorkerTest, |
+ CannotSuspendRendererWithServiceWorker); |
+#endif |
FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, CalculateNextState); |
FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, UpdateState); |
FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, SetMemoryStateForTesting); |
FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, ForceSetGlobalState); |
friend struct MemoryCoordinatorSingletonTraits; |
+ friend class MemoryCoordinatorHandleImpl; |
+ |
+ // Called when ChildMemoryCoordinator calls AddChild(). |
+ void OnChildAdded(int render_process_id); |
+ |
+ // Called by SetChildMemoryState() to determine a child memory state based on |
+ // the current status of the child process. |
+ mojom::MemoryState OverrideGlobalState(mojom::MemoryState memroy_state, |
+ const ChildInfo& child); |
+ |
+ void SetDelegateForTesting( |
+ std::unique_ptr<MemoryCoordinatorDelegate> delegate); |
+ |
+ // Helper function of CreateHandle and AddChildForTesting. |
+ void CreateChildInfoMapEntry( |
+ int render_process_id, |
+ std::unique_ptr<MemoryCoordinatorHandleImpl> handle); |
// Notifies a state change to in-process clients. |
void NotifyStateToClients(); |
@@ -80,11 +168,18 @@ class CONTENT_EXPORT MemoryCoordinatorImpl : public MemoryCoordinator, |
MemoryState next_state, |
base::TimeDelta duration); |
+ std::unique_ptr<MemoryCoordinatorDelegate> delegate_; |
std::unique_ptr<MemoryMonitor> memory_monitor_; |
- NotificationRegistrar notification_registrar_; |
std::unique_ptr<MemoryStateUpdater> state_updater_; |
+ NotificationRegistrar notification_registrar_; |
+ // The global memory state. |
MemoryState current_state_ = MemoryState::NORMAL; |
+ // The time tick of last global state change. |
base::TimeTicks last_state_change_; |
+ // Tracks child processes. An entry is added when a renderer connects to |
+ // MemoryCoordinator and removed automatically when an underlying binding is |
+ // disconnected. |
+ ChildInfoMap children_; |
DISALLOW_COPY_AND_ASSIGN(MemoryCoordinatorImpl); |
}; |