blob: 5fed51a11156cb45bbc3322cd6ba1314b3b0d2e4 [file] [log] [blame]
[email protected]f9c292b32011-09-13 16:14:051// 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]ad23a092011-12-28 07:02:0410#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0711#include "content/public/browser/notification_service.h"
[email protected]f9c292b32011-09-13 16:14:0512
[email protected]10f417c52011-12-28 21:04:2313using content::NavigationEntry;
14
[email protected]f9c292b32011-09-13 16:14:0515ExtensionNavigationObserver::ExtensionNavigationObserver(Profile* profile)
16 : profile_(profile) {
17 RegisterForNotifications();
18}
19
20ExtensionNavigationObserver::~ExtensionNavigationObserver() {}
21
[email protected]6c2381d2011-10-19 02:52:5322void ExtensionNavigationObserver::Observe(
23 int type,
24 const content::NotificationSource& source,
25 const content::NotificationDetails& details) {
[email protected]f9c292b32011-09-13 16:14:0526 if (type != content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
27 NOTREACHED();
28 return;
29 }
30
[email protected]6c2381d2011-10-19 02:52:5331 NavigationController* controller =
32 content::Source<NavigationController>(source).ptr();
[email protected]f9c292b32011-09-13 16:14:0533 if (!profile_->IsSameProfile(
[email protected]a26023822011-12-29 00:23:5534 Profile::FromBrowserContext(controller->GetBrowserContext())))
[email protected]f9c292b32011-09-13 16:14:0535 return;
36
37 PromptToEnableExtensionIfNecessary(controller);
38}
39
40void ExtensionNavigationObserver::RegisterForNotifications() {
41 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
[email protected]ad50def52011-10-19 23:17:0742 content::NotificationService::AllSources());
[email protected]f9c292b32011-09-13 16:14:0543}
44
45void 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]10f417c52011-12-28 21:04:2351 NavigationEntry* nav_entry = nav_controller->GetActiveEntry();
[email protected]f9c292b32011-09-13 16:14:0552 if (!nav_entry)
53 return;
54
55 ExtensionService* extension_service = profile_->GetExtensionService();
56 const Extension* extension =
[email protected]615d88f2011-12-13 01:47:4457 extension_service->disabled_extensions()->
[email protected]36fc0392011-12-25 03:59:5158 GetExtensionOrAppByURL(ExtensionURLInfo(nav_entry->GetURL()));
[email protected]f9c292b32011-09-13 16:14:0559 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
79void 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
97void 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}