OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "athena/content/app_activity_registry.h" | 5 #include "athena/content/app_activity_registry.h" |
6 | 6 |
7 #include "athena/activity/public/activity_manager.h" | 7 #include "athena/activity/public/activity_manager.h" |
8 #include "athena/content/app_activity.h" | 8 #include "athena/content/app_activity.h" |
9 #include "athena/content/app_activity_proxy.h" | 9 #include "athena/content/app_activity_proxy.h" |
10 #include "athena/content/public/app_registry.h" | 10 #include "athena/content/public/app_registry.h" |
11 #include "athena/extensions/public/extensions_delegate.h" | 11 #include "athena/extensions/public/extensions_delegate.h" |
12 #include "athena/resource_manager/public/resource_manager.h" | 12 #include "athena/resource_manager/public/resource_manager.h" |
13 #include "athena/wm/public/window_list_provider.h" | |
14 #include "athena/wm/public/window_manager.h" | 13 #include "athena/wm/public/window_manager.h" |
15 #include "base/bind.h" | 14 #include "base/bind.h" |
16 #include "base/location.h" | 15 #include "base/location.h" |
17 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
18 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
19 #include "ui/aura/window.h" | 18 #include "ui/aura/window.h" |
20 #include "ui/views/view.h" | 19 #include "ui/views/view.h" |
21 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
22 | 21 |
23 namespace athena { | 22 namespace athena { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 if (index >= activity_list_.size()) | 64 if (index >= activity_list_.size()) |
66 return nullptr; | 65 return nullptr; |
67 return activity_list_[index]; | 66 return activity_list_[index]; |
68 } | 67 } |
69 | 68 |
70 void AppActivityRegistry::Unload() { | 69 void AppActivityRegistry::Unload() { |
71 CHECK(!unloaded_activity_proxy_); | 70 CHECK(!unloaded_activity_proxy_); |
72 DCHECK(!activity_list_.empty()); | 71 DCHECK(!activity_list_.empty()); |
73 // In order to allow an entire application to unload we require that all of | 72 // In order to allow an entire application to unload we require that all of |
74 // its activities are marked as unloaded. | 73 // its activities are marked as unloaded. |
75 for (std::vector<AppActivity*>::iterator it = activity_list_.begin(); | 74 for (AppActivity* activity : activity_list_) { |
76 it != activity_list_.end(); ++it) { | 75 if (activity->GetCurrentState() != Activity::ACTIVITY_UNLOADED) |
77 if ((*it)->GetCurrentState() != Activity::ACTIVITY_UNLOADED) | |
78 return; | 76 return; |
79 } | 77 } |
80 | 78 |
81 // Create an activity proxy which can be used to re-activate the app. Insert | 79 // Create an activity proxy which can be used to re-activate the app. Insert |
82 // the proxy then into the activity stream at the location of the (newest) | 80 // the proxy then into the activity stream at the location of the (newest) |
83 // current activity. | 81 // current activity. |
84 unloaded_activity_proxy_ = new AppActivityProxy(GetMruActivity(), this); | 82 AppActivity* mru_activity = GetMruActivity(); |
85 ActivityManager::Get()->AddActivity(unloaded_activity_proxy_); | 83 CHECK(mru_activity); |
| 84 unloaded_activity_proxy_ = new AppActivityProxy(mru_activity, this); |
| 85 ScopedActivity removed_activity = |
| 86 ActivityManager::Get()->ReplaceActivity(mru_activity, |
| 87 unloaded_activity_proxy_); |
86 unloaded_activity_proxy_->GetWindow()->SetName("AppActivityProxy"); | 88 unloaded_activity_proxy_->GetWindow()->SetName("AppActivityProxy"); |
87 | 89 |
88 // This function can be called through an observer call. When that happens, | 90 if (!ExtensionsDelegate::Get(browser_context_)->UnloadApp(app_id_)) { |
89 // several activities will be closed / started. That can then cause a crash. | 91 removed_activity.reset(); |
90 // We postpone therefore the activity destruction till after the observer is | 92 while(!activity_list_.empty()) |
91 // done. | 93 Activity::Delete(activity_list_.back()); |
92 base::ThreadTaskRunnerHandle::Get()->PostTask( | 94 } |
93 FROM_HERE, | |
94 base::Bind(&AppActivityRegistry::DelayedUnload, base::Unretained(this))); | |
95 } | 95 } |
96 | 96 |
97 void AppActivityRegistry::ProxyDestroyed(AppActivityProxy* proxy) { | 97 void AppActivityRegistry::ProxyDestroyed(AppActivityProxy* proxy) { |
98 DCHECK_EQ(unloaded_activity_proxy_, proxy); | 98 DCHECK_EQ(unloaded_activity_proxy_, proxy); |
99 unloaded_activity_proxy_ = nullptr; | 99 unloaded_activity_proxy_ = nullptr; |
100 if (activity_list_.empty()) { | 100 if (activity_list_.empty()) { |
101 AppRegistry::Get()->RemoveAppActivityRegistry(this); | 101 AppRegistry::Get()->RemoveAppActivityRegistry(this); |
102 // |This| is gone now. | 102 // |This| is gone now. |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 void AppActivityRegistry::RestartApplication(AppActivityProxy* proxy) { | 106 void AppActivityRegistry::RestartApplication(AppActivityProxy* proxy) { |
107 DCHECK_EQ(unloaded_activity_proxy_, proxy); | 107 DCHECK_EQ(unloaded_activity_proxy_, proxy); |
108 // Restart the application. Note that the first created app window will make | 108 // Restart the application. Note that the first created app window will make |
109 // sure that the proxy gets deleted - after - the new activity got moved | 109 // sure that the proxy gets deleted - after - the new activity got moved |
110 // to the proxies activity location. | 110 // to the proxies activity location. |
111 ExtensionsDelegate::Get(browser_context_)->LaunchApp(app_id_); | 111 ExtensionsDelegate::Get(browser_context_)->LaunchApp(app_id_); |
112 } | 112 } |
113 | 113 |
114 void AppActivityRegistry::DelayedUnload() { | |
115 if (!ExtensionsDelegate::Get(browser_context_)->UnloadApp(app_id_)) { | |
116 while(!activity_list_.empty()) | |
117 Activity::Delete(activity_list_.back()); | |
118 } | |
119 } | |
120 | |
121 AppActivity* AppActivityRegistry::GetMruActivity() { | 114 AppActivity* AppActivityRegistry::GetMruActivity() { |
122 DCHECK(activity_list_.size()); | 115 DCHECK(activity_list_.size()); |
123 WindowListProvider* window_list_provider = | 116 const ActivityList& all_activities = |
124 WindowManager::Get()->GetWindowListProvider(); | 117 ActivityManager::Get()->GetActivityList(); |
125 const aura::Window::Windows& children = | 118 for (Activity* activity : all_activities) { |
126 window_list_provider->GetWindowList(); | 119 std::vector<AppActivity*>::const_iterator iter = |
127 // Find the first window in the container which is part of the application. | 120 std::find(activity_list_.begin(), activity_list_.end(), activity); |
128 for (aura::Window::Windows::const_iterator child_iterator = children.begin(); | 121 if (iter != activity_list_.end()) |
129 child_iterator != children.end(); ++child_iterator) { | 122 return *iter; |
130 for (std::vector<AppActivity*>::iterator app_iterator = | |
131 activity_list_.begin(); | |
132 app_iterator != activity_list_.end(); ++app_iterator) { | |
133 if (*child_iterator == (*app_iterator)->GetWindow()) | |
134 return *app_iterator; | |
135 } | |
136 } | 123 } |
137 NOTREACHED() << "The application does not get tracked by the mru list"; | 124 NOTREACHED() << "The application does not get tracked by the mru list"; |
138 return nullptr; | 125 return nullptr; |
139 } | 126 } |
140 | 127 |
141 } // namespace athena | 128 } // namespace athena |
OLD | NEW |