OLD | NEW |
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/extension_webstore_private_api.h" | 5 #include "chrome/browser/extensions/extension_webstore_private_api.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/extensions/crx_installer.h" | 14 #include "chrome/browser/extensions/crx_installer.h" |
15 #include "chrome/browser/extensions/extension_install_dialog.h" | 15 #include "chrome/browser/extensions/extension_install_dialog.h" |
16 #include "chrome/browser/extensions/extension_prefs.h" | 16 #include "chrome/browser/extensions/extension_prefs.h" |
17 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
18 #include "chrome/browser/net/gaia/token_service.h" | 18 #include "chrome/browser/net/gaia/token_service.h" |
19 #include "chrome/browser/profiles/profile_manager.h" | 19 #include "chrome/browser/profiles/profile_manager.h" |
20 #include "chrome/browser/sync/profile_sync_service.h" | 20 #include "chrome/browser/sync/profile_sync_service.h" |
21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/extensions/extension_constants.h" | 22 #include "chrome/common/extensions/extension_constants.h" |
23 #include "chrome/common/extensions/extension_error_utils.h" | 23 #include "chrome/common/extensions/extension_error_utils.h" |
| 24 #include "chrome/common/extensions/extension_l10n_util.h" |
24 #include "chrome/common/net/gaia/gaia_constants.h" | 25 #include "chrome/common/net/gaia/gaia_constants.h" |
25 #include "content/browser/tab_contents/tab_contents.h" | 26 #include "content/browser/tab_contents/tab_contents.h" |
26 #include "content/common/notification_details.h" | 27 #include "content/common/notification_details.h" |
27 #include "content/common/notification_source.h" | 28 #include "content/common/notification_source.h" |
28 #include "content/common/notification_type.h" | 29 #include "content/common/notification_type.h" |
29 #include "grit/chromium_strings.h" | 30 #include "grit/chromium_strings.h" |
30 #include "grit/generated_resources.h" | 31 #include "grit/generated_resources.h" |
31 #include "net/base/escape.h" | 32 #include "net/base/escape.h" |
32 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
| 37 const char kIconDataKey[] = "iconData"; |
| 38 const char kIdKey[] = "id"; |
| 39 const char kLocalizedNameKey[] = "localizedName"; |
36 const char kLoginKey[] = "login"; | 40 const char kLoginKey[] = "login"; |
| 41 const char kManifestKey[] = "manifest"; |
37 const char kTokenKey[] = "token"; | 42 const char kTokenKey[] = "token"; |
| 43 |
38 const char kImageDecodeError[] = "Image decode failed"; | 44 const char kImageDecodeError[] = "Image decode failed"; |
39 const char kInvalidIdError[] = "Invalid id"; | 45 const char kInvalidIdError[] = "Invalid id"; |
40 const char kInvalidManifestError[] = "Invalid manifest"; | 46 const char kInvalidManifestError[] = "Invalid manifest"; |
41 const char kNoPreviousBeginInstallError[] = | 47 const char kNoPreviousBeginInstallError[] = |
42 "* does not match a previous call to beginInstall"; | 48 "* does not match a previous call to beginInstall"; |
43 const char kUserCancelledError[] = "User cancelled install"; | 49 const char kUserCancelledError[] = "User cancelled install"; |
44 const char kUserGestureRequiredError[] = | 50 const char kUserGestureRequiredError[] = |
45 "This function must be called during a user gesture"; | 51 "This function must be called during a user gesture"; |
46 | 52 |
47 ProfileSyncService* test_sync_service = NULL; | 53 ProfileSyncService* test_sync_service = NULL; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 SetResult(PERMISSION_DENIED); | 282 SetResult(PERMISSION_DENIED); |
277 return false; | 283 return false; |
278 } | 284 } |
279 | 285 |
280 if (!user_gesture() && !ignore_user_gesture_for_tests) { | 286 if (!user_gesture() && !ignore_user_gesture_for_tests) { |
281 SetResult(NO_GESTURE); | 287 SetResult(NO_GESTURE); |
282 error_ = kUserGestureRequiredError; | 288 error_ = kUserGestureRequiredError; |
283 return false; | 289 return false; |
284 } | 290 } |
285 | 291 |
286 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id_)); | 292 DictionaryValue* details = NULL; |
| 293 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
| 294 CHECK(details); |
| 295 |
| 296 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_)); |
287 if (!Extension::IdIsValid(id_)) { | 297 if (!Extension::IdIsValid(id_)) { |
288 SetResult(INVALID_ID); | 298 SetResult(INVALID_ID); |
289 error_ = kInvalidIdError; | 299 error_ = kInvalidIdError; |
290 return false; | 300 return false; |
291 } | 301 } |
292 | 302 |
293 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &icon_data_)); | 303 EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); |
294 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &manifest_)); | 304 |
| 305 if (details->HasKey(kIconDataKey)) |
| 306 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconDataKey, &icon_data_)); |
| 307 |
| 308 if (details->HasKey(kLocalizedNameKey)) |
| 309 EXTENSION_FUNCTION_VALIDATE(details->GetString(kLocalizedNameKey, |
| 310 &localized_name_)); |
295 | 311 |
296 scoped_refptr<SafeBeginInstallHelper> helper = | 312 scoped_refptr<SafeBeginInstallHelper> helper = |
297 new SafeBeginInstallHelper(this, icon_data_, manifest_); | 313 new SafeBeginInstallHelper(this, icon_data_, manifest_); |
298 // The helper will call us back via OnParseSucces or OnParseFailure. | 314 // The helper will call us back via OnParseSucces or OnParseFailure. |
299 helper->Start(); | 315 helper->Start(); |
300 | 316 |
301 // Matched with a Release in OnSuccess/OnFailure. | 317 // Matched with a Release in OnSuccess/OnFailure. |
302 AddRef(); | 318 AddRef(); |
303 | 319 |
304 // The response is sent asynchronously in OnSuccess/OnFailure. | 320 // The response is sent asynchronously in OnSuccess/OnFailure. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 bool should_proceed) { | 363 bool should_proceed) { |
348 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT; | 364 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT; |
349 } | 365 } |
350 | 366 |
351 void BeginInstallWithManifestFunction::OnParseSuccess( | 367 void BeginInstallWithManifestFunction::OnParseSuccess( |
352 const SkBitmap& icon, DictionaryValue* parsed_manifest) { | 368 const SkBitmap& icon, DictionaryValue* parsed_manifest) { |
353 CHECK(parsed_manifest); | 369 CHECK(parsed_manifest); |
354 icon_ = icon; | 370 icon_ = icon; |
355 parsed_manifest_.reset(parsed_manifest); | 371 parsed_manifest_.reset(parsed_manifest); |
356 | 372 |
| 373 // If we were passed a localized name to use in the dialog, create a copy |
| 374 // of the original manifest and replace the name in it. |
| 375 scoped_ptr<DictionaryValue> localized_manifest; |
| 376 if (!localized_name_.empty()) { |
| 377 localized_manifest.reset(parsed_manifest->DeepCopy()); |
| 378 localized_manifest->SetString(extension_manifest_keys::kName, |
| 379 localized_name_); |
| 380 } |
| 381 |
357 // Create a dummy extension and show the extension install confirmation | 382 // Create a dummy extension and show the extension install confirmation |
358 // dialog. | 383 // dialog. |
359 std::string init_errors; | 384 std::string init_errors; |
360 dummy_extension_ = Extension::Create( | 385 dummy_extension_ = Extension::Create( |
361 FilePath(), | 386 FilePath(), |
362 Extension::INTERNAL, | 387 Extension::INTERNAL, |
363 *static_cast<DictionaryValue*>(parsed_manifest_.get()), | 388 localized_manifest.get() ? *localized_manifest.get() : *parsed_manifest, |
364 Extension::NO_FLAGS, | 389 Extension::NO_FLAGS, |
365 &init_errors); | 390 &init_errors); |
366 if (!dummy_extension_.get()) { | 391 if (!dummy_extension_.get()) { |
367 OnParseFailure(MANIFEST_ERROR, std::string(kInvalidManifestError)); | 392 OnParseFailure(MANIFEST_ERROR, std::string(kInvalidManifestError)); |
368 return; | 393 return; |
369 } | 394 } |
| 395 |
370 if (icon_.empty()) | 396 if (icon_.empty()) |
371 icon_ = Extension::GetDefaultIcon(dummy_extension_->is_app()); | 397 icon_ = Extension::GetDefaultIcon(dummy_extension_->is_app()); |
372 | 398 |
373 // In tests, we may have setup to proceed or abort without putting up the real | 399 // In tests, we may have setup to proceed or abort without putting up the real |
374 // confirmation dialog. | 400 // confirmation dialog. |
375 if (auto_confirm_for_tests != DO_NOT_SKIP) { | 401 if (auto_confirm_for_tests != DO_NOT_SKIP) { |
376 if (auto_confirm_for_tests == PROCEED) | 402 if (auto_confirm_for_tests == PROCEED) |
377 this->InstallUIProceed(); | 403 this->InstallUIProceed(); |
378 else | 404 else |
379 this->InstallUIAbort(); | 405 this->InstallUIAbort(); |
(...skipping 14 matching lines...) Expand all Loading... |
394 ResultCode result_code, const std::string& error_message) { | 420 ResultCode result_code, const std::string& error_message) { |
395 SetResult(result_code); | 421 SetResult(result_code); |
396 error_ = error_message; | 422 error_ = error_message; |
397 SendResponse(false); | 423 SendResponse(false); |
398 | 424 |
399 // Matches the AddRef in RunImpl(). | 425 // Matches the AddRef in RunImpl(). |
400 Release(); | 426 Release(); |
401 } | 427 } |
402 | 428 |
403 void BeginInstallWithManifestFunction::InstallUIProceed() { | 429 void BeginInstallWithManifestFunction::InstallUIProceed() { |
404 CrxInstaller::SetWhitelistedManifest(id_, parsed_manifest_.release()); | 430 CrxInstaller::WhitelistEntry* entry = new CrxInstaller::WhitelistEntry; |
| 431 entry->parsed_manifest.reset(parsed_manifest_.release()); |
| 432 entry->localized_name = localized_name_; |
| 433 CrxInstaller::SetWhitelistEntry(id_, entry); |
405 SetResult(ERROR_NONE); | 434 SetResult(ERROR_NONE); |
406 SendResponse(true); | 435 SendResponse(true); |
407 | 436 |
408 // Matches the AddRef in RunImpl(). | 437 // Matches the AddRef in RunImpl(). |
409 Release(); | 438 Release(); |
410 } | 439 } |
411 | 440 |
412 void BeginInstallWithManifestFunction::InstallUIAbort() { | 441 void BeginInstallWithManifestFunction::InstallUIAbort() { |
413 error_ = std::string(kUserCancelledError); | 442 error_ = std::string(kUserCancelledError); |
414 SetResult(USER_CANCELLED); | 443 SetResult(USER_CANCELLED); |
415 SendResponse(false); | 444 SendResponse(false); |
416 | 445 |
417 // Matches the AddRef in RunImpl(). | 446 // Matches the AddRef in RunImpl(). |
418 Release(); | 447 Release(); |
419 } | 448 } |
420 | 449 |
421 bool CompleteInstallFunction::RunImpl() { | 450 bool CompleteInstallFunction::RunImpl() { |
422 if (!IsWebStoreURL(profile_, source_url())) | 451 if (!IsWebStoreURL(profile_, source_url())) |
423 return false; | 452 return false; |
424 | 453 |
425 std::string id; | 454 std::string id; |
426 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id)); | 455 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id)); |
427 if (!Extension::IdIsValid(id)) { | 456 if (!Extension::IdIsValid(id)) { |
428 error_ = kInvalidIdError; | 457 error_ = kInvalidIdError; |
429 return false; | 458 return false; |
430 } | 459 } |
431 | 460 |
432 if (!CrxInstaller::IsIdWhitelisted(id) && | 461 if (!CrxInstaller::IsIdWhitelisted(id) && |
433 !CrxInstaller::GetWhitelistedManifest(id)) { | 462 !CrxInstaller::GetWhitelistEntry(id)) { |
434 error_ = ExtensionErrorUtils::FormatErrorMessage( | 463 error_ = ExtensionErrorUtils::FormatErrorMessage( |
435 kNoPreviousBeginInstallError, id); | 464 kNoPreviousBeginInstallError, id); |
436 return false; | 465 return false; |
437 } | 466 } |
438 | 467 |
439 std::vector<std::string> params; | 468 std::vector<std::string> params; |
440 params.push_back("id=" + id); | 469 params.push_back("id=" + id); |
441 params.push_back("lang=" + g_browser_process->GetApplicationLocale()); | 470 params.push_back("lang=" + g_browser_process->GetApplicationLocale()); |
442 params.push_back("uc"); | 471 params.push_back("uc"); |
443 std::string url_string = Extension::GalleryUpdateUrl(true).spec(); | 472 std::string url_string = Extension::GalleryUpdateUrl(true).spec(); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 } | 627 } |
599 | 628 |
600 DCHECK(waiting_for_token_); | 629 DCHECK(waiting_for_token_); |
601 | 630 |
602 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); | 631 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); |
603 SendResponse(true); | 632 SendResponse(true); |
604 | 633 |
605 // Matches the AddRef in RunImpl(). | 634 // Matches the AddRef in RunImpl(). |
606 Release(); | 635 Release(); |
607 } | 636 } |
OLD | NEW |