OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "athena/content/app_activity.h" | |
6 | |
7 #include "athena/activity/public/activity_manager.h" | |
8 #include "athena/activity/public/activity_view.h" | |
9 #include "athena/content/app_activity_registry.h" | |
10 #include "athena/content/content_proxy.h" | |
11 #include "athena/content/media_utils.h" | |
12 #include "athena/content/public/app_registry.h" | |
13 #include "athena/wm/public/window_list_provider.h" | |
14 #include "athena/wm/public/window_manager.h" | |
15 #include "content/public/browser/web_contents.h" | |
16 #include "ui/aura/window.h" | |
17 #include "ui/views/controls/webview/webview.h" | |
18 #include "ui/views/widget/widget.h" | |
19 #include "ui/wm/core/window_util.h" | |
20 | |
21 namespace athena { | |
22 | |
23 // TODO(mukai): specifies the same accelerators of WebActivity. | |
24 AppActivity::AppActivity(const std::string& app_id, views::WebView* web_view) | |
25 : app_id_(app_id), | |
26 web_view_(web_view), | |
27 current_state_(ACTIVITY_UNLOADED), | |
28 app_activity_registry_(nullptr), | |
29 activity_view_(nullptr) { | |
30 Observe(web_view->GetWebContents()); | |
31 } | |
32 | |
33 scoped_ptr<ContentProxy> AppActivity::GetContentProxy() { | |
34 // Note: After this call, the content is still valid because the contents | |
35 // destruction will destroy this |AppActivity| object. | |
36 if (content_proxy_.get()) | |
37 content_proxy_->OnPreContentDestroyed(); | |
38 return content_proxy_.Pass(); | |
39 } | |
40 | |
41 ActivityViewModel* AppActivity::GetActivityViewModel() { | |
42 return this; | |
43 } | |
44 | |
45 void AppActivity::SetCurrentState(Activity::ActivityState state) { | |
46 DCHECK_NE(state, current_state_); | |
47 ActivityState current_state = current_state_; | |
48 // Remember the last requested state now so that a call to GetCurrentState() | |
49 // returns the new state. | |
50 current_state_ = state; | |
51 | |
52 switch (state) { | |
53 case ACTIVITY_VISIBLE: | |
54 HideContentProxy(); | |
55 return; | |
56 case ACTIVITY_INVISIBLE: | |
57 if (current_state == ACTIVITY_VISIBLE) | |
58 ShowContentProxy(); | |
59 break; | |
60 case ACTIVITY_BACKGROUND_LOW_PRIORITY: | |
61 DCHECK(ACTIVITY_VISIBLE == current_state || | |
62 ACTIVITY_INVISIBLE == current_state); | |
63 // TODO(skuhne): Do this. | |
64 break; | |
65 case ACTIVITY_PERSISTENT: | |
66 DCHECK_EQ(ACTIVITY_BACKGROUND_LOW_PRIORITY, current_state); | |
67 // TODO(skuhne): Do this. | |
68 break; | |
69 case ACTIVITY_UNLOADED: | |
70 DCHECK_NE(ACTIVITY_UNLOADED, current_state); | |
71 // This will cause the application to shut down, close its windows and | |
72 // delete this object. Instead a |AppActivityProxy| will be created as | |
73 // place holder. | |
74 if (app_activity_registry_) | |
75 app_activity_registry_->Unload(); | |
76 break; | |
77 } | |
78 } | |
79 | |
80 Activity::ActivityState AppActivity::GetCurrentState() { | |
81 DCHECK(web_view_ || ACTIVITY_UNLOADED == current_state_); | |
82 return current_state_; | |
83 } | |
84 | |
85 bool AppActivity::IsVisible() { | |
86 return web_view_ && | |
87 web_view_->visible() && | |
88 current_state_ != ACTIVITY_UNLOADED; | |
89 } | |
90 | |
91 Activity::ActivityMediaState AppActivity::GetMediaState() { | |
92 return current_state_ == ACTIVITY_UNLOADED ? | |
93 Activity::ACTIVITY_MEDIA_STATE_NONE : | |
94 GetActivityMediaState(GetWebContents()); | |
95 } | |
96 | |
97 aura::Window* AppActivity::GetWindow() { | |
98 return web_view_ && web_view_->GetWidget() | |
99 ? web_view_->GetWidget()->GetNativeWindow() | |
100 : nullptr; | |
101 } | |
102 | |
103 content::WebContents* AppActivity::GetWebContents() { | |
104 return !web_view_ ? nullptr : web_view_->GetWebContents(); | |
105 } | |
106 | |
107 void AppActivity::Init() { | |
108 // Before we remove the proxy, we have to register the activity and | |
109 // initialize its to move it to the proper activity list location. | |
110 RegisterActivity(); | |
111 | |
112 DCHECK(app_activity_registry_); | |
113 Activity* app_proxy = app_activity_registry_->unloaded_activity_proxy(); | |
114 if (app_proxy) { | |
115 // Note: At this time the |AppActivity| did not get registered to the | |
116 // |ResourceManager| - so we can move it around if needed. | |
117 WindowListProvider* window_list_provider = | |
118 WindowManager::Get()->GetWindowListProvider(); | |
119 // TODO(skuhne): After the decision is made how we want to handle visibility | |
120 // transitions (issue 421680) this code might change. | |
121 // If the proxy was the active window, its deletion will cause a window | |
122 // reordering since the next activatable window in line will move up to the | |
123 // front. Since the application window is still hidden at this time, it is | |
124 // not yet activatable and the window behind it will move to the front. | |
125 if (wm::IsActiveWindow(app_proxy->GetWindow())) { | |
126 // Delete the proxy window first and then move the new window to the top | |
127 // of the stack, replacing the proxy window. Note that by deleting the | |
128 // proxy the activation will change to the next (activatable) object and | |
129 // thus we have to move the window in front at the end. | |
130 Activity::Delete(app_proxy); | |
131 if (GetWindow() != window_list_provider->GetWindowList().back()) { | |
132 window_list_provider->StackWindowFrontOf( | |
133 GetWindow(), | |
134 window_list_provider->GetWindowList().back()); | |
135 } | |
136 } else { | |
137 // The app window goes in front of the proxy window (we need to first | |
138 // place the window before we can delete it). | |
139 window_list_provider->StackWindowFrontOf(GetWindow(), | |
140 app_proxy->GetWindow()); | |
141 Activity::Delete(app_proxy); | |
142 } | |
143 // The proxy should now be deleted. | |
144 DCHECK(!app_activity_registry_->unloaded_activity_proxy()); | |
145 } | |
146 | |
147 // Make sure the content gets properly shown. | |
148 if (current_state_ == ACTIVITY_VISIBLE) { | |
149 HideContentProxy(); | |
150 } else if (current_state_ == ACTIVITY_INVISIBLE) { | |
151 ShowContentProxy(); | |
152 } else { | |
153 // If not previously specified, we change the state now to invisible.. | |
154 SetCurrentState(ACTIVITY_INVISIBLE); | |
155 } | |
156 } | |
157 | |
158 SkColor AppActivity::GetRepresentativeColor() const { | |
159 // TODO(sad): Compute the color from the favicon. | |
160 return SK_ColorGRAY; | |
161 } | |
162 | |
163 base::string16 AppActivity::GetTitle() const { | |
164 return web_view_->GetWebContents()->GetTitle(); | |
165 } | |
166 | |
167 gfx::ImageSkia AppActivity::GetIcon() const { | |
168 return gfx::ImageSkia(); | |
169 } | |
170 | |
171 void AppActivity::SetActivityView(ActivityView* view) { | |
172 DCHECK(!activity_view_); | |
173 activity_view_ = view; | |
174 } | |
175 | |
176 bool AppActivity::UsesFrame() const { | |
177 return false; | |
178 } | |
179 | |
180 views::View* AppActivity::GetContentsView() { | |
181 return web_view_; | |
182 } | |
183 | |
184 gfx::ImageSkia AppActivity::GetOverviewModeImage() { | |
185 if (content_proxy_.get()) | |
186 return content_proxy_->GetContentImage(); | |
187 return gfx::ImageSkia(); | |
188 } | |
189 | |
190 void AppActivity::PrepareContentsForOverview() { | |
191 // Turn on fast resizing to avoid re-laying out the web contents when | |
192 // entering / exiting overview mode and the content is visible. | |
193 if (!content_proxy_.get()) | |
194 web_view_->SetFastResize(true); | |
195 } | |
196 | |
197 void AppActivity::ResetContentsView() { | |
198 // Turn on fast resizing to avoid re-laying out the web contents when | |
199 // entering / exiting overview mode and the content is visible. | |
200 if (!content_proxy_.get()) { | |
201 web_view_->SetFastResize(false); | |
202 web_view_->Layout(); | |
203 } | |
204 } | |
205 | |
206 AppActivity::AppActivity(const std::string& app_id) | |
207 : app_id_(app_id), | |
208 web_view_(nullptr), | |
209 current_state_(ACTIVITY_UNLOADED), | |
210 app_activity_registry_(nullptr), | |
211 activity_view_(nullptr) { | |
212 } | |
213 | |
214 AppActivity::~AppActivity() { | |
215 // If this activity is registered, we unregister it now. | |
216 if (app_activity_registry_) | |
217 app_activity_registry_->UnregisterAppActivity(this); | |
218 } | |
219 | |
220 void AppActivity::TitleWasSet(content::NavigationEntry* entry, | |
221 bool explicit_set) { | |
222 if (activity_view_) | |
223 activity_view_->UpdateTitle(); | |
224 } | |
225 | |
226 void AppActivity::DidUpdateFaviconURL( | |
227 const std::vector<content::FaviconURL>& candidates) { | |
228 if (activity_view_) | |
229 activity_view_->UpdateIcon(); | |
230 } | |
231 | |
232 // Register an |activity| with an application. | |
233 // Note: This should only get called once for an |app_window| of the | |
234 // |activity|. | |
235 void AppActivity::RegisterActivity() { | |
236 content::WebContents* web_contents = web_view_->GetWebContents(); | |
237 AppRegistry* app_registry = AppRegistry::Get(); | |
238 // Get the application's registry. | |
239 app_activity_registry_ = app_registry->GetAppActivityRegistry( | |
240 app_id_, web_contents->GetBrowserContext()); | |
241 DCHECK(app_activity_registry_); | |
242 // Register the activity. | |
243 app_activity_registry_->RegisterAppActivity(this); | |
244 } | |
245 | |
246 void AppActivity::HideContentProxy() { | |
247 content_proxy_.reset(); | |
248 } | |
249 | |
250 void AppActivity::ShowContentProxy() { | |
251 if (!content_proxy_.get() && web_view_) | |
252 content_proxy_.reset(new ContentProxy(web_view_)); | |
253 } | |
254 | |
255 } // namespace athena | |
OLD | NEW |