// 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/extension_error_reporter.h" #include "build/build_config.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/simple_message_box.h" #include "content/public/browser/notification_service.h" #include "extensions/browser/notification_types.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" ExtensionErrorReporter* ExtensionErrorReporter::instance_ = NULL; // static void ExtensionErrorReporter::Init(bool enable_noisy_errors) { if (!instance_) { instance_ = new ExtensionErrorReporter(enable_noisy_errors); } } // static ExtensionErrorReporter* ExtensionErrorReporter::GetInstance() { CHECK(instance_) << "Init() was never called"; return instance_; } ExtensionErrorReporter::ExtensionErrorReporter(bool enable_noisy_errors) : ui_loop_(base::MessageLoop::current()), enable_noisy_errors_(enable_noisy_errors) { } ExtensionErrorReporter::~ExtensionErrorReporter() {} void ExtensionErrorReporter::ReportLoadError( const base::FilePath& extension_path, const std::string& error, content::BrowserContext* browser_context, bool be_noisy) { content::NotificationService::current()->Notify( extensions::NOTIFICATION_EXTENSION_LOAD_ERROR, content::Source(Profile::FromBrowserContext(browser_context)), content::Details(&error)); std::string path_str = base::UTF16ToUTF8(extension_path.LossyDisplayName()); base::string16 message = base::UTF8ToUTF16(base::StringPrintf( "%s %s. %s", l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE).c_str(), path_str.c_str(), error.c_str())); ReportError(message, be_noisy); FOR_EACH_OBSERVER(Observer, observers_, OnLoadFailure(browser_context, extension_path, error)); } void ExtensionErrorReporter::ReportError(const base::string16& message, bool be_noisy) { // NOTE: There won't be a ui_loop_ in the unit test environment. if (ui_loop_) { CHECK(base::MessageLoop::current() == ui_loop_) << "ReportError can only be called from the UI thread."; } errors_.push_back(message); // TODO(aa): Print the error message out somewhere better. I think we are // going to need some sort of 'extension inspector'. LOG(WARNING) << "Extension error: " << message; if (enable_noisy_errors_ && be_noisy) { chrome::ShowMessageBox( NULL, l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_ERROR_HEADING), message, chrome::MESSAGE_BOX_TYPE_WARNING); } } const std::vector* ExtensionErrorReporter::GetErrors() { return &errors_; } void ExtensionErrorReporter::ClearErrors() { errors_.clear(); } void ExtensionErrorReporter::AddObserver(Observer* observer) { observers_.AddObserver(observer); } void ExtensionErrorReporter::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); }