Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: chrome/browser/ui/intents/web_intent_picker_controller.cc

Issue 10827238: [WebIntents, Gtk] "Waiting for Suggestion" dialog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
265 SetDialogState(kPickerSetup);
266
250 pending_async_count_ += 2; 267 pending_async_count_ += 2;
251 pending_registry_calls_count_ += 1; 268 pending_registry_calls_count_ += 1;
Greg Billock 2012/08/08 23:47:11 There are two of these -- services and defaults. B
groby-ooo-7-16 2012/08/09 21:59:56 See discussion below - tempted to move to bitfield
252 269
270 pending_cws_request_ = true;
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 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices(
269 action, type, 288 picker_model_->action(), picker_model_->mimetype(),
270 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, 289 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable,
271 weak_ptr_factory_.GetWeakPtr())); 290 weak_ptr_factory_.GetWeakPtr()));
272 } 291 }
273 292
274 void WebIntentPickerController::Observe( 293 void WebIntentPickerController::Observe(
275 int type, 294 int type,
276 const content::NotificationSource& source, 295 const content::NotificationSource& source,
277 const content::NotificationDetails& details) { 296 const content::NotificationDetails& details) {
278 DCHECK(type == content::NOTIFICATION_LOAD_START || 297 DCHECK(type == content::NOTIFICATION_LOAD_START ||
279 type == chrome::NOTIFICATION_TAB_CLOSING); 298 type == chrome::NOTIFICATION_TAB_CLOSING);
280 ClosePicker(); 299 ClosePicker();
281 } 300 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 services[i].service_url, 527 services[i].service_url,
509 history::FAVICON, 528 history::FAVICON,
510 &favicon_consumer_, 529 &favicon_consumer_,
511 base::Bind( 530 base::Bind(
512 &WebIntentPickerController::OnFaviconDataAvailable, 531 &WebIntentPickerController::OnFaviconDataAvailable,
513 weak_ptr_factory_.GetWeakPtr())); 532 weak_ptr_factory_.GetWeakPtr()));
514 favicon_consumer_.SetClientData( 533 favicon_consumer_.SetClientData(
515 favicon_service, handle, 534 favicon_service, handle,
516 picker_model_->GetInstalledServiceCount() - 1); 535 picker_model_->GetInstalledServiceCount() - 1);
517 536
518 if (services[i].disposition == 537 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(); 538 AsyncOperationFinished();
524 return; 539 return;
525 } 540 }
526 541
527 // No acceptable extension. The intent cannot be dispatched. 542 // No acceptable extension. The intent cannot be dispatched.
528 intents_dispatcher_->SendReplyMessage( 543 intents_dispatcher_->SendReplyMessage(
529 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( 544 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16(
530 "Explicit extension URL is not available.")); 545 "Explicit extension URL is not available."));
531 546
532 AsyncOperationFinished(); 547 AsyncOperationFinished();
(...skipping 15 matching lines...) Expand all
548 if (pending_registry_calls_count_ != 0) return; 563 if (pending_registry_calls_count_ != 0) return;
549 564
550 if (picker_model_->default_service_url().is_valid()) { 565 if (picker_model_->default_service_url().is_valid()) {
551 // If there's a default service, dispatch to it immediately 566 // If there's a default service, dispatch to it immediately
552 // without showing the picker. 567 // without showing the picker.
553 const WebIntentPickerModel::InstalledService* default_service = 568 const WebIntentPickerModel::InstalledService* default_service =
554 picker_model_->GetInstalledServiceWithURL( 569 picker_model_->GetInstalledServiceWithURL(
555 GURL(picker_model_->default_service_url())); 570 GURL(picker_model_->default_service_url()));
556 571
557 if (default_service != NULL) { 572 if (default_service != NULL) {
558 if (default_service->disposition == 573 InvokeService(*default_service);
559 WebIntentPickerModel::DISPOSITION_INLINE)
560 CreatePicker();
561
562 OnServiceChosen(default_service->url, default_service->disposition);
563 return; 574 return;
564 } 575 }
565 } 576 }
566 577
567 CreatePicker(); 578 OnPickerEvent(kPickerEventRegistryData);
568 picker_->SetActionString(GetIntentActionString( 579 OnIntentDataArrived();
569 UTF16ToUTF8(picker_model_->action())));
570 } 580 }
571 581
572 void WebIntentPickerController::OnFaviconDataAvailable( 582 void WebIntentPickerController::OnFaviconDataAvailable(
573 FaviconService::Handle handle, history::FaviconData favicon_data) { 583 FaviconService::Handle handle, history::FaviconData favicon_data) {
574 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); 584 size_t index = favicon_consumer_.GetClientDataForCurrentRequest();
575 if (favicon_data.is_valid()) { 585 if (favicon_data.is_valid()) {
576 SkBitmap icon_bitmap; 586 SkBitmap icon_bitmap;
577 587
578 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), 588 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(),
579 favicon_data.image_data->size(), 589 favicon_data.image_data->size(),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 &WebIntentPickerController::OnExtensionIconURLFetchComplete, 623 &WebIntentPickerController::OnExtensionIconURLFetchComplete,
614 weak_ptr_factory_.GetWeakPtr(), info.id))); 624 weak_ptr_factory_.GetWeakPtr(), info.id)));
615 625
616 icon_url_fetcher->SetLoadFlags( 626 icon_url_fetcher->SetLoadFlags(
617 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 627 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
618 icon_url_fetcher->SetRequestContext( 628 icon_url_fetcher->SetRequestContext(
619 tab_contents_->profile()->GetRequestContext()); 629 tab_contents_->profile()->GetRequestContext());
620 icon_url_fetcher->Start(); 630 icon_url_fetcher->Start();
621 } 631 }
622 632
623 AsyncOperationFinished(); 633 AsyncOperationFinished();
Greg Billock 2012/08/08 23:47:11 It'd be nice to use the state machine to kill this
groby-ooo-7-16 2012/08/09 21:59:56 I'm trying to have the states correspond to actual
634 pending_cws_request_ = false;
635 OnIntentDataArrived();
624 } 636 }
625 637
626 void WebIntentPickerController::OnExtensionIconURLFetchComplete( 638 void WebIntentPickerController::OnExtensionIconURLFetchComplete(
627 const string16& extension_id, const net::URLFetcher* source) { 639 const string16& extension_id, const net::URLFetcher* source) {
628 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 640 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
629 if (source->GetResponseCode() != 200) { 641 if (source->GetResponseCode() != 200) {
630 AsyncOperationFinished(); 642 AsyncOperationFinished();
631 return; 643 return;
632 } 644 }
633 645
(...skipping 27 matching lines...) Expand all
661 673
662 // Decode PNG and resize on worker thread. 674 // Decode PNG and resize on worker thread.
663 content::BrowserThread::PostBlockingPoolTask( 675 content::BrowserThread::PostBlockingPoolTask(
664 FROM_HERE, 676 FROM_HERE,
665 base::Bind(&DecodeExtensionIconAndResize, 677 base::Bind(&DecodeExtensionIconAndResize,
666 base::Passed(&response), 678 base::Passed(&response),
667 available_callback, 679 available_callback,
668 unavailable_callback)); 680 unavailable_callback));
669 } 681 }
670 682
683 void WebIntentPickerController::OnIntentDataArrived() {
684 DCHECK(picker_model_.get());
685
686 if (!pending_cws_request_ &&
687 pending_registry_calls_count_ == 0)
Greg Billock 2012/08/08 23:47:11 Merge this into the state machine logic.
groby-ooo-7-16 2012/08/09 21:59:56 See above. I'm treating this as a mini state machi
688 OnPickerEvent(kPickerEventDataComplete);
689 }
690
671 // static 691 // static
672 void WebIntentPickerController::DecodeExtensionIconAndResize( 692 void WebIntentPickerController::DecodeExtensionIconAndResize(
673 scoped_ptr<std::string> icon_response, 693 scoped_ptr<std::string> icon_response,
674 const ExtensionIconAvailableCallback& callback, 694 const ExtensionIconAvailableCallback& callback,
675 const base::Closure& unavailable_callback) { 695 const base::Closure& unavailable_callback) {
676 SkBitmap icon_bitmap; 696 SkBitmap icon_bitmap;
677 if (gfx::PNGCodec::Decode( 697 if (gfx::PNGCodec::Decode(
678 reinterpret_cast<const unsigned char*>(icon_response->data()), 698 reinterpret_cast<const unsigned char*>(icon_response->data()),
679 icon_response->length(), 699 icon_response->length(),
680 &icon_bitmap)) { 700 &icon_bitmap)) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 const webkit_glue::WebIntentServiceData& service_data = services[0]; 769 const webkit_glue::WebIntentServiceData& service_data = services[0];
750 picker_model_->AddInstalledService( 770 picker_model_->AddInstalledService(
751 service_data.title, service_data.service_url, 771 service_data.title, service_data.service_url,
752 ConvertDisposition(service_data.disposition)); 772 ConvertDisposition(service_data.disposition));
753 OnServiceChosen( 773 OnServiceChosen(
754 service_data.service_url, 774 service_data.service_url,
755 ConvertDisposition(service_data.disposition)); 775 ConvertDisposition(service_data.disposition));
756 AsyncOperationFinished(); 776 AsyncOperationFinished();
757 } 777 }
758 778
779 void WebIntentPickerController::OnPickerEvent(WebIntentPickerEvent event) {
780 switch (event) {
781 case kPickerEventHiddenSetupTimeout:
782 DCHECK(dialog_state_ == kPickerSetup);
783 SetDialogState(kPickerWaiting);
784 break;
785
786 case kPickerEventMaxWaitTimeExceeded:
787 DCHECK(dialog_state_ == kPickerWaiting);
788
789 // If registry data is complete, go to main dialog. Otherwise, wait.
790 if (pending_registry_calls_count_ == 0)
791 SetDialogState(kPickerMain);
792 else
793 SetDialogState(kPickerWaitLong);
794 break;
795
796 case kPickerEventRegistryData:
797 DCHECK(dialog_state_ == kPickerSetup ||
798 dialog_state_ == kPickerWaiting ||
799 dialog_state_ == kPickerWaitLong);
800
801 // If minimum wait dialog time is exceeded, display main dialog.
802 // Either way, we don't do a thing.
803 break;
804
805 case kPickerEventDataComplete:
806 DCHECK(dialog_state_ == kPickerSetup ||
807 dialog_state_ == kPickerWaiting);
808
809 // In setup state, transition to main dialog. In waiting state, let
810 // timer expire.
811 if (dialog_state_ == kPickerSetup)
812 SetDialogState(kPickerMain);
813 break;
814
815 default:
816 NOTREACHED();
817 break;
818 }
819 }
820
759 void WebIntentPickerController::AsyncOperationFinished() { 821 void WebIntentPickerController::AsyncOperationFinished() {
760 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 822 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
761 if (--pending_async_count_ == 0) { 823 if (--pending_async_count_ == 0) {
762 if (picker_) 824 if (picker_)
763 picker_->OnPendingAsyncCompleted(); 825 picker_->OnPendingAsyncCompleted();
764 } 826 }
765 } 827 }
766 828
829 void WebIntentPickerController::InvokeService(
830 const WebIntentPickerModel::InstalledService& service) {
831 if (service.disposition == WebIntentPickerModel::DISPOSITION_INLINE) {
832 SetDialogState(kPickerMain);
833 }
834 OnServiceChosen(service.url, service.disposition);
835 }
836
837 void WebIntentPickerController::SetDialogState(WebIntentPickerState state) {
838 // Ignore events that don't change state.
839 if (state == dialog_state_)
840 return;
841
842 // Any pending timers are abandoned on state changes.
843 timer_factory_.InvalidateWeakPtrs();
844
845 switch (state) {
846 case kPickerSetup:
847 DCHECK(dialog_state_ == kPickerHidden);
848
849 // Post timer CWS pending
850 MessageLoop::current()->PostDelayedTask(FROM_HERE,
851 base::Bind(&WebIntentPickerController::OnPickerEvent,
852 timer_factory_.GetWeakPtr(),
853 kPickerEventHiddenSetupTimeout),
854 base::TimeDelta::FromMilliseconds(kMaxHiddenSetupTimeMs));
855 break;
856
857 case kPickerWaiting:
858 DCHECK(dialog_state_ == kPickerSetup);
859 // Waiting dialog can be dismissed after minimum wait time.
860 MessageLoop::current()->PostDelayedTask(FROM_HERE,
861 base::Bind(&WebIntentPickerController::OnPickerEvent,
862 timer_factory_.GetWeakPtr(),
863 kPickerEventMaxWaitTimeExceeded),
864 base::TimeDelta::FromMilliseconds(kMinThrobberDisplayTimeMs));
865 break;
866
867 case kPickerWaitLong:
868 DCHECK(dialog_state_ == kPickerWaiting);
869 break;
870
871 case kPickerMain:
872 // No DCHECK - main state can be reached from any state.
873 // Ready to display data.
874 picker_model_->SetWaitingForSuggestions(false);
875 break;
876
877 case kPickerHidden:
878 break;
879
880 default:
881 NOTREACHED();
882 break;
883
884 }
885
886 dialog_state_ = state;
887
888 // Create picker dialog when changing away from hidden state.
889 if (dialog_state_ != kPickerHidden && dialog_state_ != kPickerSetup)
890 CreatePicker();
891 }
892
893
767 void WebIntentPickerController::CreatePicker() { 894 void WebIntentPickerController::CreatePicker() {
768 // If picker is non-NULL, it was set by a test. 895 // If picker is non-NULL, it was set by a test.
769 if (picker_ == NULL) 896 if (picker_ == NULL)
770 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); 897 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get());
898 picker_->SetActionString(GetIntentActionString(
899 UTF16ToUTF8(picker_model_->action())));
771 picker_shown_ = true; 900 picker_shown_ = true;
772 } 901 }
773 902
774 void WebIntentPickerController::ClosePicker() { 903 void WebIntentPickerController::ClosePicker() {
904 SetDialogState(kPickerHidden);
775 if (picker_) 905 if (picker_)
776 picker_->Close(); 906 picker_->Close();
777 } 907 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698