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/webstore_standalone_installer.h" | 5 #include "chrome/browser/extensions/webstore_standalone_installer.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "extensions/browser/extension_registry.h" | 22 #include "extensions/browser/extension_registry.h" |
23 #include "extensions/browser/extension_system.h" | 23 #include "extensions/browser/extension_system.h" |
24 #include "extensions/common/extension.h" | 24 #include "extensions/common/extension.h" |
25 #include "extensions/common/extension_urls.h" | 25 #include "extensions/common/extension_urls.h" |
26 #include "url/gurl.h" | 26 #include "url/gurl.h" |
27 | 27 |
28 using content::WebContents; | 28 using content::WebContents; |
29 | 29 |
30 namespace extensions { | 30 namespace extensions { |
31 | 31 |
32 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; | |
33 const char kWebstoreRequestError[] = | |
34 "Could not fetch data from the Chrome Web Store"; | |
35 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; | |
36 const char kInvalidManifestError[] = "Invalid manifest"; | |
37 const char kUserCancelledError[] = "User cancelled install"; | |
38 const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; | |
39 const char kInstallInProgressError[] = "An install is already in progress"; | |
40 | |
41 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( | 32 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( |
42 const std::string& webstore_item_id, | 33 const std::string& webstore_item_id, |
43 Profile* profile, | 34 Profile* profile, |
44 const Callback& callback) | 35 const Callback& callback) |
45 : id_(webstore_item_id), | 36 : id_(webstore_item_id), |
46 callback_(callback), | 37 callback_(callback), |
47 profile_(profile), | 38 profile_(profile), |
48 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), | 39 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), |
49 show_user_count_(true), | 40 show_user_count_(true), |
50 average_rating_(0.0), | 41 average_rating_(0.0), |
51 rating_count_(0) { | 42 rating_count_(0) { |
52 } | 43 } |
53 | 44 |
54 void WebstoreStandaloneInstaller::BeginInstall() { | 45 void WebstoreStandaloneInstaller::BeginInstall() { |
55 // Add a ref to keep this alive for WebstoreDataFetcher. | 46 // Add a ref to keep this alive for WebstoreDataFetcher. |
56 // All code paths from here eventually lead to either CompleteInstall or | 47 // All code paths from here eventually lead to either CompleteInstall or |
57 // AbortInstall, which both release this ref. | 48 // AbortInstall, which both release this ref. |
58 AddRef(); | 49 AddRef(); |
59 | 50 |
60 if (!crx_file::id_util::IdIsValid(id_)) { | 51 if (!crx_file::id_util::IdIsValid(id_)) { |
61 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); | 52 CompleteInstall(webstore_install::INVALID_ID, |
| 53 webstore_install::kInvalidWebstoreItemId); |
62 return; | 54 return; |
63 } | 55 } |
64 | 56 |
65 webstore_install::Result result = webstore_install::OTHER_ERROR; | 57 webstore_install::Result result = webstore_install::OTHER_ERROR; |
66 std::string error; | 58 std::string error; |
67 if (!EnsureUniqueInstall(&result, &error)) { | 59 if (!EnsureUniqueInstall(&result, &error)) { |
68 CompleteInstall(result, error); | 60 CompleteInstall(result, error); |
69 return; | 61 return; |
70 } | 62 } |
71 | 63 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 bool WebstoreStandaloneInstaller::EnsureUniqueInstall( | 98 bool WebstoreStandaloneInstaller::EnsureUniqueInstall( |
107 webstore_install::Result* reason, | 99 webstore_install::Result* reason, |
108 std::string* error) { | 100 std::string* error) { |
109 InstallTracker* tracker = InstallTracker::Get(profile_); | 101 InstallTracker* tracker = InstallTracker::Get(profile_); |
110 DCHECK(tracker); | 102 DCHECK(tracker); |
111 | 103 |
112 const ActiveInstallData* existing_install_data = | 104 const ActiveInstallData* existing_install_data = |
113 tracker->GetActiveInstall(id_); | 105 tracker->GetActiveInstall(id_); |
114 if (existing_install_data) { | 106 if (existing_install_data) { |
115 *reason = webstore_install::INSTALL_IN_PROGRESS; | 107 *reason = webstore_install::INSTALL_IN_PROGRESS; |
116 *error = kInstallInProgressError; | 108 *error = webstore_install::kInstallInProgressError; |
117 return false; | 109 return false; |
118 } | 110 } |
119 | 111 |
120 ActiveInstallData install_data(id_); | 112 ActiveInstallData install_data(id_); |
121 InitInstallData(&install_data); | 113 InitInstallData(&install_data); |
122 scoped_active_install_.reset(new ScopedActiveInstall(tracker, install_data)); | 114 scoped_active_install_.reset(new ScopedActiveInstall(tracker, install_data)); |
123 return true; | 115 return true; |
124 } | 116 } |
125 | 117 |
126 void WebstoreStandaloneInstaller::CompleteInstall( | 118 void WebstoreStandaloneInstaller::CompleteInstall( |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 true)); | 177 true)); |
186 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); | 178 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); |
187 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); | 179 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); |
188 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); | 180 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); |
189 return approval; | 181 return approval; |
190 } | 182 } |
191 | 183 |
192 void WebstoreStandaloneInstaller::OnInstallPromptDone( | 184 void WebstoreStandaloneInstaller::OnInstallPromptDone( |
193 ExtensionInstallPrompt::Result result) { | 185 ExtensionInstallPrompt::Result result) { |
194 if (result == ExtensionInstallPrompt::Result::USER_CANCELED) { | 186 if (result == ExtensionInstallPrompt::Result::USER_CANCELED) { |
195 CompleteInstall(webstore_install::USER_CANCELLED, kUserCancelledError); | 187 CompleteInstall(webstore_install::USER_CANCELLED, |
| 188 webstore_install::kUserCancelledError); |
196 return; | 189 return; |
197 } | 190 } |
198 | 191 |
199 if (result == ExtensionInstallPrompt::Result::ABORTED || | 192 if (result == ExtensionInstallPrompt::Result::ABORTED || |
200 !CheckRequestorAlive()) { | 193 !CheckRequestorAlive()) { |
201 CompleteInstall(webstore_install::ABORTED, std::string()); | 194 CompleteInstall(webstore_install::ABORTED, std::string()); |
202 return; | 195 return; |
203 } | 196 } |
204 | 197 |
205 DCHECK(result == ExtensionInstallPrompt::Result::ACCEPTED); | 198 DCHECK(result == ExtensionInstallPrompt::Result::ACCEPTED); |
206 | 199 |
207 std::unique_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); | 200 std::unique_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); |
208 | 201 |
209 ExtensionService* extension_service = | 202 ExtensionService* extension_service = |
210 ExtensionSystem::Get(profile_)->extension_service(); | 203 ExtensionSystem::Get(profile_)->extension_service(); |
211 const Extension* installed_extension = | 204 const Extension* installed_extension = |
212 extension_service->GetExtensionById(id_, true /* include disabled */); | 205 extension_service->GetExtensionById(id_, true /* include disabled */); |
213 if (installed_extension) { | 206 if (installed_extension) { |
214 std::string install_message; | 207 std::string install_message; |
215 webstore_install::Result install_result = webstore_install::SUCCESS; | 208 webstore_install::Result install_result = webstore_install::SUCCESS; |
216 bool done = true; | 209 bool done = true; |
217 | 210 |
218 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { | 211 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { |
219 // Don't install a blacklisted extension. | 212 // Don't install a blacklisted extension. |
220 install_result = webstore_install::BLACKLISTED; | 213 install_result = webstore_install::BLACKLISTED; |
221 install_message = kExtensionIsBlacklisted; | 214 install_message = webstore_install::kExtensionIsBlacklisted; |
222 } else if (!extension_service->IsExtensionEnabled(id_)) { | 215 } else if (!extension_service->IsExtensionEnabled(id_)) { |
223 // If the extension is installed but disabled, and not blacklisted, | 216 // If the extension is installed but disabled, and not blacklisted, |
224 // enable it. | 217 // enable it. |
225 extension_service->EnableExtension(id_); | 218 extension_service->EnableExtension(id_); |
226 } // else extension is installed and enabled; no work to be done. | 219 } // else extension is installed and enabled; no work to be done. |
227 | 220 |
228 if (done) { | 221 if (done) { |
229 CompleteInstall(install_result, install_message); | 222 CompleteInstall(install_result, install_message); |
230 return; | 223 return; |
231 } | 224 } |
232 } | 225 } |
233 | 226 |
234 scoped_refptr<WebstoreInstaller> installer = | 227 scoped_refptr<WebstoreInstaller> installer = |
235 new WebstoreInstaller(profile_, this, GetWebContents(), id_, | 228 new WebstoreInstaller(profile_, this, GetWebContents(), id_, |
236 std::move(approval), install_source_); | 229 std::move(approval), install_source_); |
237 installer->Start(); | 230 installer->Start(); |
238 } | 231 } |
239 | 232 |
240 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { | 233 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { |
241 OnWebStoreDataFetcherDone(); | 234 OnWebStoreDataFetcherDone(); |
242 CompleteInstall(webstore_install::WEBSTORE_REQUEST_ERROR, | 235 CompleteInstall(webstore_install::WEBSTORE_REQUEST_ERROR, |
243 kWebstoreRequestError); | 236 webstore_install::kWebstoreRequestError); |
244 } | 237 } |
245 | 238 |
246 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( | 239 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( |
247 std::unique_ptr<base::DictionaryValue> webstore_data) { | 240 std::unique_ptr<base::DictionaryValue> webstore_data) { |
248 OnWebStoreDataFetcherDone(); | 241 OnWebStoreDataFetcherDone(); |
249 | 242 |
250 if (!CheckRequestorAlive()) { | 243 if (!CheckRequestorAlive()) { |
251 CompleteInstall(webstore_install::ABORTED, std::string()); | 244 CompleteInstall(webstore_install::ABORTED, std::string()); |
252 return; | 245 return; |
253 } | 246 } |
(...skipping 10 matching lines...) Expand all Loading... |
264 return; | 257 return; |
265 } | 258 } |
266 | 259 |
267 // Manifest, number of users, average rating and rating count are required. | 260 // Manifest, number of users, average rating and rating count are required. |
268 std::string manifest; | 261 std::string manifest; |
269 if (!webstore_data->GetString(kManifestKey, &manifest) || | 262 if (!webstore_data->GetString(kManifestKey, &manifest) || |
270 !webstore_data->GetString(kUsersKey, &localized_user_count_) || | 263 !webstore_data->GetString(kUsersKey, &localized_user_count_) || |
271 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || | 264 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || |
272 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { | 265 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { |
273 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, | 266 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
274 kInvalidWebstoreResponseError); | 267 webstore_install::kInvalidWebstoreResponseError); |
275 return; | 268 return; |
276 } | 269 } |
277 | 270 |
278 // Optional. | 271 // Optional. |
279 show_user_count_ = true; | 272 show_user_count_ = true; |
280 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); | 273 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); |
281 | 274 |
282 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || | 275 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || |
283 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { | 276 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { |
284 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, | 277 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
285 kInvalidWebstoreResponseError); | 278 webstore_install::kInvalidWebstoreResponseError); |
286 return; | 279 return; |
287 } | 280 } |
288 | 281 |
289 // Localized name and description are optional. | 282 // Localized name and description are optional. |
290 if ((webstore_data->HasKey(kLocalizedNameKey) && | 283 if ((webstore_data->HasKey(kLocalizedNameKey) && |
291 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || | 284 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || |
292 (webstore_data->HasKey(kLocalizedDescriptionKey) && | 285 (webstore_data->HasKey(kLocalizedDescriptionKey) && |
293 !webstore_data->GetString( | 286 !webstore_data->GetString( |
294 kLocalizedDescriptionKey, &localized_description_))) { | 287 kLocalizedDescriptionKey, &localized_description_))) { |
295 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, | 288 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
296 kInvalidWebstoreResponseError); | 289 webstore_install::kInvalidWebstoreResponseError); |
297 return; | 290 return; |
298 } | 291 } |
299 | 292 |
300 // Icon URL is optional. | 293 // Icon URL is optional. |
301 GURL icon_url; | 294 GURL icon_url; |
302 if (webstore_data->HasKey(kIconUrlKey)) { | 295 if (webstore_data->HasKey(kIconUrlKey)) { |
303 std::string icon_url_string; | 296 std::string icon_url_string; |
304 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { | 297 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { |
305 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, | 298 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
306 kInvalidWebstoreResponseError); | 299 webstore_install::kInvalidWebstoreResponseError); |
307 return; | 300 return; |
308 } | 301 } |
309 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( | 302 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( |
310 icon_url_string); | 303 icon_url_string); |
311 if (!icon_url.is_valid()) { | 304 if (!icon_url.is_valid()) { |
312 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, | 305 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
313 kInvalidWebstoreResponseError); | 306 webstore_install::kInvalidWebstoreResponseError); |
314 return; | 307 return; |
315 } | 308 } |
316 } | 309 } |
317 | 310 |
318 // Assume ownership of webstore_data. | 311 // Assume ownership of webstore_data. |
319 webstore_data_ = std::move(webstore_data); | 312 webstore_data_ = std::move(webstore_data); |
320 | 313 |
321 scoped_refptr<WebstoreInstallHelper> helper = | 314 scoped_refptr<WebstoreInstallHelper> helper = |
322 new WebstoreInstallHelper(this, | 315 new WebstoreInstallHelper(this, |
323 id_, | 316 id_, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 break; | 389 break; |
397 } | 390 } |
398 | 391 |
399 CompleteInstall(install_result, error); | 392 CompleteInstall(install_result, error); |
400 } | 393 } |
401 | 394 |
402 void WebstoreStandaloneInstaller::ShowInstallUI() { | 395 void WebstoreStandaloneInstaller::ShowInstallUI() { |
403 scoped_refptr<const Extension> localized_extension = | 396 scoped_refptr<const Extension> localized_extension = |
404 GetLocalizedExtensionForDisplay(); | 397 GetLocalizedExtensionForDisplay(); |
405 if (!localized_extension.get()) { | 398 if (!localized_extension.get()) { |
406 CompleteInstall(webstore_install::INVALID_MANIFEST, kInvalidManifestError); | 399 CompleteInstall(webstore_install::INVALID_MANIFEST, |
| 400 webstore_install::kInvalidManifestError); |
407 return; | 401 return; |
408 } | 402 } |
409 | 403 |
410 install_ui_ = CreateInstallUI(); | 404 install_ui_ = CreateInstallUI(); |
411 install_ui_->ShowDialog( | 405 install_ui_->ShowDialog( |
412 base::Bind(&WebstoreStandaloneInstaller::OnInstallPromptDone, this), | 406 base::Bind(&WebstoreStandaloneInstaller::OnInstallPromptDone, this), |
413 localized_extension.get(), &icon_, std::move(install_prompt_), | 407 localized_extension.get(), &icon_, std::move(install_prompt_), |
414 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); | 408 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); |
415 } | 409 } |
416 | 410 |
417 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 411 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
418 // An instance of this class is passed in as a delegate for the | 412 // An instance of this class is passed in as a delegate for the |
419 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 413 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
420 // therefore needs to remain alive until they are done. Clear the webstore | 414 // therefore needs to remain alive until they are done. Clear the webstore |
421 // data fetcher to avoid calling Release in AbortInstall while any of these | 415 // data fetcher to avoid calling Release in AbortInstall while any of these |
422 // operations are in progress. | 416 // operations are in progress. |
423 webstore_data_fetcher_.reset(); | 417 webstore_data_fetcher_.reset(); |
424 } | 418 } |
425 | 419 |
426 } // namespace extensions | 420 } // namespace extensions |
OLD | NEW |