Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Unified Diff: chrome/browser/extensions/chrome_test_extension_loader.cc

Issue 2524553002: [Extensions] Create ChromeTestExtensionLoader (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/chrome_test_extension_loader.cc
diff --git a/chrome/browser/extensions/chrome_test_extension_loader.cc b/chrome/browser/extensions/chrome_test_extension_loader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3ec06b238b889124fbf670060a3360bf5769222e
--- /dev/null
+++ b/chrome/browser/extensions/chrome_test_extension_loader.cc
@@ -0,0 +1,221 @@
+// Copyright 2016 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/chrome_test_extension_loader.h"
+
+#include <memory>
+
+#include "base/files/file_util.h"
+#include "base/run_loop.h"
+#include "chrome/browser/extensions/chrome_extension_test_notification_observer.h"
+#include "chrome/browser/extensions/crx_installer.h"
+#include "chrome/browser/extensions/extension_creator.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/extensions/unpacked_installer.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/test/test_utils.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/notification_types.h"
+#include "extensions/browser/test_extension_registry_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+ChromeTestExtensionLoader::ChromeTestExtensionLoader(
+ content::BrowserContext* browser_context)
+ : browser_context_(browser_context),
+ extension_system_(ExtensionSystem::Get(browser_context)),
+ extension_service_(extension_system_->extension_service()),
+ extension_registry_(ExtensionRegistry::Get(browser_context)) {}
+
+ChromeTestExtensionLoader::~ChromeTestExtensionLoader() {}
+
+scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadExtension(
+ const base::FilePath& path) {
+ scoped_refptr<const Extension> extension;
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
+ extension = LoadCrx(path);
+ } else if (pack_extension_) {
+ base::FilePath crx_path = PackExtension(path);
+ if (crx_path.empty())
+ return nullptr;
+ extension = LoadCrx(crx_path);
+ } else {
+ extension = LoadUnpacked(path);
+ }
+
+ if (should_fail_ && extension)
+ ADD_FAILURE() << "Expected extension installation failure, but succeeded";
+ else if (!should_fail_ && !extension)
+ ADD_FAILURE() << "Failed to install extension";
+
+ if (!extension)
+ return nullptr;
+
+ extension_id_ = extension->id();
+ extension = nullptr;
+ CheckPermissions(extension_id_);
+
+ if (!install_param_.empty()) {
+ ExtensionPrefs::Get(browser_context_)
+ ->SetInstallParam(extension_id_, install_param_);
+ TestExtensionRegistryObserver registry_observer(extension_registry_,
+ extension_id_);
+ extension_service_->ReloadExtension(extension_id_);
lazyboy 2016/11/23 21:27:56 Add a note on why reload is necessary.
Devlin 2016/11/23 22:19:07 Done.
+ registry_observer.WaitForExtensionLoaded();
+ }
+
+ extension = extension_registry_->enabled_extensions().GetByID(extension_id_);
+ if (!extension)
+ return nullptr;
+ if (!CheckErrors(*extension))
+ return nullptr;
+
+ base::RunLoop().RunUntilIdle();
+ if (!WaitForExtensionReady(*extension)) {
+ ADD_FAILURE() << "Failed to wait for extension ready";
+ return nullptr;
+ }
+ return extension;
+}
+
+bool ChromeTestExtensionLoader::WaitForExtensionReady(
+ const Extension& extension) {
lazyboy 2016/11/23 21:27:56 Remove |extension| param since it isn't really wai
Devlin 2016/11/23 22:19:07 Done. I was thinking this might be expanded a bit
+ return ChromeExtensionTestNotificationObserver(browser_context_)
+ .WaitForExtensionViewsToLoad();
+}
+
+base::FilePath ChromeTestExtensionLoader::PackExtension(
+ const base::FilePath& unpacked_path) {
+ if (!base::PathExists(unpacked_path)) {
+ ADD_FAILURE() << "Unpacked path does not exist: " << unpacked_path.value();
+ return base::FilePath();
+ }
+
+ base::FilePath crx_path = temp_dir_.GetPath().AppendASCII("temp.crx");
+ if (base::PathExists(crx_path)) {
+ ADD_FAILURE() << "Crx path exists: " << crx_path.value();
lazyboy 2016/11/23 21:27:57 This probably means same ChromeTestExtensionLoader
Devlin 2016/11/23 22:19:07 Done.
+ return base::FilePath();
+ }
+ base::FilePath fallback_pem_path =
+ temp_dir_.GetPath().AppendASCII("temp.pem");
+ if (base::PathExists(fallback_pem_path)) {
+ ADD_FAILURE() << "PEM path exists: " << fallback_pem_path.value();
+ return base::FilePath();
+ }
+
+ base::FilePath* pem_path_to_use = &fallback_pem_path;
+ if (!pem_path_.empty()) {
+ pem_path_to_use = &pem_path_;
+ if (!base::PathExists(pem_path_)) {
+ ADD_FAILURE() << "Provided PEM path does not exist: "
+ << pem_path_.value();
+ return base::FilePath();
+ }
+ }
+
+ ExtensionCreator creator;
+ if (!creator.Run(unpacked_path, crx_path, *pem_path_to_use, fallback_pem_path,
+ ExtensionCreator::kOverwriteCRX)) {
+ ADD_FAILURE() << "ExtensionCreator::Run() failed: "
+ << creator.error_message();
+ return base::FilePath();
+ }
+
+ DCHECK(base::PathExists(crx_path));
lazyboy 2016/11/23 21:27:56 CHECK is better?
Devlin 2016/11/23 22:19:07 Practically, I'm not sure how much of a difference
+
+ return crx_path;
+}
+
+scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadCrx(
+ const base::FilePath& file_path) {
+ if (!file_path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
+ ADD_FAILURE() << "Must pass a crx path to LoadCrx()";
+ return nullptr;
+ }
+
+ scoped_refptr<const Extension> extension;
+ {
+ std::unique_ptr<ExtensionInstallPrompt> install_ui;
+ // Do something with ^^
lazyboy 2016/11/23 21:27:56 Should this become a TODO?
Devlin 2016/11/23 22:19:07 Whoops! Done.
+ scoped_refptr<CrxInstaller> installer =
+ CrxInstaller::Create(extension_service_, std::move(install_ui));
+ installer->set_expected_id(expected_id_);
+ installer->set_creation_flags(creation_flags_);
+ installer->set_install_source(location_);
+ installer->set_install_immediately(install_immediately_);
+ installer->set_allow_silent_install(grant_permissions_);
+ if (!installer->is_gallery_install()) {
+ installer->set_off_store_install_allow_reason(
+ CrxInstaller::OffStoreInstallAllowedInTest);
+ }
+
+ content::WindowedNotificationObserver install_observer(
+ NOTIFICATION_CRX_INSTALLER_DONE,
+ content::Source<CrxInstaller>(installer.get()));
+ installer->InstallCrx(file_path);
+ install_observer.Wait();
+
+ extension =
+ content::Details<const Extension>(install_observer.details()).ptr();
+ }
+
+ return extension;
+}
+
+void ChromeTestExtensionLoader::CheckPermissions(
+ const std::string& extension_id) {
+ std::string id = extension_id;
+
+ // Toggling incognito or file access will reload the extension, so wait for
+ // the reload.
+ if (allow_file_access_ != util::AllowFileAccess(id, browser_context_)) {
+ TestExtensionRegistryObserver registry_observer(extension_registry_, id);
+ util::SetAllowFileAccess(id, browser_context_, allow_file_access_);
+ registry_observer.WaitForExtensionLoaded();
+ }
+
+ if (allow_incognito_access_ !=
+ util::IsIncognitoEnabled(id, browser_context_)) {
+ TestExtensionRegistryObserver registry_observer(extension_registry_, id);
+ util::SetIsIncognitoEnabled(id, browser_context_, true);
+ registry_observer.WaitForExtensionLoaded();
+ }
+}
+
+scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadUnpacked(
+ const base::FilePath& file_path) {
+ const Extension* extension = nullptr;
+ TestExtensionRegistryObserver registry_observer(extension_registry_);
+ scoped_refptr<UnpackedInstaller> installer =
+ UnpackedInstaller::Create(extension_service_);
+ installer->set_prompt_for_plugins(false);
+ installer->set_require_modern_manifest_version(
+ require_modern_manifest_version_);
+ installer->Load(file_path);
+ extension = registry_observer.WaitForExtensionLoaded();
+
+ return extension;
+}
+
+bool ChromeTestExtensionLoader::CheckErrors(const Extension& extension) {
+ if (ignore_manifest_warnings_)
+ return true;
+ const std::vector<InstallWarning>& install_warnings =
+ extension.install_warnings();
+ if (install_warnings.empty())
+ return true;
+
+ std::string install_warnings_message = "Unexpected warnings for extension:\n";
+ for (const InstallWarning& warning : install_warnings)
+ install_warnings_message += " " + warning.message + "\n";
+
+ ADD_FAILURE() << install_warnings_message;
+ return false;
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698