• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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_error_controller.h"
6 
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/pending_extension_manager.h"
9 #include "extensions/browser/extension_prefs.h"
10 #include "extensions/browser/extension_registry.h"
11 #include "extensions/browser/extension_system.h"
12 #include "extensions/common/extension_set.h"
13 
14 namespace extensions {
15 
16 namespace {
17 
18 ExtensionErrorController::UICreateMethod g_create_ui =
19     ExtensionErrorUI::Create;
20 
21 }
22 
ExtensionErrorController(content::BrowserContext * context,bool is_first_run)23 ExtensionErrorController::ExtensionErrorController(
24     content::BrowserContext* context,
25     bool is_first_run)
26     : browser_context_(context),
27       is_first_run_(is_first_run) {}
28 
~ExtensionErrorController()29 ExtensionErrorController::~ExtensionErrorController() {}
30 
ShowErrorIfNeeded()31 void ExtensionErrorController::ShowErrorIfNeeded() {
32   IdentifyAlertableExtensions();
33 
34   // Make sure there's something to show, and that there isn't currently a
35   // bubble displaying.
36   if (!blacklisted_extensions_.is_empty() && !error_ui_.get()) {
37     if (!is_first_run_) {
38       error_ui_.reset(g_create_ui(this));
39       if (!error_ui_->ShowErrorInBubbleView())  // Couldn't find a browser.
40         error_ui_.reset();
41     } else {
42       // First run. Just acknowledge all the extensions, silently, by
43       // shortcutting the display of the UI and going straight to the
44       // callback for pressing the Accept button.
45       OnAlertClosed();
46     }
47   }
48 }
49 
50 // static
SetUICreateMethodForTesting(UICreateMethod method)51 void ExtensionErrorController::SetUICreateMethodForTesting(
52     UICreateMethod method) {
53   g_create_ui = method;
54 }
55 
GetContext()56 content::BrowserContext* ExtensionErrorController::GetContext() {
57   return browser_context_;
58 }
59 
GetExternalExtensions()60 const ExtensionSet& ExtensionErrorController::GetExternalExtensions() {
61   return external_extensions_;
62 }
63 
GetBlacklistedExtensions()64 const ExtensionSet& ExtensionErrorController::GetBlacklistedExtensions() {
65   return blacklisted_extensions_;
66 }
67 
OnAlertAccept()68 void ExtensionErrorController::OnAlertAccept() {
69   error_ui_->Close();
70 }
71 
OnAlertDetails()72 void ExtensionErrorController::OnAlertDetails() {
73   error_ui_->ShowExtensions();
74 
75   // ShowExtensions() may cause the error UI to close synchronously, e.g. if it
76   // causes a navigation.
77   if (error_ui_)
78     error_ui_->Close();
79 }
80 
OnAlertClosed()81 void ExtensionErrorController::OnAlertClosed() {
82   ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
83   for (ExtensionSet::const_iterator iter = blacklisted_extensions_.begin();
84        iter != blacklisted_extensions_.end();
85        ++iter) {
86     prefs->AcknowledgeBlacklistedExtension((*iter)->id());
87   }
88 
89   blacklisted_extensions_.Clear();
90   error_ui_.reset();
91 }
92 
IdentifyAlertableExtensions()93 void ExtensionErrorController::IdentifyAlertableExtensions() {
94   ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
95   ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
96 
97   // This should be clear, but in case a bubble crashed somewhere along the
98   // line, let's make sure we start fresh.
99   blacklisted_extensions_.Clear();
100 
101   // Build up the lists of extensions that require acknowledgment. If this is
102   // the first time, grandfather extensions that would have caused
103   // notification.
104 
105   const ExtensionSet& blacklisted_set = registry->blacklisted_extensions();
106   for (ExtensionSet::const_iterator iter = blacklisted_set.begin();
107        iter != blacklisted_set.end();
108        ++iter) {
109     if (!prefs->IsBlacklistedExtensionAcknowledged((*iter)->id()))
110       blacklisted_extensions_.Insert(*iter);
111   }
112 
113   ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
114   ManagementPolicy* management_policy = system->management_policy();
115   PendingExtensionManager* pending_extension_manager =
116       system->extension_service()->pending_extension_manager();
117   const ExtensionSet& enabled_set = registry->enabled_extensions();
118 
119   for (ExtensionSet::const_iterator iter = enabled_set.begin();
120        iter != enabled_set.end();
121        ++iter) {
122     const Extension* extension = *iter;
123 
124     // Skip for extensions that have pending updates. They will be checked again
125     // once the pending update is finished.
126     if (pending_extension_manager->IsIdPending(extension->id()))
127       continue;
128 
129     // Extensions disabled by policy. Note: this no longer includes blacklisted
130     // extensions, though we still show the same UI.
131     if (!management_policy->UserMayLoad(extension, NULL /* ignore error */)) {
132       if (!prefs->IsBlacklistedExtensionAcknowledged(extension->id()))
133         blacklisted_extensions_.Insert(extension);
134     }
135   }
136 }
137 
138 }  // namespace extensions
139