Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / athena / content / app_activity.cc
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