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); |