OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/api/webstore_private/webstore_private_api.h" | 5 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h" |
6 | 6 |
7 #include "apps/app_launcher.h" | 7 #include "apps/app_launcher.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 #include "grit/generated_resources.h" | 45 #include "grit/generated_resources.h" |
46 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
47 | 47 |
48 using content::GpuDataManager; | 48 using content::GpuDataManager; |
49 | 49 |
50 namespace extensions { | 50 namespace extensions { |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
54 // Holds the Approvals between the time we prompt and start the installs. | 54 // Holds the Approvals between the time we prompt and start the installs. |
55 struct PendingApprovals { | 55 class PendingApprovals { |
56 typedef ScopedVector<WebstoreInstaller::Approval> ApprovalList; | 56 public: |
57 | |
58 PendingApprovals(); | 57 PendingApprovals(); |
59 ~PendingApprovals(); | 58 ~PendingApprovals(); |
60 | 59 |
61 void PushApproval(scoped_ptr<WebstoreInstaller::Approval> approval); | 60 void PushApproval(scoped_ptr<WebstoreInstaller::Approval> approval); |
62 scoped_ptr<WebstoreInstaller::Approval> PopApproval( | 61 scoped_ptr<WebstoreInstaller::Approval> PopApproval( |
63 Profile* profile, const std::string& id); | 62 Profile* profile, const std::string& id); |
63 private: | |
64 typedef ScopedVector<WebstoreInstaller::Approval> ApprovalList; | |
64 | 65 |
65 ApprovalList approvals; | 66 ApprovalList approvals_; |
67 | |
68 DISALLOW_COPY_AND_ASSIGN(PendingApprovals); | |
66 }; | 69 }; |
67 | 70 |
68 PendingApprovals::PendingApprovals() {} | 71 PendingApprovals::PendingApprovals() {} |
69 PendingApprovals::~PendingApprovals() {} | 72 PendingApprovals::~PendingApprovals() {} |
70 | 73 |
71 void PendingApprovals::PushApproval( | 74 void PendingApprovals::PushApproval( |
72 scoped_ptr<WebstoreInstaller::Approval> approval) { | 75 scoped_ptr<WebstoreInstaller::Approval> approval) { |
73 approvals.push_back(approval.release()); | 76 approvals_.push_back(approval.release()); |
74 } | 77 } |
75 | 78 |
76 scoped_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval( | 79 scoped_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval( |
77 Profile* profile, const std::string& id) { | 80 Profile* profile, const std::string& id) { |
78 for (size_t i = 0; i < approvals.size(); ++i) { | 81 for (size_t i = 0; i < approvals_.size(); ++i) { |
79 WebstoreInstaller::Approval* approval = approvals[i]; | 82 WebstoreInstaller::Approval* approval = approvals_[i]; |
80 if (approval->extension_id == id && | 83 if (approval->extension_id == id && |
81 profile->IsSameProfile(approval->profile)) { | 84 profile->IsSameProfile(approval->profile)) { |
82 approvals.weak_erase(approvals.begin() + i); | 85 approvals_.weak_erase(approvals_.begin() + i); |
83 return scoped_ptr<WebstoreInstaller::Approval>(approval); | 86 return scoped_ptr<WebstoreInstaller::Approval>(approval); |
84 } | 87 } |
85 } | 88 } |
86 return scoped_ptr<WebstoreInstaller::Approval>(NULL); | 89 return scoped_ptr<WebstoreInstaller::Approval>(NULL); |
87 } | 90 } |
88 | 91 |
92 // Uniquely holds the profile and extension id of an install between the time we | |
93 // prompt and complete the installs. | |
94 class PendingInstalls { | |
95 public: | |
96 PendingInstalls(); | |
97 ~PendingInstalls(); | |
98 | |
99 bool InsertInstall(Profile* profile, const std::string& id); | |
100 void EraseInstall(Profile* profile, const std::string& id); | |
101 private: | |
102 typedef std::pair<Profile*, std::string> ProfileAndExtensionId; | |
103 typedef std::vector<ProfileAndExtensionId> InstallList; | |
104 | |
105 InstallList::iterator FindInstall(Profile* profile, const std::string& id); | |
106 | |
107 InstallList installs_; | |
108 | |
109 DISALLOW_COPY_AND_ASSIGN(PendingInstalls); | |
110 }; | |
111 | |
112 PendingInstalls::PendingInstalls() {} | |
113 PendingInstalls::~PendingInstalls() {} | |
114 | |
115 // Returns true and inserts the profile/id pair if it is not present. Otherwise | |
116 // returns false. | |
117 bool PendingInstalls::InsertInstall(Profile* profile, const std::string& id) { | |
118 if (FindInstall(profile, id) != installs_.end()) | |
119 return false; | |
120 installs_.push_back(make_pair(profile, id)); | |
121 return true; | |
122 } | |
123 | |
124 // Removes the given profile/id pair. | |
125 void PendingInstalls::EraseInstall(Profile* profile, const std::string& id) { | |
126 InstallList::iterator it = FindInstall(profile, id); | |
127 if (it != installs_.end()) | |
128 installs_.erase(it); | |
129 } | |
130 | |
131 PendingInstalls::InstallList::iterator PendingInstalls::FindInstall( | |
132 Profile* profile, | |
133 const std::string& id) { | |
134 for (size_t i = 0; i < installs_.size(); ++i) { | |
135 ProfileAndExtensionId install = installs_[i]; | |
136 if (install.second == id && | |
137 profile->IsSameProfile(install.first)) { | |
138 return (installs_.begin() + i); | |
139 } | |
140 } | |
141 return installs_.end(); | |
142 } | |
asargent_no_longer_on_chrome
2013/05/21 19:47:24
Can you get away with not having this class at all
calamity
2013/05/24 00:24:28
We can't use set because there's no ordering, C++1
asargent_no_longer_on_chrome
2013/05/28 21:35:33
Ok, good point - sounds like it wouldn't actually
asargent_no_longer_on_chrome
2013/05/28 23:03:52
Actually, here's one other possibility for you - y
| |
143 | |
89 static base::LazyInstance<PendingApprovals> g_pending_approvals = | 144 static base::LazyInstance<PendingApprovals> g_pending_approvals = |
90 LAZY_INSTANCE_INITIALIZER; | 145 LAZY_INSTANCE_INITIALIZER; |
146 static base::LazyInstance<PendingInstalls> g_pending_installs = | |
147 LAZY_INSTANCE_INITIALIZER; | |
91 | 148 |
92 const char kAppInstallBubbleKey[] = "appInstallBubble"; | 149 const char kAppInstallBubbleKey[] = "appInstallBubble"; |
93 const char kEnableLauncherKey[] = "enableLauncher"; | 150 const char kEnableLauncherKey[] = "enableLauncher"; |
94 const char kIconDataKey[] = "iconData"; | 151 const char kIconDataKey[] = "iconData"; |
95 const char kIconUrlKey[] = "iconUrl"; | 152 const char kIconUrlKey[] = "iconUrl"; |
96 const char kIdKey[] = "id"; | 153 const char kIdKey[] = "id"; |
97 const char kLocalizedNameKey[] = "localizedName"; | 154 const char kLocalizedNameKey[] = "localizedName"; |
98 const char kLoginKey[] = "login"; | 155 const char kLoginKey[] = "login"; |
99 const char kManifestKey[] = "manifest"; | 156 const char kManifestKey[] = "manifest"; |
100 | 157 |
158 const char kAlreadyInstalledError[] = "This item is already installed"; | |
101 const char kCannotSpecifyIconDataAndUrlError[] = | 159 const char kCannotSpecifyIconDataAndUrlError[] = |
102 "You cannot specify both icon data and an icon url"; | 160 "You cannot specify both icon data and an icon url"; |
103 const char kInvalidIconUrlError[] = "Invalid icon url"; | 161 const char kInvalidIconUrlError[] = "Invalid icon url"; |
104 const char kInvalidIdError[] = "Invalid id"; | 162 const char kInvalidIdError[] = "Invalid id"; |
105 const char kInvalidManifestError[] = "Invalid manifest"; | 163 const char kInvalidManifestError[] = "Invalid manifest"; |
106 const char kNoPreviousBeginInstallWithManifestError[] = | 164 const char kNoPreviousBeginInstallWithManifestError[] = |
107 "* does not match a previous call to beginInstallWithManifest3"; | 165 "* does not match a previous call to beginInstallWithManifest3"; |
108 const char kUserCancelledError[] = "User cancelled install"; | 166 const char kUserCancelledError[] = "User cancelled install"; |
109 | 167 |
110 // Helper to create a dictionary with login properties set from the appropriate | 168 // Helper to create a dictionary with login properties set from the appropriate |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 274 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
217 CHECK(details); | 275 CHECK(details); |
218 | 276 |
219 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_)); | 277 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_)); |
220 if (!extensions::Extension::IdIsValid(id_)) { | 278 if (!extensions::Extension::IdIsValid(id_)) { |
221 SetResultCode(INVALID_ID); | 279 SetResultCode(INVALID_ID); |
222 error_ = kInvalidIdError; | 280 error_ = kInvalidIdError; |
223 return false; | 281 return false; |
224 } | 282 } |
225 | 283 |
284 ExtensionService* service = | |
285 extensions::ExtensionSystem::Get(profile_)->extension_service(); | |
286 if (service->GetInstalledExtension(id_) || | |
287 !g_pending_installs.Get().InsertInstall(profile_, id_)) { | |
288 SetResultCode(ALREADY_INSTALLED); | |
289 error_ = kAlreadyInstalledError; | |
290 return false; | |
291 } | |
292 | |
226 EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); | 293 EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); |
227 | 294 |
228 if (details->HasKey(kIconDataKey) && details->HasKey(kIconUrlKey)) { | 295 if (details->HasKey(kIconDataKey) && details->HasKey(kIconUrlKey)) { |
229 SetResultCode(ICON_ERROR); | 296 SetResultCode(ICON_ERROR); |
230 error_ = kCannotSpecifyIconDataAndUrlError; | 297 error_ = kCannotSpecifyIconDataAndUrlError; |
231 return false; | 298 return false; |
232 } | 299 } |
233 | 300 |
234 if (details->HasKey(kIconDataKey)) | 301 if (details->HasKey(kIconDataKey)) |
235 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconDataKey, &icon_data_)); | 302 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconDataKey, &icon_data_)); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 break; | 367 break; |
301 case PERMISSION_DENIED: | 368 case PERMISSION_DENIED: |
302 SetResult(Value::CreateStringValue("permission_denied")); | 369 SetResult(Value::CreateStringValue("permission_denied")); |
303 break; | 370 break; |
304 case INVALID_ICON_URL: | 371 case INVALID_ICON_URL: |
305 SetResult(Value::CreateStringValue("invalid_icon_url")); | 372 SetResult(Value::CreateStringValue("invalid_icon_url")); |
306 break; | 373 break; |
307 case SIGNIN_FAILED: | 374 case SIGNIN_FAILED: |
308 SetResult(Value::CreateStringValue("signin_failed")); | 375 SetResult(Value::CreateStringValue("signin_failed")); |
309 break; | 376 break; |
377 case ALREADY_INSTALLED: | |
378 SetResult(Value::CreateStringValue("already_installed")); | |
379 break; | |
310 default: | 380 default: |
311 CHECK(false); | 381 CHECK(false); |
312 } | 382 } |
313 } | 383 } |
314 | 384 |
315 void BeginInstallWithManifestFunction::OnWebstoreParseSuccess( | 385 void BeginInstallWithManifestFunction::OnWebstoreParseSuccess( |
316 const std::string& id, | 386 const std::string& id, |
317 const SkBitmap& icon, | 387 const SkBitmap& icon, |
318 DictionaryValue* parsed_manifest) { | 388 DictionaryValue* parsed_manifest) { |
319 CHECK_EQ(id_, id); | 389 CHECK_EQ(id_, id); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 &(dispatcher()->delegate()->GetAssociatedWebContents()->GetController()), | 595 &(dispatcher()->delegate()->GetAssociatedWebContents()->GetController()), |
526 id, approval_.Pass(), WebstoreInstaller::FLAG_NONE); | 596 id, approval_.Pass(), WebstoreInstaller::FLAG_NONE); |
527 installer->Start(); | 597 installer->Start(); |
528 } | 598 } |
529 | 599 |
530 void CompleteInstallFunction::OnExtensionInstallSuccess( | 600 void CompleteInstallFunction::OnExtensionInstallSuccess( |
531 const std::string& id) { | 601 const std::string& id) { |
532 if (test_webstore_installer_delegate) | 602 if (test_webstore_installer_delegate) |
533 test_webstore_installer_delegate->OnExtensionInstallSuccess(id); | 603 test_webstore_installer_delegate->OnExtensionInstallSuccess(id); |
534 | 604 |
605 g_pending_installs.Get().EraseInstall(profile_, id); | |
606 | |
535 LOG(INFO) << "Install success, sending response"; | 607 LOG(INFO) << "Install success, sending response"; |
536 SendResponse(true); | 608 SendResponse(true); |
537 | 609 |
538 // Matches the AddRef in RunImpl(). | 610 // Matches the AddRef in RunImpl(). |
539 Release(); | 611 Release(); |
540 } | 612 } |
541 | 613 |
542 void CompleteInstallFunction::OnExtensionInstallFailure( | 614 void CompleteInstallFunction::OnExtensionInstallFailure( |
543 const std::string& id, | 615 const std::string& id, |
544 const std::string& error, | 616 const std::string& error, |
545 WebstoreInstaller::FailureReason reason) { | 617 WebstoreInstaller::FailureReason reason) { |
546 extensions::InstallTracker* tracker = | 618 extensions::InstallTracker* tracker = |
547 extensions::InstallTrackerFactory::GetForProfile(profile()); | 619 extensions::InstallTrackerFactory::GetForProfile(profile()); |
548 tracker->OnInstallFailure(id); | 620 tracker->OnInstallFailure(id); |
549 if (test_webstore_installer_delegate) { | 621 if (test_webstore_installer_delegate) { |
550 test_webstore_installer_delegate->OnExtensionInstallFailure( | 622 test_webstore_installer_delegate->OnExtensionInstallFailure( |
551 id, error, reason); | 623 id, error, reason); |
552 } | 624 } |
553 | 625 |
626 g_pending_installs.Get().EraseInstall(profile_, id); | |
627 | |
554 error_ = error; | 628 error_ = error; |
555 LOG(INFO) << "Install failed, sending response"; | 629 LOG(INFO) << "Install failed, sending response"; |
556 SendResponse(false); | 630 SendResponse(false); |
557 | 631 |
558 // Matches the AddRef in RunImpl(). | 632 // Matches the AddRef in RunImpl(). |
559 Release(); | 633 Release(); |
560 } | 634 } |
561 | 635 |
562 void CompleteInstallFunction::OnExtensionDownloadProgress( | 636 void CompleteInstallFunction::OnExtensionDownloadProgress( |
563 const std::string& id, | 637 const std::string& id, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
640 &GetIsLauncherEnabledFunction::OnIsLauncherCheckCompleted, this)); | 714 &GetIsLauncherEnabledFunction::OnIsLauncherCheckCompleted, this)); |
641 return true; | 715 return true; |
642 } | 716 } |
643 | 717 |
644 void GetIsLauncherEnabledFunction::OnIsLauncherCheckCompleted(bool is_enabled) { | 718 void GetIsLauncherEnabledFunction::OnIsLauncherCheckCompleted(bool is_enabled) { |
645 SetResult(Value::CreateBooleanValue(is_enabled)); | 719 SetResult(Value::CreateBooleanValue(is_enabled)); |
646 SendResponse(true); | 720 SendResponse(true); |
647 } | 721 } |
648 | 722 |
649 } // namespace extensions | 723 } // namespace extensions |
OLD | NEW |