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 const bool IsContentEvicted() { return !!evicted_web_contents_.get(); } |
| 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 |
146 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); | 192 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); |
147 }; | 193 }; |
148 | 194 |
149 } // namespace | |
150 | |
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), | 197 : browser_context_(browser_context), |
154 url_(url), | 198 url_(url), |
155 web_view_(NULL) { | 199 web_view_(NULL), |
| 200 current_state_(ACTIVITY_UNLOADED) { |
156 } | 201 } |
157 | 202 |
158 WebActivity::~WebActivity() { | 203 WebActivity::~WebActivity() { |
| 204 // It is not required to change the activity state to UNLOADED - unless we |
| 205 // would add state observers. |
159 } | 206 } |
160 | 207 |
161 ActivityViewModel* WebActivity::GetActivityViewModel() { | 208 ActivityViewModel* WebActivity::GetActivityViewModel() { |
162 return this; | 209 return this; |
163 } | 210 } |
164 | 211 |
| 212 void WebActivity::SetCurrentState(Activity::ActivityState state) { |
| 213 switch (state) { |
| 214 case ACTIVITY_VISIBLE: |
| 215 // Fall through (for the moment). |
| 216 case ACTIVITY_INVISIBLE: |
| 217 // By clearing the overview mode image we allow the content to be shown. |
| 218 overview_mode_image_ = gfx::ImageSkia(); |
| 219 if (web_view_->IsContentEvicted()) { |
| 220 DCHECK_EQ(ACTIVITY_UNLOADED, current_state_); |
| 221 web_view_->ReloadContent(); |
| 222 } |
| 223 Observe(web_view_->GetWebContents()); |
| 224 break; |
| 225 case ACTIVITY_BACKGROUND_LOW_PRIORITY: |
| 226 DCHECK(ACTIVITY_VISIBLE == current_state_ || |
| 227 ACTIVITY_INVISIBLE == current_state_); |
| 228 // TODO(skuhne): Do this. |
| 229 break; |
| 230 case ACTIVITY_PERSISTENT: |
| 231 DCHECK_EQ(ACTIVITY_BACKGROUND_LOW_PRIORITY, current_state_); |
| 232 // TODO(skuhne): Do this. As soon as the new resource management is |
| 233 // agreed upon - or remove otherwise. |
| 234 break; |
| 235 case ACTIVITY_UNLOADED: |
| 236 DCHECK_NE(ACTIVITY_UNLOADED, current_state_); |
| 237 Observe(NULL); |
| 238 web_view_->EvictContent(); |
| 239 break; |
| 240 } |
| 241 // Remember the last requested state. |
| 242 current_state_ = state; |
| 243 } |
| 244 |
| 245 Activity::ActivityState WebActivity::GetCurrentState() { |
| 246 if (!web_view_ || web_view_->IsContentEvicted()) { |
| 247 DCHECK_EQ(ACTIVITY_UNLOADED, current_state_); |
| 248 return ACTIVITY_UNLOADED; |
| 249 } |
| 250 // TODO(skuhne): This should be controlled by an observer and should not |
| 251 // reside here. |
| 252 if (IsVisible() && current_state_ != ACTIVITY_VISIBLE) |
| 253 SetCurrentState(ACTIVITY_VISIBLE); |
| 254 // Note: If the activity is not visible it does not necessarily mean that it |
| 255 // does not have GPU compositor resources (yet). |
| 256 |
| 257 return current_state_; |
| 258 } |
| 259 |
| 260 bool WebActivity::IsVisible() { |
| 261 return web_view_ && web_view_->IsDrawn(); |
| 262 } |
| 263 |
| 264 Activity::ActivityMediaState WebActivity::GetMediaState() { |
| 265 // TODO(skuhne): The function GetTabMediaStateForContents(WebContents), |
| 266 // and the AudioStreamMonitor needs to be moved from Chrome into contents to |
| 267 // make it more modular and so that we can use it from here. |
| 268 return Activity::ACTIVITY_MEDIA_STATE_NONE; |
| 269 } |
| 270 |
165 void WebActivity::Init() { | 271 void WebActivity::Init() { |
166 DCHECK(web_view_); | 272 DCHECK(web_view_); |
167 static_cast<AthenaWebView*>(web_view_)->InstallAccelerators(); | 273 web_view_->InstallAccelerators(); |
168 } | 274 } |
169 | 275 |
170 SkColor WebActivity::GetRepresentativeColor() const { | 276 SkColor WebActivity::GetRepresentativeColor() const { |
171 // TODO(sad): Compute the color from the favicon. | 277 // TODO(sad): Compute the color from the favicon. |
172 return SK_ColorGRAY; | 278 return SK_ColorGRAY; |
173 } | 279 } |
174 | 280 |
175 base::string16 WebActivity::GetTitle() const { | 281 base::string16 WebActivity::GetTitle() const { |
176 return web_view_->GetWebContents()->GetTitle(); | 282 return web_view_->GetWebContents()->GetTitle(); |
177 } | 283 } |
178 | 284 |
179 bool WebActivity::UsesFrame() const { | 285 bool WebActivity::UsesFrame() const { |
180 return true; | 286 return true; |
181 } | 287 } |
182 | 288 |
183 views::View* WebActivity::GetContentsView() { | 289 views::View* WebActivity::GetContentsView() { |
184 if (!web_view_) { | 290 if (!web_view_) { |
185 web_view_ = new AthenaWebView(browser_context_); | 291 web_view_ = new AthenaWebView(browser_context_); |
186 web_view_->LoadInitialURL(url_); | 292 web_view_->LoadInitialURL(url_); |
187 Observe(web_view_->GetWebContents()); | 293 SetCurrentState(ACTIVITY_INVISIBLE); |
| 294 // Reset the overview mode image. |
| 295 overview_mode_image_ = gfx::ImageSkia(); |
188 } | 296 } |
189 return web_view_; | 297 return web_view_; |
190 } | 298 } |
191 | 299 |
| 300 void WebActivity::CreateOverviewModeImage() { |
| 301 // TODO(skuhne): Create an overview. |
| 302 } |
| 303 |
| 304 gfx::ImageSkia WebActivity::GetOverviewModeImage() { |
| 305 return overview_mode_image_; |
| 306 } |
| 307 |
192 void WebActivity::TitleWasSet(content::NavigationEntry* entry, | 308 void WebActivity::TitleWasSet(content::NavigationEntry* entry, |
193 bool explicit_set) { | 309 bool explicit_set) { |
194 ActivityManager::Get()->UpdateActivity(this); | 310 ActivityManager::Get()->UpdateActivity(this); |
195 } | 311 } |
196 | 312 |
197 void WebActivity::DidUpdateFaviconURL( | 313 void WebActivity::DidUpdateFaviconURL( |
198 const std::vector<content::FaviconURL>& candidates) { | 314 const std::vector<content::FaviconURL>& candidates) { |
199 ActivityManager::Get()->UpdateActivity(this); | 315 ActivityManager::Get()->UpdateActivity(this); |
200 } | 316 } |
201 | 317 |
202 } // namespace athena | 318 } // namespace athena |
OLD | NEW |