Chromium Code Reviews| 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 |