Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / athena / resource_manager / resource_manager_impl.cc
index 3cb303a..74a8aca 100644 (file)
@@ -16,6 +16,7 @@
 #include "athena/wm/public/window_list_provider_observer.h"
 #include "athena/wm/public/window_manager.h"
 #include "athena/wm/public/window_manager_observer.h"
+#include "base/containers/adapters.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
@@ -31,19 +32,19 @@ class ResourceManagerImpl : public ResourceManager,
                             public WindowListProviderObserver {
  public:
   ResourceManagerImpl(ResourceManagerDelegate* delegate);
-  virtual ~ResourceManagerImpl();
+  ~ResourceManagerImpl() override;
 
   // ResourceManager:
   virtual void SetMemoryPressureAndStopMonitoring(
-      MemoryPressureObserver::MemoryPressure pressure) OVERRIDE;
-  virtual void SetWaitTimeBetweenResourceManageCalls(int time_in_ms) OVERRIDE {
+      MemoryPressure pressure) override;
+  virtual void SetWaitTimeBetweenResourceManageCalls(int time_in_ms) override {
     wait_time_for_resource_deallocation_ =
         base::TimeDelta::FromMilliseconds(time_in_ms);
     // Reset the timeout to force the next resource call to execute immediately.
     next_resource_management_time_ = base::Time::Now();
   }
 
-  virtual void Pause(bool pause) OVERRIDE {
+  virtual void Pause(bool pause) override {
     if (pause) {
       if (!pause_)
         queued_command_ = false;
@@ -51,32 +52,31 @@ class ResourceManagerImpl : public ResourceManager,
     } else {
       DCHECK(pause_);
       --pause_;
-      if (!pause && queued_command_) {
-        UpdateActivityOrder();
+      if (!pause && queued_command_)
         ManageResource();
-      }
     }
   }
 
   // ActivityManagerObserver:
-  virtual void OnActivityStarted(Activity* activity) OVERRIDE;
-  virtual void OnActivityEnding(Activity* activity) OVERRIDE;
+  virtual void OnActivityStarted(Activity* activity) override;
+  virtual void OnActivityEnding(Activity* activity) override;
+  virtual void OnActivityOrderChanged() override;
 
   // WindowManagerObserver:
-  virtual void OnOverviewModeEnter() OVERRIDE;
-  virtual void OnOverviewModeExit() OVERRIDE;
-  virtual void OnSplitViewModeEnter() OVERRIDE;
-  virtual void OnSplitViewModeExit() OVERRIDE;
+  virtual void OnOverviewModeEnter() override;
+  virtual void OnOverviewModeExit() override;
+  virtual void OnSplitViewModeEnter() override;
+  virtual void OnSplitViewModeExit() override;
 
   // MemoryPressureObserver:
-  virtual void OnMemoryPressure(
-      MemoryPressureObserver::MemoryPressure pressure) OVERRIDE;
-  virtual ResourceManagerDelegate* GetDelegate() OVERRIDE;
+  virtual void OnMemoryPressure(MemoryPressure pressure) override;
+  virtual ResourceManagerDelegate* GetDelegate() override;
 
   // WindowListProviderObserver:
-  virtual void OnWindowStackingChanged() OVERRIDE;
-  virtual void OnWindowRemoved(aura::Window* removed_window,
-                               int index) OVERRIDE;
+  virtual void OnWindowStackingChangedInList() override;
+  virtual void OnWindowAddedToList(aura::Window* added_window) override {}
+  virtual void OnWindowRemovedFromList(aura::Window* removed_window,
+                                       int index) override {}
 
  private:
   // Manage the resources for our activities.
@@ -88,11 +88,6 @@ class ResourceManagerImpl : public ResourceManager,
   // Check if activities can be unloaded to reduce memory pressure.
   void TryToUnloadAnActivity();
 
-  // Order our activity list to the order of activities of the stream.
-  // TODO(skuhne): Once the ActivityManager is responsible to create this list
-  // for us, we can remove this code here.
-  void UpdateActivityOrder();
-
   // Resources were released and a quiet period is needed before we release
   // more since it takes a while to trickle through the system.
   void OnResourcesReleased();
@@ -105,16 +100,11 @@ class ResourceManagerImpl : public ResourceManager,
   // unloading another activity.
   bool AllowedToUnloadActivity();
 
-  // The sorted (new(front) -> old(back)) activity list.
-  // TODO(skuhne): Once the ActivityManager is responsible to create this list
-  // for us, we can remove this code here.
-  std::vector<Activity*> activity_list_;
-
   // The resource manager delegate.
   scoped_ptr<ResourceManagerDelegate> delegate_;
 
   // Keeping a reference to the current memory pressure.
-  MemoryPressureObserver::MemoryPressure current_memory_pressure_;
+  MemoryPressure current_memory_pressure_;
 
   // The memory pressure notifier.
   scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_;
@@ -148,7 +138,7 @@ class ResourceManagerImpl : public ResourceManager,
 };
 
 namespace {
-ResourceManagerImpl* instance = NULL;
+ResourceManagerImpl* instance = nullptr;
 
 // We allow this many activities to be visible. All others must be at state of
 // invisible or below.
@@ -158,7 +148,7 @@ const int kMaxVisibleActivities = 3;
 
 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate)
     : delegate_(delegate),
-      current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN),
+      current_memory_pressure_(MEMORY_PRESSURE_UNKNOWN),
       memory_pressure_notifier_(new MemoryPressureNotifier(this)),
       pause_(false),
       queued_command_(false),
@@ -177,36 +167,25 @@ ResourceManagerImpl::~ResourceManagerImpl() {
   ActivityManager::Get()->RemoveObserver(this);
   WindowManager::Get()->GetWindowListProvider()->RemoveObserver(this);
   WindowManager::Get()->RemoveObserver(this);
-
-  while (!activity_list_.empty())
-    OnActivityEnding(activity_list_.front());
 }
 
 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring(
-    MemoryPressureObserver::MemoryPressure pressure) {
+    MemoryPressure pressure) {
   memory_pressure_notifier_->StopObserving();
   OnMemoryPressure(pressure);
 }
 
 void ResourceManagerImpl::OnActivityStarted(Activity* activity) {
-  // As long as we have to manage the list of activities ourselves, we need to
-  // order it here.
-  activity_list_.push_back(activity);
-  UpdateActivityOrder();
   // Update the activity states.
   ManageResource();
-  // Remember that the activity order has changed.
   activity_order_changed_ = true;
 }
 
 void ResourceManagerImpl::OnActivityEnding(Activity* activity) {
-  DCHECK(activity->GetWindow());
-  // Remove the activity from the list again.
-  std::vector<Activity*>::iterator it =
-      std::find(activity_list_.begin(), activity_list_.end(), activity);
-  DCHECK(it != activity_list_.end());
-  activity_list_.erase(it);
-  // Remember that the activity order has changed.
+  activity_order_changed_ = true;
+}
+
+void ResourceManagerImpl::OnActivityOrderChanged() {
   activity_order_changed_ = true;
 }
 
@@ -216,9 +195,6 @@ void ResourceManagerImpl::OnOverviewModeEnter() {
 
 void ResourceManagerImpl::OnOverviewModeExit() {
   in_overview_mode_ = false;
-  // Reorder the activities and manage the resources again since an order change
-  // might have caused a visibility change.
-  UpdateActivityOrder();
   ManageResource();
 }
 
@@ -235,8 +211,7 @@ void ResourceManagerImpl::OnSplitViewModeExit() {
   in_split_view_mode_ = false;
 }
 
-void ResourceManagerImpl::OnWindowStackingChanged() {
-  activity_order_changed_ = true;
+void ResourceManagerImpl::OnWindowStackingChangedInList() {
   if (pause_) {
     queued_command_ = true;
     return;
@@ -246,20 +221,11 @@ void ResourceManagerImpl::OnWindowStackingChanged() {
   if (in_overview_mode_)
     return;
 
-  // As long as we have to manage the list of activities ourselves, we need to
-  // order it here.
-  UpdateActivityOrder();
-
   // Manage the resources of each activity.
   ManageResource();
 }
 
-void ResourceManagerImpl::OnWindowRemoved(aura::Window* removed_window,
-                                          int index) {
-}
-
-void ResourceManagerImpl::OnMemoryPressure(
-      MemoryPressureObserver::MemoryPressure pressure) {
+void ResourceManagerImpl::OnMemoryPressure(MemoryPressure pressure) {
   if (pressure > current_memory_pressure_)
     OnMemoryPressureIncreased();
   current_memory_pressure_ = pressure;
@@ -272,7 +238,7 @@ ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() {
 
 void ResourceManagerImpl::ManageResource() {
   // If there is none or only one app running we cannot do anything.
-  if (activity_list_.size() <= 1U)
+  if (ActivityManager::Get()->GetActivityList().size() <= 1U)
     return;
 
   if (pause_) {
@@ -301,47 +267,46 @@ void ResourceManagerImpl::UpdateVisibilityStates() {
   if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL)
     max_activities = in_split_view_mode_ ? 2 : 1;
 
-  // Restart and / or bail if the order of activities changes due to our calls.
-  activity_order_changed_ = false;
-
-  // Change the visibility of our activities in a pre-processing step. This is
-  // required since it might change the order/number of activities.
-  size_t index = 0;
-  while (index < activity_list_.size()) {
-    Activity* activity = activity_list_[index];
-    Activity::ActivityState state = activity->GetCurrentState();
-
-    // The first |kMaxVisibleActivities| entries should be visible, all others
-    // invisible or at a lower activity state.
-    if (index < max_activities ||
-        (state == Activity::ACTIVITY_INVISIBLE ||
-         state == Activity::ACTIVITY_VISIBLE)) {
-      Activity::ActivityState visiblity_state =
-          index < max_activities ? Activity::ACTIVITY_VISIBLE :
-                                   Activity::ACTIVITY_INVISIBLE;
-      // Only change the state when it changes. Note that when the memory
-      // pressure is critical, only the primary activities (1 or 2) are made
-      // visible. Furthermore, in relaxed mode we only want to turn visible,
-      // never invisible.
-      if (visiblity_state != state &&
-          (current_memory_pressure_ != MEMORY_PRESSURE_LOW ||
-           visiblity_state == Activity::ACTIVITY_VISIBLE)) {
-        activity->SetCurrentState(visiblity_state);
-        // If we turned an activity invisible, we are already releasing memory
-        // and can hold off releasing more for now.
-        if (visiblity_state == Activity::ACTIVITY_INVISIBLE)
-          OnResourcesReleased();
+  do {
+    activity_order_changed_ = false;
+
+    // Change the visibility of our activities in a pre-processing step. This is
+    // required since it might change the order/number of activities.
+    size_t count = 0;
+    for (Activity* activity : ActivityManager::Get()->GetActivityList()) {
+      Activity::ActivityState state = activity->GetCurrentState();
+
+      // The first |kMaxVisibleActivities| entries should be visible, all others
+      // invisible or at a lower activity state.
+      if (count < max_activities ||
+          (state == Activity::ACTIVITY_INVISIBLE ||
+           state == Activity::ACTIVITY_VISIBLE)) {
+        Activity::ActivityState visiblity_state =
+            count < max_activities ? Activity::ACTIVITY_VISIBLE :
+                                     Activity::ACTIVITY_INVISIBLE;
+        // Only change the state when it changes. Note that when the memory
+        // pressure is critical, only the primary activities (1 or 2) are made
+        // visible. Furthermore, in relaxed mode we only want to turn visible,
+        // never invisible.
+        if (visiblity_state != state &&
+            (current_memory_pressure_ != MEMORY_PRESSURE_LOW ||
+             visiblity_state == Activity::ACTIVITY_VISIBLE)) {
+          activity->SetCurrentState(visiblity_state);
+          // If we turned an activity invisible, we are already releasing memory
+          // and can hold off releasing more for now.
+          if (visiblity_state == Activity::ACTIVITY_INVISIBLE)
+            OnResourcesReleased();
+        }
       }
-    }
 
-    // See which index we should handle next.
-    if (activity_order_changed_) {
-      activity_order_changed_ = false;
-      index = 0;
-    } else {
-      ++index;
+      // See which count we should handle next.
+      if (activity_order_changed_)
+        break;
+      ++count;
     }
-  }
+    // If we stopped iterating over the list of activities because of the change
+    // in ordering, then restart processing the activities from the beginning.
+  } while (activity_order_changed_);
 }
 
 void ResourceManagerImpl::TryToUnloadAnActivity() {
@@ -369,26 +334,29 @@ void ResourceManagerImpl::TryToUnloadAnActivity() {
   }
 
   // Check if / which activity we want to unload.
-  Activity* oldest_media_activity = NULL;
-  std::vector<Activity*> unloadable_activities;
-  for (std::vector<Activity*>::iterator it = activity_list_.begin();
-       it != activity_list_.end(); ++it) {
-    Activity::ActivityState state = (*it)->GetCurrentState();
+  Activity* oldest_media_activity = nullptr;
+  Activity* oldest_unloadable_activity = nullptr;
+  size_t unloadable_activity_count = 0;
+  const ActivityList& activity_list = ActivityManager::Get()->GetActivityList();
+  for (Activity* activity : activity_list) {
+    Activity::ActivityState state = activity->GetCurrentState();
     // The activity should neither be unloaded nor visible.
     if (state != Activity::ACTIVITY_UNLOADED &&
         state != Activity::ACTIVITY_VISIBLE) {
-      if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) {
+      if (activity->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) {
         // Does not play media - so we can unload this immediately.
-        unloadable_activities.push_back(*it);
+        ++unloadable_activity_count;
+        oldest_unloadable_activity = activity;
       } else {
-        oldest_media_activity = *it;
+        oldest_media_activity = activity;
       }
     }
   }
 
-  if (unloadable_activities.size() > max_running_activities) {
+  if (unloadable_activity_count > max_running_activities) {
+    CHECK(oldest_unloadable_activity);
     OnResourcesReleased();
-    unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED);
+    oldest_unloadable_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
     return;
   } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) {
     if (oldest_media_activity) {
@@ -407,39 +375,10 @@ void ResourceManagerImpl::TryToUnloadAnActivity() {
     LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" <<
         current_memory_pressure_ <<
         "), Activities (running, allowed, unloadable)=(" <<
-        activity_list_.size() << ", " <<
+        activity_list.size() << ", " <<
         max_running_activities << ", " <<
-        unloadable_activities.size() << ")";
-  }
-}
-
-void ResourceManagerImpl::UpdateActivityOrder() {
-  queued_command_ = true;
-  if (activity_list_.empty())
-    return;
-  std::vector<Activity*> new_activity_list;
-  const aura::Window::Windows children =
-      WindowManager::Get()->GetWindowListProvider()->GetWindowList();
-  // Find the first window in the container which is part of the application.
-  for (aura::Window::Windows::const_reverse_iterator child_iterator =
-         children.rbegin();
-      child_iterator != children.rend(); ++child_iterator) {
-    for (std::vector<Activity*>::iterator activity_iterator =
-             activity_list_.begin();
-        activity_iterator != activity_list_.end(); ++activity_iterator) {
-      if (*child_iterator == (*activity_iterator)->GetWindow()) {
-        new_activity_list.push_back(*activity_iterator);
-        activity_list_.erase(activity_iterator);
-        break;
-      }
-    }
+        unloadable_activity_count << ")";
   }
-  // At this point the old list should be empty and we can swap the lists.
-  DCHECK(!activity_list_.size());
-  activity_list_ = new_activity_list;
-
-  // Remember that the activity order has changed.
-  activity_order_changed_ = true;
 }
 
 void ResourceManagerImpl::OnResourcesReleased() {
@@ -478,14 +417,14 @@ ResourceManager* ResourceManager::Get() {
 void ResourceManager::Shutdown() {
   DCHECK(instance);
   delete instance;
-  instance = NULL;
+  instance = nullptr;
 }
 
 ResourceManager::ResourceManager() {}
 
 ResourceManager::~ResourceManager() {
   DCHECK(instance);
-  instance = NULL;
+  instance = nullptr;
 }
 
 }  // namespace athena