[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "chrome/browser/extensions/extension_navigation_observer.h" |
| 6 | |
| 7 | #include "chrome/browser/extensions/extension_service.h" |
| 8 | #include "chrome/browser/profiles/profile.h" |
| 9 | #include "content/browser/tab_contents/navigation_controller.h" |
[email protected] | ad23a09 | 2011-12-28 07:02:04 | [diff] [blame] | 10 | #include "content/public/browser/navigation_entry.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 11 | #include "content/public/browser/notification_service.h" |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 12 | |
[email protected] | 10f417c5 | 2011-12-28 21:04:23 | [diff] [blame] | 13 | using content::NavigationEntry; |
| 14 | |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 15 | ExtensionNavigationObserver::ExtensionNavigationObserver(Profile* profile) |
| 16 | : profile_(profile) { |
| 17 | RegisterForNotifications(); |
| 18 | } |
| 19 | |
| 20 | ExtensionNavigationObserver::~ExtensionNavigationObserver() {} |
| 21 | |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 22 | void ExtensionNavigationObserver::Observe( |
| 23 | int type, |
| 24 | const content::NotificationSource& source, |
| 25 | const content::NotificationDetails& details) { |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 26 | if (type != content::NOTIFICATION_NAV_ENTRY_COMMITTED) { |
| 27 | NOTREACHED(); |
| 28 | return; |
| 29 | } |
| 30 | |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 31 | NavigationController* controller = |
| 32 | content::Source<NavigationController>(source).ptr(); |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 33 | if (!profile_->IsSameProfile( |
[email protected] | a2602382 | 2011-12-29 00:23:55 | [diff] [blame^] | 34 | Profile::FromBrowserContext(controller->GetBrowserContext()))) |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 35 | return; |
| 36 | |
| 37 | PromptToEnableExtensionIfNecessary(controller); |
| 38 | } |
| 39 | |
| 40 | void ExtensionNavigationObserver::RegisterForNotifications() { |
| 41 | registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 42 | content::NotificationService::AllSources()); |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | void ExtensionNavigationObserver::PromptToEnableExtensionIfNecessary( |
| 46 | NavigationController* nav_controller) { |
| 47 | // Bail out if we're already running a prompt. |
| 48 | if (!in_progress_prompt_extension_id_.empty()) |
| 49 | return; |
| 50 | |
[email protected] | 10f417c5 | 2011-12-28 21:04:23 | [diff] [blame] | 51 | NavigationEntry* nav_entry = nav_controller->GetActiveEntry(); |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 52 | if (!nav_entry) |
| 53 | return; |
| 54 | |
| 55 | ExtensionService* extension_service = profile_->GetExtensionService(); |
| 56 | const Extension* extension = |
[email protected] | 615d88f | 2011-12-13 01:47:44 | [diff] [blame] | 57 | extension_service->disabled_extensions()-> |
[email protected] | 36fc039 | 2011-12-25 03:59:51 | [diff] [blame] | 58 | GetExtensionOrAppByURL(ExtensionURLInfo(nav_entry->GetURL())); |
[email protected] | f9c292b3 | 2011-09-13 16:14:05 | [diff] [blame] | 59 | if (!extension) |
| 60 | return; |
| 61 | |
| 62 | // Try not to repeatedly prompt the user about the same extension. |
| 63 | if (prompted_extensions_.find(extension->id()) != prompted_extensions_.end()) |
| 64 | return; |
| 65 | prompted_extensions_.insert(extension->id()); |
| 66 | |
| 67 | ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); |
| 68 | if (extension_prefs->DidExtensionEscalatePermissions(extension->id())) { |
| 69 | // Keep track of the extension id and nav controller we're prompting for. |
| 70 | // These must be reset in InstallUIProceed and InstallUIAbort. |
| 71 | in_progress_prompt_extension_id_ = extension->id(); |
| 72 | in_progress_prompt_navigation_controller_ = nav_controller; |
| 73 | |
| 74 | extension_install_ui_.reset(new ExtensionInstallUI(profile_)); |
| 75 | extension_install_ui_->ConfirmReEnable(this, extension); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | void ExtensionNavigationObserver::InstallUIProceed() { |
| 80 | ExtensionService* extension_service = profile_->GetExtensionService(); |
| 81 | const Extension* extension = extension_service->GetExtensionById( |
| 82 | in_progress_prompt_extension_id_, true); |
| 83 | NavigationController* nav_controller = |
| 84 | in_progress_prompt_navigation_controller_; |
| 85 | CHECK(extension); |
| 86 | CHECK(nav_controller); |
| 87 | |
| 88 | in_progress_prompt_extension_id_ = ""; |
| 89 | in_progress_prompt_navigation_controller_ = NULL; |
| 90 | extension_install_ui_.reset(); |
| 91 | |
| 92 | // Grant permissions, re-enable the extension, and then reload the tab. |
| 93 | extension_service->GrantPermissionsAndEnableExtension(extension); |
| 94 | nav_controller->Reload(true); |
| 95 | } |
| 96 | |
| 97 | void ExtensionNavigationObserver::InstallUIAbort(bool user_initiated) { |
| 98 | ExtensionService* extension_service = profile_->GetExtensionService(); |
| 99 | const Extension* extension = extension_service->GetExtensionById( |
| 100 | in_progress_prompt_extension_id_, true); |
| 101 | |
| 102 | in_progress_prompt_extension_id_ = ""; |
| 103 | in_progress_prompt_navigation_controller_ = NULL; |
| 104 | extension_install_ui_.reset(); |
| 105 | |
| 106 | std::string histogram_name = user_initiated ? |
| 107 | "Extensions.Permissions_ReEnableCancel" : |
| 108 | "Extensions.Permissions_ReEnableAbort"; |
| 109 | ExtensionService::RecordPermissionMessagesHistogram( |
| 110 | extension, histogram_name.c_str()); |
| 111 | } |