Chromium Code Reviews| 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(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(InstallResult result, | |
| 87 const std::string& error) { | |
| 88 if (!callback_.is_null()) | |
| 89 callback_.Run(result == INSTALL_SUCCESS, error); | |
| 90 Release(); // Matches the AddRef in BeginInstall. | |
| 91 } | |
| 92 | |
| 93 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { | |
| 94 install_prompt_ = CreateInstallPrompt(); | |
| 95 if (install_prompt_) { | |
| 96 ShowInstallUI(); | |
| 97 // Control flow finishes up in InstallUIProceed or InstallUIAbort. | |
| 98 } else { | |
| 99 InstallUIProceed(); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 scoped_refptr<const Extension> | |
| 104 WebstoreStandaloneInstaller::GetLocalizedExtensionForDisplay() { | |
| 105 if (!localized_extension_for_display_.get()) { | |
| 106 DCHECK(manifest_.get()); | |
| 107 if (!manifest_.get()) | |
| 108 return NULL; | |
| 109 | |
| 110 std::string error; | |
| 111 localized_extension_for_display_ = | |
| 112 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( | |
| 113 manifest_.get(), | |
| 114 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, | |
| 115 id_, | |
| 116 localized_name_, | |
| 117 localized_description_, | |
| 118 &error); | |
| 119 } | |
| 120 return localized_extension_for_display_.get(); | |
| 121 } | |
| 122 | |
| 123 void WebstoreStandaloneInstaller::OnManifestParsed() { | |
| 124 ProceedWithInstallPrompt(); | |
| 79 } | 125 } |
| 80 | 126 |
| 81 scoped_ptr<ExtensionInstallPrompt> | 127 scoped_ptr<ExtensionInstallPrompt> |
| 82 WebstoreStandaloneInstaller::CreateInstallUI() { | 128 WebstoreStandaloneInstaller::CreateInstallUI() { |
| 83 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); | 129 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); |
| 84 } | 130 } |
| 85 | 131 |
| 86 scoped_ptr<WebstoreInstaller::Approval> | 132 scoped_ptr<WebstoreInstaller::Approval> |
| 87 WebstoreStandaloneInstaller::CreateApproval() const { | 133 WebstoreStandaloneInstaller::CreateApproval() const { |
| 88 scoped_ptr<WebstoreInstaller::Approval> approval( | 134 scoped_ptr<WebstoreInstaller::Approval> approval( |
| 89 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( | 135 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
| 90 profile_, | 136 profile_, |
| 91 id_, | 137 id_, |
| 92 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), | 138 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), |
| 93 true)); | 139 true)); |
| 94 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); | 140 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); |
| 95 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); | 141 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); |
| 96 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); | 142 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); |
| 97 return approval.Pass(); | 143 return approval.Pass(); |
| 98 } | 144 } |
| 99 | 145 |
| 100 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { | 146 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { |
| 101 OnWebStoreDataFetcherDone(); | 147 OnWebStoreDataFetcherDone(); |
| 102 CompleteInstall(kWebstoreRequestError); | 148 CompleteInstall(INSTALL_WEBSTORE_REQUEST_ERROR, kWebstoreRequestError); |
| 103 } | 149 } |
| 104 | 150 |
| 105 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( | 151 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( |
| 106 scoped_ptr<base::DictionaryValue> webstore_data) { | 152 scoped_ptr<base::DictionaryValue> webstore_data) { |
| 107 OnWebStoreDataFetcherDone(); | 153 OnWebStoreDataFetcherDone(); |
| 108 | 154 |
| 109 if (!CheckRequestorAlive()) { | 155 if (!CheckRequestorAlive()) { |
| 110 CompleteInstall(std::string()); | 156 CompleteInstall(INSTALL_ABORTED, std::string()); |
| 111 return; | 157 return; |
| 112 } | 158 } |
| 113 | 159 |
| 114 std::string error; | 160 std::string error; |
| 115 | 161 |
| 116 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { | 162 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { |
| 117 CompleteInstall(error); | 163 CompleteInstall(INSTALL_NOT_PERMITTED, error); |
| 118 return; | 164 return; |
| 119 } | 165 } |
| 120 | 166 |
| 121 if (!CheckRequestorPermitted(*webstore_data, &error)) { | 167 if (!CheckRequestorPermitted(*webstore_data, &error)) { |
| 122 CompleteInstall(error); | 168 CompleteInstall(INSTALL_NOT_PERMITTED, error); |
| 123 return; | 169 return; |
| 124 } | 170 } |
| 125 | 171 |
| 126 // Manifest, number of users, average rating and rating count are required. | 172 // Manifest, number of users, average rating and rating count are required. |
| 127 std::string manifest; | 173 std::string manifest; |
| 128 if (!webstore_data->GetString(kManifestKey, &manifest) || | 174 if (!webstore_data->GetString(kManifestKey, &manifest) || |
| 129 !webstore_data->GetString(kUsersKey, &localized_user_count_) || | 175 !webstore_data->GetString(kUsersKey, &localized_user_count_) || |
| 130 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || | 176 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || |
| 131 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { | 177 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { |
| 132 CompleteInstall(kInvalidWebstoreResponseError); | 178 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, |
| 179 kInvalidWebstoreResponseError); | |
| 133 return; | 180 return; |
| 134 } | 181 } |
| 135 | 182 |
| 136 // Optional. | 183 // Optional. |
| 137 show_user_count_ = true; | 184 show_user_count_ = true; |
| 138 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); | 185 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); |
| 139 | 186 |
| 140 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || | 187 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || |
| 141 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { | 188 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { |
| 142 CompleteInstall(kInvalidWebstoreResponseError); | 189 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, |
| 190 kInvalidWebstoreResponseError); | |
| 143 return; | 191 return; |
| 144 } | 192 } |
| 145 | 193 |
| 146 // Localized name and description are optional. | 194 // Localized name and description are optional. |
| 147 if ((webstore_data->HasKey(kLocalizedNameKey) && | 195 if ((webstore_data->HasKey(kLocalizedNameKey) && |
| 148 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || | 196 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || |
| 149 (webstore_data->HasKey(kLocalizedDescriptionKey) && | 197 (webstore_data->HasKey(kLocalizedDescriptionKey) && |
| 150 !webstore_data->GetString( | 198 !webstore_data->GetString( |
| 151 kLocalizedDescriptionKey, &localized_description_))) { | 199 kLocalizedDescriptionKey, &localized_description_))) { |
| 152 CompleteInstall(kInvalidWebstoreResponseError); | 200 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, |
| 201 kInvalidWebstoreResponseError); | |
| 153 return; | 202 return; |
| 154 } | 203 } |
| 155 | 204 |
| 156 // Icon URL is optional. | 205 // Icon URL is optional. |
| 157 GURL icon_url; | 206 GURL icon_url; |
| 158 if (webstore_data->HasKey(kIconUrlKey)) { | 207 if (webstore_data->HasKey(kIconUrlKey)) { |
| 159 std::string icon_url_string; | 208 std::string icon_url_string; |
| 160 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { | 209 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { |
| 161 CompleteInstall(kInvalidWebstoreResponseError); | 210 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, |
| 211 kInvalidWebstoreResponseError); | |
| 162 return; | 212 return; |
| 163 } | 213 } |
| 164 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( | 214 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( |
| 165 icon_url_string); | 215 icon_url_string); |
| 166 if (!icon_url.is_valid()) { | 216 if (!icon_url.is_valid()) { |
| 167 CompleteInstall(kInvalidWebstoreResponseError); | 217 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, |
| 218 kInvalidWebstoreResponseError); | |
| 168 return; | 219 return; |
| 169 } | 220 } |
| 170 } | 221 } |
| 171 | 222 |
| 172 // Assume ownership of webstore_data. | 223 // Assume ownership of webstore_data. |
| 173 webstore_data_ = webstore_data.Pass(); | 224 webstore_data_ = webstore_data.Pass(); |
| 174 | 225 |
| 175 scoped_refptr<WebstoreInstallHelper> helper = | 226 scoped_refptr<WebstoreInstallHelper> helper = |
| 176 new WebstoreInstallHelper(this, | 227 new WebstoreInstallHelper(this, |
| 177 id_, | 228 id_, |
| 178 manifest, | 229 manifest, |
| 179 std::string(), // We don't have any icon data. | 230 std::string(), // We don't have any icon data. |
| 180 icon_url, | 231 icon_url, |
| 181 profile_->GetRequestContext()); | 232 profile_->GetRequestContext()); |
| 182 // The helper will call us back via OnWebstoreParseSucces or | 233 // The helper will call us back via OnWebstoreParseSucces or |
| 183 // OnWebstoreParseFailure. | 234 // OnWebstoreParseFailure. |
| 184 helper->Start(); | 235 helper->Start(); |
| 185 } | 236 } |
| 186 | 237 |
| 187 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( | 238 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( |
| 188 const std::string& error) { | 239 const std::string& error) { |
| 189 OnWebStoreDataFetcherDone(); | 240 OnWebStoreDataFetcherDone(); |
| 190 CompleteInstall(error); | 241 CompleteInstall(INSTALL_INVALID_WEBSTORE_RESPONSE, error); |
| 191 } | 242 } |
| 192 | 243 |
| 193 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( | 244 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( |
| 194 const std::string& id, | 245 const std::string& id, |
| 195 const SkBitmap& icon, | 246 const SkBitmap& icon, |
| 196 base::DictionaryValue* manifest) { | 247 base::DictionaryValue* manifest) { |
| 197 CHECK_EQ(id_, id); | 248 CHECK_EQ(id_, id); |
| 198 | 249 |
| 199 if (!CheckRequestorAlive()) { | 250 if (!CheckRequestorAlive()) { |
| 200 CompleteInstall(std::string()); | 251 CompleteInstall(INSTALL_ABORTED, std::string()); |
| 201 return; | 252 return; |
| 202 } | 253 } |
| 203 | 254 |
| 204 manifest_.reset(manifest); | 255 manifest_.reset(manifest); |
| 205 icon_ = icon; | 256 icon_ = icon; |
| 206 | 257 |
| 207 std::string error; | 258 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 } | 259 } |
| 222 | 260 |
| 223 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( | 261 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( |
| 224 const std::string& id, | 262 const std::string& id, |
| 225 InstallHelperResultCode result_code, | 263 InstallHelperResultCode result_code, |
| 226 const std::string& error_message) { | 264 const std::string& error_message) { |
| 227 CompleteInstall(error_message); | 265 InstallResult install_result = INSTALL_UNKNOWN_ERROR; |
| 266 switch (result_code) { | |
| 267 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR: | |
| 268 install_result = INSTALL_INVALID_MANIFEST; | |
| 269 break; | |
| 270 case WebstoreInstallHelper::Delegate::ICON_ERROR: | |
| 271 install_result = INSTALL_ICON_ERROR; | |
| 272 break; | |
| 273 default: | |
| 274 break; | |
| 275 } | |
| 276 | |
| 277 CompleteInstall(install_result, error_message); | |
| 228 } | 278 } |
| 229 | 279 |
| 230 void WebstoreStandaloneInstaller::InstallUIProceed() { | 280 void WebstoreStandaloneInstaller::InstallUIProceed() { |
| 231 if (!CheckRequestorAlive()) { | 281 if (!CheckRequestorAlive()) { |
| 232 CompleteInstall(std::string()); | 282 CompleteInstall(INSTALL_ABORTED, std::string()); |
| 233 return; | 283 return; |
| 234 } | 284 } |
| 235 | 285 |
| 236 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); | 286 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); |
| 237 | 287 |
| 238 ExtensionService* extension_service = | 288 ExtensionService* extension_service = |
| 239 ExtensionSystem::Get(profile_)->extension_service(); | 289 ExtensionSystem::Get(profile_)->extension_service(); |
| 240 const Extension* extension = | 290 const Extension* installed_extension = |
| 241 extension_service->GetExtensionById(id_, true /* include disabled */); | 291 extension_service->GetExtensionById(id_, true /* include disabled */); |
| 242 if (extension) { | 292 if (installed_extension) { |
| 243 std::string install_result; // Empty string for install success. | 293 std::string install_message; |
| 294 InstallResult install_result = INSTALL_SUCCESS; | |
| 295 bool done = true; | |
| 244 | 296 |
| 245 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { | 297 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { |
| 246 // Don't install a blacklisted extension. | 298 // Don't install a blacklisted extension. |
| 247 install_result = kExtensionIsBlacklisted; | 299 install_result = INSTALL_BLACKLISTED; |
| 248 } else if (util::IsEphemeralApp(extension->id(), profile_) && | 300 install_message = kExtensionIsBlacklisted; |
| 301 } else if (util::IsEphemeralApp(installed_extension->id(), profile_) && | |
| 249 !approval->is_ephemeral) { | 302 !approval->is_ephemeral) { |
|
asargent_no_longer_on_chrome
2014/06/18 20:25:10
Something to think about for a future refactoring
tmdiep
2014/06/18 22:28:34
This is actually not specific to the EphemeralAppL
asargent_no_longer_on_chrome
2014/06/19 00:16:43
Ah, ok, that makes sense.
| |
| 250 // If the target extension has already been installed ephemerally, it can | 303 // If the target extension has already been installed ephemerally and is |
| 251 // be promoted to a regular installed extension and downloading from the | 304 // up to date, it can be promoted to a regular installed extension and |
| 252 // Web Store is not necessary. | 305 // downloading from the Web Store is not necessary. |
| 253 extension_service->PromoteEphemeralApp(extension, false); | 306 const Extension* extension_to_install = GetLocalizedExtensionForDisplay(); |
| 307 if (!extension_to_install) { | |
| 308 CompleteInstall(INSTALL_INVALID_MANIFEST, kInvalidManifestError); | |
| 309 return; | |
| 310 } | |
| 311 | |
| 312 if (installed_extension->version()->CompareTo( | |
| 313 *extension_to_install->version()) < 0) { | |
| 314 // If the existing extension is out of date, proceed with the install | |
| 315 // to update the extension. | |
| 316 done = false; | |
| 317 } else { | |
| 318 extension_service->PromoteEphemeralApp(installed_extension, false); | |
| 319 } | |
| 254 } else if (!extension_service->IsExtensionEnabled(id_)) { | 320 } else if (!extension_service->IsExtensionEnabled(id_)) { |
| 255 // If the extension is installed but disabled, and not blacklisted, | 321 // If the extension is installed but disabled, and not blacklisted, |
| 256 // enable it. | 322 // enable it. |
| 257 extension_service->EnableExtension(id_); | 323 extension_service->EnableExtension(id_); |
| 258 } // else extension is installed and enabled; no work to be done. | 324 } // else extension is installed and enabled; no work to be done. |
| 259 | 325 |
| 260 CompleteInstall(install_result); | 326 if (done) { |
| 261 return; | 327 CompleteInstall(install_result, install_message); |
| 328 return; | |
| 329 } | |
| 262 } | 330 } |
| 263 | 331 |
| 264 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 332 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| 265 profile_, | 333 profile_, |
| 266 this, | 334 this, |
| 267 GetWebContents(), | 335 GetWebContents(), |
| 268 id_, | 336 id_, |
| 269 approval.Pass(), | 337 approval.Pass(), |
| 270 install_source_); | 338 install_source_); |
| 271 installer->Start(); | 339 installer->Start(); |
| 272 } | 340 } |
| 273 | 341 |
| 274 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { | 342 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { |
| 275 CompleteInstall(kUserCancelledError); | 343 CompleteInstall(INSTALL_USER_CANCELLED, kUserCancelledError); |
| 276 } | 344 } |
| 277 | 345 |
| 278 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( | 346 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( |
| 279 const std::string& id) { | 347 const std::string& id) { |
| 280 CHECK_EQ(id_, id); | 348 CHECK_EQ(id_, id); |
| 281 CompleteInstall(std::string()); | 349 CompleteInstall(INSTALL_SUCCESS, std::string()); |
| 282 } | 350 } |
| 283 | 351 |
| 284 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( | 352 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( |
| 285 const std::string& id, | 353 const std::string& id, |
| 286 const std::string& error, | 354 const std::string& error, |
| 287 WebstoreInstaller::FailureReason cancelled) { | 355 WebstoreInstaller::FailureReason reason) { |
| 288 CHECK_EQ(id_, id); | 356 CHECK_EQ(id_, id); |
| 289 CompleteInstall(error); | |
| 290 } | |
| 291 | 357 |
| 292 void WebstoreStandaloneInstaller::AbortInstall() { | 358 InstallResult install_result = INSTALL_UNKNOWN_ERROR; |
| 293 callback_.Reset(); | 359 switch (reason) { |
| 294 // Abort any in-progress fetches. | 360 case WebstoreInstaller::FAILURE_REASON_CANCELLED: |
| 295 if (webstore_data_fetcher_) { | 361 install_result = INSTALL_USER_CANCELLED; |
| 296 webstore_data_fetcher_.reset(); | 362 break; |
| 297 Release(); // Matches the AddRef in BeginInstall. | 363 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_FOUND: |
| 364 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE: | |
| 365 install_result = INSTALL_MISSING_DEPENDENCIES; | |
| 366 break; | |
| 367 default: | |
| 368 break; | |
| 298 } | 369 } |
| 299 } | |
| 300 | 370 |
| 301 void WebstoreStandaloneInstaller::InvokeCallback(const std::string& error) { | 371 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 } | 372 } |
| 310 | 373 |
| 311 void WebstoreStandaloneInstaller::ShowInstallUI() { | 374 void WebstoreStandaloneInstaller::ShowInstallUI() { |
| 312 std::string error; | 375 const Extension* localized_extension = GetLocalizedExtensionForDisplay(); |
| 313 localized_extension_for_display_ = | 376 if (!localized_extension) { |
| 314 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( | 377 CompleteInstall(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; | 378 return; |
| 324 } | 379 } |
| 325 | 380 |
| 326 install_ui_ = CreateInstallUI(); | 381 install_ui_ = CreateInstallUI(); |
| 327 install_ui_->ConfirmStandaloneInstall( | 382 install_ui_->ConfirmStandaloneInstall( |
| 328 this, localized_extension_for_display_.get(), &icon_, *install_prompt_); | 383 this, localized_extension, &icon_, *install_prompt_); |
| 329 } | 384 } |
| 330 | 385 |
| 331 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 386 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
| 332 // An instance of this class is passed in as a delegate for the | 387 // An instance of this class is passed in as a delegate for the |
| 333 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 388 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
| 334 // therefore needs to remain alive until they are done. Clear the webstore | 389 // 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 | 390 // data fetcher to avoid calling Release in AbortInstall while any of these |
| 336 // operations are in progress. | 391 // operations are in progress. |
| 337 webstore_data_fetcher_.reset(); | 392 webstore_data_fetcher_.reset(); |
| 338 } | 393 } |
| 339 | 394 |
| 340 } // namespace extensions | 395 } // namespace extensions |
| OLD | NEW |