Chromium Code Reviews| Index: athena/content/web_activity.cc |
| diff --git a/athena/content/web_activity.cc b/athena/content/web_activity.cc |
| index 0385b47460f797f543e033690cf7167da9d038b9..041a161a9245c9e67591bb85b9d0037cf04ca0cf 100644 |
| --- a/athena/content/web_activity.cc |
| +++ b/athena/content/web_activity.cc |
| @@ -116,15 +116,57 @@ class WebActivityController : public AcceleratorHandler { |
| DISALLOW_COPY_AND_ASSIGN(WebActivityController); |
| }; |
| -// A web view for athena's web activity. |
| +} // namespace |
| + |
| +// A web view for athena's web activity. Note that AthenaWebView will create its |
| +// own content so that it can eject and reload it. |
| class AthenaWebView : public views::WebView { |
| public: |
| AthenaWebView(content::BrowserContext* context) |
| - : views::WebView(context), controller_(new WebActivityController(this)) {} |
| - virtual ~AthenaWebView() {} |
| + : views::WebView(context), controller_(new WebActivityController(this)) { |
| + // We create the first web contents ourselves to allow us to replace it |
| + // later on. |
| + SetWebContents(content::WebContents::Create( |
| + content::WebContents::CreateParams(context))); |
| + // TODO(skuhne): Add content observer to detect renderer crash and set |
| + // content status to unloaded if that happens. |
| + } |
| + virtual ~AthenaWebView() { |
| + // |WebView| does not own the content, so we need to destroy it here. |
| + content::WebContents* current_contents = GetWebContents(); |
| + SetWebContents(NULL); |
| + delete current_contents; |
| + } |
| void InstallAccelerators() { controller_->InstallAccelerators(); } |
| + void EvictContent() { |
| + content::WebContents* old_contents = GetWebContents(); |
| + evicted_web_contents_.reset( |
| + content::WebContents::Create(content::WebContents::CreateParams( |
| + old_contents->GetBrowserContext()))); |
| + evicted_web_contents_->GetController().CopyStateFrom( |
| + old_contents->GetController()); |
| + SetWebContents(content::WebContents::Create( |
| + content::WebContents::CreateParams(old_contents->GetBrowserContext()))); |
| + delete old_contents; |
| + // As soon as the new contents becomes visible, it should reload. |
| + // TODO(skuhne): This breaks script connections with other activities. |
| + // Even though this is the same technique as used by the TabStripModel, |
| + // we might want to address this cleaner since we are more likely to |
| + // run into this state. by unloading. |
| + } |
| + |
| + void ReloadContent() { |
| + CHECK(evicted_web_contents_.get()); |
| + content::WebContents* null_contents = GetWebContents(); |
| + SetWebContents(evicted_web_contents_.release()); |
| + delete null_contents; |
| + } |
| + |
| + // Check if the content got evicted. |
| + 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!
|
| + |
| private: |
| // WebContentsDelegate: |
| virtual bool PreHandleKeyboardEvent( |
| @@ -143,26 +185,95 @@ class AthenaWebView : public views::WebView { |
| scoped_ptr<WebActivityController> controller_; |
| + // If the activity got evicted, this is the web content which holds the known |
| + // state of the content before eviction. |
| + scoped_ptr<content::WebContents> evicted_web_contents_; |
| + |
|
oshima
2014/07/11 18:02:59
remove extra new line
Mr4D (OOO till 08-26)
2014/07/11 22:38:08
Done.
|
| + |
| DISALLOW_COPY_AND_ASSIGN(AthenaWebView); |
| }; |
| -} // namespace |
| - |
| WebActivity::WebActivity(content::BrowserContext* browser_context, |
| const GURL& url) |
| - : browser_context_(browser_context), url_(url), web_view_(NULL) { |
| + : browser_context_(browser_context), |
| + url_(url), |
| + web_view_(NULL), |
| + last_requested_state_(ACTIVITY_UNLOAD) { |
| } |
| WebActivity::~WebActivity() { |
| + // It is not required to change the activity state to UNLOADED - unless we |
| + // would add state observers. |
| } |
| ActivityViewModel* WebActivity::GetActivityViewModel() { |
| return this; |
| } |
| +void WebActivity::SetCurrentState(Activity::ActivityStateTransition state) { |
| + switch (state) { |
| + case ACTIVITY_LOAD: |
| + // By clearing the overview mode image we allow the content to be shown. |
| + overview_mode_image_ = gfx::ImageSkia(); |
| + if (web_view_->IsContentEvicted()) { |
| + DCHECK_EQ(ACTIVITY_UNLOAD, last_requested_state_); |
| + web_view_->ReloadContent(); |
| + } |
| + Observe(web_view_->GetWebContents()); |
| + break; |
| + case ACTIVITY_DEEP_SLEEP_1: |
| + DCHECK_EQ(ACTIVITY_LOAD, last_requested_state_); |
| + // TODO(skuhne): Do this. As soon as the new resource management is |
| + // agreed upon - or remove otherwise. |
| + break; |
| + case ACTIVITY_DEEP_SLEEP_2: |
| + DCHECK_EQ(ACTIVITY_DEEP_SLEEP_1, last_requested_state_); |
| + // TODO(skuhne): Do this. As soon as the new resource management is |
| + // agreed upon - or remove otherwise. |
| + break; |
| + case ACTIVITY_UNLOAD: |
| + DCHECK_NE(ACTIVITY_UNLOAD, last_requested_state_); |
| + Observe(NULL); |
| + web_view_->EvictContent(); |
| + break; |
| + } |
| + // Remember the last requested state. |
| + last_requested_state_ = state; |
| +} |
| + |
| +Activity::ActivityState WebActivity::GetCurrentState() { |
| + if (!web_view_ || web_view_->IsContentEvicted()) { |
| + DCHECK_EQ(ACTIVITY_UNLOAD, last_requested_state_); |
| + return ACTIVITY_STATE_UNLOADED; |
| + } |
| + |
| + switch(last_requested_state_) { |
| + case ACTIVITY_LOAD: |
| + if (web_view_->IsDrawn()) |
| + return ACTIVITY_STATE_VISIBLE; |
| + /* |
| + // TODO(skuhne): AudioStreamMonitor is currently a part of Chrome and |
| + // needs to be moved some levels up. |
| + WebContents* contents = web_view_-> |
| + AudioStreamMonitor* const audio_stream_monitor = |
| + AudioStreamMonitor::FromWebContents(contents); |
| + if (audio_stream_monitor && audio_stream_monitor->WasRecentlyAudible()) |
| + return ACTIVITY_STATE_BACKGROUND_ACTIVE; |
| + */ |
| + return ACTIVITY_STATE_HIDDEN; |
| + case ACTIVITY_DEEP_SLEEP_1: |
| + return ACTIVITY_STATE_DEEP_SLEEP_1; |
| + case ACTIVITY_DEEP_SLEEP_2: |
| + return ACTIVITY_STATE_DEEP_SLEEP_2; |
| + case ACTIVITY_UNLOAD: |
| + return ACTIVITY_STATE_UNLOADED; |
| + } |
| + return ACTIVITY_STATE_UNLOADED; |
| +} |
| + |
| void WebActivity::Init() { |
| DCHECK(web_view_); |
| - static_cast<AthenaWebView*>(web_view_)->InstallAccelerators(); |
| + web_view_->InstallAccelerators(); |
| } |
| SkColor WebActivity::GetRepresentativeColor() { |
| @@ -178,11 +289,21 @@ views::View* WebActivity::GetContentsView() { |
| if (!web_view_) { |
| web_view_ = new AthenaWebView(browser_context_); |
| web_view_->LoadInitialURL(url_); |
| - Observe(web_view_->GetWebContents()); |
| + SetCurrentState(ACTIVITY_LOAD); |
| + // Reset the overview mode image. |
| + overview_mode_image_ = gfx::ImageSkia(); |
| } |
| return web_view_; |
| } |
| +void WebActivity::CreateOverviewModeImage() { |
| + // TODO(skuhne): Create an overview. |
| +} |
| + |
| +gfx::ImageSkia WebActivity::GetOverviewModeImage() { |
| + return overview_mode_image_; |
| +} |
| + |
| void WebActivity::TitleWasSet(content::NavigationEntry* entry, |
| bool explicit_set) { |
| ActivityManager::Get()->UpdateActivity(this); |