blob: cf2f07c779126fdcc57f29053eebba233db739b9 [file] [log] [blame]
// 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