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 |