| 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 |