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_factory.h" |
7 #include "athena/activity/public/activity_manager.h" | 8 #include "athena/activity/public/activity_manager.h" |
8 #include "athena/input/public/accelerator_manager.h" | 9 #include "athena/input/public/accelerator_manager.h" |
9 #include "content/public/browser/native_web_keyboard_event.h" | 10 #include "content/public/browser/native_web_keyboard_event.h" |
| 11 #include "content/public/browser/navigation_controller.h" |
10 #include "content/public/browser/web_contents.h" | 12 #include "content/public/browser/web_contents.h" |
| 13 #include "content/public/browser/web_contents_delegate.h" |
11 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" | 14 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" |
12 #include "ui/views/controls/webview/webview.h" | 15 #include "ui/views/controls/webview/webview.h" |
13 #include "ui/views/focus/focus_manager.h" | 16 #include "ui/views/focus/focus_manager.h" |
14 | 17 |
15 namespace athena { | 18 namespace athena { |
16 namespace { | 19 namespace { |
17 | 20 |
18 class WebActivityController : public AcceleratorHandler { | 21 class WebActivityController : public AcceleratorHandler { |
19 public: | 22 public: |
20 enum Command { | 23 enum Command { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 }; | 120 }; |
118 | 121 |
119 } // namespace | 122 } // namespace |
120 | 123 |
121 // A web view for athena's web activity. Note that AthenaWebView will create its | 124 // 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. | 125 // own content so that it can eject and reload it. |
123 class AthenaWebView : public views::WebView { | 126 class AthenaWebView : public views::WebView { |
124 public: | 127 public: |
125 AthenaWebView(content::BrowserContext* context) | 128 AthenaWebView(content::BrowserContext* context) |
126 : views::WebView(context), controller_(new WebActivityController(this)) { | 129 : views::WebView(context), controller_(new WebActivityController(this)) { |
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 | 130 // TODO(skuhne): Add content observer to detect renderer crash and set |
132 // content status to unloaded if that happens. | 131 // content status to unloaded if that happens. |
133 } | 132 } |
134 virtual ~AthenaWebView() { | 133 |
135 // |WebView| does not own the content, so we need to destroy it here. | 134 AthenaWebView(content::WebContents* web_contents) |
136 content::WebContents* current_contents = GetWebContents(); | 135 : views::WebView(web_contents->GetBrowserContext()), |
137 SetWebContents(NULL); | 136 controller_(new WebActivityController(this)) { |
138 delete current_contents; | 137 scoped_ptr<content::WebContents> old_contents( |
| 138 SwapWebContents(scoped_ptr<content::WebContents>(web_contents))); |
139 } | 139 } |
140 | 140 |
| 141 virtual ~AthenaWebView() {} |
| 142 |
141 void InstallAccelerators() { controller_->InstallAccelerators(); } | 143 void InstallAccelerators() { controller_->InstallAccelerators(); } |
142 | 144 |
143 void EvictContent() { | 145 void EvictContent() { |
144 content::WebContents* old_contents = GetWebContents(); | 146 scoped_ptr<content::WebContents> old_contents(SwapWebContents( |
| 147 scoped_ptr<content::WebContents>(content::WebContents::Create( |
| 148 content::WebContents::CreateParams(browser_context()))))); |
145 evicted_web_contents_.reset( | 149 evicted_web_contents_.reset( |
146 content::WebContents::Create(content::WebContents::CreateParams( | 150 content::WebContents::Create(content::WebContents::CreateParams( |
147 old_contents->GetBrowserContext()))); | 151 old_contents->GetBrowserContext()))); |
148 evicted_web_contents_->GetController().CopyStateFrom( | 152 evicted_web_contents_->GetController().CopyStateFrom( |
149 old_contents->GetController()); | 153 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 // As soon as the new contents becomes visible, it should reload. |
154 // TODO(skuhne): This breaks script connections with other activities. | 155 // TODO(skuhne): This breaks script connections with other activities. |
155 // Even though this is the same technique as used by the TabStripModel, | 156 // 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 // we might want to address this cleaner since we are more likely to |
157 // run into this state. by unloading. | 158 // run into this state. by unloading. |
158 } | 159 } |
159 | 160 |
160 void ReloadContent() { | 161 void ReloadContent() { |
161 CHECK(evicted_web_contents_.get()); | 162 CHECK(evicted_web_contents_.get()); |
162 content::WebContents* null_contents = GetWebContents(); | 163 scoped_ptr<content::WebContents> replaced_contents(SwapWebContents( |
163 SetWebContents(evicted_web_contents_.release()); | 164 evicted_web_contents_.Pass())); |
164 delete null_contents; | |
165 } | 165 } |
166 | 166 |
167 // Check if the content got evicted. | 167 // Check if the content got evicted. |
168 const bool IsContentEvicted() { return !!evicted_web_contents_.get(); } | 168 const bool IsContentEvicted() { return !!evicted_web_contents_.get(); } |
169 | 169 |
170 private: | 170 // content::WebContentsDelegate: |
171 // WebContentsDelegate: | 171 virtual content::WebContents* OpenURLFromTab( |
| 172 content::WebContents* source, |
| 173 const content::OpenURLParams& params) OVERRIDE { |
| 174 switch(params.disposition) { |
| 175 case CURRENT_TAB: { |
| 176 DCHECK(source == web_contents()); |
| 177 content::NavigationController::LoadURLParams load_url_params( |
| 178 params.url); |
| 179 load_url_params.referrer = params.referrer; |
| 180 load_url_params.frame_tree_node_id = params.frame_tree_node_id; |
| 181 load_url_params.transition_type = params.transition; |
| 182 load_url_params.extra_headers = params.extra_headers; |
| 183 load_url_params.should_replace_current_entry = |
| 184 params.should_replace_current_entry; |
| 185 load_url_params.is_renderer_initiated = params.is_renderer_initiated; |
| 186 load_url_params.transferred_global_request_id = |
| 187 params.transferred_global_request_id; |
| 188 web_contents()->GetController().LoadURLWithParams(load_url_params); |
| 189 return web_contents(); |
| 190 } |
| 191 case NEW_FOREGROUND_TAB: |
| 192 case NEW_BACKGROUND_TAB: |
| 193 case NEW_POPUP: |
| 194 case NEW_WINDOW: { |
| 195 ActivityManager::Get()->AddActivity( |
| 196 ActivityFactory::Get()->CreateWebActivity(browser_context(), |
| 197 params.url)); |
| 198 break; |
| 199 } |
| 200 default: |
| 201 break; |
| 202 } |
| 203 // NULL is returned if the URL wasn't opened immediately. |
| 204 return NULL; |
| 205 } |
| 206 |
| 207 virtual void AddNewContents(content::WebContents* source, |
| 208 content::WebContents* new_contents, |
| 209 WindowOpenDisposition disposition, |
| 210 const gfx::Rect& initial_pos, |
| 211 bool user_gesture, |
| 212 bool* was_blocked) OVERRIDE { |
| 213 ActivityManager::Get()->AddActivity( |
| 214 new WebActivity(new AthenaWebView(new_contents))); |
| 215 } |
| 216 |
172 virtual bool PreHandleKeyboardEvent( | 217 virtual bool PreHandleKeyboardEvent( |
173 content::WebContents* source, | 218 content::WebContents* source, |
174 const content::NativeWebKeyboardEvent& event, | 219 const content::NativeWebKeyboardEvent& event, |
175 bool* is_keyboard_shortcut) OVERRIDE { | 220 bool* is_keyboard_shortcut) OVERRIDE { |
176 return controller_->PreHandleKeyboardEvent( | 221 return controller_->PreHandleKeyboardEvent( |
177 source, event, is_keyboard_shortcut); | 222 source, event, is_keyboard_shortcut); |
178 } | 223 } |
179 | 224 |
180 virtual void HandleKeyboardEvent( | 225 virtual void HandleKeyboardEvent( |
181 content::WebContents* source, | 226 content::WebContents* source, |
182 const content::NativeWebKeyboardEvent& event) OVERRIDE { | 227 const content::NativeWebKeyboardEvent& event) OVERRIDE { |
183 controller_->HandleKeyboardEvent(source, event); | 228 controller_->HandleKeyboardEvent(source, event); |
184 } | 229 } |
185 | 230 |
| 231 private: |
186 scoped_ptr<WebActivityController> controller_; | 232 scoped_ptr<WebActivityController> controller_; |
187 | 233 |
188 // If the activity got evicted, this is the web content which holds the known | 234 // If the activity got evicted, this is the web content which holds the known |
189 // state of the content before eviction. | 235 // state of the content before eviction. |
190 scoped_ptr<content::WebContents> evicted_web_contents_; | 236 scoped_ptr<content::WebContents> evicted_web_contents_; |
191 | 237 |
192 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); | 238 DISALLOW_COPY_AND_ASSIGN(AthenaWebView); |
193 }; | 239 }; |
194 | 240 |
195 WebActivity::WebActivity(content::BrowserContext* browser_context, | 241 WebActivity::WebActivity(content::BrowserContext* browser_context, |
196 const GURL& url) | 242 const GURL& url) |
197 : browser_context_(browser_context), | 243 : browser_context_(browser_context), |
198 url_(url), | 244 url_(url), |
199 web_view_(NULL), | 245 web_view_(NULL), |
200 current_state_(ACTIVITY_UNLOADED) { | 246 current_state_(ACTIVITY_UNLOADED) { |
201 } | 247 } |
202 | 248 |
| 249 WebActivity::WebActivity(AthenaWebView* web_view) |
| 250 : browser_context_(web_view->browser_context()), |
| 251 url_(web_view->GetWebContents()->GetURL()), |
| 252 web_view_(web_view), |
| 253 current_state_(ACTIVITY_UNLOADED) { |
| 254 // Transition to state ACTIVITY_INVISIBLE to perform the same setup steps |
| 255 // as on new activities (namely adding a WebContentsObserver). |
| 256 SetCurrentState(ACTIVITY_INVISIBLE); |
| 257 } |
| 258 |
203 WebActivity::~WebActivity() { | 259 WebActivity::~WebActivity() { |
204 // It is not required to change the activity state to UNLOADED - unless we | 260 // It is not required to change the activity state to UNLOADED - unless we |
205 // would add state observers. | 261 // would add state observers. |
206 } | 262 } |
207 | 263 |
208 ActivityViewModel* WebActivity::GetActivityViewModel() { | 264 ActivityViewModel* WebActivity::GetActivityViewModel() { |
209 return this; | 265 return this; |
210 } | 266 } |
211 | 267 |
212 void WebActivity::SetCurrentState(Activity::ActivityState state) { | 268 void WebActivity::SetCurrentState(Activity::ActivityState state) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 bool explicit_set) { | 365 bool explicit_set) { |
310 ActivityManager::Get()->UpdateActivity(this); | 366 ActivityManager::Get()->UpdateActivity(this); |
311 } | 367 } |
312 | 368 |
313 void WebActivity::DidUpdateFaviconURL( | 369 void WebActivity::DidUpdateFaviconURL( |
314 const std::vector<content::FaviconURL>& candidates) { | 370 const std::vector<content::FaviconURL>& candidates) { |
315 ActivityManager::Get()->UpdateActivity(this); | 371 ActivityManager::Get()->UpdateActivity(this); |
316 } | 372 } |
317 | 373 |
318 } // namespace athena | 374 } // namespace athena |
OLD | NEW |