// Copyright 2014 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/extension_error_controller.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/pending_extension_manager.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/extension_set.h" namespace extensions { namespace { ExtensionErrorController::UICreateMethod g_create_ui = ExtensionErrorUI::Create; } ExtensionErrorController::ExtensionErrorController( content::BrowserContext* context, bool is_first_run) : browser_context_(context), is_first_run_(is_first_run) {} ExtensionErrorController::~ExtensionErrorController() {} void ExtensionErrorController::ShowErrorIfNeeded() { IdentifyAlertableExtensions(); // Make sure there's something to show, and that there isn't currently a // bubble displaying. if (!blacklisted_extensions_.is_empty() && !error_ui_.get()) { if (!is_first_run_) { error_ui_.reset(g_create_ui(this)); if (!error_ui_->ShowErrorInBubbleView()) // Couldn't find a browser. error_ui_.reset(); } else { // First run. Just acknowledge all the extensions, silently, by // shortcutting the display of the UI and going straight to the // callback for pressing the Accept button. OnAlertClosed(); } } } // static void ExtensionErrorController::SetUICreateMethodForTesting( UICreateMethod method) { g_create_ui = method; } content::BrowserContext* ExtensionErrorController::GetContext() { return browser_context_; } const ExtensionSet& ExtensionErrorController::GetExternalExtensions() { return external_extensions_; } const ExtensionSet& ExtensionErrorController::GetBlacklistedExtensions() { return blacklisted_extensions_; } void ExtensionErrorController::OnAlertAccept() { error_ui_->Close(); } void ExtensionErrorController::OnAlertDetails() { error_ui_->ShowExtensions(); // ShowExtensions() may cause the error UI to close synchronously, e.g. if it // causes a navigation. if (error_ui_) error_ui_->Close(); } void ExtensionErrorController::OnAlertClosed() { ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); for (ExtensionSet::const_iterator iter = blacklisted_extensions_.begin(); iter != blacklisted_extensions_.end(); ++iter) { prefs->AcknowledgeBlacklistedExtension((*iter)->id()); } blacklisted_extensions_.Clear(); error_ui_.reset(); } void ExtensionErrorController::IdentifyAlertableExtensions() { ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); // This should be clear, but in case a bubble crashed somewhere along the // line, let's make sure we start fresh. blacklisted_extensions_.Clear(); // Build up the lists of extensions that require acknowledgment. If this is // the first time, grandfather extensions that would have caused // notification. const ExtensionSet& blacklisted_set = registry->blacklisted_extensions(); for (ExtensionSet::const_iterator iter = blacklisted_set.begin(); iter != blacklisted_set.end(); ++iter) { if (!prefs->IsBlacklistedExtensionAcknowledged((*iter)->id())) blacklisted_extensions_.Insert(*iter); } ExtensionSystem* system = ExtensionSystem::Get(browser_context_); ManagementPolicy* management_policy = system->management_policy(); PendingExtensionManager* pending_extension_manager = system->extension_service()->pending_extension_manager(); const ExtensionSet& enabled_set = registry->enabled_extensions(); for (ExtensionSet::const_iterator iter = enabled_set.begin(); iter != enabled_set.end(); ++iter) { const Extension* extension = iter->get(); // Skip for extensions that have pending updates. They will be checked again // once the pending update is finished. if (pending_extension_manager->IsIdPending(extension->id())) continue; // Extensions disabled by policy. Note: this no longer includes blacklisted // extensions, though we still show the same UI. if (!management_policy->UserMayLoad(extension, NULL /* ignore error */)) { if (!prefs->IsBlacklistedExtensionAcknowledged(extension->id())) blacklisted_extensions_.Insert(extension); } } } } // namespace extensions