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