1// Copyright (c) 2012 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_reporter.h" 6 7#include "build/build_config.h" 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/files/file_path.h" 12#include "base/logging.h" 13#include "base/message_loop/message_loop.h" 14#include "base/strings/stringprintf.h" 15#include "base/strings/utf_string_conversions.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/ui/simple_message_box.h" 18#include "content/public/browser/notification_service.h" 19#include "extensions/browser/notification_types.h" 20 21ExtensionErrorReporter* ExtensionErrorReporter::instance_ = NULL; 22 23// static 24void ExtensionErrorReporter::Init(bool enable_noisy_errors) { 25 if (!instance_) { 26 instance_ = new ExtensionErrorReporter(enable_noisy_errors); 27 } 28} 29 30// static 31ExtensionErrorReporter* ExtensionErrorReporter::GetInstance() { 32 CHECK(instance_) << "Init() was never called"; 33 return instance_; 34} 35 36ExtensionErrorReporter::ExtensionErrorReporter(bool enable_noisy_errors) 37 : ui_loop_(base::MessageLoop::current()), 38 enable_noisy_errors_(enable_noisy_errors) { 39} 40 41ExtensionErrorReporter::~ExtensionErrorReporter() {} 42 43void ExtensionErrorReporter::ReportLoadError( 44 const base::FilePath& extension_path, 45 const std::string& error, 46 content::BrowserContext* browser_context, 47 bool be_noisy) { 48 content::NotificationService::current()->Notify( 49 extensions::NOTIFICATION_EXTENSION_LOAD_ERROR, 50 content::Source<Profile>(Profile::FromBrowserContext(browser_context)), 51 content::Details<const std::string>(&error)); 52 53 std::string path_str = base::UTF16ToUTF8(extension_path.LossyDisplayName()); 54 base::string16 message = base::UTF8ToUTF16( 55 base::StringPrintf("Could not load extension from '%s'. %s", 56 path_str.c_str(), 57 error.c_str())); 58 ReportError(message, be_noisy); 59 FOR_EACH_OBSERVER(Observer, 60 observers_, 61 OnLoadFailure(browser_context, extension_path, error)); 62} 63 64void ExtensionErrorReporter::ReportError(const base::string16& message, 65 bool be_noisy) { 66 // NOTE: There won't be a ui_loop_ in the unit test environment. 67 if (ui_loop_) { 68 CHECK(base::MessageLoop::current() == ui_loop_) 69 << "ReportError can only be called from the UI thread."; 70 } 71 72 errors_.push_back(message); 73 74 // TODO(aa): Print the error message out somewhere better. I think we are 75 // going to need some sort of 'extension inspector'. 76 LOG(WARNING) << "Extension error: " << message; 77 78 if (enable_noisy_errors_ && be_noisy) { 79 chrome::ShowMessageBox(NULL, 80 base::ASCIIToUTF16("Extension error"), 81 message, 82 chrome::MESSAGE_BOX_TYPE_WARNING); 83 } 84} 85 86const std::vector<base::string16>* ExtensionErrorReporter::GetErrors() { 87 return &errors_; 88} 89 90void ExtensionErrorReporter::ClearErrors() { 91 errors_.clear(); 92} 93 94void ExtensionErrorReporter::AddObserver(Observer* observer) { 95 observers_.AddObserver(observer); 96} 97 98void ExtensionErrorReporter::RemoveObserver(Observer* observer) { 99 observers_.RemoveObserver(observer); 100} 101