| 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/webui/extensions/extension_settings_handler.h" | 5 #include "chrome/browser/ui/webui/extensions/extension_settings_handler.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "apps/app_load_service.h" | |
| 10 #include "apps/saved_files_service.h" | |
| 11 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 12 #include "base/bind.h" | 10 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 14 #include "base/location.h" | 12 #include "base/location.h" |
| 15 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 16 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 17 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
| 18 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/values.h" | 18 #include "base/values.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 81 |
| 84 namespace { | 82 namespace { |
| 85 | 83 |
| 86 const char kAppsDeveloperToolsExtensionId[] = | 84 const char kAppsDeveloperToolsExtensionId[] = |
| 87 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc"; | 85 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc"; |
| 88 | 86 |
| 89 } // namespace | 87 } // namespace |
| 90 | 88 |
| 91 namespace extensions { | 89 namespace extensions { |
| 92 | 90 |
| 93 // The install prompt is not necessarily modal (e.g. Mac, Linux Unity). This | |
| 94 // means that the user can navigate while the dialog is up, causing the dialog | |
| 95 // handler to outlive the ExtensionSettingsHandler. That's a problem because the | |
| 96 // dialog framework will try to contact us back once the dialog is closed, which | |
| 97 // causes a crash. This class is designed to broker the message between the two | |
| 98 // objects, while managing its own lifetime so that it can outlive the | |
| 99 // ExtensionSettingsHandler and (when doing so) gracefully ignore the message | |
| 100 // from the dialog. | |
| 101 class BrokerDelegate : public ExtensionInstallPrompt::Delegate { | |
| 102 public: | |
| 103 explicit BrokerDelegate( | |
| 104 const base::WeakPtr<ExtensionSettingsHandler>& delegate) | |
| 105 : delegate_(delegate) {} | |
| 106 | |
| 107 // ExtensionInstallPrompt::Delegate implementation. | |
| 108 void InstallUIProceed() override { | |
| 109 if (delegate_) | |
| 110 delegate_->InstallUIProceed(); | |
| 111 delete this; | |
| 112 }; | |
| 113 | |
| 114 void InstallUIAbort(bool user_initiated) override { | |
| 115 if (delegate_) | |
| 116 delegate_->InstallUIAbort(user_initiated); | |
| 117 delete this; | |
| 118 }; | |
| 119 | |
| 120 void AppInfoDialogClosed() { | |
| 121 if (delegate_) | |
| 122 delegate_->AppInfoDialogClosed(); | |
| 123 delete this; | |
| 124 } | |
| 125 | |
| 126 private: | |
| 127 base::WeakPtr<ExtensionSettingsHandler> delegate_; | |
| 128 | |
| 129 DISALLOW_COPY_AND_ASSIGN(BrokerDelegate); | |
| 130 }; | |
| 131 | |
| 132 /////////////////////////////////////////////////////////////////////////////// | 91 /////////////////////////////////////////////////////////////////////////////// |
| 133 // | 92 // |
| 134 // ExtensionSettingsHandler | 93 // ExtensionSettingsHandler |
| 135 // | 94 // |
| 136 /////////////////////////////////////////////////////////////////////////////// | 95 /////////////////////////////////////////////////////////////////////////////// |
| 137 | 96 |
| 138 ExtensionSettingsHandler::ExtensionSettingsHandler() | 97 ExtensionSettingsHandler::ExtensionSettingsHandler() |
| 139 : extension_service_(NULL), | 98 : extension_service_(NULL), |
| 140 ignore_notifications_(false), | 99 ignore_notifications_(false), |
| 141 deleting_rvh_(NULL), | 100 deleting_rvh_(NULL), |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 AsWeakPtr())); | 359 AsWeakPtr())); |
| 401 web_ui()->RegisterMessageCallback("extensionSettingsEnableErrorCollection", | 360 web_ui()->RegisterMessageCallback("extensionSettingsEnableErrorCollection", |
| 402 base::Bind(&ExtensionSettingsHandler::HandleEnableErrorCollectionMessage, | 361 base::Bind(&ExtensionSettingsHandler::HandleEnableErrorCollectionMessage, |
| 403 AsWeakPtr())); | 362 AsWeakPtr())); |
| 404 web_ui()->RegisterMessageCallback("extensionSettingsAllowOnAllUrls", | 363 web_ui()->RegisterMessageCallback("extensionSettingsAllowOnAllUrls", |
| 405 base::Bind(&ExtensionSettingsHandler::HandleAllowOnAllUrlsMessage, | 364 base::Bind(&ExtensionSettingsHandler::HandleAllowOnAllUrlsMessage, |
| 406 AsWeakPtr())); | 365 AsWeakPtr())); |
| 407 web_ui()->RegisterMessageCallback("extensionSettingsOptions", | 366 web_ui()->RegisterMessageCallback("extensionSettingsOptions", |
| 408 base::Bind(&ExtensionSettingsHandler::HandleOptionsMessage, | 367 base::Bind(&ExtensionSettingsHandler::HandleOptionsMessage, |
| 409 AsWeakPtr())); | 368 AsWeakPtr())); |
| 410 web_ui()->RegisterMessageCallback("extensionSettingsPermissions", | |
| 411 base::Bind(&ExtensionSettingsHandler::HandlePermissionsMessage, | |
| 412 AsWeakPtr())); | |
| 413 web_ui()->RegisterMessageCallback("extensionSettingsShowButton", | 369 web_ui()->RegisterMessageCallback("extensionSettingsShowButton", |
| 414 base::Bind(&ExtensionSettingsHandler::HandleShowButtonMessage, | 370 base::Bind(&ExtensionSettingsHandler::HandleShowButtonMessage, |
| 415 AsWeakPtr())); | 371 AsWeakPtr())); |
| 416 web_ui()->RegisterMessageCallback("extensionSettingsAutoupdate", | 372 web_ui()->RegisterMessageCallback("extensionSettingsAutoupdate", |
| 417 base::Bind(&ExtensionSettingsHandler::HandleAutoUpdateMessage, | 373 base::Bind(&ExtensionSettingsHandler::HandleAutoUpdateMessage, |
| 418 AsWeakPtr())); | 374 AsWeakPtr())); |
| 419 web_ui()->RegisterMessageCallback("extensionSettingsDismissADTPromo", | 375 web_ui()->RegisterMessageCallback("extensionSettingsDismissADTPromo", |
| 420 base::Bind(&ExtensionSettingsHandler::HandleDismissADTPromoMessage, | 376 base::Bind(&ExtensionSettingsHandler::HandleDismissADTPromoMessage, |
| 421 AsWeakPtr())); | 377 AsWeakPtr())); |
| 422 web_ui()->RegisterMessageCallback("extensionSettingsShowPath", | 378 web_ui()->RegisterMessageCallback("extensionSettingsShowPath", |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 } | 463 } |
| 508 | 464 |
| 509 void ExtensionSettingsHandler::OnExtensionManagementSettingsChanged() { | 465 void ExtensionSettingsHandler::OnExtensionManagementSettingsChanged() { |
| 510 MaybeUpdateAfterNotification(); | 466 MaybeUpdateAfterNotification(); |
| 511 } | 467 } |
| 512 | 468 |
| 513 void ExtensionSettingsHandler::ExtensionWarningsChanged() { | 469 void ExtensionSettingsHandler::ExtensionWarningsChanged() { |
| 514 MaybeUpdateAfterNotification(); | 470 MaybeUpdateAfterNotification(); |
| 515 } | 471 } |
| 516 | 472 |
| 517 // This is called when the user clicks "Revoke File/Device Access." | |
| 518 void ExtensionSettingsHandler::InstallUIProceed() { | |
| 519 Profile* profile = Profile::FromWebUI(web_ui()); | |
| 520 extensions::DevicePermissionsManager::Get(profile) | |
| 521 ->Clear(extension_id_prompting_); | |
| 522 apps::SavedFilesService::Get(profile)->ClearQueue( | |
| 523 extension_service_->GetExtensionById(extension_id_prompting_, true)); | |
| 524 apps::AppLoadService::Get(profile) | |
| 525 ->RestartApplicationIfRunning(extension_id_prompting_); | |
| 526 extension_id_prompting_.clear(); | |
| 527 } | |
| 528 | |
| 529 void ExtensionSettingsHandler::InstallUIAbort(bool user_initiated) { | |
| 530 extension_id_prompting_.clear(); | |
| 531 } | |
| 532 | |
| 533 void ExtensionSettingsHandler::AppInfoDialogClosed() { | |
| 534 extension_id_prompting_.clear(); | |
| 535 } | |
| 536 | |
| 537 void ExtensionSettingsHandler::ReloadUnpackedExtensions() { | 473 void ExtensionSettingsHandler::ReloadUnpackedExtensions() { |
| 538 ExtensionRegistry* registry = | 474 ExtensionRegistry* registry = |
| 539 ExtensionRegistry::Get(extension_service_->profile()); | 475 ExtensionRegistry::Get(extension_service_->profile()); |
| 540 std::vector<const Extension*> unpacked_extensions; | 476 std::vector<const Extension*> unpacked_extensions; |
| 541 for (const scoped_refptr<const extensions::Extension>& extension : | 477 for (const scoped_refptr<const extensions::Extension>& extension : |
| 542 registry->enabled_extensions()) { | 478 registry->enabled_extensions()) { |
| 543 if (Manifest::IsUnpackedLocation(extension->location())) | 479 if (Manifest::IsUnpackedLocation(extension->location())) |
| 544 unpacked_extensions.push_back(extension.get()); | 480 unpacked_extensions.push_back(extension.get()); |
| 545 } | 481 } |
| 546 | 482 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 | 602 |
| 667 void ExtensionSettingsHandler::HandleOptionsMessage( | 603 void ExtensionSettingsHandler::HandleOptionsMessage( |
| 668 const base::ListValue* args) { | 604 const base::ListValue* args) { |
| 669 const Extension* extension = GetActiveExtension(args); | 605 const Extension* extension = GetActiveExtension(args); |
| 670 if (!extension || OptionsPageInfo::GetOptionsPage(extension).is_empty()) | 606 if (!extension || OptionsPageInfo::GetOptionsPage(extension).is_empty()) |
| 671 return; | 607 return; |
| 672 ExtensionTabUtil::OpenOptionsPage(extension, | 608 ExtensionTabUtil::OpenOptionsPage(extension, |
| 673 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); | 609 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); |
| 674 } | 610 } |
| 675 | 611 |
| 676 void ExtensionSettingsHandler::HandlePermissionsMessage( | |
| 677 const base::ListValue* args) { | |
| 678 std::string extension_id(base::UTF16ToUTF8(ExtractStringValue(args))); | |
| 679 CHECK(!extension_id.empty()); | |
| 680 const Extension* extension = | |
| 681 ExtensionRegistry::Get(Profile::FromWebUI(web_ui())) | |
| 682 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); | |
| 683 if (!extension) | |
| 684 return; | |
| 685 | |
| 686 if (!extension_id_prompting_.empty()) | |
| 687 return; // Only one prompt at a time. | |
| 688 extension_id_prompting_ = extension->id(); | |
| 689 | |
| 690 // The BrokerDelegate manages its own lifetime. | |
| 691 BrokerDelegate* broker_delegate = new BrokerDelegate(AsWeakPtr()); | |
| 692 | |
| 693 // Show the new-style extensions dialog when it is available. It is currently | |
| 694 // unavailable by default on Mac. | |
| 695 if (CanShowAppInfoDialog()) { | |
| 696 UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialog.Launches", | |
| 697 AppInfoLaunchSource::FROM_EXTENSIONS_PAGE, | |
| 698 AppInfoLaunchSource::NUM_LAUNCH_SOURCES); | |
| 699 | |
| 700 // Display the dialog at a size similar to the app list. | |
| 701 ShowAppInfoInNativeDialog( | |
| 702 web_contents()->GetTopLevelNativeWindow(), | |
| 703 GetAppInfoNativeDialogSize(), | |
| 704 Profile::FromWebUI(web_ui()), extension, | |
| 705 base::Bind(&BrokerDelegate::AppInfoDialogClosed, | |
| 706 base::Unretained(broker_delegate))); | |
| 707 } else { | |
| 708 prompt_.reset(new ExtensionInstallPrompt(web_contents())); | |
| 709 std::vector<base::FilePath> retained_file_paths; | |
| 710 if (extension->permissions_data()->HasAPIPermission( | |
| 711 APIPermission::kFileSystem)) { | |
| 712 std::vector<apps::SavedFileEntry> retained_file_entries = | |
| 713 apps::SavedFilesService::Get(Profile::FromWebUI(web_ui())) | |
| 714 ->GetAllFileEntries(extension_id_prompting_); | |
| 715 for (size_t i = 0; i < retained_file_entries.size(); ++i) { | |
| 716 retained_file_paths.push_back(retained_file_entries[i].path); | |
| 717 } | |
| 718 } | |
| 719 std::vector<base::string16> retained_device_messages; | |
| 720 if (extension->permissions_data()->HasAPIPermission(APIPermission::kUsb)) { | |
| 721 retained_device_messages = | |
| 722 extensions::DevicePermissionsManager::Get( | |
| 723 Profile::FromWebUI(web_ui())) | |
| 724 ->GetPermissionMessageStrings(extension_id_prompting_); | |
| 725 } | |
| 726 | |
| 727 prompt_->ReviewPermissions(broker_delegate, extension, retained_file_paths, | |
| 728 retained_device_messages); | |
| 729 } | |
| 730 } | |
| 731 | |
| 732 void ExtensionSettingsHandler::HandleShowButtonMessage( | 612 void ExtensionSettingsHandler::HandleShowButtonMessage( |
| 733 const base::ListValue* args) { | 613 const base::ListValue* args) { |
| 734 const Extension* extension = GetActiveExtension(args); | 614 const Extension* extension = GetActiveExtension(args); |
| 735 if (!extension) | 615 if (!extension) |
| 736 return; | 616 return; |
| 737 ExtensionActionAPI::SetBrowserActionVisibility( | 617 ExtensionActionAPI::SetBrowserActionVisibility( |
| 738 ExtensionPrefs::Get(extension_service_->profile()), | 618 ExtensionPrefs::Get(extension_service_->profile()), |
| 739 extension->id(), | 619 extension->id(), |
| 740 true); | 620 true); |
| 741 } | 621 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 } | 711 } |
| 832 | 712 |
| 833 void ExtensionSettingsHandler::OnReinstallComplete( | 713 void ExtensionSettingsHandler::OnReinstallComplete( |
| 834 bool success, | 714 bool success, |
| 835 const std::string& error, | 715 const std::string& error, |
| 836 webstore_install::Result result) { | 716 webstore_install::Result result) { |
| 837 MaybeUpdateAfterNotification(); | 717 MaybeUpdateAfterNotification(); |
| 838 } | 718 } |
| 839 | 719 |
| 840 } // namespace extensions | 720 } // namespace extensions |
| OLD | NEW |