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 | 8 |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/extensions/crx_installer.h" | 13 #include "chrome/browser/extensions/crx_installer.h" |
14 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 14 #include "chrome/browser/extensions/extension_function_dispatcher.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_notification_types.h" | 21 #include "chrome/common/chrome_notification_types.h" |
22 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/common/pref_names.h" |
23 #include "chrome/common/extensions/extension_constants.h" | 24 #include "chrome/common/extensions/extension_constants.h" |
24 #include "chrome/common/extensions/extension_error_utils.h" | 25 #include "chrome/common/extensions/extension_error_utils.h" |
25 #include "chrome/common/extensions/extension_l10n_util.h" | 26 #include "chrome/common/extensions/extension_l10n_util.h" |
26 #include "chrome/common/net/gaia/gaia_constants.h" | 27 #include "chrome/common/net/gaia/gaia_constants.h" |
27 #include "content/browser/tab_contents/tab_contents.h" | 28 #include "content/browser/tab_contents/tab_contents.h" |
28 #include "content/common/notification_details.h" | 29 #include "content/common/notification_details.h" |
29 #include "content/common/notification_source.h" | 30 #include "content/common/notification_source.h" |
30 #include "grit/chromium_strings.h" | 31 #include "grit/chromium_strings.h" |
31 #include "grit/generated_resources.h" | 32 #include "grit/generated_resources.h" |
32 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
(...skipping 14 matching lines...) Expand all Loading... |
47 const char kInvalidIconUrlError[] = "Invalid icon url"; | 48 const char kInvalidIconUrlError[] = "Invalid icon url"; |
48 const char kInvalidIdError[] = "Invalid id"; | 49 const char kInvalidIdError[] = "Invalid id"; |
49 const char kInvalidManifestError[] = "Invalid manifest"; | 50 const char kInvalidManifestError[] = "Invalid manifest"; |
50 const char kNoPreviousBeginInstallError[] = | 51 const char kNoPreviousBeginInstallError[] = |
51 "* does not match a previous call to beginInstall"; | 52 "* does not match a previous call to beginInstall"; |
52 const char kUserCancelledError[] = "User cancelled install"; | 53 const char kUserCancelledError[] = "User cancelled install"; |
53 const char kUserGestureRequiredError[] = | 54 const char kUserGestureRequiredError[] = |
54 "This function must be called during a user gesture"; | 55 "This function must be called during a user gesture"; |
55 | 56 |
56 ProfileSyncService* test_sync_service = NULL; | 57 ProfileSyncService* test_sync_service = NULL; |
57 BrowserSignin* test_signin = NULL; | |
58 bool ignore_user_gesture_for_tests = false; | 58 bool ignore_user_gesture_for_tests = false; |
59 | 59 |
60 // A flag used for BeginInstallWithManifest::SetAutoConfirmForTests. | 60 // A flag used for BeginInstallWithManifest::SetAutoConfirmForTests. |
61 enum AutoConfirmForTest { | 61 enum AutoConfirmForTest { |
62 DO_NOT_SKIP = 0, | 62 DO_NOT_SKIP = 0, |
63 PROCEED, | 63 PROCEED, |
64 ABORT | 64 ABORT |
65 }; | 65 }; |
66 AutoConfirmForTest auto_confirm_for_tests = DO_NOT_SKIP; | 66 AutoConfirmForTest auto_confirm_for_tests = DO_NOT_SKIP; |
67 | 67 |
68 | 68 |
69 // Returns either the test sync service, or the real one from |profile|. | 69 // Returns either the test sync service, or the real one from |profile|. |
70 ProfileSyncService* GetSyncService(Profile* profile) { | 70 ProfileSyncService* GetSyncService(Profile* profile) { |
71 if (test_sync_service) | 71 if (test_sync_service) |
72 return test_sync_service; | 72 return test_sync_service; |
73 else | 73 else |
74 return profile->GetProfileSyncService(); | 74 return profile->GetProfileSyncService(); |
75 } | 75 } |
76 | 76 |
77 BrowserSignin* GetBrowserSignin(Profile* profile) { | |
78 if (test_signin) | |
79 return test_signin; | |
80 else | |
81 return profile->GetBrowserSignin(); | |
82 } | |
83 | |
84 bool IsWebStoreURL(Profile* profile, const GURL& url) { | 77 bool IsWebStoreURL(Profile* profile, const GURL& url) { |
85 ExtensionService* service = profile->GetExtensionService(); | 78 ExtensionService* service = profile->GetExtensionService(); |
86 const Extension* store = service->GetWebStoreApp(); | 79 const Extension* store = service->GetWebStoreApp(); |
87 if (!store) { | 80 if (!store) { |
88 NOTREACHED(); | 81 NOTREACHED(); |
89 return false; | 82 return false; |
90 } | 83 } |
91 return (service->GetExtensionByWebExtent(url) == store); | 84 return (service->GetExtensionByWebExtent(url) == store); |
92 } | 85 } |
93 | 86 |
94 // Helper to create a dictionary with login and token properties set from | 87 // Helper to create a dictionary with login and token properties set from |
95 // the appropriate values in the passed-in |profile|. | 88 // the appropriate values in the passed-in |profile|. |
96 DictionaryValue* CreateLoginResult(Profile* profile) { | 89 DictionaryValue* CreateLoginResult(Profile* profile) { |
97 DictionaryValue* dictionary = new DictionaryValue(); | 90 DictionaryValue* dictionary = new DictionaryValue(); |
98 std::string username = GetBrowserSignin(profile)->GetSignedInUsername(); | 91 std::string username = profile->GetPrefs()->GetString( |
| 92 prefs::kGoogleServicesUsername); |
99 dictionary->SetString(kLoginKey, username); | 93 dictionary->SetString(kLoginKey, username); |
100 if (!username.empty()) { | 94 if (!username.empty()) { |
101 CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 95 CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
102 TokenService* token_service = profile->GetTokenService(); | 96 TokenService* token_service = profile->GetTokenService(); |
103 if (cmdline->HasSwitch(switches::kAppsGalleryReturnTokens) && | 97 if (cmdline->HasSwitch(switches::kAppsGalleryReturnTokens) && |
104 token_service->HasTokenForService(GaiaConstants::kGaiaService)) { | 98 token_service->HasTokenForService(GaiaConstants::kGaiaService)) { |
105 dictionary->SetString(kTokenKey, | 99 dictionary->SetString(kTokenKey, |
106 token_service->GetTokenForService( | 100 token_service->GetTokenForService( |
107 GaiaConstants::kGaiaService)); | 101 GaiaConstants::kGaiaService)); |
108 } | 102 } |
109 } | 103 } |
110 return dictionary; | 104 return dictionary; |
111 } | 105 } |
112 | 106 |
113 } // namespace | 107 } // namespace |
114 | 108 |
115 // static | 109 // static |
116 void WebstorePrivateApi::SetTestingProfileSyncService( | 110 void WebstorePrivateApi::SetTestingProfileSyncService( |
117 ProfileSyncService* service) { | 111 ProfileSyncService* service) { |
118 test_sync_service = service; | 112 test_sync_service = service; |
119 } | 113 } |
120 | 114 |
121 // static | 115 // static |
122 void WebstorePrivateApi::SetTestingBrowserSignin(BrowserSignin* signin) { | |
123 test_signin = signin; | |
124 } | |
125 | |
126 // static | |
127 void BeginInstallFunction::SetIgnoreUserGestureForTests(bool ignore) { | 116 void BeginInstallFunction::SetIgnoreUserGestureForTests(bool ignore) { |
128 ignore_user_gesture_for_tests = ignore; | 117 ignore_user_gesture_for_tests = ignore; |
129 } | 118 } |
130 | 119 |
131 bool BeginInstallFunction::RunImpl() { | 120 bool BeginInstallFunction::RunImpl() { |
132 if (!IsWebStoreURL(profile_, source_url())) | 121 if (!IsWebStoreURL(profile_, source_url())) |
133 return false; | 122 return false; |
134 | 123 |
135 std::string id; | 124 std::string id; |
136 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id)); | 125 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id)); |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 bool SetStoreLoginFunction::RunImpl() { | 442 bool SetStoreLoginFunction::RunImpl() { |
454 if (!IsWebStoreURL(profile_, source_url())) | 443 if (!IsWebStoreURL(profile_, source_url())) |
455 return false; | 444 return false; |
456 std::string login; | 445 std::string login; |
457 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &login)); | 446 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &login)); |
458 ExtensionService* service = profile_->GetExtensionService(); | 447 ExtensionService* service = profile_->GetExtensionService(); |
459 ExtensionPrefs* prefs = service->extension_prefs(); | 448 ExtensionPrefs* prefs = service->extension_prefs(); |
460 prefs->SetWebStoreLogin(login); | 449 prefs->SetWebStoreLogin(login); |
461 return true; | 450 return true; |
462 } | 451 } |
463 | |
464 PromptBrowserLoginFunction::PromptBrowserLoginFunction() | |
465 : waiting_for_token_(false) {} | |
466 | |
467 PromptBrowserLoginFunction::~PromptBrowserLoginFunction() { | |
468 } | |
469 | |
470 bool PromptBrowserLoginFunction::RunImpl() { | |
471 if (!IsWebStoreURL(profile_, source_url())) | |
472 return false; | |
473 | |
474 std::string preferred_email; | |
475 if (args_->GetSize() > 0) { | |
476 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &preferred_email)); | |
477 } | |
478 | |
479 Profile* profile = profile_->GetOriginalProfile(); | |
480 | |
481 // Login can currently only be invoked tab-modal. Since this is | |
482 // coming from the webstore, we should always have a tab, but check | |
483 // just in case. | |
484 TabContents* tab = dispatcher()->delegate()->GetAssociatedTabContents(); | |
485 if (!tab) | |
486 return false; | |
487 | |
488 // We return the result asynchronously, so we addref to keep ourself alive. | |
489 // Matched with a Release in OnLoginSuccess() and OnLoginFailure(). | |
490 AddRef(); | |
491 | |
492 // Start listening for notifications about the token. | |
493 TokenService* token_service = profile->GetTokenService(); | |
494 registrar_.Add(this, | |
495 chrome::NOTIFICATION_TOKEN_AVAILABLE, | |
496 Source<TokenService>(token_service)); | |
497 registrar_.Add(this, | |
498 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, | |
499 Source<TokenService>(token_service)); | |
500 | |
501 GetBrowserSignin(profile)->RequestSignin(tab, | |
502 ASCIIToUTF16(preferred_email), | |
503 GetLoginMessage(), | |
504 this); | |
505 | |
506 // The response will be sent asynchronously in OnLoginSuccess/OnLoginFailure. | |
507 return true; | |
508 } | |
509 | |
510 string16 PromptBrowserLoginFunction::GetLoginMessage() { | |
511 using l10n_util::GetStringUTF16; | |
512 using l10n_util::GetStringFUTF16; | |
513 | |
514 // TODO(johnnyg): This would be cleaner as an HTML template. | |
515 // http://crbug.com/60216 | |
516 string16 message; | |
517 message = ASCIIToUTF16("<p>") | |
518 + GetStringUTF16(IDS_WEB_STORE_LOGIN_INTRODUCTION_1) | |
519 + ASCIIToUTF16("</p>"); | |
520 message = message + ASCIIToUTF16("<p>") | |
521 + GetStringFUTF16(IDS_WEB_STORE_LOGIN_INTRODUCTION_2, | |
522 GetStringUTF16(IDS_PRODUCT_NAME)) | |
523 + ASCIIToUTF16("</p>"); | |
524 return message; | |
525 } | |
526 | |
527 void PromptBrowserLoginFunction::OnLoginSuccess() { | |
528 // Ensure that apps are synced. | |
529 // - If the user has already setup sync, we add Apps to the current types. | |
530 // - If not, we create a new set which is just Apps. | |
531 ProfileSyncService* service = GetSyncService(profile_->GetOriginalProfile()); | |
532 syncable::ModelTypeSet types; | |
533 if (service->HasSyncSetupCompleted()) | |
534 service->GetPreferredDataTypes(&types); | |
535 types.insert(syncable::APPS); | |
536 service->ChangePreferredDataTypes(types); | |
537 service->SetSyncSetupCompleted(); | |
538 | |
539 // We'll finish up in Observe() when the token is ready. | |
540 waiting_for_token_ = true; | |
541 } | |
542 | |
543 void PromptBrowserLoginFunction::OnLoginFailure( | |
544 const GoogleServiceAuthError& error) { | |
545 SendResponse(false); | |
546 // Matches the AddRef in RunImpl(). | |
547 Release(); | |
548 } | |
549 | |
550 void PromptBrowserLoginFunction::Observe(int type, | |
551 const NotificationSource& source, | |
552 const NotificationDetails& details) { | |
553 // Make sure this notification is for the service we are interested in. | |
554 std::string service; | |
555 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) { | |
556 TokenService::TokenAvailableDetails* available = | |
557 Details<TokenService::TokenAvailableDetails>(details).ptr(); | |
558 service = available->service(); | |
559 } else if (type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED) { | |
560 TokenService::TokenRequestFailedDetails* failed = | |
561 Details<TokenService::TokenRequestFailedDetails>(details).ptr(); | |
562 service = failed->service(); | |
563 } else { | |
564 NOTREACHED(); | |
565 } | |
566 | |
567 if (service != GaiaConstants::kGaiaService) { | |
568 return; | |
569 } | |
570 | |
571 DCHECK(waiting_for_token_); | |
572 | |
573 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); | |
574 SendResponse(true); | |
575 | |
576 // Matches the AddRef in RunImpl(). | |
577 Release(); | |
578 } | |
OLD | NEW |