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" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
14 #include "chrome/browser/extensions/platform_app_launcher.h" | 14 #include "chrome/browser/extensions/platform_app_launcher.h" |
15 #include "chrome/browser/extensions/webstore_installer.h" | 15 #include "chrome/browser/extensions/webstore_installer.h" |
16 #include "chrome/browser/favicon/favicon_service.h" | 16 #include "chrome/browser/favicon/favicon_service.h" |
17 #include "chrome/browser/intents/cws_intents_registry_factory.h" | 17 #include "chrome/browser/intents/cws_intents_registry_factory.h" |
18 #include "chrome/browser/intents/default_web_intent_service.h" | 18 #include "chrome/browser/intents/default_web_intent_service.h" |
19 #include "chrome/browser/intents/web_intents_registry_factory.h" | 19 #include "chrome/browser/intents/web_intents_registry_factory.h" |
20 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
21 #include "chrome/browser/tab_contents/tab_util.h" | 21 #include "chrome/browser/tab_contents/tab_util.h" |
22 #include "chrome/browser/ui/browser.h" | 22 #include "chrome/browser/ui/browser.h" |
23 #include "chrome/browser/ui/browser_finder.h" | 23 #include "chrome/browser/ui/browser_finder.h" |
24 #include "chrome/browser/ui/browser_list.h" | 24 #include "chrome/browser/ui/browser_list.h" |
25 #include "chrome/browser/ui/browser_navigator.h" | 25 #include "chrome/browser/ui/browser_navigator.h" |
26 #include "chrome/browser/ui/browser_tabstrip.h" | 26 #include "chrome/browser/ui/browser_tabstrip.h" |
27 #include "chrome/browser/ui/constrained_window_tab_helper.h" | |
27 #include "chrome/browser/ui/intents/web_intent_picker.h" | 28 #include "chrome/browser/ui/intents/web_intent_picker.h" |
28 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 29 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
29 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 30 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
30 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 31 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
31 #include "chrome/browser/webdata/web_data_service.h" | 32 #include "chrome/browser/webdata/web_data_service.h" |
32 #include "chrome/common/chrome_notification_types.h" | 33 #include "chrome/common/chrome_notification_types.h" |
33 #include "chrome/common/url_constants.h" | 34 #include "chrome/common/url_constants.h" |
34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
35 #include "content/public/browser/navigation_controller.h" | 36 #include "content/public/browser/navigation_controller.h" |
36 #include "content/public/browser/notification_source.h" | 37 #include "content/public/browser/notification_source.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
53 | 54 |
54 namespace { | 55 namespace { |
55 | 56 |
56 const char kShareActionURL[] = "http://webintents.org/share"; | 57 const char kShareActionURL[] = "http://webintents.org/share"; |
57 const char kEditActionURL[] = "http://webintents.org/edit"; | 58 const char kEditActionURL[] = "http://webintents.org/edit"; |
58 const char kViewActionURL[] = "http://webintents.org/view"; | 59 const char kViewActionURL[] = "http://webintents.org/view"; |
59 const char kPickActionURL[] = "http://webintents.org/pick"; | 60 const char kPickActionURL[] = "http://webintents.org/pick"; |
60 const char kSubscribeActionURL[] = "http://webintents.org/subscribe"; | 61 const char kSubscribeActionURL[] = "http://webintents.org/subscribe"; |
61 const char kSaveActionURL[] = "http://webintents.org/save"; | 62 const char kSaveActionURL[] = "http://webintents.org/save"; |
62 | 63 |
64 // Maximum amount of time to delay displaying dialog while waiting for data. | |
65 const int kMaxHiddenSetupTimeMs = 200; | |
66 | |
67 // Minimum amount of time to show waiting dialog, if it is shown. | |
68 const int kMinThrobberDisplayTimeMs = 2000; | |
69 | |
70 | |
63 // Gets the favicon service for the profile in |tab_contents|. | 71 // Gets the favicon service for the profile in |tab_contents|. |
64 FaviconService* GetFaviconService(TabContents* tab_contents) { | 72 FaviconService* GetFaviconService(TabContents* tab_contents) { |
65 return tab_contents->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); | 73 return tab_contents->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); |
66 } | 74 } |
67 | 75 |
68 // Gets the web intents registry for the profile in |tab_contents|. | 76 // Gets the web intents registry for the profile in |tab_contents|. |
69 WebIntentsRegistry* GetWebIntentsRegistry(TabContents* tab_contents) { | 77 WebIntentsRegistry* GetWebIntentsRegistry(TabContents* tab_contents) { |
70 return WebIntentsRegistryFactory::GetForProfile(tab_contents->profile()); | 78 return WebIntentsRegistryFactory::GetForProfile(tab_contents->profile()); |
71 } | 79 } |
72 | 80 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 } | 162 } |
155 | 163 |
156 private: | 164 private: |
157 base::WeakPtr<WebIntentPickerController> controller_; | 165 base::WeakPtr<WebIntentPickerController> controller_; |
158 }; | 166 }; |
159 | 167 |
160 } // namespace | 168 } // namespace |
161 | 169 |
162 WebIntentPickerController::WebIntentPickerController( | 170 WebIntentPickerController::WebIntentPickerController( |
163 TabContents* tab_contents) | 171 TabContents* tab_contents) |
164 : tab_contents_(tab_contents), | 172 : dialog_state_(kPickerHidden), |
173 tab_contents_(tab_contents), | |
165 picker_(NULL), | 174 picker_(NULL), |
166 picker_model_(new WebIntentPickerModel()), | 175 picker_model_(new WebIntentPickerModel()), |
167 pending_async_count_(0), | 176 pending_async_count_(0), |
168 pending_registry_calls_count_(0), | 177 pending_registry_calls_count_(0), |
178 pending_cws_request_(false), | |
169 picker_shown_(false), | 179 picker_shown_(false), |
170 window_disposition_source_(NULL), | 180 window_disposition_source_(NULL), |
171 source_intents_dispatcher_(NULL), | 181 source_intents_dispatcher_(NULL), |
172 intents_dispatcher_(NULL), | 182 intents_dispatcher_(NULL), |
173 service_tab_(NULL), | 183 service_tab_(NULL), |
174 weak_ptr_factory_(this) { | 184 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
185 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) { | |
175 content::NavigationController* controller = | 186 content::NavigationController* controller = |
176 &tab_contents->web_contents()->GetController(); | 187 &tab_contents->web_contents()->GetController(); |
177 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 188 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
178 content::Source<content::NavigationController>(controller)); | 189 content::Source<content::NavigationController>(controller)); |
179 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, | 190 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, |
180 content::Source<content::NavigationController>(controller)); | 191 content::Source<content::NavigationController>(controller)); |
181 } | 192 } |
182 | 193 |
183 WebIntentPickerController::~WebIntentPickerController() { | 194 WebIntentPickerController::~WebIntentPickerController() { |
184 } | 195 } |
185 | 196 |
186 // TODO(gbillock): combine this with ShowDialog. | 197 // TODO(gbillock): combine this with ShowDialog. |
187 void WebIntentPickerController::SetIntentsDispatcher( | 198 void WebIntentPickerController::SetIntentsDispatcher( |
188 content::WebIntentsDispatcher* intents_dispatcher) { | 199 content::WebIntentsDispatcher* intents_dispatcher) { |
189 intents_dispatcher_ = intents_dispatcher; | 200 intents_dispatcher_ = intents_dispatcher; |
190 intents_dispatcher_->RegisterReplyNotification( | 201 intents_dispatcher_->RegisterReplyNotification( |
191 base::Bind(&WebIntentPickerController::OnSendReturnMessage, | 202 base::Bind(&WebIntentPickerController::OnSendReturnMessage, |
192 weak_ptr_factory_.GetWeakPtr())); | 203 weak_ptr_factory_.GetWeakPtr())); |
193 } | 204 } |
194 | |
195 void WebIntentPickerController::ShowDialog(const string16& action, | 205 void WebIntentPickerController::ShowDialog(const string16& action, |
196 const string16& type) { | 206 const string16& type) { |
207 | |
208 // As soon as the dialog is requested, block all input events | |
209 // on the original tab. | |
210 tab_contents_->constrained_window_tab_helper()->BlockTabContent(true); | |
211 | |
197 // Only show a picker once. | 212 // Only show a picker once. |
198 // TODO(gbillock): There's a hole potentially admitting multiple | 213 // TODO(gbillock): There's a hole potentially admitting multiple |
199 // in-flight dispatches since we don't create the picker | 214 // in-flight dispatches since we don't create the picker |
200 // in this method, but only after calling the registry. | 215 // in this method, but only after calling the registry. |
201 if (picker_shown_) { | 216 if (picker_shown_) { |
202 if (intents_dispatcher_) { | 217 if (intents_dispatcher_) { |
203 intents_dispatcher_->SendReplyMessage( | 218 intents_dispatcher_->SendReplyMessage( |
204 webkit_glue::WEB_INTENT_REPLY_FAILURE, | 219 webkit_glue::WEB_INTENT_REPLY_FAILURE, |
205 ASCIIToUTF16("Simultaneous intent invocation.")); | 220 ASCIIToUTF16("Simultaneous intent invocation.")); |
206 } | 221 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 // required to find disposition set by service.) | 255 // required to find disposition set by service.) |
241 pending_async_count_++; | 256 pending_async_count_++; |
242 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( | 257 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( |
243 action, type, base::Bind( | 258 action, type, base::Bind( |
244 &WebIntentPickerController::WebIntentServicesForExplicitIntent, | 259 &WebIntentPickerController::WebIntentServicesForExplicitIntent, |
245 weak_ptr_factory_.GetWeakPtr())); | 260 weak_ptr_factory_.GetWeakPtr())); |
246 return; | 261 return; |
247 } | 262 } |
248 } | 263 } |
249 | 264 |
250 pending_async_count_ += 2; | 265 SetDialogState(kPickerSetup); |
251 pending_registry_calls_count_ += 1; | 266 |
267 pending_async_count_++; | |
268 pending_registry_calls_count_++; | |
Greg Billock
2012/08/10 19:39:50
move these into same para as GetIntentServices
| |
269 | |
270 pending_cws_request_ = true; | |
Greg Billock
2012/08/10 19:39:50
move this right by cws call
groby-ooo-7-16
2012/08/10 22:55:10
Can't. We're already waiting for CWS data at this
Greg Billock
2012/08/13 15:17:24
I'm not seeing that. Isn't the CWS request the "Ge
groby-ooo-7-16
2012/08/13 22:03:33
It works currently, because WebIntentsRegistry->Ge
Greg Billock
2012/08/14 05:22:00
I see what you mean, but this means the logic is p
| |
252 | 271 |
253 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( | 272 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( |
254 action, type, | 273 action, type, |
255 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, | 274 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, |
256 weak_ptr_factory_.GetWeakPtr())); | 275 weak_ptr_factory_.GetWeakPtr())); |
257 | 276 |
258 GURL invoking_url = tab_contents_->web_contents()->GetURL(); | 277 GURL invoking_url = tab_contents_->web_contents()->GetURL(); |
259 if (invoking_url.is_valid()) { | 278 if (invoking_url.is_valid()) { |
260 pending_async_count_++; | 279 pending_async_count_++; |
261 pending_registry_calls_count_++; | 280 pending_registry_calls_count_++; |
262 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( | 281 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( |
263 action, type, invoking_url, | 282 action, type, invoking_url, |
264 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, | 283 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, |
265 weak_ptr_factory_.GetWeakPtr())); | 284 weak_ptr_factory_.GetWeakPtr())); |
266 } | 285 } |
267 | 286 |
268 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( | 287 pending_async_count_++; |
269 action, type, | 288 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( |
270 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, | 289 picker_model_->action(), picker_model_->mimetype(), |
271 weak_ptr_factory_.GetWeakPtr())); | 290 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, |
291 weak_ptr_factory_.GetWeakPtr())); | |
272 } | 292 } |
273 | 293 |
274 void WebIntentPickerController::Observe( | 294 void WebIntentPickerController::Observe( |
275 int type, | 295 int type, |
276 const content::NotificationSource& source, | 296 const content::NotificationSource& source, |
277 const content::NotificationDetails& details) { | 297 const content::NotificationDetails& details) { |
278 DCHECK(type == content::NOTIFICATION_LOAD_START || | 298 DCHECK(type == content::NOTIFICATION_LOAD_START || |
279 type == chrome::NOTIFICATION_TAB_CLOSING); | 299 type == chrome::NOTIFICATION_TAB_CLOSING); |
280 ClosePicker(); | 300 ClosePicker(); |
281 } | 301 } |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 services[i].service_url, | 528 services[i].service_url, |
509 history::FAVICON, | 529 history::FAVICON, |
510 &favicon_consumer_, | 530 &favicon_consumer_, |
511 base::Bind( | 531 base::Bind( |
512 &WebIntentPickerController::OnFaviconDataAvailable, | 532 &WebIntentPickerController::OnFaviconDataAvailable, |
513 weak_ptr_factory_.GetWeakPtr())); | 533 weak_ptr_factory_.GetWeakPtr())); |
514 favicon_consumer_.SetClientData( | 534 favicon_consumer_.SetClientData( |
515 favicon_service, handle, | 535 favicon_service, handle, |
516 picker_model_->GetInstalledServiceCount() - 1); | 536 picker_model_->GetInstalledServiceCount() - 1); |
517 | 537 |
518 if (services[i].disposition == | 538 InvokeService(picker_model_->GetInstalledServiceAt(i)); |
519 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE) | |
520 CreatePicker(); | |
521 OnServiceChosen(services[i].service_url, | |
522 ConvertDisposition(services[i].disposition)); | |
523 AsyncOperationFinished(); | 539 AsyncOperationFinished(); |
524 return; | 540 return; |
525 } | 541 } |
526 | 542 |
527 // No acceptable extension. The intent cannot be dispatched. | 543 // No acceptable extension. The intent cannot be dispatched. |
528 intents_dispatcher_->SendReplyMessage( | 544 intents_dispatcher_->SendReplyMessage( |
529 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( | 545 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( |
530 "Explicit extension URL is not available.")); | 546 "Explicit extension URL is not available.")); |
531 | 547 |
532 AsyncOperationFinished(); | 548 AsyncOperationFinished(); |
(...skipping 15 matching lines...) Expand all Loading... | |
548 if (pending_registry_calls_count_ != 0) return; | 564 if (pending_registry_calls_count_ != 0) return; |
549 | 565 |
550 if (picker_model_->default_service_url().is_valid()) { | 566 if (picker_model_->default_service_url().is_valid()) { |
551 // If there's a default service, dispatch to it immediately | 567 // If there's a default service, dispatch to it immediately |
552 // without showing the picker. | 568 // without showing the picker. |
553 const WebIntentPickerModel::InstalledService* default_service = | 569 const WebIntentPickerModel::InstalledService* default_service = |
554 picker_model_->GetInstalledServiceWithURL( | 570 picker_model_->GetInstalledServiceWithURL( |
555 GURL(picker_model_->default_service_url())); | 571 GURL(picker_model_->default_service_url())); |
556 | 572 |
557 if (default_service != NULL) { | 573 if (default_service != NULL) { |
558 if (default_service->disposition == | 574 InvokeService(*default_service); |
559 WebIntentPickerModel::DISPOSITION_INLINE) | |
560 CreatePicker(); | |
561 | |
562 OnServiceChosen(default_service->url, default_service->disposition); | |
563 return; | 575 return; |
564 } | 576 } |
565 } | 577 } |
566 | 578 |
567 CreatePicker(); | 579 OnPickerEvent(kPickerEventRegistryData); |
Greg Billock
2012/08/10 19:39:50
...RegistryDataComplete
In refactors, it'd be nic
groby-ooo-7-16
2012/08/10 22:55:10
Done.
| |
568 picker_->SetActionString(GetIntentActionString( | 580 OnIntentDataArrived(); |
569 UTF16ToUTF8(picker_model_->action()))); | |
570 } | 581 } |
571 | 582 |
572 void WebIntentPickerController::OnFaviconDataAvailable( | 583 void WebIntentPickerController::OnFaviconDataAvailable( |
573 FaviconService::Handle handle, history::FaviconData favicon_data) { | 584 FaviconService::Handle handle, history::FaviconData favicon_data) { |
574 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); | 585 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); |
575 if (favicon_data.is_valid()) { | 586 if (favicon_data.is_valid()) { |
576 SkBitmap icon_bitmap; | 587 SkBitmap icon_bitmap; |
577 | 588 |
578 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), | 589 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), |
579 favicon_data.image_data->size(), | 590 favicon_data.image_data->size(), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
614 weak_ptr_factory_.GetWeakPtr(), info.id))); | 625 weak_ptr_factory_.GetWeakPtr(), info.id))); |
615 | 626 |
616 icon_url_fetcher->SetLoadFlags( | 627 icon_url_fetcher->SetLoadFlags( |
617 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); | 628 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); |
618 icon_url_fetcher->SetRequestContext( | 629 icon_url_fetcher->SetRequestContext( |
619 tab_contents_->profile()->GetRequestContext()); | 630 tab_contents_->profile()->GetRequestContext()); |
620 icon_url_fetcher->Start(); | 631 icon_url_fetcher->Start(); |
621 } | 632 } |
622 | 633 |
623 AsyncOperationFinished(); | 634 AsyncOperationFinished(); |
635 pending_cws_request_ = false; | |
636 OnIntentDataArrived(); | |
624 } | 637 } |
625 | 638 |
626 void WebIntentPickerController::OnExtensionIconURLFetchComplete( | 639 void WebIntentPickerController::OnExtensionIconURLFetchComplete( |
627 const string16& extension_id, const net::URLFetcher* source) { | 640 const string16& extension_id, const net::URLFetcher* source) { |
628 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 641 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
629 if (source->GetResponseCode() != 200) { | 642 if (source->GetResponseCode() != 200) { |
630 AsyncOperationFinished(); | 643 AsyncOperationFinished(); |
631 return; | 644 return; |
632 } | 645 } |
633 | 646 |
(...skipping 27 matching lines...) Expand all Loading... | |
661 | 674 |
662 // Decode PNG and resize on worker thread. | 675 // Decode PNG and resize on worker thread. |
663 content::BrowserThread::PostBlockingPoolTask( | 676 content::BrowserThread::PostBlockingPoolTask( |
664 FROM_HERE, | 677 FROM_HERE, |
665 base::Bind(&DecodeExtensionIconAndResize, | 678 base::Bind(&DecodeExtensionIconAndResize, |
666 base::Passed(&response), | 679 base::Passed(&response), |
667 available_callback, | 680 available_callback, |
668 unavailable_callback)); | 681 unavailable_callback)); |
669 } | 682 } |
670 | 683 |
684 void WebIntentPickerController::OnIntentDataArrived() { | |
685 DCHECK(picker_model_.get()); | |
686 | |
687 if (!pending_cws_request_ && | |
688 pending_registry_calls_count_ == 0) | |
689 OnPickerEvent(kPickerEventDataComplete); | |
Greg Billock
2012/08/10 19:39:50
How about ...AsyncDataComplete
again, probably be
groby-ooo-7-16
2012/08/10 22:55:10
Changed the name. As for the remaining refactor yo
Greg Billock
2012/08/13 15:17:24
OK, I believe you. :-) It's nice to have all the t
| |
690 } | |
691 | |
671 // static | 692 // static |
672 void WebIntentPickerController::DecodeExtensionIconAndResize( | 693 void WebIntentPickerController::DecodeExtensionIconAndResize( |
673 scoped_ptr<std::string> icon_response, | 694 scoped_ptr<std::string> icon_response, |
674 const ExtensionIconAvailableCallback& callback, | 695 const ExtensionIconAvailableCallback& callback, |
675 const base::Closure& unavailable_callback) { | 696 const base::Closure& unavailable_callback) { |
676 SkBitmap icon_bitmap; | 697 SkBitmap icon_bitmap; |
677 if (gfx::PNGCodec::Decode( | 698 if (gfx::PNGCodec::Decode( |
678 reinterpret_cast<const unsigned char*>(icon_response->data()), | 699 reinterpret_cast<const unsigned char*>(icon_response->data()), |
679 icon_response->length(), | 700 icon_response->length(), |
680 &icon_bitmap)) { | 701 &icon_bitmap)) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 const webkit_glue::WebIntentServiceData& service_data = services[0]; | 770 const webkit_glue::WebIntentServiceData& service_data = services[0]; |
750 picker_model_->AddInstalledService( | 771 picker_model_->AddInstalledService( |
751 service_data.title, service_data.service_url, | 772 service_data.title, service_data.service_url, |
752 ConvertDisposition(service_data.disposition)); | 773 ConvertDisposition(service_data.disposition)); |
753 OnServiceChosen( | 774 OnServiceChosen( |
754 service_data.service_url, | 775 service_data.service_url, |
755 ConvertDisposition(service_data.disposition)); | 776 ConvertDisposition(service_data.disposition)); |
756 AsyncOperationFinished(); | 777 AsyncOperationFinished(); |
757 } | 778 } |
758 | 779 |
780 void WebIntentPickerController::OnPickerEvent(WebIntentPickerEvent event) { | |
781 switch (event) { | |
Greg Billock
2012/08/10 19:39:50
Would this be easier to read if it switched on cur
groby-ooo-7-16
2012/08/10 22:55:10
I'm not convinced.
The important part, at least
Greg Billock
2012/08/13 15:17:24
Sounds good.
| |
782 case kPickerEventHiddenSetupTimeout: | |
783 DCHECK(dialog_state_ == kPickerSetup); | |
784 SetDialogState(kPickerWaiting); | |
785 break; | |
786 | |
787 case kPickerEventMaxWaitTimeExceeded: | |
788 DCHECK(dialog_state_ == kPickerWaiting); | |
789 | |
790 // If registry data is complete, go to main dialog. Otherwise, wait. | |
791 if (pending_registry_calls_count_ == 0) | |
792 SetDialogState(kPickerMain); | |
793 else | |
794 SetDialogState(kPickerWaitLong); | |
795 break; | |
796 | |
797 case kPickerEventRegistryData: | |
798 DCHECK(dialog_state_ == kPickerSetup || | |
799 dialog_state_ == kPickerWaiting || | |
800 dialog_state_ == kPickerWaitLong); | |
801 | |
802 // If minimum wait dialog time is exceeded, display main dialog. | |
803 // Either way, we don't do a thing. | |
804 break; | |
805 | |
806 case kPickerEventDataComplete: | |
807 DCHECK(dialog_state_ == kPickerSetup || | |
808 dialog_state_ == kPickerWaiting); | |
809 | |
810 // In setup state, transition to main dialog. In waiting state, let | |
811 // timer expire. | |
812 if (dialog_state_ == kPickerSetup) | |
813 SetDialogState(kPickerMain); | |
814 break; | |
815 | |
816 default: | |
817 NOTREACHED(); | |
818 break; | |
819 } | |
820 } | |
821 | |
759 void WebIntentPickerController::AsyncOperationFinished() { | 822 void WebIntentPickerController::AsyncOperationFinished() { |
760 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 823 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
761 if (--pending_async_count_ == 0) { | 824 if (--pending_async_count_ == 0) { |
762 if (picker_) | 825 if (picker_) |
763 picker_->OnPendingAsyncCompleted(); | 826 picker_->OnPendingAsyncCompleted(); |
764 } | 827 } |
765 } | 828 } |
766 | 829 |
830 void WebIntentPickerController::InvokeService( | |
831 const WebIntentPickerModel::InstalledService& service) { | |
832 if (service.disposition == WebIntentPickerModel::DISPOSITION_INLINE) { | |
833 SetDialogState(kPickerMain); | |
834 } | |
835 OnServiceChosen(service.url, service.disposition); | |
836 } | |
837 | |
838 void WebIntentPickerController::SetDialogState(WebIntentPickerState state) { | |
839 // Ignore events that don't change state. | |
840 if (state == dialog_state_) | |
841 return; | |
842 | |
843 // Any pending timers are abandoned on state changes. | |
844 timer_factory_.InvalidateWeakPtrs(); | |
845 | |
846 switch (state) { | |
847 case kPickerSetup: | |
848 DCHECK(dialog_state_ == kPickerHidden); | |
849 | |
850 // Post timer CWS pending | |
851 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
852 base::Bind(&WebIntentPickerController::OnPickerEvent, | |
853 timer_factory_.GetWeakPtr(), | |
854 kPickerEventHiddenSetupTimeout), | |
855 base::TimeDelta::FromMilliseconds(kMaxHiddenSetupTimeMs)); | |
856 break; | |
857 | |
858 case kPickerWaiting: | |
859 DCHECK(dialog_state_ == kPickerSetup); | |
860 // Waiting dialog can be dismissed after minimum wait time. | |
861 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
862 base::Bind(&WebIntentPickerController::OnPickerEvent, | |
863 timer_factory_.GetWeakPtr(), | |
864 kPickerEventMaxWaitTimeExceeded), | |
865 base::TimeDelta::FromMilliseconds(kMinThrobberDisplayTimeMs)); | |
866 break; | |
867 | |
868 case kPickerWaitLong: | |
869 DCHECK(dialog_state_ == kPickerWaiting); | |
870 break; | |
871 | |
872 case kPickerMain: | |
873 // No DCHECK - main state can be reached from any state. | |
874 // Ready to display data. | |
875 picker_model_->SetWaitingForSuggestions(false); | |
876 break; | |
877 | |
878 case kPickerHidden: | |
879 break; | |
880 | |
881 default: | |
882 NOTREACHED(); | |
883 break; | |
884 | |
885 } | |
886 | |
887 dialog_state_ = state; | |
888 | |
889 // Create picker dialog when changing away from hidden state. | |
890 if (dialog_state_ != kPickerHidden && dialog_state_ != kPickerSetup) | |
891 CreatePicker(); | |
892 } | |
893 | |
894 | |
767 void WebIntentPickerController::CreatePicker() { | 895 void WebIntentPickerController::CreatePicker() { |
768 // If picker is non-NULL, it was set by a test. | 896 // If picker is non-NULL, it was set by a test. |
769 if (picker_ == NULL) | 897 if (picker_ == NULL) |
770 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); | 898 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); |
899 picker_->SetActionString(GetIntentActionString( | |
900 UTF16ToUTF8(picker_model_->action()))); | |
771 picker_shown_ = true; | 901 picker_shown_ = true; |
772 } | 902 } |
773 | 903 |
774 void WebIntentPickerController::ClosePicker() { | 904 void WebIntentPickerController::ClosePicker() { |
905 SetDialogState(kPickerHidden); | |
775 if (picker_) | 906 if (picker_) |
776 picker_->Close(); | 907 picker_->Close(); |
777 } | 908 } |
OLD | NEW |