diff options
-rw-r--r-- | chrome/browser/browser.scons | 2 | ||||
-rw-r--r-- | chrome/browser/browser.vcproj | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_error_reporter.cc | 65 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_error_reporter.h | 52 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 36 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 16 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 97 | ||||
-rw-r--r-- | chrome/browser/profile.cc | 2 | ||||
-rw-r--r-- | chrome/chrome.xcodeproj/project.pbxproj | 6 |
9 files changed, 193 insertions, 91 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons index 6bce4d9..7e94112 100644 --- a/chrome/browser/browser.scons +++ b/chrome/browser/browser.scons @@ -506,6 +506,8 @@ input_files = ChromeFileList([ MSVSFilter('Extensions', [ 'extensions/extension.cc', 'extensions/extension.h', + 'extensions/extension_error_reporter.cc', + 'extensions/extension_error_reporter.h', 'extensions/extension_protocols.h', 'extensions/extensions_service.cc', 'extensions/extensions_service.h', diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index 1325f66..e5995c1 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -1906,6 +1906,14 @@ > </File> <File + RelativePath=".\extensions\extension_error_reporter.cc" + > + </File> + <File + RelativePath=".\extensions\extension_error_reporter.h" + > + </File> + <File RelativePath=".\extensions\extension_protocols.cc" > </File> diff --git a/chrome/browser/extensions/extension_error_reporter.cc b/chrome/browser/extensions/extension_error_reporter.cc new file mode 100644 index 0000000..bd923f5 --- /dev/null +++ b/chrome/browser/extensions/extension_error_reporter.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2006-2009 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 "base/string_util.h" + +#if defined(OS_WIN) +#include "chrome/common/win_util.h" +#endif + +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_(MessageLoop::current()), + enable_noisy_errors_(enable_noisy_errors) { +} + +void ExtensionErrorReporter::ReportError(const std::string& message, + bool be_noisy) { + // NOTE: There won't be a ui_loop_ in the unit test environment. + if (ui_loop_ && MessageLoop::current() != ui_loop_) { + ui_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &ExtensionErrorReporter::ReportError, message, + be_noisy)); + return; + } + + 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) << message; + + if (enable_noisy_errors_ && be_noisy) { +#if defined(OS_WIN) + win_util::MessageBox(NULL, UTF8ToWide(message), L"Extension error", + MB_OK | MB_SETFOREGROUND); +#else + // TODO(port) +#endif + } +} + +const std::vector<std::string>* ExtensionErrorReporter::GetErrors() { + return &errors_; +} + +void ExtensionErrorReporter::ClearErrors() { + errors_.clear(); +} diff --git a/chrome/browser/extensions/extension_error_reporter.h b/chrome/browser/extensions/extension_error_reporter.h new file mode 100644 index 0000000..737e276 --- /dev/null +++ b/chrome/browser/extensions/extension_error_reporter.h @@ -0,0 +1,52 @@ +// Copyright (c) 2006-2009 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_ERROR_REPORTER_H_ +#define CHROME_BROWSER_EXTENSIONS_ERROR_REPORTER_H_ + +#include <string> +#include <vector> + +#include "base/message_loop.h" +#include "base/ref_counted.h" + +// Exposes an easy way for the various components of the extension system to +// report errors. This is a singleton that lives on the UI thread, with the +// exception of ReportError() which may be called from any thread. +// TODO(aa): Hook this up to about:extensions, when we have about:extensions. +// TODO(aa): Consider exposing directly, or via a helper, to the renderer +// process and plumbing the errors out to the browser. +// TODO(aa): Add ReportError(extension_id, message, be_noisy), so that we can +// report errors that are specific to a particular extension. +class ExtensionErrorReporter + : public base::RefCountedThreadSafe<ExtensionErrorReporter> { + public: + // Initializes the error reporter. Must be called before any other methods + // and on the UI thread. + static void Init(bool enable_noisy_errors); + + // Get the singleton instance. + static ExtensionErrorReporter* GetInstance(); + + // Report an error. Errors always go to LOG(INFO). Optionally, they can also + // cause a noisy alert box. This method can be called from any thread. + void ReportError(const std::string& message, bool be_noisy); + + // Get the errors that have been reported so far. + const std::vector<std::string>* GetErrors(); + + // Clear the list of errors reported so far. + void ClearErrors(); + + private: + static ExtensionErrorReporter* instance_; + + ExtensionErrorReporter(bool enable_noisy_errors); + + MessageLoop* ui_loop_; + std::vector<std::string> errors_; + bool enable_noisy_errors_; +}; + +#endif // CHROME_BROWSER_EXTENSIONS_ERROR_REPORTER_H_ diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 4c1a40f..9fc0040 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -14,6 +14,7 @@ #include "base/values.h" #include "net/base/file_stream.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/plugin_service.h" #include "chrome/common/json_value_serializer.h" @@ -22,7 +23,6 @@ #if defined(OS_WIN) #include "base/registry.h" -#include "chrome/common/win_util.h" #endif // ExtensionsService @@ -170,31 +170,6 @@ void ExtensionsService::OnExtensionsLoadedFromDirectory( delete new_extensions; } -void ExtensionsService::OnExtensionLoadError(bool alert_on_error, - const std::string& error) { - // TODO(aa): Print the error message out somewhere better. I think we are - // going to need some sort of 'extension inspector'. - LOG(WARNING) << error; - if (alert_on_error) { -#if defined(OS_WIN) - win_util::MessageBox(NULL, UTF8ToWide(error), - L"Extension load error", MB_OK | MB_SETFOREGROUND); -#endif - } -} - -void ExtensionsService::OnExtensionInstallError(bool alert_on_error, - const std::string& error) { - // TODO(erikkay): Print the error message out somewhere better. - LOG(WARNING) << error; - if (alert_on_error) { -#if defined(OS_WIN) - win_util::MessageBox(NULL, UTF8ToWide(error), - L"Extension load error", MB_OK | MB_SETFOREGROUND); -#endif - } -} - void ExtensionsService::OnExtensionInstalled(FilePath path, bool update) { NotificationService::current()->Notify( NotificationType::EXTENSION_INSTALLED, @@ -339,14 +314,11 @@ Extension* ExtensionsServiceBackend::LoadExtension() { void ExtensionsServiceBackend::ReportExtensionLoadError( const std::string &error) { - // TODO(port): note that this isn't guaranteed to work properly on Linux. std::string path_str = WideToASCII(extension_path_.ToWStringHack()); std::string message = StringPrintf("Could not load extension from '%s'. %s", path_str.c_str(), error.c_str()); - frontend_->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod( - frontend_, &ExtensionsServiceFrontendInterface::OnExtensionLoadError, - alert_on_error_, message)); + ExtensionErrorReporter::GetInstance()->ReportError(message, alert_on_error_); } void ExtensionsServiceBackend::ReportExtensionsLoaded( @@ -702,9 +674,7 @@ void ExtensionsServiceBackend::ReportExtensionInstallError( std::string message = StringPrintf("Could not install extension from '%s'. %s", path_str.c_str(), error.c_str()); - frontend_->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod( - frontend_, &ExtensionsServiceFrontendInterface::OnExtensionInstallError, - alert_on_error_, message)); + ExtensionErrorReporter::GetInstance()->ReportError(message, alert_on_error_); } void ExtensionsServiceBackend::ReportExtensionInstalled( diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index c8f04b0..efba0086 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -37,18 +37,10 @@ class ExtensionsServiceFrontendInterface // Load the extension from the directory |extension_path|. virtual void LoadExtension(const FilePath& extension_path) = 0; - // Called when loading an extension fails. - virtual void OnExtensionLoadError(bool alert_on_error, - const std::string& message) = 0; - // Called with results from LoadExtensionsFromDirectory(). The frontend // takes ownership of the list. virtual void OnExtensionsLoadedFromDirectory(ExtensionList* extensions) = 0; - // Called when installing an extension fails. - virtual void OnExtensionInstallError(bool alert_on_error, - const std::string& message) = 0; - // Called with results from InstallExtension(). // |is_update| is true if the installation was an update to an existing // installed extension rather than a new installation. @@ -75,11 +67,7 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface { virtual MessageLoop* GetMessageLoop(); virtual void InstallExtension(const FilePath& extension_path); virtual void LoadExtension(const FilePath& extension_path); - virtual void OnExtensionLoadError(bool alert_on_error, - const std::string& message); virtual void OnExtensionsLoadedFromDirectory(ExtensionList* extensions); - virtual void OnExtensionInstallError(bool alert_on_error, - const std::string& message); virtual void OnExtensionInstalled(FilePath path, bool is_update); // The name of the file that the current active version number is stored in. @@ -118,7 +106,7 @@ class ExtensionsServiceBackend // Loads extensions from a directory. The extensions are assumed to be // unpacked in directories that are direct children of the specified path. - // Errors are reported through OnExtensionLoadError(). On completion, + // Errors are reported through ExtensionErrorReporter. On completion, // OnExtensionsLoadedFromDirectory() is called with any successfully loaded // extensions. void LoadExtensionsFromDirectory( @@ -127,7 +115,7 @@ class ExtensionsServiceBackend // Loads a single extension from |path| where |path| is the top directory of // a specific extension where its manifest file lives. - // Errors are reported through OnExtensionLoadError(). On completion, + // Errors are reported through ExtensionErrorReporter. On completion, // OnExtensionsLoadedFromDirectory() is called with any successfully loaded // extensions. // TODO(erikkay): It might be useful to be able to load a packed extension diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index a49399d..b3ab36a 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -12,6 +12,7 @@ #include "base/path_service.h" #include "base/string_util.h" #include "chrome/browser/extensions/extension.h" +#include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_value_serializer.h" @@ -26,6 +27,25 @@ struct ExtensionsOrder { } }; +static std::vector<std::string> GetErrors() { + const std::vector<std::string>* errors = + ExtensionErrorReporter::GetInstance()->GetErrors(); + std::vector<std::string> ret_val; + + for (std::vector<std::string>::const_iterator iter = errors->begin(); + iter != errors->end(); ++iter) { + if (iter->find(".svn") == std::string::npos) { + ret_val.push_back(*iter); + } + } + + // The tests rely on the errors being in a certain order, which can vary + // depending on how filesystem iteration works. + std::stable_sort(ret_val.begin(), ret_val.end()); + + return ret_val; +} + } // namespace // A mock implementation of ExtensionsServiceFrontendInterface for testing the @@ -46,10 +66,6 @@ class ExtensionsServiceTestFrontend } } - std::vector<std::string>* errors() { - return &errors_; - } - ExtensionList* extensions() { return &extensions_; } @@ -73,29 +89,13 @@ class ExtensionsServiceTestFrontend virtual void LoadExtension(const FilePath& extension_path) { } - virtual void OnExtensionLoadError(bool alert_on_error, - const std::string& message) { - // In the development environment, we get errors when trying to load - // extensions out of the .svn directories. - if (message.find(".svn") != std::string::npos) - return; - - errors_.push_back(message); - } - virtual void OnExtensionsLoadedFromDirectory(ExtensionList* new_extensions) { extensions_.insert(extensions_.end(), new_extensions->begin(), new_extensions->end()); delete new_extensions; - // In the tests we rely on extensions and errors being in particular order, - // which is not always the case (and is not guaranteed by used APIs). + // In the tests we rely on extensions being in particular order, which is + // not always the case (and is not guaranteed by used APIs). std::stable_sort(extensions_.begin(), extensions_.end(), ExtensionsOrder()); - std::stable_sort(errors_.begin(), errors_.end()); - } - - virtual void OnExtensionInstallError(bool alert_on_error, - const std::string& message) { - errors_.push_back(message); } virtual void OnExtensionInstalled(FilePath path, bool is_update) { @@ -109,32 +109,42 @@ class ExtensionsServiceTestFrontend backend->InstallExtension(path, install_dir_, false, scoped_refptr<ExtensionsServiceFrontendInterface>(this)); message_loop_.RunAllPending(); + std::vector<std::string> errors = GetErrors(); if (should_succeed) { EXPECT_EQ(1u, installed_.size()) << path.value(); - EXPECT_EQ(0u, errors_.size()) << path.value(); - for (std::vector<std::string>::iterator err = errors_.begin(); - err != errors_.end(); ++err) { + EXPECT_EQ(0u, errors.size()) << path.value(); + for (std::vector<std::string>::iterator err = errors.begin(); + err != errors.end(); ++err) { LOG(ERROR) << *err; } } else { EXPECT_EQ(0u, installed_.size()) << path.value(); - EXPECT_EQ(1u, errors_.size()) << path.value(); + EXPECT_EQ(1u, errors.size()) << path.value(); } + installed_.clear(); - errors_.clear(); + ExtensionErrorReporter::GetInstance()->ClearErrors(); } private: MessageLoop message_loop_; ExtensionList extensions_; - std::vector<std::string> errors_; std::vector<FilePath> installed_; FilePath install_dir_; }; // make the test a PlatformTest to setup autorelease pools properly on mac -typedef PlatformTest ExtensionsServiceTest; +class ExtensionsServiceTest : public testing::Test { + public: + static void SetUpTestCase() { + ExtensionErrorReporter::Init(false); // no noisy errors + } + + virtual void SetUp() { + ExtensionErrorReporter::GetInstance()->ClearErrors(); + } +}; // Test loading good extensions from the profile directory. TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) { @@ -152,9 +162,9 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) { scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); frontend->GetMessageLoop()->RunAllPending(); - std::vector<std::string>* errors = frontend->errors(); - for (std::vector<std::string>::iterator err = errors->begin(); - err != errors->end(); ++err) { + std::vector<std::string> errors = GetErrors(); + for (std::vector<std::string>::iterator err = errors.begin(); + err != errors.end(); ++err) { LOG(ERROR) << *err; } ASSERT_EQ(3u, frontend->extensions()->size()); @@ -216,24 +226,24 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) { scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); frontend->GetMessageLoop()->RunAllPending(); - EXPECT_EQ(4u, frontend->errors()->size()); + EXPECT_EQ(4u, GetErrors().size()); EXPECT_EQ(0u, frontend->extensions()->size()); - EXPECT_TRUE(MatchPattern(frontend->errors()->at(0), + EXPECT_TRUE(MatchPattern(GetErrors()[0], std::string("Could not load extension from '*'. * ") + - JSONReader::kBadRootElementType)) << frontend->errors()->at(0); + JSONReader::kBadRootElementType)) << GetErrors()[0]; - EXPECT_TRUE(MatchPattern(frontend->errors()->at(1), + EXPECT_TRUE(MatchPattern(GetErrors()[1], std::string("Could not load extension from '*'. ") + - Extension::kInvalidJsListError)) << frontend->errors()->at(1); + Extension::kInvalidJsListError)) << GetErrors()[1]; - EXPECT_TRUE(MatchPattern(frontend->errors()->at(2), + EXPECT_TRUE(MatchPattern(GetErrors()[2], std::string("Could not load extension from '*'. ") + - Extension::kInvalidManifestError)) << frontend->errors()->at(2); + Extension::kInvalidManifestError)) << GetErrors()[2]; - EXPECT_TRUE(MatchPattern(frontend->errors()->at(3), + EXPECT_TRUE(MatchPattern(GetErrors()[3], "Could not load extension from '*'. Could not read '*' file.")) << - frontend->errors()->at(3); + GetErrors()[3]; }; // Test installing extensions. @@ -289,7 +299,7 @@ TEST_F(ExtensionsServiceTest, LoadExtension) { backend->LoadSingleExtension(ext1, scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); frontend->GetMessageLoop()->RunAllPending(); - EXPECT_EQ(0u, frontend->errors()->size()); + EXPECT_EQ(0u, GetErrors().size()); ASSERT_EQ(1u, frontend->extensions()->size()); FilePath no_manifest = extensions_path.AppendASCII("bad") @@ -297,7 +307,6 @@ TEST_F(ExtensionsServiceTest, LoadExtension) { backend->LoadSingleExtension(no_manifest, scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); frontend->GetMessageLoop()->RunAllPending(); - EXPECT_EQ(1u, frontend->errors()->size()); + EXPECT_EQ(1u, GetErrors().size()); ASSERT_EQ(1u, frontend->extensions()->size()); } - diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 86e9d16..9600c6c 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -14,6 +14,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_manager.h" +#include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/history/history.h" @@ -367,6 +368,7 @@ void ProfileImpl::InitExtensions() { script_dir = script_dir.Append(chrome::kUserScriptsDirname); } + ExtensionErrorReporter::Init(true); // allow noisy errors. user_script_master_ = new UserScriptMaster( g_browser_process->file_thread()->message_loop(), script_dir); extensions_service_ = new ExtensionsService( diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj index 6ddba28..7b958a3 100644 --- a/chrome/chrome.xcodeproj/project.pbxproj +++ b/chrome/chrome.xcodeproj/project.pbxproj @@ -387,6 +387,7 @@ ABFA34C50F4255CC008FCF5D /* libmedia.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABFA33880F424EC5008FCF5D /* libmedia.a */; }; ABFA34C70F425637008FCF5D /* libmedia.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABFA33880F424EC5008FCF5D /* libmedia.a */; }; ABFA34C80F425677008FCF5D /* libmedia.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABFA33880F424EC5008FCF5D /* libmedia.a */; }; + AC021BD1578D51C5FC94AA16 /* extension_error_reporter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 68948A0302AADFF9A8419E28 /* extension_error_reporter.cc */; }; B0AC9501DED2809AC208AEEA /* resolve_proxy_msg_helper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4F9429998AC2703984BAB828 /* resolve_proxy_msg_helper.cc */; }; B502DA280F098056005BE90C /* visit_database_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA180E9D48F7009A6919 /* visit_database_unittest.cc */; }; B502DA520F098888005BE90C /* l10n_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBC90E9D4C9F009A6919 /* l10n_util.cc */; }; @@ -436,6 +437,7 @@ BDBF78593E5B3E355CCF3FF8 /* download_item_model.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9CC0E9D48CE009A6919 /* download_item_model.cc */; }; C53EBF7E1E204C3780FD4A7D /* ssl_policy.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D16ED10F21451600861FAC /* ssl_policy.cc */; }; C6C256C56BA114D53849523F /* greasemonkey_api_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1F43A7C85092C58AAF011F78 /* greasemonkey_api_unittest.cc */; }; + C81B41FCBD9DDB0BF97B3780 /* extension_error_reporter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 68948A0302AADFF9A8419E28 /* extension_error_reporter.cc */; }; C8F5EB819EA38CE9D50AF5B5 /* history.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9EC0E9D48F7009A6919 /* history.cc */; }; CA81330E0F423C4D0096C1DC /* query_parser_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA020E9D48F7009A6919 /* query_parser_unittest.cc */; }; CA8133120F423C710096C1DC /* url_database_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA150E9D48F7009A6919 /* url_database_unittest.cc */; }; @@ -2521,6 +2523,7 @@ 622534301BD3F4A908D426D0 /* user_data_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user_data_manager.cc; sourceTree = "<group>"; }; 629BF493DEA096E2DD844F2B /* autofill_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = autofill_manager.cc; sourceTree = "<group>"; }; 6447F24FADC63E58A44DB762 /* url_pattern.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = url_pattern.cc; path = extensions/url_pattern.cc; sourceTree = "<group>"; }; + 68948A0302AADFF9A8419E28 /* extension_error_reporter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = extension_error_reporter.cc; sourceTree = "<group>"; }; 699499C4FBA07FB2D7B298A2 /* user_script.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user_script.cc; path = extensions/user_script.cc; sourceTree = "<group>"; }; 759B3A1B81E261598122B03B /* v8_unit_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v8_unit_test.cc; sourceTree = "<group>"; }; 778D7927798B7E3FAA498D3D /* url_fetcher.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fetcher.cc; sourceTree = "<group>"; }; @@ -4695,6 +4698,7 @@ children = ( E4F324400EE5CE94002533CE /* extension.cc */, E4F324410EE5CE94002533CE /* extension.h */, + 68948A0302AADFF9A8419E28 /* extension_error_reporter.cc */, E48B6C270F2783E9002E47EC /* extension_protocols.cc */, E48B6C260F2783E9002E47EC /* extension_protocols.h */, E4F324420EE5CE94002533CE /* extension_unittest.cc */, @@ -5728,6 +5732,7 @@ E45075E30F150A6F003BE099 /* download_throttling_resource_handler.cc in Sources */, E4F324470EE5CF1F002533CE /* expire_history_backend.cc in Sources */, E4F324430EE5CE94002533CE /* extension.cc in Sources */, + AC021BD1578D51C5FC94AA16 /* extension_error_reporter.cc in Sources */, E48B6C280F2783E9002E47EC /* extension_protocols.cc in Sources */, A54612E20EE995F600A8EE5D /* extensions_service.cc in Sources */, 9E85B39CA40439D93CE52E60 /* fav_icon_helper.cc in Sources */, @@ -5882,6 +5887,7 @@ 331218330F3C0123006CB2B0 /* debug_message_handler.cc in Sources */, 4D7BFB510E9D4C3E009A6919 /* dns_host_info_unittest.cc in Sources */, 623E5BE905E098E8280304DA /* dns_master_unittest.cc in Sources */, + C81B41FCBD9DDB0BF97B3780 /* extension_error_reporter.cc in Sources */, E4F324950EE5D758002533CE /* extension_unittest.cc in Sources */, A54612DC0EE9958600A8EE5D /* extensions_service_unittest.cc in Sources */, 331218300F3C010A006CB2B0 /* external_js_object.cc in Sources */, |