OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/intents/web_intent_picker_controller.h" | 5 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 28 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
29 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 29 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
30 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 30 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
31 #include "chrome/browser/webdata/web_data_service.h" | 31 #include "chrome/browser/webdata/web_data_service.h" |
32 #include "chrome/common/chrome_notification_types.h" | 32 #include "chrome/common/chrome_notification_types.h" |
33 #include "chrome/common/url_constants.h" | 33 #include "chrome/common/url_constants.h" |
34 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
35 #include "content/public/browser/navigation_controller.h" | 35 #include "content/public/browser/navigation_controller.h" |
36 #include "content/public/browser/notification_source.h" | 36 #include "content/public/browser/notification_source.h" |
37 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 38 #include "content/public/browser/web_contents_observer.h" |
38 #include "content/public/browser/web_intents_dispatcher.h" | 39 #include "content/public/browser/web_intents_dispatcher.h" |
39 #include "grit/generated_resources.h" | 40 #include "grit/generated_resources.h" |
40 #include "ipc/ipc_message.h" | 41 #include "ipc/ipc_message.h" |
41 #include "net/base/load_flags.h" | 42 #include "net/base/load_flags.h" |
42 #include "net/url_request/url_fetcher.h" | 43 #include "net/url_request/url_fetcher.h" |
43 #include "net/url_request/url_fetcher_delegate.h" | 44 #include "net/url_request/url_fetcher_delegate.h" |
44 #include "skia/ext/image_operations.h" | 45 #include "skia/ext/image_operations.h" |
45 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
46 #include "ui/gfx/codec/png_codec.h" | 47 #include "ui/gfx/codec/png_codec.h" |
47 #include "ui/gfx/favicon_size.h" | 48 #include "ui/gfx/favicon_size.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 131 } |
131 | 132 |
132 void URLFetcherTrampoline::OnURLFetchComplete( | 133 void URLFetcherTrampoline::OnURLFetchComplete( |
133 const net::URLFetcher* source) { | 134 const net::URLFetcher* source) { |
134 DCHECK(!callback_.is_null()); | 135 DCHECK(!callback_.is_null()); |
135 callback_.Run(source); | 136 callback_.Run(source); |
136 delete source; | 137 delete source; |
137 delete this; | 138 delete this; |
138 } | 139 } |
139 | 140 |
| 141 class SourceWindowObserver : content::WebContentsObserver { |
| 142 public: |
| 143 SourceWindowObserver(content::WebContents* web_contents, |
| 144 base::WeakPtr<WebIntentPickerController> controller) |
| 145 : content::WebContentsObserver(web_contents), |
| 146 controller_(controller) {} |
| 147 virtual ~SourceWindowObserver() {} |
| 148 |
| 149 // Implement WebContentsObserver |
| 150 virtual void WebContentsDestroyed(content::WebContents* web_contents) { |
| 151 if (controller_) |
| 152 controller_->SourceWebContentsDestroyed(web_contents); |
| 153 delete this; |
| 154 } |
| 155 |
| 156 private: |
| 157 base::WeakPtr<WebIntentPickerController> controller_; |
| 158 }; |
| 159 |
140 } // namespace | 160 } // namespace |
141 | 161 |
142 WebIntentPickerController::WebIntentPickerController( | 162 WebIntentPickerController::WebIntentPickerController( |
143 TabContents* tab_contents) | 163 TabContents* tab_contents) |
144 : tab_contents_(tab_contents), | 164 : tab_contents_(tab_contents), |
145 picker_(NULL), | 165 picker_(NULL), |
146 picker_model_(new WebIntentPickerModel()), | 166 picker_model_(new WebIntentPickerModel()), |
147 pending_async_count_(0), | 167 pending_async_count_(0), |
148 pending_registry_calls_count_(0), | 168 pending_registry_calls_count_(0), |
149 picker_shown_(false), | 169 picker_shown_(false), |
| 170 window_disposition_source_(NULL), |
| 171 source_intents_dispatcher_(NULL), |
150 intents_dispatcher_(NULL), | 172 intents_dispatcher_(NULL), |
151 service_tab_(NULL), | 173 service_tab_(NULL), |
152 weak_ptr_factory_(this) { | 174 weak_ptr_factory_(this) { |
153 content::NavigationController* controller = | 175 content::NavigationController* controller = |
154 &tab_contents->web_contents()->GetController(); | 176 &tab_contents->web_contents()->GetController(); |
155 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 177 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
156 content::Source<content::NavigationController>(controller)); | 178 content::Source<content::NavigationController>(controller)); |
157 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, | 179 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, |
158 content::Source<content::NavigationController>(controller)); | 180 content::Source<content::NavigationController>(controller)); |
159 } | 181 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( | 262 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( |
241 action, type, invoking_url, | 263 action, type, invoking_url, |
242 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, | 264 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, |
243 weak_ptr_factory_.GetWeakPtr())); | 265 weak_ptr_factory_.GetWeakPtr())); |
244 } | 266 } |
245 | 267 |
246 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( | 268 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( |
247 action, type, | 269 action, type, |
248 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, | 270 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, |
249 weak_ptr_factory_.GetWeakPtr())); | 271 weak_ptr_factory_.GetWeakPtr())); |
250 } | 272 } |
251 | 273 |
252 void WebIntentPickerController::Observe( | 274 void WebIntentPickerController::Observe( |
253 int type, | 275 int type, |
254 const content::NotificationSource& source, | 276 const content::NotificationSource& source, |
255 const content::NotificationDetails& details) { | 277 const content::NotificationDetails& details) { |
256 DCHECK(type == content::NOTIFICATION_LOAD_START || | 278 DCHECK(type == content::NOTIFICATION_LOAD_START || |
257 type == chrome::NOTIFICATION_TAB_CLOSING); | 279 type == chrome::NOTIFICATION_TAB_CLOSING); |
258 ClosePicker(); | 280 ClosePicker(); |
259 } | 281 } |
260 | 282 |
(...skipping 23 matching lines...) Expand all Loading... |
284 | 306 |
285 case WebIntentPickerModel::DISPOSITION_WINDOW: { | 307 case WebIntentPickerModel::DISPOSITION_WINDOW: { |
286 Browser* browser = browser::FindBrowserWithWebContents( | 308 Browser* browser = browser::FindBrowserWithWebContents( |
287 tab_contents_->web_contents()); | 309 tab_contents_->web_contents()); |
288 TabContents* contents = chrome::TabContentsFactory( | 310 TabContents* contents = chrome::TabContentsFactory( |
289 tab_contents_->profile(), | 311 tab_contents_->profile(), |
290 tab_util::GetSiteInstanceForNewTab( | 312 tab_util::GetSiteInstanceForNewTab( |
291 tab_contents_->profile(), url), | 313 tab_contents_->profile(), url), |
292 MSG_ROUTING_NONE, NULL, NULL); | 314 MSG_ROUTING_NONE, NULL, NULL); |
293 | 315 |
| 316 // Let the controller for the target TabContents know that it is hosting a |
| 317 // web intents service. |
| 318 contents->web_intent_picker_controller()->SetWindowDispositionSource( |
| 319 tab_contents_->web_contents(), intents_dispatcher_); |
| 320 |
294 intents_dispatcher_->DispatchIntent(contents->web_contents()); | 321 intents_dispatcher_->DispatchIntent(contents->web_contents()); |
295 service_tab_ = contents->web_contents(); | 322 service_tab_ = contents->web_contents(); |
296 | 323 |
297 // This call performs all the tab strip manipulation, notifications, etc. | 324 // This call performs all the tab strip manipulation, notifications, etc. |
298 // Since we're passing in a target_contents, it assumes that we will | 325 // Since we're passing in a target_contents, it assumes that we will |
299 // navigate the page ourselves, though. | 326 // navigate the page ourselves, though. |
300 chrome::NavigateParams params(browser, url, | 327 chrome::NavigateParams params(browser, url, |
301 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 328 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
302 params.target_contents = contents; | 329 params.target_contents = contents; |
303 params.disposition = NEW_FOREGROUND_TAB; | 330 params.disposition = NEW_FOREGROUND_TAB; |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 const gfx::Image& icon_image) { | 701 const gfx::Image& icon_image) { |
675 picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image); | 702 picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image); |
676 AsyncOperationFinished(); | 703 AsyncOperationFinished(); |
677 } | 704 } |
678 | 705 |
679 void WebIntentPickerController::OnExtensionIconUnavailable( | 706 void WebIntentPickerController::OnExtensionIconUnavailable( |
680 const string16& extension_id) { | 707 const string16& extension_id) { |
681 AsyncOperationFinished(); | 708 AsyncOperationFinished(); |
682 } | 709 } |
683 | 710 |
| 711 void WebIntentPickerController::SetWindowDispositionSource( |
| 712 content::WebContents* source, |
| 713 content::WebIntentsDispatcher* dispatcher) { |
| 714 window_disposition_source_ = source; |
| 715 if (window_disposition_source_) { |
| 716 // This object is self-deleting when the source WebContents is destroyed. |
| 717 new SourceWindowObserver(window_disposition_source_, |
| 718 weak_ptr_factory_.GetWeakPtr()); |
| 719 } |
| 720 |
| 721 source_intents_dispatcher_ = dispatcher; |
| 722 if (dispatcher) { |
| 723 dispatcher->RegisterReplyNotification( |
| 724 base::Bind(&WebIntentPickerController::SourceDispatcherReplied, |
| 725 weak_ptr_factory_.GetWeakPtr())); |
| 726 } |
| 727 } |
| 728 |
| 729 void WebIntentPickerController::SourceWebContentsDestroyed( |
| 730 content::WebContents* source) { |
| 731 window_disposition_source_ = NULL; |
| 732 } |
| 733 |
| 734 void WebIntentPickerController::SourceDispatcherReplied( |
| 735 webkit_glue::WebIntentReplyType reply_type) { |
| 736 source_intents_dispatcher_ = NULL; |
| 737 } |
| 738 |
| 739 bool WebIntentPickerController::ShowLocationBarPickerTool() { |
| 740 return window_disposition_source_ || source_intents_dispatcher_; |
| 741 } |
| 742 |
684 void WebIntentPickerController::OnExtensionInstallServiceAvailable( | 743 void WebIntentPickerController::OnExtensionInstallServiceAvailable( |
685 const std::vector<webkit_glue::WebIntentServiceData>& services) { | 744 const std::vector<webkit_glue::WebIntentServiceData>& services) { |
686 DCHECK(services.size() > 0); | 745 DCHECK(services.size() > 0); |
687 | 746 |
688 // TODO(binji): We're going to need to disambiguate if there are multiple | 747 // TODO(binji): We're going to need to disambiguate if there are multiple |
689 // services. For now, just choose the first. | 748 // services. For now, just choose the first. |
690 const webkit_glue::WebIntentServiceData& service_data = services[0]; | 749 const webkit_glue::WebIntentServiceData& service_data = services[0]; |
691 picker_model_->AddInstalledService( | 750 picker_model_->AddInstalledService( |
692 service_data.title, service_data.service_url, | 751 service_data.title, service_data.service_url, |
693 ConvertDisposition(service_data.disposition)); | 752 ConvertDisposition(service_data.disposition)); |
(...skipping 15 matching lines...) Expand all Loading... |
709 // If picker is non-NULL, it was set by a test. | 768 // If picker is non-NULL, it was set by a test. |
710 if (picker_ == NULL) | 769 if (picker_ == NULL) |
711 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); | 770 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); |
712 picker_shown_ = true; | 771 picker_shown_ = true; |
713 } | 772 } |
714 | 773 |
715 void WebIntentPickerController::ClosePicker() { | 774 void WebIntentPickerController::ClosePicker() { |
716 if (picker_) | 775 if (picker_) |
717 picker_->Close(); | 776 picker_->Close(); |
718 } | 777 } |
OLD | NEW |