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

Side by Side Diff: chrome/browser/extensions/crx_installer.cc

Issue 6992047: Change the web store private install API to accept a localized extension name. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased, removed test files I added in separate CL Created 9 years, 7 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/crx_installer.h" 5 #include "chrome/browser/extensions/crx_installer.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 23 matching lines...) Expand all
34 #include "content/common/notification_type.h" 34 #include "content/common/notification_type.h"
35 #include "grit/chromium_strings.h" 35 #include "grit/chromium_strings.h"
36 #include "grit/generated_resources.h" 36 #include "grit/generated_resources.h"
37 #include "grit/theme_resources.h" 37 #include "grit/theme_resources.h"
38 #include "third_party/skia/include/core/SkBitmap.h" 38 #include "third_party/skia/include/core/SkBitmap.h"
39 #include "ui/base/l10n/l10n_util.h" 39 #include "ui/base/l10n/l10n_util.h"
40 #include "ui/base/resource/resource_bundle.h" 40 #include "ui/base/resource/resource_bundle.h"
41 41
42 namespace { 42 namespace {
43 43
44 struct WhitelistedInstallData { 44 struct Whitelist {
45 WhitelistedInstallData() {} 45 Whitelist() {}
46 std::set<std::string> ids; 46 std::set<std::string> ids;
47 std::map<std::string, linked_ptr<DictionaryValue> > manifests; 47 std::map<std::string, linked_ptr<CrxInstaller::WhitelistEntry> > entries;
48 }; 48 };
49 49
50 static base::LazyInstance<WhitelistedInstallData> 50 static base::LazyInstance<Whitelist>
51 g_whitelisted_install_data(base::LINKER_INITIALIZED); 51 g_whitelisted_install_data(base::LINKER_INITIALIZED);
52 52
53 } // namespace 53 } // namespace
54 54
55 // static 55 // static
56 void CrxInstaller::SetWhitelistedInstallId(const std::string& id) { 56 void CrxInstaller::SetWhitelistedInstallId(const std::string& id) {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 57 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58 g_whitelisted_install_data.Get().ids.insert(id); 58 g_whitelisted_install_data.Get().ids.insert(id);
59 } 59 }
60 60
61 // static 61 // static
62 void CrxInstaller::SetWhitelistedManifest(const std::string& id, 62 void CrxInstaller::SetWhitelistEntry(const std::string& id,
63 DictionaryValue* parsed_manifest) { 63 CrxInstaller::WhitelistEntry* entry) {
64 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 64 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
65 WhitelistedInstallData& data = g_whitelisted_install_data.Get(); 65 Whitelist& data = g_whitelisted_install_data.Get();
66 data.manifests[id] = linked_ptr<DictionaryValue>(parsed_manifest); 66 data.entries[id] = linked_ptr<CrxInstaller::WhitelistEntry>(entry);
67 } 67 }
68 68
69 // static 69 // static
70 const DictionaryValue* CrxInstaller::GetWhitelistedManifest( 70 const CrxInstaller::WhitelistEntry* CrxInstaller::GetWhitelistEntry(
71 const std::string& id) { 71 const std::string& id) {
72 WhitelistedInstallData& data = g_whitelisted_install_data.Get(); 72 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73 if (ContainsKey(data.manifests, id)) 73 Whitelist& data = g_whitelisted_install_data.Get();
74 return data.manifests[id].get(); 74 if (ContainsKey(data.entries, id))
75 return data.entries[id].get();
75 else 76 else
76 return NULL; 77 return NULL;
77 } 78 }
78 79
79 // static 80 // static
80 DictionaryValue* CrxInstaller::RemoveWhitelistedManifest( 81 CrxInstaller::WhitelistEntry* CrxInstaller::RemoveWhitelistEntry(
81 const std::string& id) { 82 const std::string& id) {
82 WhitelistedInstallData& data = g_whitelisted_install_data.Get(); 83 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83 if (ContainsKey(data.manifests, id)) { 84 Whitelist& data = g_whitelisted_install_data.Get();
84 DictionaryValue* manifest = data.manifests[id].release(); 85 if (ContainsKey(data.entries, id)) {
85 data.manifests.erase(id); 86 CrxInstaller::WhitelistEntry* entry = data.entries[id].release();
86 return manifest; 87 data.entries.erase(id);
88 return entry;
87 } 89 }
88 return NULL; 90 return NULL;
89 } 91 }
90 92
91 // static 93 // static
92 bool CrxInstaller::IsIdWhitelisted(const std::string& id) { 94 bool CrxInstaller::IsIdWhitelisted(const std::string& id) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 95 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
94 std::set<std::string>& ids = g_whitelisted_install_data.Get().ids; 96 std::set<std::string>& ids = g_whitelisted_install_data.Get().ids;
95 return ContainsKey(ids, id); 97 return ContainsKey(ids, id);
96 } 98 }
97 99
98 // static 100 // static
99 bool CrxInstaller::ClearWhitelistedInstallId(const std::string& id) { 101 bool CrxInstaller::ClearWhitelistedInstallId(const std::string& id) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 102 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101 std::set<std::string>& ids = g_whitelisted_install_data.Get().ids; 103 std::set<std::string>& ids = g_whitelisted_install_data.Get().ids;
102 if (ContainsKey(ids, id)) { 104 if (ContainsKey(ids, id)) {
103 ids.erase(id); 105 ids.erase(id);
104 return true; 106 return true;
105 } 107 }
106 return false; 108 return false;
107 } 109 }
108 110
109 CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> frontend_weak, 111 CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> frontend_weak,
110 ExtensionInstallUI* client) 112 ExtensionInstallUI* client)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 180
179 void CrxInstaller::ConvertUserScriptOnFileThread() { 181 void CrxInstaller::ConvertUserScriptOnFileThread() {
180 std::string error; 182 std::string error;
181 scoped_refptr<Extension> extension = 183 scoped_refptr<Extension> extension =
182 ConvertUserScriptToExtension(source_file_, original_url_, &error); 184 ConvertUserScriptToExtension(source_file_, original_url_, &error);
183 if (!extension) { 185 if (!extension) {
184 ReportFailureFromFileThread(error); 186 ReportFailureFromFileThread(error);
185 return; 187 return;
186 } 188 }
187 189
188 OnUnpackSuccess(extension->path(), extension->path(), extension); 190 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension);
189 } 191 }
190 192
191 void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) { 193 void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) {
192 if (!BrowserThread::PostTask( 194 if (!BrowserThread::PostTask(
193 BrowserThread::FILE, FROM_HERE, 195 BrowserThread::FILE, FROM_HERE,
194 NewRunnableMethod(this, &CrxInstaller::ConvertWebAppOnFileThread, 196 NewRunnableMethod(this, &CrxInstaller::ConvertWebAppOnFileThread,
195 web_app))) 197 web_app)))
196 NOTREACHED(); 198 NOTREACHED();
197 } 199 }
198 200
199 void CrxInstaller::ConvertWebAppOnFileThread( 201 void CrxInstaller::ConvertWebAppOnFileThread(
200 const WebApplicationInfo& web_app) { 202 const WebApplicationInfo& web_app) {
201 std::string error; 203 std::string error;
202 scoped_refptr<Extension> extension( 204 scoped_refptr<Extension> extension(
203 ConvertWebAppToExtension(web_app, base::Time::Now())); 205 ConvertWebAppToExtension(web_app, base::Time::Now()));
204 if (!extension) { 206 if (!extension) {
205 // Validation should have stopped any potential errors before getting here. 207 // Validation should have stopped any potential errors before getting here.
206 NOTREACHED() << "Could not convert web app to extension."; 208 NOTREACHED() << "Could not convert web app to extension.";
207 return; 209 return;
208 } 210 }
209 211
210 // TODO(aa): conversion data gets lost here :( 212 // TODO(aa): conversion data gets lost here :(
211 213
212 OnUnpackSuccess(extension->path(), extension->path(), extension); 214 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension);
213 } 215 }
214 216
215 bool CrxInstaller::AllowInstall(const Extension* extension, 217 bool CrxInstaller::AllowInstall(const Extension* extension,
216 std::string* error) { 218 std::string* error) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
218 DCHECK(error); 220 DCHECK(error);
219 221
220 // Make sure the expected id matches. 222 // Make sure the expected id matches.
221 if (!expected_id_.empty() && expected_id_ != extension->id()) { 223 if (!expected_id_.empty() && expected_id_ != extension->id()) {
222 *error = base::StringPrintf( 224 *error = base::StringPrintf(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 306
305 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallCause", 307 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallCause",
306 install_cause(), 308 install_cause(),
307 extension_misc::NUM_INSTALL_CAUSES); 309 extension_misc::NUM_INSTALL_CAUSES);
308 310
309 ReportFailureFromFileThread(error_message); 311 ReportFailureFromFileThread(error_message);
310 } 312 }
311 313
312 void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, 314 void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir,
313 const FilePath& extension_dir, 315 const FilePath& extension_dir,
316 const DictionaryValue* original_manifest,
314 const Extension* extension) { 317 const Extension* extension) {
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
316 319
317 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", 320 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource",
318 install_source(), Extension::NUM_LOCATIONS); 321 install_source(), Extension::NUM_LOCATIONS);
319 322
320 323
321 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause", 324 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause",
322 install_cause(), 325 install_cause(),
323 extension_misc::NUM_INSTALL_CAUSES); 326 extension_misc::NUM_INSTALL_CAUSES);
324 327
325 // Note: We take ownership of |extension| and |temp_dir|. 328 // Note: We take ownership of |extension| and |temp_dir|.
326 extension_ = extension; 329 extension_ = extension;
327 temp_dir_ = temp_dir; 330 temp_dir_ = temp_dir;
328 331
332 if (original_manifest)
333 original_manifest_.reset(original_manifest->DeepCopy());
334
329 // We don't have to delete the unpack dir explicity since it is a child of 335 // We don't have to delete the unpack dir explicity since it is a child of
330 // the temp dir. 336 // the temp dir.
331 unpacked_extension_root_ = extension_dir; 337 unpacked_extension_root_ = extension_dir;
332 338
333 std::string error; 339 std::string error;
334 if (!AllowInstall(extension, &error)) { 340 if (!AllowInstall(extension, &error)) {
335 ReportFailureFromFileThread(error); 341 ReportFailureFromFileThread(error);
336 return; 342 return;
337 } 343 }
338 344
339 if (client_) { 345 if (client_) {
340 Extension::DecodeIcon(extension_.get(), Extension::EXTENSION_ICON_LARGE, 346 Extension::DecodeIcon(extension_.get(), Extension::EXTENSION_ICON_LARGE,
341 &install_icon_); 347 &install_icon_);
342 } 348 }
343 349
344 if (!BrowserThread::PostTask( 350 if (!BrowserThread::PostTask(
345 BrowserThread::UI, FROM_HERE, 351 BrowserThread::UI, FROM_HERE,
346 NewRunnableMethod(this, &CrxInstaller::ConfirmInstall))) 352 NewRunnableMethod(this, &CrxInstaller::ConfirmInstall)))
347 NOTREACHED(); 353 NOTREACHED();
348 } 354 }
349 355
350 // Helper method to let us compare a whitelisted manifest with the actual
351 // downloaded extension's manifest, but ignoring the kPublicKey since the
352 // whitelisted manifest doesn't have that value.
353 static bool EqualsIgnoringPublicKey(
354 const DictionaryValue& extension_manifest,
355 const DictionaryValue& whitelisted_manifest) {
356 scoped_ptr<DictionaryValue> manifest_copy(extension_manifest.DeepCopy());
357 manifest_copy->Remove(extension_manifest_keys::kPublicKey, NULL);
358 return manifest_copy->Equals(&whitelisted_manifest);
359 }
360
361 void CrxInstaller::ConfirmInstall() { 356 void CrxInstaller::ConfirmInstall() {
362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
363 if (!frontend_weak_.get()) 358 if (!frontend_weak_.get())
364 return; 359 return;
365 360
366 if (frontend_weak_->extension_prefs() 361 if (frontend_weak_->extension_prefs()
367 ->IsExtensionBlacklisted(extension_->id())) { 362 ->IsExtensionBlacklisted(extension_->id())) {
368 VLOG(1) << "This extension: " << extension_->id() 363 VLOG(1) << "This extension: " << extension_->id()
369 << " is blacklisted. Install failed."; 364 << " is blacklisted. Install failed.";
370 ReportFailureFromUIThread( 365 ReportFailureFromUIThread(
(...skipping 20 matching lines...) Expand all
391 return; 386 return;
392 } 387 }
393 388
394 current_version_ = 389 current_version_ =
395 frontend_weak_->extension_prefs()->GetVersionString(extension_->id()); 390 frontend_weak_->extension_prefs()->GetVersionString(extension_->id());
396 391
397 // First see if it's whitelisted by id (the old mechanism). 392 // First see if it's whitelisted by id (the old mechanism).
398 bool whitelisted = ClearWhitelistedInstallId(extension_->id()) && 393 bool whitelisted = ClearWhitelistedInstallId(extension_->id()) &&
399 extension_->plugins().empty() && is_gallery_install_; 394 extension_->plugins().empty() && is_gallery_install_;
400 395
401 // Now check if it's whitelisted by manifest. 396 // Now check if there's a WhitelistEntry.
402 scoped_ptr<DictionaryValue> whitelisted_manifest( 397 scoped_ptr<CrxInstaller::WhitelistEntry> entry(
403 RemoveWhitelistedManifest(extension_->id())); 398 RemoveWhitelistEntry(extension_->id()));
404 if (is_gallery_install_ && whitelisted_manifest.get()) { 399 if (is_gallery_install_ && entry.get() && original_manifest_.get()) {
405 if (!EqualsIgnoringPublicKey(*extension_->manifest_value(), 400 if (!(original_manifest_->Equals(entry->parsed_manifest.get()))) {
406 *whitelisted_manifest)) {
407 ReportFailureFromUIThread( 401 ReportFailureFromUIThread(
408 l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_INVALID)); 402 l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_INVALID));
409 return; 403 return;
410 } 404 }
411 whitelisted = true; 405 whitelisted = true;
412 } 406 }
413 407
414 if (client_ && 408 if (client_ &&
415 (!allow_silent_install_ || !whitelisted)) { 409 (!allow_silent_install_ || !whitelisted)) {
416 AddRef(); // Balanced in Proceed() and Abort(). 410 AddRef(); // Balanced in Proceed() and Abort().
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 // Some users (such as the download shelf) need to know when a 557 // Some users (such as the download shelf) need to know when a
564 // CRXInstaller is done. Listening for the EXTENSION_* events 558 // CRXInstaller is done. Listening for the EXTENSION_* events
565 // is problematic because they don't know anything about the 559 // is problematic because they don't know anything about the
566 // extension before it is unpacked, so they can not filter based 560 // extension before it is unpacked, so they can not filter based
567 // on the extension. 561 // on the extension.
568 NotificationService::current()->Notify( 562 NotificationService::current()->Notify(
569 NotificationType::CRX_INSTALLER_DONE, 563 NotificationType::CRX_INSTALLER_DONE,
570 Source<CrxInstaller>(this), 564 Source<CrxInstaller>(this),
571 NotificationService::NoDetails()); 565 NotificationService::NoDetails());
572 } 566 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/crx_installer.h ('k') | chrome/browser/extensions/extension_webstore_private_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698