// Copyright 2014 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. #include "athena/activity/activity_manager_impl.h" #include #include "athena/activity/activity_widget_delegate.h" #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 { namespace { ActivityManager* instance = nullptr; views::Widget* CreateWidget(Activity* activity) { aura::Window* window = activity->GetWindow(); views::Widget* widget = window ? views::Widget::GetWidgetForNativeView(window) : nullptr; if (widget) return widget; widget = new views::Widget; views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); params.delegate = new ActivityWidgetDelegate(activity->GetActivityViewModel()); widget->Init(params); return widget; } views::Widget* GetWidget(Activity* activity) { CHECK(activity); CHECK(activity->GetWindow()); return views::Widget::GetWidgetForNativeWindow(activity->GetWindow()); } } // namespace 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()); CHECK_EQ(this, instance); instance = nullptr; } void ActivityManagerImpl::AddActivity(Activity* activity) { CHECK(activities_.end() == std::find(activities_.begin(), activities_.end(), activity)); activities_.insert(activities_.begin(), activity); views::Widget* widget = CreateWidget(activity); widget->GetNativeView()->AddObserver(this); activity->GetActivityViewModel()->Init(); FOR_EACH_OBSERVER(ActivityManagerObserver, observers_, OnActivityStarted(activity)); } void ActivityManagerImpl::RemoveActivity(Activity* activity) { std::vector::iterator find = std::find(activities_.begin(), activities_.end(), activity); DCHECK(find != activities_.end()); if (find != activities_.end()) { FOR_EACH_OBSERVER( ActivityManagerObserver, observers_, OnActivityEnding(activity)); activities_.erase(find); views::Widget* widget = GetWidget(activity); widget->GetNativeView()->RemoveObserver(this); widget->Close(); } } const ActivityList& ActivityManagerImpl::GetActivityList() { return activities_; } Activity* ActivityManagerImpl::GetActivityForWindow(aura::Window* window) { struct Matcher { Matcher(aura::Window* w) : window(w) {} bool operator()(Activity* activity) { return activity->GetWindow() == window; } aura::Window* window; }; std::vector::iterator iter = std::find_if(activities_.begin(), activities_.end(), Matcher(window)); return iter != activities_.end() ? *iter : nullptr; } void ActivityManagerImpl::AddObserver(ActivityManagerObserver* observer) { observers_.AddObserver(observer); } void ActivityManagerImpl::RemoveObserver(ActivityManagerObserver* observer) { observers_.RemoveObserver(observer); } void ActivityManagerImpl::OnWindowDestroying(aura::Window* window) { Activity* activity = GetActivityForWindow(window); if (activity) { 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(); CHECK(instance); return instance; } ActivityManager* ActivityManager::Get() { return instance; } void ActivityManager::Shutdown() { CHECK(instance); delete instance; } } // namespace athena