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/web_activity.h" | 5 #include "athena/content/web_activity.h" |
6 | 6 |
7 #include "athena/activity/public/activity_manager.h" | 7 #include "athena/activity/public/activity_manager.h" |
8 #include "athena/input/public/accelerator_manager.h" | 8 #include "athena/input/public/accelerator_manager.h" |
9 #include "content/public/browser/native_web_keyboard_event.h" | 9 #include "content/public/browser/native_web_keyboard_event.h" |
10 #include "content/public/browser/web_contents.h" | 10 #include "content/public/browser/web_contents.h" |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 } | 109 } |
110 | 110 |
111 views::WebView* web_view_; | 111 views::WebView* web_view_; |
112 bool reserved_accelerator_enabled_; | 112 bool reserved_accelerator_enabled_; |
113 scoped_ptr<AcceleratorManager> accelerator_manager_; | 113 scoped_ptr<AcceleratorManager> accelerator_manager_; |
114 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; | 114 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; |
115 | 115 |
116 DISALLOW_COPY_AND_ASSIGN(WebActivityController); | 116 DISALLOW_COPY_AND_ASSIGN(WebActivityController); |
117 }; | 117 }; |
118 | 118 |
119 // A web view for athena's web activity. | 119 // A web view for athena's web activity. Note that AthenaWebView will create its |
120 // own content so that it can eject and reload it. | |
120 class AthenaWebView : public views::WebView { | 121 class AthenaWebView : public views::WebView { |
121 public: | 122 public: |
122 AthenaWebView(content::BrowserContext* context) | 123 AthenaWebView(content::BrowserContext* context) |
123 : views::WebView(context), controller_(new WebActivityController(this)) {} | 124 : views::WebView(context), controller_(new WebActivityController(this)) { |
124 virtual ~AthenaWebView() {} | 125 // We create the first web contents ourselves to allow us to replace it |
126 // later on. | |
127 SetWebContents(WebContents::Create(WebContents::CreateParams(context))); | |
128 // TODO(skuhne): Add content observer to detect renderer crash and set | |
129 // content status to unloaded if that happens. | |
130 } | |
131 virtual ~AthenaWebView() { | |
132 // |WebView| does not own the content, so we need to destroy it here. | |
133 WebContents* current_contents = web_view_->GetWebContents(); | |
134 web_view_->SetWebContents(NULL); | |
135 delete current_contents; | |
136 } | |
125 | 137 |
126 void InstallAccelerators() { controller_->InstallAccelerators(); } | 138 void InstallAccelerators() { controller_->InstallAccelerators(); } |
127 | 139 |
140 void EvictContent() { | |
141 WebContents* old_contents = GetWebContents(); | |
142 evicted_web_contents_.reset( | |
143 WebContents::Create(WebContents::CreateParams( | |
144 old_contents->profile()))); | |
145 evicted_web_contents_->GetController().CopyStateFrom( | |
146 old_contents->GetController()); | |
147 SetContents(WebContents::Create(WebContents::CreateParams( | |
148 old_contents->profile()))); | |
149 delete old_contents; | |
150 // As soon as the new contents becomes visible, it should reload. | |
151 // TODO(skuhne): This breaks script connections with other activities. | |
152 // Even though this is the same technique as used by the TabStripModel, | |
153 // we might want to address this cleaner since we are more likely to | |
154 // run into this state. by unloading. | |
155 } | |
156 | |
157 void ReloadContent() { | |
158 CHECK(evicted_web_contents_.get()); | |
159 WebContents* null_contents = GetWebContents(); | |
160 SetContents(evicted_web_contents_.release()); | |
161 delete null_contents; | |
162 } | |
163 | |
164 // Check if the content got evicted. | |
165 bool IsContentEvicted() { return !evicted_web_contents_.get(); } | |
166 | |
128 private: | 167 private: |
129 // WebContentsDelegate: | 168 // WebContentsDelegate: |
130 virtual bool PreHandleKeyboardEvent( | 169 virtual bool PreHandleKeyboardEvent( |
131 content::WebContents* source, | 170 content::WebContents* source, |
132 const content::NativeWebKeyboardEvent& event, | 171 const content::NativeWebKeyboardEvent& event, |
133 bool* is_keyboard_shortcut) OVERRIDE { | 172 bool* is_keyboard_shortcut) OVERRIDE { |
134 return controller_->PreHandleKeyboardEvent( | 173 return controller_->PreHandleKeyboardEvent( |
135 source, event, is_keyboard_shortcut); | 174 source, event, is_keyboard_shortcut); |
136 } | 175 } |
137 | 176 |
138 virtual void HandleKeyboardEvent( | 177 virtual void HandleKeyboardEvent( |
139 content::WebContents* source, | 178 content::WebContents* source, |
140 const content::NativeWebKeyboardEvent& event) OVERRIDE { | 179 const content::NativeWebKeyboardEvent& event) OVERRIDE { |
141 controller_->HandleKeyboardEvent(source, event); | 180 controller_->HandleKeyboardEvent(source, event); |
142 } | 181 } |
143 | 182 |
144 scoped_ptr<WebActivityController> controller_; | 183 scoped_ptr<WebActivityController> controller_; |
145 | 184 |
185 // If the activity got evicted, this is the web content which holds the known | |
186 // state of the content before eviction. | |
187 scoped_ptr<content::WebContents> evicted_web_contents_; | |
188 | |
189 | |
146 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); | 190 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); |
147 }; | 191 }; |
148 | 192 |
149 } // namespace | 193 } // namespace |
150 | 194 |
151 WebActivity::WebActivity(content::BrowserContext* browser_context, | 195 WebActivity::WebActivity(content::BrowserContext* browser_context, |
152 const GURL& url) | 196 const GURL& url) |
153 : browser_context_(browser_context), url_(url), web_view_(NULL) { | 197 : browser_context_(browser_context), |
198 url_(url), | |
199 web_view_(NULL), | |
200 last_requested_state_(ACTIVITY_UNLOAD) { | |
154 } | 201 } |
155 | 202 |
156 WebActivity::~WebActivity() { | 203 WebActivity::~WebActivity() { |
204 // It is not required to change the activity state to UNLOADED - unless we | |
205 // would add state observers. | |
157 } | 206 } |
158 | 207 |
159 ActivityViewModel* WebActivity::GetActivityViewModel() { | 208 ActivityViewModel* WebActivity::GetActivityViewModel() { |
160 return this; | 209 return this; |
161 } | 210 } |
162 | 211 |
212 void WebActivity::SetCurrentState(ActivityStateTranstion state) { | |
213 switch (state) { | |
214 case ACTIVITY_LOAD: | |
215 // By clearing the overview mode image we allow the content to be shown. | |
216 overview_mode_image_ = gfx::ImageSkia(); | |
217 if (web_view_->IsContentEvicted()) { | |
218 DCHECK_EQ(ACTIVITY_UNLOAD, last_requested_state_); | |
219 web_view_->ReloadContent(); | |
220 } | |
221 Observe(web_view_->GetWebContents()); | |
222 break; | |
223 case ACTIVITY_DEEP_SLEEP_1: | |
224 DCHECK_EQ(ACTIVITY_LOAD, last_requested_state_); | |
225 // TODO(skuhne): Do this. As soon as the new resource management is | |
226 // agreed upon - or remove otherwise. | |
227 break; | |
228 case ACTIVITY_DEEP_SLEEP_2: | |
229 DCHECK_EQ(ACTIVITY_DEEP_SLEEP_1, last_requested_state_); | |
230 // TODO(skuhne): Do this. As soon as the new resource management is | |
231 // agreed upon - or remove otherwise. | |
232 break; | |
233 case ACTIVITY_UNLOAD: | |
234 DCHECK_NE(ACTIVITY_UNLOAD, last_requested_state_); | |
235 Observe(NULL); | |
236 web_view_->EvictContent(); | |
Jun Mukai
2014/06/26 19:48:01
Can we just discard web_view_ itself instead of im
Mr4D (OOO till 08-26)
2014/06/26 20:25:39
Well... WebView is used by another instance (the o
Jun Mukai
2014/06/26 21:45:26
Okay, doing the same approach as TabModel sounds p
| |
237 break; | |
238 } | |
239 // Remember the last requested state. | |
240 last_requested_state_ = state; | |
241 } | |
242 | |
243 ActivityState WebActivity::GetCurrentState() { | |
244 if (!web_view_ || web_view_->IsContentEvicted()) { | |
245 DCHECK_EQ(ACTIVITY_UNLOAD, last_requested_state_); | |
246 return ACTIVITY_STATE_UNLOADED; | |
247 } | |
248 | |
249 switch(last_requested_state_) { | |
250 case ACTIVITY_LOAD: | |
251 if (web_view_->IsDrawn()) | |
252 return ACTIVITY_STATE_VISIBLE; | |
253 /* | |
254 // TODO(skuhne): AudioStreamMonitor is currently a part of Chrome and | |
255 // needs to be moved some levels up. | |
256 WebContents* contents = web_view_-> | |
257 AudioStreamMonitor* const audio_stream_monitor = | |
258 AudioStreamMonitor::FromWebContents(contents); | |
259 if (audio_stream_monitor && audio_stream_monitor->WasRecentlyAudible()) | |
260 return ACTIVITY_STATE_ACTIVE; | |
261 */ | |
262 return ACTIVITY_STATE_HIDDEN; | |
263 case ACTIVITY_DEEP_SLEEP_1: | |
264 return ACTIVITY_DEEP_SLEEP_1; | |
265 case ACTIVITY_DEEP_SLEEP_2: | |
266 return ACTIVITY_DEEP_SLEEP_2; | |
267 case ACTIVITY_UNLOAD: | |
268 return ACTIVITY_STATE_UNLOADED; | |
269 } | |
270 } | |
271 | |
163 void WebActivity::Init() { | 272 void WebActivity::Init() { |
164 DCHECK(web_view_); | 273 DCHECK(web_view_); |
165 static_cast<AthenaWebView*>(web_view_)->InstallAccelerators(); | 274 web_view_->InstallAccelerators(); |
166 } | 275 } |
167 | 276 |
168 SkColor WebActivity::GetRepresentativeColor() { | 277 SkColor WebActivity::GetRepresentativeColor() { |
169 // TODO(sad): Compute the color from the favicon. | 278 // TODO(sad): Compute the color from the favicon. |
170 return SK_ColorGRAY; | 279 return SK_ColorGRAY; |
171 } | 280 } |
172 | 281 |
173 base::string16 WebActivity::GetTitle() { | 282 base::string16 WebActivity::GetTitle() { |
174 return web_view_->GetWebContents()->GetTitle(); | 283 return web_view_->GetWebContents()->GetTitle(); |
175 } | 284 } |
176 | 285 |
177 views::View* WebActivity::GetContentsView() { | 286 views::View* WebActivity::GetContentsView() { |
178 if (!web_view_) { | 287 if (!web_view_) { |
179 web_view_ = new AthenaWebView(browser_context_); | 288 web_view_ = new AthenaWebView(browser_context_); |
180 web_view_->LoadInitialURL(url_); | 289 web_view_->LoadInitialURL(url_); |
181 Observe(web_view_->GetWebContents()); | 290 SetCurrentState(ACTIVITY_LOAD); |
291 // Reset the overview mode image. | |
292 overview_mode_image_ = gfx::ImageSkia(); | |
182 } | 293 } |
183 return web_view_; | 294 return web_view_; |
184 } | 295 } |
185 | 296 |
186 void WebActivity::TitleWasSet(content::NavigationEntry* entry, | 297 void WebActivity::TitleWasSet(content::NavigationEntry* entry, |
187 bool explicit_set) { | 298 bool explicit_set) { |
188 ActivityManager::Get()->UpdateActivity(this); | 299 ActivityManager::Get()->UpdateActivity(this); |
189 } | 300 } |
190 | 301 |
191 void WebActivity::DidUpdateFaviconURL( | 302 void WebActivity::DidUpdateFaviconURL( |
192 const std::vector<content::FaviconURL>& candidates) { | 303 const std::vector<content::FaviconURL>& candidates) { |
193 ActivityManager::Get()->UpdateActivity(this); | 304 ActivityManager::Get()->UpdateActivity(this); |
194 } | 305 } |
195 | 306 |
196 } // namespace athena | 307 } // namespace athena |
OLD | NEW |