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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/chrome_test_extension_loader.h"
6
7 #include <memory>
8
9 #include "base/files/file_util.h"
10 #include "base/run_loop.h"
11 #include "chrome/browser/extensions/chrome_extension_test_notification_observer. h"
12 #include "chrome/browser/extensions/crx_installer.h"
13 #include "chrome/browser/extensions/extension_creator.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extension_util.h"
16 #include "chrome/browser/extensions/unpacked_installer.h"
17 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_source.h"
19 #include "content/public/test/test_utils.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/notification_types.h"
23 #include "extensions/browser/test_extension_registry_observer.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace extensions {
27
28 ChromeTestExtensionLoader::ChromeTestExtensionLoader(
29 content::BrowserContext* browser_context)
30 : browser_context_(browser_context),
31 extension_system_(ExtensionSystem::Get(browser_context)),
32 extension_service_(extension_system_->extension_service()),
33 extension_registry_(ExtensionRegistry::Get(browser_context)) {}
34
35 ChromeTestExtensionLoader::~ChromeTestExtensionLoader() {}
36
37 scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadExtension(
38 const base::FilePath& path) {
39 scoped_refptr<const Extension> extension;
40 if (path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
41 extension = LoadCrx(path);
42 } else if (pack_extension_) {
43 base::FilePath crx_path = PackExtension(path);
44 if (crx_path.empty())
45 return nullptr;
46 extension = LoadCrx(crx_path);
47 } else {
48 extension = LoadUnpacked(path);
49 }
50
51 if (should_fail_ && extension)
52 ADD_FAILURE() << "Expected extension installation failure, but succeeded";
53 else if (!should_fail_ && !extension)
54 ADD_FAILURE() << "Failed to install extension";
55
56 if (!extension)
57 return nullptr;
58
59 extension_id_ = extension->id();
60 extension = nullptr;
61 CheckPermissions(extension_id_);
62
63 if (!install_param_.empty()) {
64 ExtensionPrefs::Get(browser_context_)
65 ->SetInstallParam(extension_id_, install_param_);
66 TestExtensionRegistryObserver registry_observer(extension_registry_,
67 extension_id_);
68 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.
69 registry_observer.WaitForExtensionLoaded();
70 }
71
72 extension = extension_registry_->enabled_extensions().GetByID(extension_id_);
73 if (!extension)
74 return nullptr;
75 if (!CheckErrors(*extension))
76 return nullptr;
77
78 base::RunLoop().RunUntilIdle();
79 if (!WaitForExtensionReady(*extension)) {
80 ADD_FAILURE() << "Failed to wait for extension ready";
81 return nullptr;
82 }
83 return extension;
84 }
85
86 bool ChromeTestExtensionLoader::WaitForExtensionReady(
87 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
88 return ChromeExtensionTestNotificationObserver(browser_context_)
89 .WaitForExtensionViewsToLoad();
90 }
91
92 base::FilePath ChromeTestExtensionLoader::PackExtension(
93 const base::FilePath& unpacked_path) {
94 if (!base::PathExists(unpacked_path)) {
95 ADD_FAILURE() << "Unpacked path does not exist: " << unpacked_path.value();
96 return base::FilePath();
97 }
98
99 base::FilePath crx_path = temp_dir_.GetPath().AppendASCII("temp.crx");
100 if (base::PathExists(crx_path)) {
101 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.
102 return base::FilePath();
103 }
104 base::FilePath fallback_pem_path =
105 temp_dir_.GetPath().AppendASCII("temp.pem");
106 if (base::PathExists(fallback_pem_path)) {
107 ADD_FAILURE() << "PEM path exists: " << fallback_pem_path.value();
108 return base::FilePath();
109 }
110
111 base::FilePath* pem_path_to_use = &fallback_pem_path;
112 if (!pem_path_.empty()) {
113 pem_path_to_use = &pem_path_;
114 if (!base::PathExists(pem_path_)) {
115 ADD_FAILURE() << "Provided PEM path does not exist: "
116 << pem_path_.value();
117 return base::FilePath();
118 }
119 }
120
121 ExtensionCreator creator;
122 if (!creator.Run(unpacked_path, crx_path, *pem_path_to_use, fallback_pem_path,
123 ExtensionCreator::kOverwriteCRX)) {
124 ADD_FAILURE() << "ExtensionCreator::Run() failed: "
125 << creator.error_message();
126 return base::FilePath();
127 }
128
129 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
130
131 return crx_path;
132 }
133
134 scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadCrx(
135 const base::FilePath& file_path) {
136 if (!file_path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
137 ADD_FAILURE() << "Must pass a crx path to LoadCrx()";
138 return nullptr;
139 }
140
141 scoped_refptr<const Extension> extension;
142 {
143 std::unique_ptr<ExtensionInstallPrompt> install_ui;
144 // Do something with ^^
lazyboy 2016/11/23 21:27:56 Should this become a TODO?
Devlin 2016/11/23 22:19:07 Whoops! Done.
145 scoped_refptr<CrxInstaller> installer =
146 CrxInstaller::Create(extension_service_, std::move(install_ui));
147 installer->set_expected_id(expected_id_);
148 installer->set_creation_flags(creation_flags_);
149 installer->set_install_source(location_);
150 installer->set_install_immediately(install_immediately_);
151 installer->set_allow_silent_install(grant_permissions_);
152 if (!installer->is_gallery_install()) {
153 installer->set_off_store_install_allow_reason(
154 CrxInstaller::OffStoreInstallAllowedInTest);
155 }
156
157 content::WindowedNotificationObserver install_observer(
158 NOTIFICATION_CRX_INSTALLER_DONE,
159 content::Source<CrxInstaller>(installer.get()));
160 installer->InstallCrx(file_path);
161 install_observer.Wait();
162
163 extension =
164 content::Details<const Extension>(install_observer.details()).ptr();
165 }
166
167 return extension;
168 }
169
170 void ChromeTestExtensionLoader::CheckPermissions(
171 const std::string& extension_id) {
172 std::string id = extension_id;
173
174 // Toggling incognito or file access will reload the extension, so wait for
175 // the reload.
176 if (allow_file_access_ != util::AllowFileAccess(id, browser_context_)) {
177 TestExtensionRegistryObserver registry_observer(extension_registry_, id);
178 util::SetAllowFileAccess(id, browser_context_, allow_file_access_);
179 registry_observer.WaitForExtensionLoaded();
180 }
181
182 if (allow_incognito_access_ !=
183 util::IsIncognitoEnabled(id, browser_context_)) {
184 TestExtensionRegistryObserver registry_observer(extension_registry_, id);
185 util::SetIsIncognitoEnabled(id, browser_context_, true);
186 registry_observer.WaitForExtensionLoaded();
187 }
188 }
189
190 scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadUnpacked(
191 const base::FilePath& file_path) {
192 const Extension* extension = nullptr;
193 TestExtensionRegistryObserver registry_observer(extension_registry_);
194 scoped_refptr<UnpackedInstaller> installer =
195 UnpackedInstaller::Create(extension_service_);
196 installer->set_prompt_for_plugins(false);
197 installer->set_require_modern_manifest_version(
198 require_modern_manifest_version_);
199 installer->Load(file_path);
200 extension = registry_observer.WaitForExtensionLoaded();
201
202 return extension;
203 }
204
205 bool ChromeTestExtensionLoader::CheckErrors(const Extension& extension) {
206 if (ignore_manifest_warnings_)
207 return true;
208 const std::vector<InstallWarning>& install_warnings =
209 extension.install_warnings();
210 if (install_warnings.empty())
211 return true;
212
213 std::string install_warnings_message = "Unexpected warnings for extension:\n";
214 for (const InstallWarning& warning : install_warnings)
215 install_warnings_message += " " + warning.message + "\n";
216
217 ADD_FAILURE() << install_warnings_message;
218 return false;
219 }
220
221 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698