| 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 "base/values.h" | 7 #include "base/values.h" |
| 8 #include "base/version.h" |
| 8 #include "chrome/browser/extensions/crx_installer.h" | 9 #include "chrome/browser/extensions/crx_installer.h" |
| 9 #include "chrome/browser/extensions/extension_install_prompt.h" | 10 #include "chrome/browser/extensions/extension_install_prompt.h" |
| 10 #include "chrome/browser/extensions/extension_install_ui.h" | 11 #include "chrome/browser/extensions/extension_install_ui.h" |
| 11 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
| 12 #include "chrome/browser/extensions/webstore_data_fetcher.h" | 13 #include "chrome/browser/extensions/webstore_data_fetcher.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 14 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
| 15 #include "extensions/browser/extension_prefs.h" | 16 #include "extensions/browser/extension_prefs.h" |
| 16 #include "extensions/browser/extension_registry.h" | 17 #include "extensions/browser/extension_registry.h" |
| 17 #include "extensions/browser/extension_system.h" | 18 #include "extensions/browser/extension_system.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 37 const Callback& callback) | 38 const Callback& callback) |
| 38 : id_(webstore_item_id), | 39 : id_(webstore_item_id), |
| 39 callback_(callback), | 40 callback_(callback), |
| 40 profile_(profile), | 41 profile_(profile), |
| 41 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), | 42 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), |
| 42 show_user_count_(true), | 43 show_user_count_(true), |
| 43 average_rating_(0.0), | 44 average_rating_(0.0), |
| 44 rating_count_(0) { | 45 rating_count_(0) { |
| 45 } | 46 } |
| 46 | 47 |
| 47 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {} | |
| 48 | |
| 49 // | |
| 50 // Private interface implementation. | |
| 51 // | |
| 52 | |
| 53 void WebstoreStandaloneInstaller::BeginInstall() { | 48 void WebstoreStandaloneInstaller::BeginInstall() { |
| 54 // Add a ref to keep this alive for WebstoreDataFetcher. | 49 // Add a ref to keep this alive for WebstoreDataFetcher. |
| 55 // All code paths from here eventually lead to either CompleteInstall or | 50 // All code paths from here eventually lead to either CompleteInstall or |
| 56 // AbortInstall, which both release this ref. | 51 // AbortInstall, which both release this ref. |
| 57 AddRef(); | 52 AddRef(); |
| 58 | 53 |
| 59 if (!Extension::IdIsValid(id_)) { | 54 if (!Extension::IdIsValid(id_)) { |
| 60 CompleteInstall(kInvalidWebstoreItemId); | 55 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); |
| 61 return; | 56 return; |
| 62 } | 57 } |
| 63 | 58 |
| 64 // Use the requesting page as the referrer both since that is more correct | 59 // Use the requesting page as the referrer both since that is more correct |
| 65 // (it is the page that caused this request to happen) and so that we can | 60 // (it is the page that caused this request to happen) and so that we can |
| 66 // track top sites that trigger inline install requests. | 61 // track top sites that trigger inline install requests. |
| 67 webstore_data_fetcher_.reset(new WebstoreDataFetcher( | 62 webstore_data_fetcher_.reset(new WebstoreDataFetcher( |
| 68 this, | 63 this, |
| 69 profile_->GetRequestContext(), | 64 profile_->GetRequestContext(), |
| 70 GetRequestorURL(), | 65 GetRequestorURL(), |
| 71 id_)); | 66 id_)); |
| 72 webstore_data_fetcher_->Start(); | 67 webstore_data_fetcher_->Start(); |
| 73 } | 68 } |
| 74 | 69 |
| 75 bool WebstoreStandaloneInstaller::CheckInstallValid( | 70 // |
| 76 const base::DictionaryValue& manifest, | 71 // Private interface implementation. |
| 77 std::string* error) { | 72 // |
| 78 return true; | 73 |
| 74 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() { |
| 75 } |
| 76 |
| 77 void WebstoreStandaloneInstaller::AbortInstall() { |
| 78 callback_.Reset(); |
| 79 // Abort any in-progress fetches. |
| 80 if (webstore_data_fetcher_) { |
| 81 webstore_data_fetcher_.reset(); |
| 82 Release(); // Matches the AddRef in BeginInstall. |
| 83 } |
| 84 } |
| 85 |
| 86 void WebstoreStandaloneInstaller::CompleteInstall( |
| 87 webstore_install::Result result, |
| 88 const std::string& error) { |
| 89 if (!callback_.is_null()) |
| 90 callback_.Run(result == webstore_install::SUCCESS, error); |
| 91 Release(); // Matches the AddRef in BeginInstall. |
| 92 } |
| 93 |
| 94 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { |
| 95 install_prompt_ = CreateInstallPrompt(); |
| 96 if (install_prompt_) { |
| 97 ShowInstallUI(); |
| 98 // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| 99 } else { |
| 100 InstallUIProceed(); |
| 101 } |
| 102 } |
| 103 |
| 104 scoped_refptr<const Extension> |
| 105 WebstoreStandaloneInstaller::GetLocalizedExtensionForDisplay() { |
| 106 if (!localized_extension_for_display_.get()) { |
| 107 DCHECK(manifest_.get()); |
| 108 if (!manifest_.get()) |
| 109 return NULL; |
| 110 |
| 111 std::string error; |
| 112 localized_extension_for_display_ = |
| 113 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( |
| 114 manifest_.get(), |
| 115 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, |
| 116 id_, |
| 117 localized_name_, |
| 118 localized_description_, |
| 119 &error); |
| 120 } |
| 121 return localized_extension_for_display_.get(); |
| 122 } |
| 123 |
| 124 void WebstoreStandaloneInstaller::OnManifestParsed() { |
| 125 ProceedWithInstallPrompt(); |
| 79 } | 126 } |
| 80 | 127 |
| 81 scoped_ptr<ExtensionInstallPrompt> | 128 scoped_ptr<ExtensionInstallPrompt> |
| 82 WebstoreStandaloneInstaller::CreateInstallUI() { | 129 WebstoreStandaloneInstaller::CreateInstallUI() { |
| 83 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); | 130 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); |
| 84 } | 131 } |
| 85 | 132 |
| 86 scoped_ptr<WebstoreInstaller::Approval> | 133 scoped_ptr<WebstoreInstaller::Approval> |
| 87 WebstoreStandaloneInstaller::CreateApproval() const { | 134 WebstoreStandaloneInstaller::CreateApproval() const { |
| 88 scoped_ptr<WebstoreInstaller::Approval> approval( | 135 scoped_ptr<WebstoreInstaller::Approval> approval( |
| 89 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( | 136 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
| 90 profile_, | 137 profile_, |
| 91 id_, | 138 id_, |
| 92 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), | 139 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), |
| 93 true)); | 140 true)); |
| 94 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); | 141 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); |
| 95 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); | 142 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); |
| 96 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); | 143 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); |
| 97 return approval.Pass(); | 144 return approval.Pass(); |
| 98 } | 145 } |
| 99 | 146 |
| 100 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { | 147 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { |
| 101 OnWebStoreDataFetcherDone(); | 148 OnWebStoreDataFetcherDone(); |
| 102 CompleteInstall(kWebstoreRequestError); | 149 CompleteInstall(webstore_install::WEBSTORE_REQUEST_ERROR, |
| 150 kWebstoreRequestError); |
| 103 } | 151 } |
| 104 | 152 |
| 105 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( | 153 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( |
| 106 scoped_ptr<base::DictionaryValue> webstore_data) { | 154 scoped_ptr<base::DictionaryValue> webstore_data) { |
| 107 OnWebStoreDataFetcherDone(); | 155 OnWebStoreDataFetcherDone(); |
| 108 | 156 |
| 109 if (!CheckRequestorAlive()) { | 157 if (!CheckRequestorAlive()) { |
| 110 CompleteInstall(std::string()); | 158 CompleteInstall(webstore_install::ABORTED, std::string()); |
| 111 return; | 159 return; |
| 112 } | 160 } |
| 113 | 161 |
| 114 std::string error; | 162 std::string error; |
| 115 | 163 |
| 116 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { | 164 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { |
| 117 CompleteInstall(error); | 165 CompleteInstall(webstore_install::NOT_PERMITTED, error); |
| 118 return; | 166 return; |
| 119 } | 167 } |
| 120 | 168 |
| 121 if (!CheckRequestorPermitted(*webstore_data, &error)) { | 169 if (!CheckRequestorPermitted(*webstore_data, &error)) { |
| 122 CompleteInstall(error); | 170 CompleteInstall(webstore_install::NOT_PERMITTED, error); |
| 123 return; | 171 return; |
| 124 } | 172 } |
| 125 | 173 |
| 126 // Manifest, number of users, average rating and rating count are required. | 174 // Manifest, number of users, average rating and rating count are required. |
| 127 std::string manifest; | 175 std::string manifest; |
| 128 if (!webstore_data->GetString(kManifestKey, &manifest) || | 176 if (!webstore_data->GetString(kManifestKey, &manifest) || |
| 129 !webstore_data->GetString(kUsersKey, &localized_user_count_) || | 177 !webstore_data->GetString(kUsersKey, &localized_user_count_) || |
| 130 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || | 178 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || |
| 131 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { | 179 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { |
| 132 CompleteInstall(kInvalidWebstoreResponseError); | 180 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 181 kInvalidWebstoreResponseError); |
| 133 return; | 182 return; |
| 134 } | 183 } |
| 135 | 184 |
| 136 // Optional. | 185 // Optional. |
| 137 show_user_count_ = true; | 186 show_user_count_ = true; |
| 138 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); | 187 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); |
| 139 | 188 |
| 140 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || | 189 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || |
| 141 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { | 190 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { |
| 142 CompleteInstall(kInvalidWebstoreResponseError); | 191 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 192 kInvalidWebstoreResponseError); |
| 143 return; | 193 return; |
| 144 } | 194 } |
| 145 | 195 |
| 146 // Localized name and description are optional. | 196 // Localized name and description are optional. |
| 147 if ((webstore_data->HasKey(kLocalizedNameKey) && | 197 if ((webstore_data->HasKey(kLocalizedNameKey) && |
| 148 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || | 198 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || |
| 149 (webstore_data->HasKey(kLocalizedDescriptionKey) && | 199 (webstore_data->HasKey(kLocalizedDescriptionKey) && |
| 150 !webstore_data->GetString( | 200 !webstore_data->GetString( |
| 151 kLocalizedDescriptionKey, &localized_description_))) { | 201 kLocalizedDescriptionKey, &localized_description_))) { |
| 152 CompleteInstall(kInvalidWebstoreResponseError); | 202 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 203 kInvalidWebstoreResponseError); |
| 153 return; | 204 return; |
| 154 } | 205 } |
| 155 | 206 |
| 156 // Icon URL is optional. | 207 // Icon URL is optional. |
| 157 GURL icon_url; | 208 GURL icon_url; |
| 158 if (webstore_data->HasKey(kIconUrlKey)) { | 209 if (webstore_data->HasKey(kIconUrlKey)) { |
| 159 std::string icon_url_string; | 210 std::string icon_url_string; |
| 160 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { | 211 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { |
| 161 CompleteInstall(kInvalidWebstoreResponseError); | 212 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 213 kInvalidWebstoreResponseError); |
| 162 return; | 214 return; |
| 163 } | 215 } |
| 164 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( | 216 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( |
| 165 icon_url_string); | 217 icon_url_string); |
| 166 if (!icon_url.is_valid()) { | 218 if (!icon_url.is_valid()) { |
| 167 CompleteInstall(kInvalidWebstoreResponseError); | 219 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 220 kInvalidWebstoreResponseError); |
| 168 return; | 221 return; |
| 169 } | 222 } |
| 170 } | 223 } |
| 171 | 224 |
| 172 // Assume ownership of webstore_data. | 225 // Assume ownership of webstore_data. |
| 173 webstore_data_ = webstore_data.Pass(); | 226 webstore_data_ = webstore_data.Pass(); |
| 174 | 227 |
| 175 scoped_refptr<WebstoreInstallHelper> helper = | 228 scoped_refptr<WebstoreInstallHelper> helper = |
| 176 new WebstoreInstallHelper(this, | 229 new WebstoreInstallHelper(this, |
| 177 id_, | 230 id_, |
| 178 manifest, | 231 manifest, |
| 179 std::string(), // We don't have any icon data. | 232 std::string(), // We don't have any icon data. |
| 180 icon_url, | 233 icon_url, |
| 181 profile_->GetRequestContext()); | 234 profile_->GetRequestContext()); |
| 182 // The helper will call us back via OnWebstoreParseSucces or | 235 // The helper will call us back via OnWebstoreParseSucces or |
| 183 // OnWebstoreParseFailure. | 236 // OnWebstoreParseFailure. |
| 184 helper->Start(); | 237 helper->Start(); |
| 185 } | 238 } |
| 186 | 239 |
| 187 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( | 240 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( |
| 188 const std::string& error) { | 241 const std::string& error) { |
| 189 OnWebStoreDataFetcherDone(); | 242 OnWebStoreDataFetcherDone(); |
| 190 CompleteInstall(error); | 243 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, error); |
| 191 } | 244 } |
| 192 | 245 |
| 193 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( | 246 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( |
| 194 const std::string& id, | 247 const std::string& id, |
| 195 const SkBitmap& icon, | 248 const SkBitmap& icon, |
| 196 base::DictionaryValue* manifest) { | 249 base::DictionaryValue* manifest) { |
| 197 CHECK_EQ(id_, id); | 250 CHECK_EQ(id_, id); |
| 198 | 251 |
| 199 if (!CheckRequestorAlive()) { | 252 if (!CheckRequestorAlive()) { |
| 200 CompleteInstall(std::string()); | 253 CompleteInstall(webstore_install::ABORTED, std::string()); |
| 201 return; | 254 return; |
| 202 } | 255 } |
| 203 | 256 |
| 204 manifest_.reset(manifest); | 257 manifest_.reset(manifest); |
| 205 icon_ = icon; | 258 icon_ = icon; |
| 206 | 259 |
| 207 std::string error; | 260 OnManifestParsed(); |
| 208 if (!CheckInstallValid(*manifest, &error)) { | |
| 209 DCHECK(!error.empty()); | |
| 210 CompleteInstall(error); | |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 install_prompt_ = CreateInstallPrompt(); | |
| 215 if (install_prompt_) { | |
| 216 ShowInstallUI(); | |
| 217 // Control flow finishes up in InstallUIProceed or InstallUIAbort. | |
| 218 } else { | |
| 219 InstallUIProceed(); | |
| 220 } | |
| 221 } | 261 } |
| 222 | 262 |
| 223 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( | 263 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( |
| 224 const std::string& id, | 264 const std::string& id, |
| 225 InstallHelperResultCode result_code, | 265 InstallHelperResultCode result_code, |
| 226 const std::string& error_message) { | 266 const std::string& error_message) { |
| 227 CompleteInstall(error_message); | 267 webstore_install::Result install_result = webstore_install::UNKNOWN_ERROR; |
| 268 switch (result_code) { |
| 269 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR: |
| 270 install_result = webstore_install::INVALID_MANIFEST; |
| 271 break; |
| 272 case WebstoreInstallHelper::Delegate::ICON_ERROR: |
| 273 install_result = webstore_install::ICON_ERROR; |
| 274 break; |
| 275 default: |
| 276 break; |
| 277 } |
| 278 |
| 279 CompleteInstall(install_result, error_message); |
| 228 } | 280 } |
| 229 | 281 |
| 230 void WebstoreStandaloneInstaller::InstallUIProceed() { | 282 void WebstoreStandaloneInstaller::InstallUIProceed() { |
| 231 if (!CheckRequestorAlive()) { | 283 if (!CheckRequestorAlive()) { |
| 232 CompleteInstall(std::string()); | 284 CompleteInstall(webstore_install::ABORTED, std::string()); |
| 233 return; | 285 return; |
| 234 } | 286 } |
| 235 | 287 |
| 236 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); | 288 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); |
| 237 | 289 |
| 238 ExtensionService* extension_service = | 290 ExtensionService* extension_service = |
| 239 ExtensionSystem::Get(profile_)->extension_service(); | 291 ExtensionSystem::Get(profile_)->extension_service(); |
| 240 const Extension* extension = | 292 const Extension* installed_extension = |
| 241 extension_service->GetExtensionById(id_, true /* include disabled */); | 293 extension_service->GetExtensionById(id_, true /* include disabled */); |
| 242 if (extension) { | 294 if (installed_extension) { |
| 243 std::string install_result; // Empty string for install success. | 295 std::string install_message; |
| 296 webstore_install::Result install_result = webstore_install::SUCCESS; |
| 297 bool done = true; |
| 244 | 298 |
| 245 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { | 299 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { |
| 246 // Don't install a blacklisted extension. | 300 // Don't install a blacklisted extension. |
| 247 install_result = kExtensionIsBlacklisted; | 301 install_result = webstore_install::BLACKLISTED; |
| 248 } else if (util::IsEphemeralApp(extension->id(), profile_) && | 302 install_message = kExtensionIsBlacklisted; |
| 303 } else if (util::IsEphemeralApp(installed_extension->id(), profile_) && |
| 249 !approval->is_ephemeral) { | 304 !approval->is_ephemeral) { |
| 250 // If the target extension has already been installed ephemerally, it can | 305 // If the target extension has already been installed ephemerally and is |
| 251 // be promoted to a regular installed extension and downloading from the | 306 // up to date, it can be promoted to a regular installed extension and |
| 252 // Web Store is not necessary. | 307 // downloading from the Web Store is not necessary. |
| 253 extension_service->PromoteEphemeralApp(extension, false); | 308 const Extension* extension_to_install = GetLocalizedExtensionForDisplay(); |
| 309 if (!extension_to_install) { |
| 310 CompleteInstall(webstore_install::INVALID_MANIFEST, |
| 311 kInvalidManifestError); |
| 312 return; |
| 313 } |
| 314 |
| 315 if (installed_extension->version()->CompareTo( |
| 316 *extension_to_install->version()) < 0) { |
| 317 // If the existing extension is out of date, proceed with the install |
| 318 // to update the extension. |
| 319 done = false; |
| 320 } else { |
| 321 extension_service->PromoteEphemeralApp(installed_extension, false); |
| 322 } |
| 254 } else if (!extension_service->IsExtensionEnabled(id_)) { | 323 } else if (!extension_service->IsExtensionEnabled(id_)) { |
| 255 // If the extension is installed but disabled, and not blacklisted, | 324 // If the extension is installed but disabled, and not blacklisted, |
| 256 // enable it. | 325 // enable it. |
| 257 extension_service->EnableExtension(id_); | 326 extension_service->EnableExtension(id_); |
| 258 } // else extension is installed and enabled; no work to be done. | 327 } // else extension is installed and enabled; no work to be done. |
| 259 | 328 |
| 260 CompleteInstall(install_result); | 329 if (done) { |
| 261 return; | 330 CompleteInstall(install_result, install_message); |
| 331 return; |
| 332 } |
| 262 } | 333 } |
| 263 | 334 |
| 264 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 335 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| 265 profile_, | 336 profile_, |
| 266 this, | 337 this, |
| 267 GetWebContents(), | 338 GetWebContents(), |
| 268 id_, | 339 id_, |
| 269 approval.Pass(), | 340 approval.Pass(), |
| 270 install_source_); | 341 install_source_); |
| 271 installer->Start(); | 342 installer->Start(); |
| 272 } | 343 } |
| 273 | 344 |
| 274 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { | 345 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { |
| 275 CompleteInstall(kUserCancelledError); | 346 CompleteInstall(webstore_install::USER_CANCELLED, kUserCancelledError); |
| 276 } | 347 } |
| 277 | 348 |
| 278 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( | 349 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( |
| 279 const std::string& id) { | 350 const std::string& id) { |
| 280 CHECK_EQ(id_, id); | 351 CHECK_EQ(id_, id); |
| 281 CompleteInstall(std::string()); | 352 CompleteInstall(webstore_install::SUCCESS, std::string()); |
| 282 } | 353 } |
| 283 | 354 |
| 284 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( | 355 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( |
| 285 const std::string& id, | 356 const std::string& id, |
| 286 const std::string& error, | 357 const std::string& error, |
| 287 WebstoreInstaller::FailureReason cancelled) { | 358 WebstoreInstaller::FailureReason reason) { |
| 288 CHECK_EQ(id_, id); | 359 CHECK_EQ(id_, id); |
| 289 CompleteInstall(error); | |
| 290 } | |
| 291 | 360 |
| 292 void WebstoreStandaloneInstaller::AbortInstall() { | 361 webstore_install::Result install_result = webstore_install::UNKNOWN_ERROR; |
| 293 callback_.Reset(); | 362 switch (reason) { |
| 294 // Abort any in-progress fetches. | 363 case WebstoreInstaller::FAILURE_REASON_CANCELLED: |
| 295 if (webstore_data_fetcher_) { | 364 install_result = webstore_install::USER_CANCELLED; |
| 296 webstore_data_fetcher_.reset(); | 365 break; |
| 297 Release(); // Matches the AddRef in BeginInstall. | 366 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_FOUND: |
| 367 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE: |
| 368 install_result = webstore_install::MISSING_DEPENDENCIES; |
| 369 break; |
| 370 default: |
| 371 break; |
| 298 } | 372 } |
| 299 } | |
| 300 | 373 |
| 301 void WebstoreStandaloneInstaller::InvokeCallback(const std::string& error) { | 374 CompleteInstall(install_result, error); |
| 302 if (!callback_.is_null()) | |
| 303 callback_.Run(error.empty(), error); | |
| 304 } | |
| 305 | |
| 306 void WebstoreStandaloneInstaller::CompleteInstall(const std::string& error) { | |
| 307 InvokeCallback(error); | |
| 308 Release(); // Matches the AddRef in BeginInstall. | |
| 309 } | 375 } |
| 310 | 376 |
| 311 void WebstoreStandaloneInstaller::ShowInstallUI() { | 377 void WebstoreStandaloneInstaller::ShowInstallUI() { |
| 312 std::string error; | 378 const Extension* localized_extension = GetLocalizedExtensionForDisplay(); |
| 313 localized_extension_for_display_ = | 379 if (!localized_extension) { |
| 314 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( | 380 CompleteInstall(webstore_install::INVALID_MANIFEST, kInvalidManifestError); |
| 315 manifest_.get(), | |
| 316 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, | |
| 317 id_, | |
| 318 localized_name_, | |
| 319 localized_description_, | |
| 320 &error); | |
| 321 if (!localized_extension_for_display_.get()) { | |
| 322 CompleteInstall(kInvalidManifestError); | |
| 323 return; | 381 return; |
| 324 } | 382 } |
| 325 | 383 |
| 326 install_ui_ = CreateInstallUI(); | 384 install_ui_ = CreateInstallUI(); |
| 327 install_ui_->ConfirmStandaloneInstall( | 385 install_ui_->ConfirmStandaloneInstall( |
| 328 this, localized_extension_for_display_.get(), &icon_, install_prompt_); | 386 this, localized_extension, &icon_, install_prompt_); |
| 329 } | 387 } |
| 330 | 388 |
| 331 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 389 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
| 332 // An instance of this class is passed in as a delegate for the | 390 // An instance of this class is passed in as a delegate for the |
| 333 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 391 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
| 334 // therefore needs to remain alive until they are done. Clear the webstore | 392 // therefore needs to remain alive until they are done. Clear the webstore |
| 335 // data fetcher to avoid calling Release in AbortInstall while any of these | 393 // data fetcher to avoid calling Release in AbortInstall while any of these |
| 336 // operations are in progress. | 394 // operations are in progress. |
| 337 webstore_data_fetcher_.reset(); | 395 webstore_data_fetcher_.reset(); |
| 338 } | 396 } |
| 339 | 397 |
| 340 } // namespace extensions | 398 } // namespace extensions |
| OLD | NEW |