| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 #include "net/url_request/url_fetcher.h" | 50 #include "net/url_request/url_fetcher.h" |
| 51 #include "net/url_request/url_fetcher_delegate.h" | 51 #include "net/url_request/url_fetcher_delegate.h" |
| 52 #include "skia/ext/image_operations.h" | 52 #include "skia/ext/image_operations.h" |
| 53 #include "ui/base/l10n/l10n_util.h" | 53 #include "ui/base/l10n/l10n_util.h" |
| 54 #include "ui/gfx/codec/png_codec.h" | 54 #include "ui/gfx/codec/png_codec.h" |
| 55 #include "ui/gfx/favicon_size.h" | 55 #include "ui/gfx/favicon_size.h" |
| 56 #include "ui/gfx/image/image.h" | 56 #include "ui/gfx/image/image.h" |
| 57 | 57 |
| 58 using extensions::WebstoreInstaller; | 58 using extensions::WebstoreInstaller; |
| 59 | 59 |
| 60 int WebIntentPickerController::kUserDataKey; |
| 61 |
| 60 namespace { | 62 namespace { |
| 61 | 63 |
| 62 // Maximum amount of time to delay displaying dialog while waiting for data. | 64 // Maximum amount of time to delay displaying dialog while waiting for data. |
| 63 const int kMaxHiddenSetupTimeMs = 200; | 65 const int kMaxHiddenSetupTimeMs = 200; |
| 64 | 66 |
| 65 // Minimum amount of time to show waiting dialog, if it is shown. | 67 // Minimum amount of time to show waiting dialog, if it is shown. |
| 66 const int kMinThrobberDisplayTimeMs = 800; | 68 const int kMinThrobberDisplayTimeMs = 800; |
| 67 | 69 |
| 68 | 70 |
| 69 // Gets the favicon service for the profile in |tab_contents|. | 71 // Gets the favicon service for the specified profile. |
| 70 FaviconService* GetFaviconService(TabContents* tab_contents) { | 72 FaviconService* GetFaviconService(Profile* profile) { |
| 71 return FaviconServiceFactory::GetForProfile(tab_contents->profile(), | 73 return FaviconServiceFactory::GetForProfile(profile, |
| 72 Profile::EXPLICIT_ACCESS); | 74 Profile::EXPLICIT_ACCESS); |
| 73 } | 75 } |
| 74 | 76 |
| 75 // Gets the web intents registry for the profile in |tab_contents|. | 77 // Gets the web intents registry for the specified profile. |
| 76 WebIntentsRegistry* GetWebIntentsRegistry(TabContents* tab_contents) { | 78 WebIntentsRegistry* GetWebIntentsRegistry(Profile* profile) { |
| 77 return WebIntentsRegistryFactory::GetForProfile(tab_contents->profile()); | 79 return WebIntentsRegistryFactory::GetForProfile(profile); |
| 78 } | 80 } |
| 79 | 81 |
| 80 // Gets the Chrome web store intents registry for the profile in |tab_contents|. | 82 // Gets the Chrome web store intents registry for the specified profile. |
| 81 CWSIntentsRegistry* GetCWSIntentsRegistry(TabContents* tab_contents) { | 83 CWSIntentsRegistry* GetCWSIntentsRegistry(Profile* profile) { |
| 82 return CWSIntentsRegistryFactory::GetForProfile(tab_contents->profile()); | 84 return CWSIntentsRegistryFactory::GetForProfile(profile); |
| 83 } | 85 } |
| 84 | 86 |
| 85 // Returns the action-specific string for |action|. | 87 // Returns the action-specific string for |action|. |
| 86 string16 GetIntentActionString(const std::string& action) { | 88 string16 GetIntentActionString(const std::string& action) { |
| 87 if (!action.compare(web_intents::kActionShare)) | 89 if (!action.compare(web_intents::kActionShare)) |
| 88 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_SHARE); | 90 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_SHARE); |
| 89 else if (!action.compare(web_intents::kActionEdit)) | 91 else if (!action.compare(web_intents::kActionEdit)) |
| 90 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_EDIT); | 92 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_EDIT); |
| 91 else if (!action.compare(web_intents::kActionView)) | 93 else if (!action.compare(web_intents::kActionView)) |
| 92 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_VIEW); | 94 return l10n_util::GetStringUTF16(IDS_WEB_INTENTS_ACTION_VIEW); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 | 179 |
| 178 void WebIntentPickerController::UMAReporter::RecordServiceActiveDuration( | 180 void WebIntentPickerController::UMAReporter::RecordServiceActiveDuration( |
| 179 webkit_glue::WebIntentReplyType reply_type) { | 181 webkit_glue::WebIntentReplyType reply_type) { |
| 180 if (!service_start_time_.is_null()) { | 182 if (!service_start_time_.is_null()) { |
| 181 web_intents::RecordServiceActiveDuration(reply_type, | 183 web_intents::RecordServiceActiveDuration(reply_type, |
| 182 base::TimeTicks::Now() - service_start_time_); | 184 base::TimeTicks::Now() - service_start_time_); |
| 183 } | 185 } |
| 184 } | 186 } |
| 185 | 187 |
| 186 WebIntentPickerController::WebIntentPickerController( | 188 WebIntentPickerController::WebIntentPickerController( |
| 187 TabContents* tab_contents) | 189 content::WebContents* web_contents) |
| 188 : dialog_state_(kPickerHidden), | 190 : dialog_state_(kPickerHidden), |
| 189 tab_contents_(tab_contents), | 191 web_contents_(web_contents), |
| 192 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), |
| 190 picker_(NULL), | 193 picker_(NULL), |
| 191 picker_model_(new WebIntentPickerModel()), | 194 picker_model_(new WebIntentPickerModel()), |
| 192 uma_reporter_(new UMAReporter()), | 195 uma_reporter_(new UMAReporter()), |
| 193 pending_async_count_(0), | 196 pending_async_count_(0), |
| 194 pending_registry_calls_count_(0), | 197 pending_registry_calls_count_(0), |
| 195 pending_cws_request_(false), | 198 pending_cws_request_(false), |
| 196 picker_shown_(false), | 199 picker_shown_(false), |
| 197 window_disposition_source_(NULL), | 200 window_disposition_source_(NULL), |
| 198 source_intents_dispatcher_(NULL), | 201 source_intents_dispatcher_(NULL), |
| 199 intents_dispatcher_(NULL), | 202 intents_dispatcher_(NULL), |
| 200 service_tab_(NULL), | 203 service_tab_(NULL), |
| 201 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | 204 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
| 202 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)), | 205 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)), |
| 203 ALLOW_THIS_IN_INITIALIZER_LIST(dispatcher_factory_(this)) { | 206 ALLOW_THIS_IN_INITIALIZER_LIST(dispatcher_factory_(this)) { |
| 204 content::NavigationController* controller = | 207 content::NavigationController* controller = &web_contents->GetController(); |
| 205 &tab_contents->web_contents()->GetController(); | |
| 206 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 208 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
| 207 content::Source<content::NavigationController>(controller)); | 209 content::Source<content::NavigationController>(controller)); |
| 208 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, | 210 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, |
| 209 content::Source<content::NavigationController>(controller)); | 211 content::Source<content::NavigationController>(controller)); |
| 210 #if defined(TOOLKIT_VIEWS) | 212 #if defined(TOOLKIT_VIEWS) |
| 211 cancelled_ = true; | 213 cancelled_ = true; |
| 212 #endif | 214 #endif |
| 213 } | 215 } |
| 214 | 216 |
| 215 WebIntentPickerController::~WebIntentPickerController() { | 217 WebIntentPickerController::~WebIntentPickerController() { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 // in this method, but only after calling the registry. | 258 // in this method, but only after calling the registry. |
| 257 if (picker_shown_) { | 259 if (picker_shown_) { |
| 258 intents_dispatcher_->SendReplyMessage( | 260 intents_dispatcher_->SendReplyMessage( |
| 259 webkit_glue::WEB_INTENT_REPLY_FAILURE, | 261 webkit_glue::WEB_INTENT_REPLY_FAILURE, |
| 260 ASCIIToUTF16("Simultaneous intent invocation.")); | 262 ASCIIToUTF16("Simultaneous intent invocation.")); |
| 261 return; | 263 return; |
| 262 } | 264 } |
| 263 | 265 |
| 264 // TODO(binji): Figure out what to do when intents are invoked from incognito | 266 // TODO(binji): Figure out what to do when intents are invoked from incognito |
| 265 // mode. | 267 // mode. |
| 266 if (tab_contents_->profile()->IsOffTheRecord()) { | 268 if (profile_->IsOffTheRecord()) { |
| 267 intents_dispatcher_->SendReplyMessage( | 269 intents_dispatcher_->SendReplyMessage( |
| 268 webkit_glue::WEB_INTENT_REPLY_FAILURE, string16()); | 270 webkit_glue::WEB_INTENT_REPLY_FAILURE, string16()); |
| 269 return; | 271 return; |
| 270 } | 272 } |
| 271 | 273 |
| 272 picker_model_->Clear(); | 274 picker_model_->Clear(); |
| 273 picker_model_->set_action(intents_dispatcher_->GetIntent().action); | 275 picker_model_->set_action(intents_dispatcher_->GetIntent().action); |
| 274 picker_model_->set_type(intents_dispatcher_->GetIntent().type); | 276 picker_model_->set_type(intents_dispatcher_->GetIntent().type); |
| 275 | 277 |
| 276 // If the intent is explicit, skip showing the picker. | 278 // If the intent is explicit, skip showing the picker. |
| 277 const GURL& service = intents_dispatcher_->GetIntent().service; | 279 const GURL& service = intents_dispatcher_->GetIntent().service; |
| 278 // TODO(gbillock): Decide whether to honor the default suppression flag | 280 // TODO(gbillock): Decide whether to honor the default suppression flag |
| 279 // here or suppress the control for explicit intents. | 281 // here or suppress the control for explicit intents. |
| 280 if (service.is_valid() && !suppress_defaults) { | 282 if (service.is_valid() && !suppress_defaults) { |
| 281 // TODO(gbillock): When we can parse pages for the intent tag, | 283 // TODO(gbillock): When we can parse pages for the intent tag, |
| 282 // take out this requirement that explicit intents dispatch to | 284 // take out this requirement that explicit intents dispatch to |
| 283 // extension urls. | 285 // extension urls. |
| 284 if (!service.SchemeIs(chrome::kExtensionScheme)) { | 286 if (!service.SchemeIs(chrome::kExtensionScheme)) { |
| 285 intents_dispatcher_->SendReplyMessage( | 287 intents_dispatcher_->SendReplyMessage( |
| 286 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( | 288 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( |
| 287 "Only extension urls are supported for explicit invocation")); | 289 "Only extension urls are supported for explicit invocation")); |
| 288 return; | 290 return; |
| 289 } | 291 } |
| 290 | 292 |
| 291 // Get services from the registry to verify a registered extension | 293 // Get services from the registry to verify a registered extension |
| 292 // page for this action/type if it is permitted to be dispatched. (Also | 294 // page for this action/type if it is permitted to be dispatched. (Also |
| 293 // required to find disposition set by service.) | 295 // required to find disposition set by service.) |
| 294 pending_async_count_++; | 296 pending_async_count_++; |
| 295 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( | 297 GetWebIntentsRegistry(profile_)->GetIntentServices( |
| 296 picker_model_->action(), picker_model_->type(), | 298 picker_model_->action(), picker_model_->type(), |
| 297 base::Bind( | 299 base::Bind( |
| 298 &WebIntentPickerController:: | 300 &WebIntentPickerController:: |
| 299 OnWebIntentServicesAvailableForExplicitIntent, | 301 OnWebIntentServicesAvailableForExplicitIntent, |
| 300 weak_ptr_factory_.GetWeakPtr())); | 302 weak_ptr_factory_.GetWeakPtr())); |
| 301 return; | 303 return; |
| 302 } | 304 } |
| 303 | 305 |
| 304 // As soon as the dialog is requested, block all input events | 306 // As soon as the dialog is requested, block all input events |
| 305 // on the original tab. | 307 // on the original tab. |
| 306 tab_contents_->constrained_window_tab_helper()->BlockTabContent(true); | 308 TabContents* tab_contents = TabContents::FromWebContents(web_contents_); |
| 309 tab_contents->constrained_window_tab_helper()->BlockTabContent(true); |
| 307 SetDialogState(kPickerSetup); | 310 SetDialogState(kPickerSetup); |
| 308 | 311 |
| 309 pending_async_count_++; | 312 pending_async_count_++; |
| 310 pending_registry_calls_count_++; | 313 pending_registry_calls_count_++; |
| 311 GetWebIntentsRegistry(tab_contents_)->GetIntentServices( | 314 GetWebIntentsRegistry(profile_)->GetIntentServices( |
| 312 picker_model_->action(), picker_model_->type(), | 315 picker_model_->action(), picker_model_->type(), |
| 313 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, | 316 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, |
| 314 weak_ptr_factory_.GetWeakPtr())); | 317 weak_ptr_factory_.GetWeakPtr())); |
| 315 | 318 |
| 316 GURL invoking_url = tab_contents_->web_contents()->GetURL(); | 319 GURL invoking_url = web_contents_->GetURL(); |
| 317 if (invoking_url.is_valid() && !suppress_defaults) { | 320 if (invoking_url.is_valid() && !suppress_defaults) { |
| 318 pending_async_count_++; | 321 pending_async_count_++; |
| 319 pending_registry_calls_count_++; | 322 pending_registry_calls_count_++; |
| 320 GetWebIntentsRegistry(tab_contents_)->GetDefaultIntentService( | 323 GetWebIntentsRegistry(profile_)->GetDefaultIntentService( |
| 321 picker_model_->action(), picker_model_->type(), invoking_url, | 324 picker_model_->action(), picker_model_->type(), invoking_url, |
| 322 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, | 325 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, |
| 323 weak_ptr_factory_.GetWeakPtr())); | 326 weak_ptr_factory_.GetWeakPtr())); |
| 324 } | 327 } |
| 325 | 328 |
| 326 pending_cws_request_ = true; | 329 pending_cws_request_ = true; |
| 327 pending_async_count_++; | 330 pending_async_count_++; |
| 328 GetCWSIntentsRegistry(tab_contents_)->GetIntentServices( | 331 GetCWSIntentsRegistry(profile_)->GetIntentServices( |
| 329 picker_model_->action(), picker_model_->type(), | 332 picker_model_->action(), picker_model_->type(), |
| 330 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, | 333 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, |
| 331 weak_ptr_factory_.GetWeakPtr())); | 334 weak_ptr_factory_.GetWeakPtr())); |
| 332 } | 335 } |
| 333 | 336 |
| 334 void WebIntentPickerController::Observe( | 337 void WebIntentPickerController::Observe( |
| 335 int type, | 338 int type, |
| 336 const content::NotificationSource& source, | 339 const content::NotificationSource& source, |
| 337 const content::NotificationDetails& details) { | 340 const content::NotificationDetails& details) { |
| 338 DCHECK(type == content::NOTIFICATION_LOAD_START || | 341 DCHECK(type == content::NOTIFICATION_LOAD_START || |
| 339 type == chrome::NOTIFICATION_TAB_CLOSING); | 342 type == chrome::NOTIFICATION_TAB_CLOSING); |
| 340 ClosePicker(); | 343 ClosePicker(); |
| 341 } | 344 } |
| 342 | 345 |
| 343 void WebIntentPickerController::OnServiceChosen( | 346 void WebIntentPickerController::OnServiceChosen( |
| 344 const GURL& url, | 347 const GURL& url, |
| 345 webkit_glue::WebIntentServiceData::Disposition disposition) { | 348 webkit_glue::WebIntentServiceData::Disposition disposition) { |
| 346 web_intents::RecordServiceInvoke(uma_bucket_); | 349 web_intents::RecordServiceInvoke(uma_bucket_); |
| 347 uma_reporter_->ResetServiceActiveTimer(); | 350 uma_reporter_->ResetServiceActiveTimer(); |
| 348 ExtensionService* service = tab_contents_->profile()->GetExtensionService(); | 351 ExtensionService* service = profile_->GetExtensionService(); |
| 349 DCHECK(service); | 352 DCHECK(service); |
| 350 | 353 |
| 351 #if defined(TOOLKIT_VIEWS) | 354 #if defined(TOOLKIT_VIEWS) |
| 352 cancelled_ = false; | 355 cancelled_ = false; |
| 353 #endif | 356 #endif |
| 354 | 357 |
| 355 // Set the default here. Activating the intent resets the picker model. | 358 // Set the default here. Activating the intent resets the picker model. |
| 356 // TODO(gbillock): we should perhaps couple the model to the dispatcher so | 359 // TODO(gbillock): we should perhaps couple the model to the dispatcher so |
| 357 // we can re-activate the model on use-another-service. | 360 // we can re-activate the model on use-another-service. |
| 358 SetDefaultServiceForSelection(url); | 361 SetDefaultServiceForSelection(url); |
| 359 | 362 |
| 360 const extensions::Extension* extension = service->GetInstalledApp(url); | 363 const extensions::Extension* extension = service->GetInstalledApp(url); |
| 361 | 364 |
| 362 // TODO(smckay): this basically smells like another disposition. | 365 // TODO(smckay): this basically smells like another disposition. |
| 363 if (extension && extension->is_platform_app()) { | 366 if (extension && extension->is_platform_app()) { |
| 364 extensions::LaunchPlatformAppWithWebIntent(tab_contents_->profile(), | 367 extensions::LaunchPlatformAppWithWebIntent(profile_, |
| 365 extension, intents_dispatcher_, tab_contents_->web_contents()); | 368 extension, intents_dispatcher_, web_contents_); |
| 366 ClosePicker(); | 369 ClosePicker(); |
| 367 return; | 370 return; |
| 368 } | 371 } |
| 369 | 372 |
| 370 switch (disposition) { | 373 switch (disposition) { |
| 371 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE: | 374 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE: |
| 372 // Set the model to inline disposition. It will notify the picker which | 375 // Set the model to inline disposition. It will notify the picker which |
| 373 // will respond (via OnInlineDispositionWebContentsCreated) with the | 376 // will respond (via OnInlineDispositionWebContentsCreated) with the |
| 374 // WebContents to dispatch the intent to. | 377 // WebContents to dispatch the intent to. |
| 375 picker_model_->SetInlineDisposition(url); | 378 picker_model_->SetInlineDisposition(url); |
| 376 break; | 379 break; |
| 377 | 380 |
| 378 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW: { | 381 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW: { |
| 379 TabContents* contents = chrome::TabContentsFactory( | 382 TabContents* contents = chrome::TabContentsFactory( |
| 380 tab_contents_->profile(), | 383 profile_, |
| 381 tab_util::GetSiteInstanceForNewTab( | 384 tab_util::GetSiteInstanceForNewTab(profile_, url), |
| 382 tab_contents_->profile(), url), | |
| 383 MSG_ROUTING_NONE, NULL); | 385 MSG_ROUTING_NONE, NULL); |
| 384 | 386 |
| 385 // Let the controller for the target TabContents know that it is hosting a | 387 // Let the controller for the target TabContents know that it is hosting a |
| 386 // web intents service. | 388 // web intents service. |
| 387 contents->web_intent_picker_controller()->SetWindowDispositionSource( | 389 WebIntentPickerController::FromWebContents(contents->web_contents())-> |
| 388 tab_contents_->web_contents(), intents_dispatcher_); | 390 SetWindowDispositionSource(web_contents_, intents_dispatcher_); |
| 389 | 391 |
| 390 intents_dispatcher_->DispatchIntent(contents->web_contents()); | 392 intents_dispatcher_->DispatchIntent(contents->web_contents()); |
| 391 service_tab_ = contents->web_contents(); | 393 service_tab_ = contents->web_contents(); |
| 392 | 394 |
| 393 // This call performs all the tab strip manipulation, notifications, etc. | 395 // This call performs all the tab strip manipulation, notifications, etc. |
| 394 // Since we're passing in a target_contents, it assumes that we will | 396 // Since we're passing in a target_contents, it assumes that we will |
| 395 // navigate the page ourselves, though. | 397 // navigate the page ourselves, though. |
| 396 chrome::NavigateParams params(tab_contents_->profile(), url, | 398 chrome::NavigateParams params(profile_, url, |
| 397 content::PAGE_TRANSITION_LINK); | 399 content::PAGE_TRANSITION_LINK); |
| 398 params.target_contents = contents; | 400 params.target_contents = contents; |
| 399 params.disposition = NEW_FOREGROUND_TAB; | 401 params.disposition = NEW_FOREGROUND_TAB; |
| 400 params.tabstrip_add_types = TabStripModel::ADD_INHERIT_GROUP; | 402 params.tabstrip_add_types = TabStripModel::ADD_INHERIT_GROUP; |
| 401 chrome::Navigate(¶ms); | 403 chrome::Navigate(¶ms); |
| 402 | 404 |
| 403 service_tab_->GetController().LoadURL( | 405 service_tab_->GetController().LoadURL( |
| 404 url, content::Referrer(), | 406 url, content::Referrer(), |
| 405 content::PAGE_TRANSITION_AUTO_BOOKMARK, std::string()); | 407 content::PAGE_TRANSITION_AUTO_BOOKMARK, std::string()); |
| 406 | 408 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 service_hash == picker_model_->default_service_hash()) { | 453 service_hash == picker_model_->default_service_hash()) { |
| 452 return; | 454 return; |
| 453 } | 455 } |
| 454 | 456 |
| 455 DefaultWebIntentService record; | 457 DefaultWebIntentService record; |
| 456 record.action = picker_model_->action(); | 458 record.action = picker_model_->action(); |
| 457 record.type = picker_model_->type(); | 459 record.type = picker_model_->type(); |
| 458 record.service_url = url.spec(); | 460 record.service_url = url.spec(); |
| 459 record.suppression = service_hash; | 461 record.suppression = service_hash; |
| 460 record.user_date = static_cast<int>(floor(base::Time::Now().ToDoubleT())); | 462 record.user_date = static_cast<int>(floor(base::Time::Now().ToDoubleT())); |
| 461 GetWebIntentsRegistry(tab_contents_)->RegisterDefaultIntentService(record); | 463 GetWebIntentsRegistry(profile_)->RegisterDefaultIntentService(record); |
| 462 } | 464 } |
| 463 | 465 |
| 464 void WebIntentPickerController::OnInlineDispositionWebContentsCreated( | 466 void WebIntentPickerController::OnInlineDispositionWebContentsCreated( |
| 465 content::WebContents* web_contents) { | 467 content::WebContents* web_contents) { |
| 466 if (web_contents) | 468 if (web_contents) |
| 467 intents_dispatcher_->DispatchIntent(web_contents); | 469 intents_dispatcher_->DispatchIntent(web_contents); |
| 468 } | 470 } |
| 469 | 471 |
| 470 void WebIntentPickerController::OnExtensionInstallRequested( | 472 void WebIntentPickerController::OnExtensionInstallRequested( |
| 471 const std::string& id) { | 473 const std::string& id) { |
| 472 scoped_ptr<WebstoreInstaller::Approval> approval( | 474 scoped_ptr<WebstoreInstaller::Approval> approval( |
| 473 WebstoreInstaller::Approval::CreateWithInstallPrompt( | 475 WebstoreInstaller::Approval::CreateWithInstallPrompt(profile_)); |
| 474 tab_contents_->profile())); | |
| 475 | 476 |
| 476 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 477 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| 477 tab_contents_->profile(), this, | 478 profile_, this, |
| 478 &tab_contents_->web_contents()->GetController(), id, | 479 &web_contents_->GetController(), id, |
| 479 approval.Pass(), WebstoreInstaller::FLAG_INLINE_INSTALL); | 480 approval.Pass(), WebstoreInstaller::FLAG_INLINE_INSTALL); |
| 480 | 481 |
| 481 pending_async_count_++; | 482 pending_async_count_++; |
| 482 installer->Start(); | 483 installer->Start(); |
| 483 } | 484 } |
| 484 | 485 |
| 485 void WebIntentPickerController::OnExtensionLinkClicked( | 486 void WebIntentPickerController::OnExtensionLinkClicked( |
| 486 const std::string& id, | 487 const std::string& id, |
| 487 WindowOpenDisposition disposition) { | 488 WindowOpenDisposition disposition) { |
| 488 // Navigate from source tab. | 489 // Navigate from source tab. |
| 489 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() + id); | 490 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() + id); |
| 490 chrome::NavigateParams params(tab_contents_->profile(), extension_url, | 491 chrome::NavigateParams params(profile_, extension_url, |
| 491 content::PAGE_TRANSITION_LINK); | 492 content::PAGE_TRANSITION_LINK); |
| 492 params.disposition = | 493 params.disposition = |
| 493 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition; | 494 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition; |
| 494 chrome::Navigate(¶ms); | 495 chrome::Navigate(¶ms); |
| 495 } | 496 } |
| 496 | 497 |
| 497 void WebIntentPickerController::OnSuggestionsLinkClicked( | 498 void WebIntentPickerController::OnSuggestionsLinkClicked( |
| 498 WindowOpenDisposition disposition) { | 499 WindowOpenDisposition disposition) { |
| 499 // Navigate from source tab. | 500 // Navigate from source tab. |
| 500 GURL query_url = extension_urls::GetWebstoreIntentQueryURL( | 501 GURL query_url = extension_urls::GetWebstoreIntentQueryURL( |
| 501 UTF16ToUTF8(picker_model_->action()), | 502 UTF16ToUTF8(picker_model_->action()), |
| 502 UTF16ToUTF8(picker_model_->type())); | 503 UTF16ToUTF8(picker_model_->type())); |
| 503 chrome::NavigateParams params(tab_contents_->profile(), query_url, | 504 chrome::NavigateParams params(profile_, query_url, |
| 504 content::PAGE_TRANSITION_LINK); | 505 content::PAGE_TRANSITION_LINK); |
| 505 params.disposition = | 506 params.disposition = |
| 506 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition; | 507 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition; |
| 507 chrome::Navigate(¶ms); | 508 chrome::Navigate(¶ms); |
| 508 } | 509 } |
| 509 | 510 |
| 510 void WebIntentPickerController::OnUserCancelledPickerDialog() { | 511 void WebIntentPickerController::OnUserCancelledPickerDialog() { |
| 511 if (!intents_dispatcher_) | 512 if (!intents_dispatcher_) |
| 512 return; | 513 return; |
| 513 | 514 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 544 &WebIntentPickerController::DispatchToInstalledExtension, | 545 &WebIntentPickerController::DispatchToInstalledExtension, |
| 545 base::Unretained(this), | 546 base::Unretained(this), |
| 546 extension_id)); | 547 extension_id)); |
| 547 } | 548 } |
| 548 | 549 |
| 549 void WebIntentPickerController::DispatchToInstalledExtension( | 550 void WebIntentPickerController::DispatchToInstalledExtension( |
| 550 const std::string& extension_id) { | 551 const std::string& extension_id) { |
| 551 web_intents::RecordCWSExtensionInstalled(uma_bucket_); | 552 web_intents::RecordCWSExtensionInstalled(uma_bucket_); |
| 552 picker_->OnExtensionInstallSuccess(extension_id); | 553 picker_->OnExtensionInstallSuccess(extension_id); |
| 553 WebIntentsRegistry::IntentServiceList services; | 554 WebIntentsRegistry::IntentServiceList services; |
| 554 GetWebIntentsRegistry(tab_contents_)->GetIntentServicesForExtensionFilter( | 555 GetWebIntentsRegistry(profile_)->GetIntentServicesForExtensionFilter( |
| 555 picker_model_->action(), picker_model_->type(), | 556 picker_model_->action(), picker_model_->type(), |
| 556 extension_id, | 557 extension_id, |
| 557 &services); | 558 &services); |
| 558 | 559 |
| 559 // Extension must be registered with registry by now. | 560 // Extension must be registered with registry by now. |
| 560 DCHECK(services.size() > 0); | 561 DCHECK(services.size() > 0); |
| 561 | 562 |
| 562 // TODO(binji): We're going to need to disambiguate if there are multiple | 563 // TODO(binji): We're going to need to disambiguate if there are multiple |
| 563 // services. For now, just choose the first. | 564 // services. For now, just choose the first. |
| 564 const webkit_glue::WebIntentServiceData& service_data = services[0]; | 565 const webkit_glue::WebIntentServiceData& service_data = services[0]; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 586 reply_type != webkit_glue::WEB_INTENT_SERVICE_CONTENTS_CLOSED) { | 587 reply_type != webkit_glue::WEB_INTENT_SERVICE_CONTENTS_CLOSED) { |
| 587 Browser* browser = browser::FindBrowserWithWebContents(service_tab_); | 588 Browser* browser = browser::FindBrowserWithWebContents(service_tab_); |
| 588 if (browser) { | 589 if (browser) { |
| 589 int index = browser->tab_strip_model()->GetIndexOfWebContents( | 590 int index = browser->tab_strip_model()->GetIndexOfWebContents( |
| 590 service_tab_); | 591 service_tab_); |
| 591 browser->tab_strip_model()->CloseTabContentsAt( | 592 browser->tab_strip_model()->CloseTabContentsAt( |
| 592 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); | 593 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); |
| 593 | 594 |
| 594 // Activate source tab. | 595 // Activate source tab. |
| 595 Browser* source_browser = | 596 Browser* source_browser = |
| 596 browser::FindBrowserWithWebContents(tab_contents_->web_contents()); | 597 browser::FindBrowserWithWebContents(web_contents_); |
| 597 if (source_browser) { | 598 if (source_browser) { |
| 598 int source_index = source_browser->tab_strip_model()-> | 599 int source_index = source_browser->tab_strip_model()-> |
| 599 GetIndexOfTabContents(tab_contents_); | 600 GetIndexOfWebContents(web_contents_); |
| 600 chrome::ActivateTabAt(source_browser, source_index, false); | 601 chrome::ActivateTabAt(source_browser, source_index, false); |
| 601 } | 602 } |
| 602 } | 603 } |
| 603 service_tab_ = NULL; | 604 service_tab_ = NULL; |
| 604 } | 605 } |
| 605 | 606 |
| 606 intents_dispatcher_ = NULL; | 607 intents_dispatcher_ = NULL; |
| 607 } | 608 } |
| 608 | 609 |
| 609 void WebIntentPickerController::AddServiceToModel( | 610 void WebIntentPickerController::AddServiceToModel( |
| 610 const webkit_glue::WebIntentServiceData& service) { | 611 const webkit_glue::WebIntentServiceData& service) { |
| 611 FaviconService* favicon_service = GetFaviconService(tab_contents_); | 612 FaviconService* favicon_service = GetFaviconService(profile_); |
| 612 | 613 |
| 613 picker_model_->AddInstalledService( | 614 picker_model_->AddInstalledService( |
| 614 service.title, | 615 service.title, |
| 615 service.service_url, | 616 service.service_url, |
| 616 service.disposition); | 617 service.disposition); |
| 617 | 618 |
| 618 pending_async_count_++; | 619 pending_async_count_++; |
| 619 FaviconService::Handle handle = favicon_service->GetFaviconImageForURL( | 620 FaviconService::Handle handle = favicon_service->GetFaviconImageForURL( |
| 620 FaviconService::FaviconForURLParams( | 621 FaviconService::FaviconForURLParams( |
| 621 tab_contents_->profile(), | 622 profile_, |
| 622 service.service_url, | 623 service.service_url, |
| 623 history::FAVICON, | 624 history::FAVICON, |
| 624 gfx::kFaviconSize, | 625 gfx::kFaviconSize, |
| 625 &favicon_consumer_), | 626 &favicon_consumer_), |
| 626 base::Bind( | 627 base::Bind( |
| 627 &WebIntentPickerController::OnFaviconDataAvailable, | 628 &WebIntentPickerController::OnFaviconDataAvailable, |
| 628 weak_ptr_factory_.GetWeakPtr())); | 629 weak_ptr_factory_.GetWeakPtr())); |
| 629 favicon_consumer_.SetClientData( | 630 favicon_consumer_.SetClientData( |
| 630 favicon_service, handle, picker_model_->GetInstalledServiceCount() - 1); | 631 favicon_service, handle, picker_model_->GetInstalledServiceCount() - 1); |
| 631 } | 632 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 picker_model_->UpdateFaviconAt(index, image_result.image); | 704 picker_model_->UpdateFaviconAt(index, image_result.image); |
| 704 return; | 705 return; |
| 705 } | 706 } |
| 706 | 707 |
| 707 AsyncOperationFinished(); | 708 AsyncOperationFinished(); |
| 708 } | 709 } |
| 709 | 710 |
| 710 void WebIntentPickerController::OnCWSIntentServicesAvailable( | 711 void WebIntentPickerController::OnCWSIntentServicesAvailable( |
| 711 const CWSIntentsRegistry::IntentExtensionList& extensions) { | 712 const CWSIntentsRegistry::IntentExtensionList& extensions) { |
| 712 ExtensionServiceInterface* extension_service = | 713 ExtensionServiceInterface* extension_service = |
| 713 tab_contents_->profile()->GetExtensionService(); | 714 profile_->GetExtensionService(); |
| 714 | 715 |
| 715 std::vector<WebIntentPickerModel::SuggestedExtension> suggestions; | 716 std::vector<WebIntentPickerModel::SuggestedExtension> suggestions; |
| 716 for (size_t i = 0; i < extensions.size(); ++i) { | 717 for (size_t i = 0; i < extensions.size(); ++i) { |
| 717 const CWSIntentsRegistry::IntentExtensionInfo& info = extensions[i]; | 718 const CWSIntentsRegistry::IntentExtensionInfo& info = extensions[i]; |
| 718 | 719 |
| 719 // Do not include suggestions for already installed extensions. | 720 // Do not include suggestions for already installed extensions. |
| 720 if (extension_service->GetExtensionById(UTF16ToUTF8(info.id), | 721 if (extension_service->GetExtensionById(UTF16ToUTF8(info.id), |
| 721 true)) { | 722 true)) { |
| 722 continue; | 723 continue; |
| 723 } | 724 } |
| 724 | 725 |
| 725 suggestions.push_back(WebIntentPickerModel::SuggestedExtension( | 726 suggestions.push_back(WebIntentPickerModel::SuggestedExtension( |
| 726 info.name, info.id, info.average_rating)); | 727 info.name, info.id, info.average_rating)); |
| 727 | 728 |
| 728 pending_async_count_++; | 729 pending_async_count_++; |
| 729 net::URLFetcher* icon_url_fetcher = net::URLFetcher::Create( | 730 net::URLFetcher* icon_url_fetcher = net::URLFetcher::Create( |
| 730 0, | 731 0, |
| 731 info.icon_url, | 732 info.icon_url, |
| 732 net::URLFetcher::GET, | 733 net::URLFetcher::GET, |
| 733 new URLFetcherTrampoline( | 734 new URLFetcherTrampoline( |
| 734 base::Bind( | 735 base::Bind( |
| 735 &WebIntentPickerController::OnExtensionIconURLFetchComplete, | 736 &WebIntentPickerController::OnExtensionIconURLFetchComplete, |
| 736 weak_ptr_factory_.GetWeakPtr(), info.id))); | 737 weak_ptr_factory_.GetWeakPtr(), info.id))); |
| 737 | 738 |
| 738 icon_url_fetcher->SetLoadFlags( | 739 icon_url_fetcher->SetLoadFlags( |
| 739 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); | 740 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); |
| 740 icon_url_fetcher->SetRequestContext( | 741 icon_url_fetcher->SetRequestContext(profile_->GetRequestContext()); |
| 741 tab_contents_->profile()->GetRequestContext()); | |
| 742 icon_url_fetcher->Start(); | 742 icon_url_fetcher->Start(); |
| 743 } | 743 } |
| 744 | 744 |
| 745 picker_model_->AddSuggestedExtensions(suggestions); | 745 picker_model_->AddSuggestedExtensions(suggestions); |
| 746 | 746 |
| 747 AsyncOperationFinished(); | 747 AsyncOperationFinished(); |
| 748 pending_cws_request_ = false; | 748 pending_cws_request_ = false; |
| 749 OnIntentDataArrived(); | 749 OnIntentDataArrived(); |
| 750 } | 750 } |
| 751 | 751 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 | 809 |
| 810 // Reset state associated with callbacks. | 810 // Reset state associated with callbacks. |
| 811 pending_async_count_ = 0; | 811 pending_async_count_ = 0; |
| 812 pending_registry_calls_count_ = 0; | 812 pending_registry_calls_count_ = 0; |
| 813 pending_cws_request_ = false; | 813 pending_cws_request_ = false; |
| 814 | 814 |
| 815 // Reset picker. | 815 // Reset picker. |
| 816 picker_model_.reset(new WebIntentPickerModel()); | 816 picker_model_.reset(new WebIntentPickerModel()); |
| 817 picker_shown_ = false; | 817 picker_shown_ = false; |
| 818 | 818 |
| 819 DCHECK(tab_contents_); | 819 DCHECK(web_contents_); |
| 820 tab_contents_->constrained_window_tab_helper()->BlockTabContent(false); | 820 TabContents* tab_contents = TabContents::FromWebContents(web_contents_); |
| 821 tab_contents->constrained_window_tab_helper()->BlockTabContent(false); |
| 821 } | 822 } |
| 822 | 823 |
| 823 // static | 824 // static |
| 824 void WebIntentPickerController::DecodeExtensionIconAndResize( | 825 void WebIntentPickerController::DecodeExtensionIconAndResize( |
| 825 scoped_ptr<std::string> icon_response, | 826 scoped_ptr<std::string> icon_response, |
| 826 const ExtensionIconAvailableCallback& callback, | 827 const ExtensionIconAvailableCallback& callback, |
| 827 const base::Closure& unavailable_callback) { | 828 const base::Closure& unavailable_callback) { |
| 828 SkBitmap icon_bitmap; | 829 SkBitmap icon_bitmap; |
| 829 if (gfx::PNGCodec::Decode( | 830 if (gfx::PNGCodec::Decode( |
| 830 reinterpret_cast<const unsigned char*>(icon_response->data()), | 831 reinterpret_cast<const unsigned char*>(icon_response->data()), |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 SetDialogState(kPickerMain); | 935 SetDialogState(kPickerMain); |
| 935 break; | 936 break; |
| 936 | 937 |
| 937 default: | 938 default: |
| 938 NOTREACHED(); | 939 NOTREACHED(); |
| 939 break; | 940 break; |
| 940 } | 941 } |
| 941 } | 942 } |
| 942 | 943 |
| 943 void WebIntentPickerController::LocationBarPickerToolClicked() { | 944 void WebIntentPickerController::LocationBarPickerToolClicked() { |
| 944 DCHECK(tab_contents_); | 945 DCHECK(web_contents_); |
| 945 if (window_disposition_source_ && source_intents_dispatcher_) { | 946 if (window_disposition_source_ && source_intents_dispatcher_) { |
| 946 Browser* service_browser = | 947 Browser* service_browser = |
| 947 browser::FindBrowserWithWebContents(tab_contents_->web_contents()); | 948 browser::FindBrowserWithWebContents(web_contents_); |
| 948 if (!service_browser) return; | 949 if (!service_browser) return; |
| 949 | 950 |
| 950 TabContents* client_tab = | 951 TabContents* client_tab = |
| 951 TabContents::FromWebContents(window_disposition_source_); | 952 TabContents::FromWebContents(window_disposition_source_); |
| 952 Browser* client_browser = | 953 Browser* client_browser = |
| 953 browser::FindBrowserWithWebContents(window_disposition_source_); | 954 browser::FindBrowserWithWebContents(window_disposition_source_); |
| 954 if (!client_browser || !client_tab) return; | 955 if (!client_browser || !client_tab) return; |
| 955 int client_index = | 956 int client_index = |
| 956 client_browser->tab_strip_model()->GetIndexOfTabContents(client_tab); | 957 client_browser->tab_strip_model()->GetIndexOfTabContents(client_tab); |
| 957 DCHECK(client_index != TabStripModel::kNoTab); | 958 DCHECK(client_index != TabStripModel::kNoTab); |
| 958 | 959 |
| 959 source_intents_dispatcher_->ResetDispatch(); | 960 source_intents_dispatcher_->ResetDispatch(); |
| 960 | 961 |
| 961 chrome::CloseWebContents(service_browser, tab_contents_->web_contents()); | 962 chrome::CloseWebContents(service_browser, web_contents_); |
| 962 | 963 |
| 963 // Re-open the other tab and activate the picker. | 964 // Re-open the other tab and activate the picker. |
| 964 client_browser->window()->Activate(); | 965 client_browser->window()->Activate(); |
| 965 client_browser->tab_strip_model()->ActivateTabAt(client_index, true); | 966 client_browser->tab_strip_model()->ActivateTabAt(client_index, true); |
| 966 // The picker has been Reset() when the new tab is created; need to fully | 967 // The picker has been Reset() when the new tab is created; need to fully |
| 967 // reload. | 968 // reload. |
| 968 client_tab->web_intent_picker_controller()->ReshowDialog(); | 969 WebIntentPickerController::FromWebContents(window_disposition_source_)-> |
| 970 ReshowDialog(); |
| 969 } | 971 } |
| 970 // TODO(gbillock): figure out what we ought to do in this case. Probably | 972 // TODO(gbillock): figure out what we ought to do in this case. Probably |
| 971 // nothing? Refresh the location bar? | 973 // nothing? Refresh the location bar? |
| 972 } | 974 } |
| 973 | 975 |
| 974 void WebIntentPickerController::AsyncOperationFinished() { | 976 void WebIntentPickerController::AsyncOperationFinished() { |
| 975 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 977 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 976 if (--pending_async_count_ == 0) { | 978 if (--pending_async_count_ == 0) { |
| 977 if (picker_) | 979 if (picker_) |
| 978 picker_->OnPendingAsyncCompleted(); | 980 picker_->OnPendingAsyncCompleted(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 dialog_state_ = state; | 1044 dialog_state_ = state; |
| 1043 | 1045 |
| 1044 // Create picker dialog when changing away from hidden state. | 1046 // Create picker dialog when changing away from hidden state. |
| 1045 if (dialog_state_ != kPickerHidden && dialog_state_ != kPickerSetup) | 1047 if (dialog_state_ != kPickerHidden && dialog_state_ != kPickerSetup) |
| 1046 CreatePicker(); | 1048 CreatePicker(); |
| 1047 } | 1049 } |
| 1048 | 1050 |
| 1049 void WebIntentPickerController::CreatePicker() { | 1051 void WebIntentPickerController::CreatePicker() { |
| 1050 // If picker is non-NULL, it was set by a test. | 1052 // If picker is non-NULL, it was set by a test. |
| 1051 if (picker_ == NULL) | 1053 if (picker_ == NULL) |
| 1052 picker_ = WebIntentPicker::Create(tab_contents_, this, picker_model_.get()); | 1054 picker_ = WebIntentPicker::Create(web_contents_, this, picker_model_.get()); |
| 1053 picker_->SetActionString(GetIntentActionString( | 1055 picker_->SetActionString(GetIntentActionString( |
| 1054 UTF16ToUTF8(picker_model_->action()))); | 1056 UTF16ToUTF8(picker_model_->action()))); |
| 1055 web_intents::RecordPickerShow( | 1057 web_intents::RecordPickerShow( |
| 1056 uma_bucket_, picker_model_->GetInstalledServiceCount()); | 1058 uma_bucket_, picker_model_->GetInstalledServiceCount()); |
| 1057 picker_shown_ = true; | 1059 picker_shown_ = true; |
| 1058 } | 1060 } |
| 1059 | 1061 |
| 1060 void WebIntentPickerController::ClosePicker() { | 1062 void WebIntentPickerController::ClosePicker() { |
| 1061 SetDialogState(kPickerHidden); | 1063 SetDialogState(kPickerHidden); |
| 1062 if (picker_) | 1064 if (picker_) |
| 1063 picker_->Close(); | 1065 picker_->Close(); |
| 1064 } | 1066 } |
| OLD | NEW |