| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/extensions/navigation_observer.h" |
| |
| #include "chrome/browser/extensions/extension_install_ui.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_system.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_types.h" |
| |
| using content::NavigationController; |
| using content::NavigationEntry; |
| |
| namespace extensions { |
| |
| NavigationObserver::NavigationObserver(Profile* profile) : profile_(profile) { |
| RegisterForNotifications(); |
| } |
| |
| NavigationObserver::~NavigationObserver() {} |
| |
| void NavigationObserver::Observe(int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| if (type != content::NOTIFICATION_NAV_ENTRY_COMMITTED) { |
| NOTREACHED(); |
| return; |
| } |
| |
| NavigationController* controller = |
| content::Source<NavigationController>(source).ptr(); |
| if (!profile_->IsSameProfile( |
| Profile::FromBrowserContext(controller->GetBrowserContext()))) |
| return; |
| |
| PromptToEnableExtensionIfNecessary(controller); |
| } |
| |
| void NavigationObserver::RegisterForNotifications() { |
| registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| content::NotificationService::AllSources()); |
| } |
| |
| void NavigationObserver::PromptToEnableExtensionIfNecessary( |
| NavigationController* nav_controller) { |
| // Bail out if we're already running a prompt. |
| if (!in_progress_prompt_extension_id_.empty()) |
| return; |
| |
| NavigationEntry* nav_entry = nav_controller->GetVisibleEntry(); |
| if (!nav_entry) |
| return; |
| |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| const Extension* extension = extension_service->disabled_extensions()-> |
| GetExtensionOrAppByURL(nav_entry->GetURL()); |
| if (!extension) |
| return; |
| |
| // Try not to repeatedly prompt the user about the same extension. |
| if (prompted_extensions_.find(extension->id()) != prompted_extensions_.end()) |
| return; |
| prompted_extensions_.insert(extension->id()); |
| |
| ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); |
| if (extension_prefs->DidExtensionEscalatePermissions(extension->id())) { |
| // Keep track of the extension id and nav controller we're prompting for. |
| // These must be reset in InstallUIProceed and InstallUIAbort. |
| in_progress_prompt_extension_id_ = extension->id(); |
| in_progress_prompt_navigation_controller_ = nav_controller; |
| |
| extension_install_prompt_.reset( |
| new ExtensionInstallPrompt(nav_controller->GetWebContents())); |
| extension_install_prompt_->ConfirmReEnable(this, extension); |
| } |
| } |
| |
| void NavigationObserver::InstallUIProceed() { |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| const Extension* extension = extension_service->GetExtensionById( |
| in_progress_prompt_extension_id_, true); |
| NavigationController* nav_controller = |
| in_progress_prompt_navigation_controller_; |
| CHECK(extension); |
| CHECK(nav_controller); |
| |
| in_progress_prompt_extension_id_ = ""; |
| in_progress_prompt_navigation_controller_ = NULL; |
| extension_install_prompt_.reset(); |
| |
| // Grant permissions, re-enable the extension, and then reload the tab. |
| extension_service->GrantPermissionsAndEnableExtension(extension); |
| nav_controller->Reload(true); |
| } |
| |
| void NavigationObserver::InstallUIAbort(bool user_initiated) { |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| const Extension* extension = extension_service->GetExtensionById( |
| in_progress_prompt_extension_id_, true); |
| |
| in_progress_prompt_extension_id_ = ""; |
| in_progress_prompt_navigation_controller_ = NULL; |
| extension_install_prompt_.reset(); |
| |
| std::string histogram_name = user_initiated ? |
| "Extensions.Permissions_ReEnableCancel" : |
| "Extensions.Permissions_ReEnableAbort"; |
| ExtensionService::RecordPermissionMessagesHistogram( |
| extension, histogram_name.c_str()); |
| } |
| |
| } // namespace extensions |