athena: Expose the list of activities from the ActivityManager.

Notable implementation details of the change:
. Have ActivityManagerImpl observer each aura::Window of the activities, and
  update order of the activities when their windows are restacked.
. Introduce ActivityManagerObserver::OnActivityOrderChanged().
. Remove the code from ResourceManagerImpl that tracks the activity order, and
  replace it to get the list from ActivityManager instead.
  - Make sure the code traverses the activities in the correct order.

BUG=413928
R=oshima@chromium.org, skuhne@chromium.org

Review URL: https://codereview.chromium.org/694353004

Cr-Commit-Position: refs/heads/master@{#302574}
parent 395b6533
......@@ -6,4 +6,5 @@ include_rules = [
"+ui/base",
"+ui/gfx",
"+ui/views",
"+ui/wm",
]
......@@ -10,9 +10,12 @@
#include "athena/activity/public/activity.h"
#include "athena/activity/public/activity_manager_observer.h"
#include "athena/activity/public/activity_view_model.h"
#include "athena/screen/public/screen_manager.h"
#include "base/logging.h"
#include "base/observer_list.h"
#include "ui/aura/window.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/public/activation_client.h"
namespace athena {
......@@ -46,9 +49,16 @@ views::Widget* GetWidget(Activity* activity) {
ActivityManagerImpl::ActivityManagerImpl() {
CHECK(!instance);
instance = this;
aura::Window* root_window =
ScreenManager::Get()->GetContext()->GetRootWindow();
aura::client::GetActivationClient(root_window)->AddObserver(this);
}
ActivityManagerImpl::~ActivityManagerImpl() {
aura::Window* root_window =
ScreenManager::Get()->GetContext()->GetRootWindow();
aura::client::GetActivationClient(root_window)->RemoveObserver(this);
while (!activities_.empty())
Activity::Delete(activities_.front());
......@@ -59,9 +69,9 @@ ActivityManagerImpl::~ActivityManagerImpl() {
void ActivityManagerImpl::AddActivity(Activity* activity) {
CHECK(activities_.end() ==
std::find(activities_.begin(), activities_.end(), activity));
activities_.push_back(activity);
activities_.insert(activities_.begin(), activity);
views::Widget* widget = CreateWidget(activity);
widget->AddObserver(this);
widget->GetNativeView()->AddObserver(this);
FOR_EACH_OBSERVER(ActivityManagerObserver,
observers_,
OnActivityStarted(activity));
......@@ -76,7 +86,7 @@ void ActivityManagerImpl::RemoveActivity(Activity* activity) {
ActivityManagerObserver, observers_, OnActivityEnding(activity));
activities_.erase(find);
views::Widget* widget = GetWidget(activity);
widget->RemoveObserver(this);
widget->GetNativeView()->RemoveObserver(this);
widget->Close();
}
}
......@@ -87,6 +97,10 @@ void ActivityManagerImpl::UpdateActivity(Activity* activity) {
widget->UpdateWindowTitle();
}
const ActivityList& ActivityManagerImpl::GetActivityList() {
return activities_;
}
Activity* ActivityManagerImpl::GetActivityForWindow(aura::Window* window) {
struct Matcher {
Matcher(aura::Window* w) : window(w) {}
......@@ -108,14 +122,33 @@ void ActivityManagerImpl::RemoveObserver(ActivityManagerObserver* observer) {
observers_.RemoveObserver(observer);
}
void ActivityManagerImpl::OnWidgetDestroying(views::Widget* widget) {
Activity* activity = GetActivityForWindow(widget->GetNativeWindow());
void ActivityManagerImpl::OnWindowDestroying(aura::Window* window) {
Activity* activity = GetActivityForWindow(window);
if (activity) {
widget->RemoveObserver(this);
window->RemoveObserver(this);
Activity::Delete(activity);
}
}
void ActivityManagerImpl::OnWindowActivated(aura::Window* gained_active,
aura::Window* lost_active) {
Activity* activity = GetActivityForWindow(gained_active);
if (!activity)
return;
CHECK(!activities_.empty());
if (activity == activities_.front())
return;
// Move the activity for |gained_active| at the front of the list.
ActivityList::reverse_iterator iter = std::find(activities_.rbegin(),
activities_.rend(),
activity);
CHECK(iter != activities_.rend());
std::rotate(iter, iter + 1, activities_.rend());
FOR_EACH_OBSERVER(ActivityManagerObserver,
observers_,
OnActivityOrderChanged());
}
// static
ActivityManager* ActivityManager::Create() {
new ActivityManagerImpl();
......
......@@ -8,14 +8,16 @@
#include "base/macros.h"
#include "base/observer_list.h"
#include "ui/views/widget/widget_observer.h"
#include "ui/aura/window_observer.h"
#include "ui/wm/public/activation_change_observer.h"
namespace athena {
class ActivityManagerObserver;
class ActivityManagerImpl : public ActivityManager,
public views::WidgetObserver {
public aura::WindowObserver,
public aura::client::ActivationChangeObserver {
public:
ActivityManagerImpl();
~ActivityManagerImpl() override;
......@@ -26,14 +28,19 @@ class ActivityManagerImpl : public ActivityManager,
void AddActivity(Activity* activity) override;
void RemoveActivity(Activity* activity) override;
void UpdateActivity(Activity* activity) override;
const ActivityList& GetActivityList() override;
Activity* GetActivityForWindow(aura::Window* window) override;
void AddObserver(ActivityManagerObserver* observer) override;
void RemoveObserver(ActivityManagerObserver* observer) override;
// views::WidgetObserver
void OnWidgetDestroying(views::Widget* widget) override;
private:
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
// aura::client::ActivationChangeObserver:
void OnWindowActivated(aura::Window* gained_active,
aura::Window* lost_active) override;
std::vector<Activity*> activities_;
ObserverList<ActivityManagerObserver> observers_;
......
......@@ -9,6 +9,7 @@
#include "athena/test/base/athena_test_base.h"
#include "athena/test/base/test_windows.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
namespace athena {
......@@ -58,4 +59,25 @@ TEST_F(ActivityManagerTest, GetActivityForWindow) {
EXPECT_EQ(nullptr, manager->GetActivityForWindow(window.get()));
}
TEST_F(ActivityManagerTest, ActivationBringsActivityToTop) {
ActivityManager* manager = ActivityManager::Get();
ActivityFactory* factory = ActivityFactory::Get();
Activity* activity1 =
factory->CreateWebActivity(nullptr, base::string16(), GURL());
Activity* activity2 =
factory->CreateWebActivity(nullptr, base::string16(), GURL());
activity1->GetWindow()->Show();
activity2->GetWindow()->Show();
ASSERT_EQ(2u, manager->GetActivityList().size());
EXPECT_EQ(activity2, manager->GetActivityList()[0]);
EXPECT_EQ(activity1, manager->GetActivityList()[1]);
wm::ActivateWindow(activity1->GetWindow());
ASSERT_EQ(2u, manager->GetActivityList().size());
EXPECT_EQ(activity1, manager->GetActivityList()[0]);
EXPECT_EQ(activity2, manager->GetActivityList()[1]);
}
} // namespace athena
......@@ -5,6 +5,8 @@
#ifndef ATHENA_ACTIVITY_PUBLIC_ACTIVITY_MANAGER_H_
#define ATHENA_ACTIVITY_PUBLIC_ACTIVITY_MANAGER_H_
#include <vector>
#include "athena/athena_export.h"
namespace aura {
......@@ -16,6 +18,8 @@ namespace athena {
class Activity;
class ActivityManagerObserver;
using ActivityList = std::vector<Activity*>;
// Manages a set of activities.
class ATHENA_EXPORT ActivityManager {
public:
......@@ -29,13 +33,17 @@ class ATHENA_EXPORT ActivityManager {
virtual void AddActivity(Activity* activity) = 0;
virtual void RemoveActivity(Activity* activity) = 0;
// Updates the UI when the task color/title changes.
virtual void UpdateActivity(Activity* activity) = 0;
// Returns a list of activities, sorted in their activation order (the most
// recently used activity is at the front of the returned list).
virtual const ActivityList& GetActivityList() = 0;
// Returns the activity that has a |window| as toplevel window, or
// nullptr if such activity does not exist.
virtual Activity* GetActivityForWindow(aura::Window* window) = 0;
// Updates the UI when the task color/title changes.
virtual void UpdateActivity(Activity* activity) = 0;
virtual void AddObserver(ActivityManagerObserver* observer) = 0;
virtual void RemoveObserver(ActivityManagerObserver* observer) = 0;
};
......
......@@ -20,6 +20,9 @@ class ATHENA_EXPORT ActivityManagerObserver {
// Called before an |activity| gets destroyed.
virtual void OnActivityEnding(Activity* activity) = 0;
// Called when the order of the activities in the list has changed.
virtual void OnActivityOrderChanged() = 0;
};
} // namespace athena
......
......@@ -25,6 +25,9 @@ void ActivityLifetimeTracker::OnActivityEnding(Activity* activity) {
deleted_activity_ = activity;
}
void ActivityLifetimeTracker::OnActivityOrderChanged() {
}
Activity* ActivityLifetimeTracker::GetNewActivityAndReset() {
Activity* activity = new_activity_;
new_activity_ = nullptr;
......
......@@ -17,11 +17,10 @@ class ActivityLifetimeTracker : public ActivityManagerObserver {
ActivityLifetimeTracker();
~ActivityLifetimeTracker() override;
// Called after an |activity| got created.
// ActivityManagerObserver:
void OnActivityStarted(Activity* activity) override;
// Called before an |activity| gets destroyed.
void OnActivityEnding(Activity* activity) override;
void OnActivityOrderChanged() override;
// Returns the newly created activity (if any) and resets its reference.
Activity* GetNewActivityAndReset();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment