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

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: Remove flag, rebase to HEAD. 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
250 pending_async_count_ += 2; 265 SetDialogState(kPickerSetup);
251 pending_registry_calls_count_ += 1;
252 266
267 pending_async_count_++;
268 pending_registry_calls_count_++;
253 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( 269 GetWebIntentsRegistry(tab_contents_)->GetIntentServices(
254 action, type, 270 action, type,
255 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, 271 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable,
256 weak_ptr_factory_.GetWeakPtr())); 272 weak_ptr_factory_.GetWeakPtr()));
257 273
258 GURL invoking_url = tab_contents_->web_contents()->GetURL(); 274 GURL invoking_url = tab_contents_->web_contents()->GetURL();
259 if (invoking_url.is_valid()) { 275 if (invoking_url.is_valid()) {
260 pending_async_count_++; 276 pending_async_count_++;
261 pending_registry_calls_count_++; 277 pending_registry_calls_count_++;
262 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( 278 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService(
263 action, type, invoking_url, 279 action, type, invoking_url,
264 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, 280 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable,
265 weak_ptr_factory_.GetWeakPtr())); 281 weak_ptr_factory_.GetWeakPtr()));
266 } 282 }
267 283
268 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( 284 pending_cws_request_ = true;
269 action, type, 285 pending_async_count_++;
270 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, 286 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices(
271 weak_ptr_factory_.GetWeakPtr())); 287 picker_model_->action(), picker_model_->type(),
288 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable,
289 weak_ptr_factory_.GetWeakPtr()));
272 } 290 }
273 291
274 void WebIntentPickerController::Observe( 292 void WebIntentPickerController::Observe(
275 int type, 293 int type,
276 const content::NotificationSource& source, 294 const content::NotificationSource& source,
277 const content::NotificationDetails& details) { 295 const content::NotificationDetails& details) {
278 DCHECK(type == content::NOTIFICATION_LOAD_START || 296 DCHECK(type == content::NOTIFICATION_LOAD_START ||
279 type == chrome::NOTIFICATION_TAB_CLOSING); 297 type == chrome::NOTIFICATION_TAB_CLOSING);
280 ClosePicker(); 298 ClosePicker();
281 } 299 }
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 void WebIntentPickerController::WebIntentServicesForExplicitIntent( 541 void WebIntentPickerController::WebIntentServicesForExplicitIntent(
524 const std::vector<webkit_glue::WebIntentServiceData>& services) { 542 const std::vector<webkit_glue::WebIntentServiceData>& services) {
525 DCHECK(intents_dispatcher_); 543 DCHECK(intents_dispatcher_);
526 DCHECK(intents_dispatcher_->GetIntent().service.is_valid()); 544 DCHECK(intents_dispatcher_->GetIntent().service.is_valid());
527 for (size_t i = 0; i < services.size(); ++i) { 545 for (size_t i = 0; i < services.size(); ++i) {
528 if (services[i].service_url != intents_dispatcher_->GetIntent().service) 546 if (services[i].service_url != intents_dispatcher_->GetIntent().service)
529 continue; 547 continue;
530 548
531 AddServiceToModel(services[i]); 549 AddServiceToModel(services[i]);
532 550
533 if (services[i].disposition == 551 InvokeService(picker_model_->GetInstalledServiceAt(i));
534 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE)
535 CreatePicker();
536 OnServiceChosen(services[i].service_url,
537 ConvertDisposition(services[i].disposition));
538 AsyncOperationFinished(); 552 AsyncOperationFinished();
539 return; 553 return;
540 } 554 }
541 555
542 // No acceptable extension. The intent cannot be dispatched. 556 // No acceptable extension. The intent cannot be dispatched.
543 intents_dispatcher_->SendReplyMessage( 557 intents_dispatcher_->SendReplyMessage(
544 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( 558 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16(
545 "Explicit extension URL is not available.")); 559 "Explicit extension URL is not available."));
546 560
547 AsyncOperationFinished(); 561 AsyncOperationFinished();
(...skipping 15 matching lines...) Expand all
563 if (pending_registry_calls_count_ != 0) return; 577 if (pending_registry_calls_count_ != 0) return;
564 578
565 if (picker_model_->default_service_url().is_valid()) { 579 if (picker_model_->default_service_url().is_valid()) {
566 // If there's a default service, dispatch to it immediately 580 // If there's a default service, dispatch to it immediately
567 // without showing the picker. 581 // without showing the picker.
568 const WebIntentPickerModel::InstalledService* default_service = 582 const WebIntentPickerModel::InstalledService* default_service =
569 picker_model_->GetInstalledServiceWithURL( 583 picker_model_->GetInstalledServiceWithURL(
570 GURL(picker_model_->default_service_url())); 584 GURL(picker_model_->default_service_url()));
571 585
572 if (default_service != NULL) { 586 if (default_service != NULL) {
573 if (default_service->disposition == 587 InvokeService(*default_service);
574 WebIntentPickerModel::DISPOSITION_INLINE)
575 CreatePicker();
576
577 OnServiceChosen(default_service->url, default_service->disposition);
578 return; 588 return;
579 } 589 }
580 } 590 }
581 591
582 CreatePicker(); 592 OnPickerEvent(kPickerEventRegistryDataComplete);
583 picker_->SetActionString(GetIntentActionString( 593 OnIntentDataArrived();
584 UTF16ToUTF8(picker_model_->action())));
585 } 594 }
586 595
587 void WebIntentPickerController::OnFaviconDataAvailable( 596 void WebIntentPickerController::OnFaviconDataAvailable(
588 FaviconService::Handle handle, history::FaviconData favicon_data) { 597 FaviconService::Handle handle, history::FaviconData favicon_data) {
589 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); 598 size_t index = favicon_consumer_.GetClientDataForCurrentRequest();
590 if (favicon_data.is_valid()) { 599 if (favicon_data.is_valid()) {
591 SkBitmap icon_bitmap; 600 SkBitmap icon_bitmap;
592 601
593 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), 602 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(),
594 favicon_data.image_data->size(), 603 favicon_data.image_data->size(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 weak_ptr_factory_.GetWeakPtr(), info.id))); 638 weak_ptr_factory_.GetWeakPtr(), info.id)));
630 639
631 icon_url_fetcher->SetLoadFlags( 640 icon_url_fetcher->SetLoadFlags(
632 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 641 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
633 icon_url_fetcher->SetRequestContext( 642 icon_url_fetcher->SetRequestContext(
634 tab_contents_->profile()->GetRequestContext()); 643 tab_contents_->profile()->GetRequestContext());
635 icon_url_fetcher->Start(); 644 icon_url_fetcher->Start();
636 } 645 }
637 646
638 AsyncOperationFinished(); 647 AsyncOperationFinished();
648 pending_cws_request_ = false;
649 OnIntentDataArrived();
639 } 650 }
640 651
641 void WebIntentPickerController::OnExtensionIconURLFetchComplete( 652 void WebIntentPickerController::OnExtensionIconURLFetchComplete(
642 const string16& extension_id, const net::URLFetcher* source) { 653 const string16& extension_id, const net::URLFetcher* source) {
643 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 654 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
644 if (source->GetResponseCode() != 200) { 655 if (source->GetResponseCode() != 200) {
645 AsyncOperationFinished(); 656 AsyncOperationFinished();
646 return; 657 return;
647 } 658 }
648 659
(...skipping 27 matching lines...) Expand all
676 687
677 // Decode PNG and resize on worker thread. 688 // Decode PNG and resize on worker thread.
678 content::BrowserThread::PostBlockingPoolTask( 689 content::BrowserThread::PostBlockingPoolTask(
679 FROM_HERE, 690 FROM_HERE,
680 base::Bind(&DecodeExtensionIconAndResize, 691 base::Bind(&DecodeExtensionIconAndResize,
681 base::Passed(&response), 692 base::Passed(&response),
682 available_callback, 693 available_callback,
683 unavailable_callback)); 694 unavailable_callback));
684 } 695 }
685 696
697 void WebIntentPickerController::OnIntentDataArrived() {
698 DCHECK(picker_model_.get());
699
700 if (!pending_cws_request_ &&
701 pending_registry_calls_count_ == 0)
702 OnPickerEvent(kPickerEventAsyncDataComplete);
703 }
704
686 // static 705 // static
687 void WebIntentPickerController::DecodeExtensionIconAndResize( 706 void WebIntentPickerController::DecodeExtensionIconAndResize(
688 scoped_ptr<std::string> icon_response, 707 scoped_ptr<std::string> icon_response,
689 const ExtensionIconAvailableCallback& callback, 708 const ExtensionIconAvailableCallback& callback,
690 const base::Closure& unavailable_callback) { 709 const base::Closure& unavailable_callback) {
691 SkBitmap icon_bitmap; 710 SkBitmap icon_bitmap;
692 if (gfx::PNGCodec::Decode( 711 if (gfx::PNGCodec::Decode(
693 reinterpret_cast<const unsigned char*>(icon_response->data()), 712 reinterpret_cast<const unsigned char*>(icon_response->data()),
694 icon_response->length(), 713 icon_response->length(),
695 &icon_bitmap)) { 714 &icon_bitmap)) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 767
749 void WebIntentPickerController::SourceDispatcherReplied( 768 void WebIntentPickerController::SourceDispatcherReplied(
750 webkit_glue::WebIntentReplyType reply_type) { 769 webkit_glue::WebIntentReplyType reply_type) {
751 source_intents_dispatcher_ = NULL; 770 source_intents_dispatcher_ = NULL;
752 } 771 }
753 772
754 bool WebIntentPickerController::ShowLocationBarPickerTool() { 773 bool WebIntentPickerController::ShowLocationBarPickerTool() {
755 return window_disposition_source_ || source_intents_dispatcher_; 774 return window_disposition_source_ || source_intents_dispatcher_;
756 } 775 }
757 776
777 void WebIntentPickerController::OnPickerEvent(WebIntentPickerEvent event) {
778 switch (event) {
779 case kPickerEventHiddenSetupTimeout:
780 DCHECK(dialog_state_ == kPickerSetup);
781 SetDialogState(kPickerWaiting);
782 break;
783
784 case kPickerEventMaxWaitTimeExceeded:
785 DCHECK(dialog_state_ == kPickerWaiting);
786
787 // If registry data is complete, go to main dialog. Otherwise, wait.
788 if (pending_registry_calls_count_ == 0)
789 SetDialogState(kPickerMain);
790 else
791 SetDialogState(kPickerWaitLong);
792 break;
793
794 case kPickerEventRegistryDataComplete:
795 DCHECK(dialog_state_ == kPickerSetup ||
796 dialog_state_ == kPickerWaiting ||
797 dialog_state_ == kPickerWaitLong);
798
799 // If minimum wait dialog time is exceeded, display main dialog.
800 // Either way, we don't do a thing.
801 break;
802
803 case kPickerEventAsyncDataComplete:
804 DCHECK(dialog_state_ == kPickerSetup ||
805 dialog_state_ == kPickerWaiting);
806
807 // In setup state, transition to main dialog. In waiting state, let
808 // timer expire.
809 if (dialog_state_ == kPickerSetup)
810 SetDialogState(kPickerMain);
811 break;
812
813 default:
814 NOTREACHED();
815 break;
816 }
817 }
818
758 void WebIntentPickerController::AsyncOperationFinished() { 819 void WebIntentPickerController::AsyncOperationFinished() {
759 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 820 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
760 if (--pending_async_count_ == 0) { 821 if (--pending_async_count_ == 0) {
761 if (picker_) 822 if (picker_)
762 picker_->OnPendingAsyncCompleted(); 823 picker_->OnPendingAsyncCompleted();
763 } 824 }
764 } 825 }
765 826
827 void WebIntentPickerController::InvokeService(
828 const WebIntentPickerModel::InstalledService& service) {
829 if (service.disposition == WebIntentPickerModel::DISPOSITION_INLINE) {
830 SetDialogState(kPickerMain);
831 }
832 OnServiceChosen(service.url, service.disposition);
833 }
834
835 void WebIntentPickerController::SetDialogState(WebIntentPickerState state) {
836 // Ignore events that don't change state.
837 if (state == dialog_state_)
838 return;
839
840 // Any pending timers are abandoned on state changes.
841 timer_factory_.InvalidateWeakPtrs();
842
843 switch (state) {
844 case kPickerSetup:
845 DCHECK(dialog_state_ == kPickerHidden);
846
847 // Post timer CWS pending
848 MessageLoop::current()->PostDelayedTask(FROM_HERE,
849 base::Bind(&WebIntentPickerController::OnPickerEvent,
850 timer_factory_.GetWeakPtr(),
851 kPickerEventHiddenSetupTimeout),
852 base::TimeDelta::FromMilliseconds(kMaxHiddenSetupTimeMs));
853 break;
854
855 case kPickerWaiting:
856 DCHECK(dialog_state_ == kPickerSetup);
857 // Waiting dialog can be dismissed after minimum wait time.
858 MessageLoop::current()->PostDelayedTask(FROM_HERE,
859 base::Bind(&WebIntentPickerController::OnPickerEvent,
860 timer_factory_.GetWeakPtr(),
861 kPickerEventMaxWaitTimeExceeded),
862 base::TimeDelta::FromMilliseconds(kMinThrobberDisplayTimeMs));
863 break;
864
865 case kPickerWaitLong:
866 DCHECK(dialog_state_ == kPickerWaiting);
867 break;
868
869 case kPickerMain:
870 // No DCHECK - main state can be reached from any state.
871 // Ready to display data.
872 picker_model_->SetWaitingForSuggestions(false);
873 break;
874
875 case kPickerHidden:
876 break;
877
878 default:
879 NOTREACHED();
880 break;
881
882 }
883
884 dialog_state_ = state;
885
886 // Create picker dialog when changing away from hidden state.
887 if (dialog_state_ != kPickerHidden && dialog_state_ != kPickerSetup)
888 CreatePicker();
889 }
890
891
766 void WebIntentPickerController::CreatePicker() { 892 void WebIntentPickerController::CreatePicker() {
767 // If picker is non-NULL, it was set by a test. 893 // If picker is non-NULL, it was set by a test.
768 if (picker_ == NULL) 894 if (picker_ == NULL)
769 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); 895 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get());
896 picker_->SetActionString(GetIntentActionString(
897 UTF16ToUTF8(picker_model_->action())));
770 picker_shown_ = true; 898 picker_shown_ = true;
771 } 899 }
772 900
773 void WebIntentPickerController::ClosePicker() { 901 void WebIntentPickerController::ClosePicker() {
902 SetDialogState(kPickerHidden);
774 if (picker_) 903 if (picker_)
775 picker_->Close(); 904 picker_->Close();
776 } 905 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/intents/web_intent_picker_controller.h ('k') | chrome/browser/ui/intents/web_intent_picker_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698