| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_webstore_private_api.h" | 5 #include "chrome/browser/extensions/extension_webstore_private_api.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | |
| 9 | 8 |
| 10 #include "base/scoped_temp_dir.h" | |
| 11 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 12 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 13 #include "base/values.h" | 11 #include "base/values.h" |
| 14 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/extensions/crx_installer.h" | 13 #include "chrome/browser/extensions/crx_installer.h" |
| 16 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 14 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 17 #include "chrome/browser/extensions/extension_install_dialog.h" | 15 #include "chrome/browser/extensions/extension_install_dialog.h" |
| 18 #include "chrome/browser/extensions/extension_prefs.h" | 16 #include "chrome/browser/extensions/extension_prefs.h" |
| 19 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 20 #include "chrome/browser/net/gaia/token_service.h" | 18 #include "chrome/browser/net/gaia/token_service.h" |
| 21 #include "chrome/browser/profiles/profile_manager.h" | 19 #include "chrome/browser/profiles/profile_manager.h" |
| 22 #include "chrome/browser/sync/profile_sync_service.h" | 20 #include "chrome/browser/sync/profile_sync_service.h" |
| 23 #include "chrome/common/chrome_notification_types.h" | 21 #include "chrome/common/chrome_notification_types.h" |
| 24 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 25 #include "chrome/common/chrome_utility_messages.h" | |
| 26 #include "chrome/common/extensions/extension_constants.h" | 23 #include "chrome/common/extensions/extension_constants.h" |
| 27 #include "chrome/common/extensions/extension_error_utils.h" | 24 #include "chrome/common/extensions/extension_error_utils.h" |
| 28 #include "chrome/common/extensions/extension_l10n_util.h" | 25 #include "chrome/common/extensions/extension_l10n_util.h" |
| 29 #include "chrome/common/net/gaia/gaia_constants.h" | 26 #include "chrome/common/net/gaia/gaia_constants.h" |
| 30 #include "content/browser/tab_contents/tab_contents.h" | 27 #include "content/browser/tab_contents/tab_contents.h" |
| 31 #include "content/common/notification_details.h" | 28 #include "content/common/notification_details.h" |
| 32 #include "content/common/notification_source.h" | 29 #include "content/common/notification_source.h" |
| 33 #include "content/common/url_fetcher.h" | |
| 34 #include "grit/chromium_strings.h" | 30 #include "grit/chromium_strings.h" |
| 35 #include "grit/generated_resources.h" | 31 #include "grit/generated_resources.h" |
| 36 #include "net/url_request/url_request_status.h" | |
| 37 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" |
| 38 | 33 |
| 39 namespace { | 34 namespace { |
| 40 | 35 |
| 41 const char kAppInstallBubbleKey[] = "appInstallBubble"; | 36 const char kAppInstallBubbleKey[] = "appInstallBubble"; |
| 42 const char kIconDataKey[] = "iconData"; | 37 const char kIconDataKey[] = "iconData"; |
| 43 const char kIconUrlKey[] = "iconUrl"; | 38 const char kIconUrlKey[] = "iconUrl"; |
| 44 const char kIdKey[] = "id"; | 39 const char kIdKey[] = "id"; |
| 45 const char kLocalizedNameKey[] = "localizedName"; | 40 const char kLocalizedNameKey[] = "localizedName"; |
| 46 const char kLoginKey[] = "login"; | 41 const char kLoginKey[] = "login"; |
| 47 const char kManifestKey[] = "manifest"; | 42 const char kManifestKey[] = "manifest"; |
| 48 const char kTokenKey[] = "token"; | 43 const char kTokenKey[] = "token"; |
| 49 | 44 |
| 50 const char kCannotSpecifyIconDataAndUrlError[] = | 45 const char kCannotSpecifyIconDataAndUrlError[] = |
| 51 "You cannot specify both icon data and an icon url"; | 46 "You cannot specify both icon data and an icon url"; |
| 52 const char kImageDecodeError[] = "Image decode failed"; | |
| 53 const char kInvalidIconUrlError[] = "Invalid icon url"; | 47 const char kInvalidIconUrlError[] = "Invalid icon url"; |
| 54 const char kInvalidIdError[] = "Invalid id"; | 48 const char kInvalidIdError[] = "Invalid id"; |
| 55 const char kInvalidManifestError[] = "Invalid manifest"; | 49 const char kInvalidManifestError[] = "Invalid manifest"; |
| 56 const char kNoPreviousBeginInstallError[] = | 50 const char kNoPreviousBeginInstallError[] = |
| 57 "* does not match a previous call to beginInstall"; | 51 "* does not match a previous call to beginInstall"; |
| 58 const char kUserCancelledError[] = "User cancelled install"; | 52 const char kUserCancelledError[] = "User cancelled install"; |
| 59 const char kUserGestureRequiredError[] = | 53 const char kUserGestureRequiredError[] = |
| 60 "This function must be called during a user gesture"; | 54 "This function must be called during a user gesture"; |
| 61 | 55 |
| 62 ProfileSyncService* test_sync_service = NULL; | 56 ProfileSyncService* test_sync_service = NULL; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 return false; | 144 return false; |
| 151 } | 145 } |
| 152 | 146 |
| 153 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in | 147 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in |
| 154 // the future we may also want to add time-based expiration, where a whitelist | 148 // the future we may also want to add time-based expiration, where a whitelist |
| 155 // entry is only valid for some number of minutes. | 149 // entry is only valid for some number of minutes. |
| 156 CrxInstaller::SetWhitelistedInstallId(id); | 150 CrxInstaller::SetWhitelistedInstallId(id); |
| 157 return true; | 151 return true; |
| 158 } | 152 } |
| 159 | 153 |
| 160 // This is a class to help BeginInstallWithManifestFunction manage sending | |
| 161 // work to the utility process for parsing manifests and fetching/decoding | |
| 162 // icon data. | |
| 163 class SafeBeginInstallHelper : public UtilityProcessHost::Client, | |
| 164 public URLFetcher::Delegate { | |
| 165 public: | |
| 166 // Only one of icon_data or icon_url should be non-empty. If icon_url is | |
| 167 // non-empty, context_getter should be filled in, but otherwise NULL. | |
| 168 SafeBeginInstallHelper(BeginInstallWithManifestFunction* client, | |
| 169 const std::string& manifest, | |
| 170 const std::string& icon_data, | |
| 171 const GURL& icon_url, | |
| 172 net::URLRequestContextGetter* context_getter) | |
| 173 : client_(client), | |
| 174 manifest_(manifest), | |
| 175 icon_base64_data_(icon_data), | |
| 176 icon_url_(icon_url), | |
| 177 context_getter_(context_getter), | |
| 178 utility_host_(NULL), | |
| 179 icon_decode_complete_(false), | |
| 180 manifest_parse_complete_(false), | |
| 181 parse_error_(BeginInstallWithManifestFunction::UNKNOWN_ERROR) {} | |
| 182 | |
| 183 void Start() { | |
| 184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 185 CHECK(icon_base64_data_.empty() || icon_url_.is_empty()); | |
| 186 | |
| 187 if (icon_base64_data_.empty() && icon_url_.is_empty()) | |
| 188 icon_decode_complete_ = true; | |
| 189 | |
| 190 BrowserThread::PostTask( | |
| 191 BrowserThread::IO, | |
| 192 FROM_HERE, | |
| 193 NewRunnableMethod(this, | |
| 194 &SafeBeginInstallHelper::StartWorkOnIOThread)); | |
| 195 | |
| 196 if (!icon_url_.is_empty()) { | |
| 197 CHECK(context_getter_); | |
| 198 url_fetcher_.reset(new URLFetcher(icon_url_, URLFetcher::GET, this)); | |
| 199 url_fetcher_->set_request_context(context_getter_); | |
| 200 | |
| 201 url_fetcher_->Start(); | |
| 202 // We'll get called back in OnURLFetchComplete. | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 void StartWorkOnIOThread() { | |
| 207 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 208 utility_host_ = new UtilityProcessHost(this, BrowserThread::IO); | |
| 209 utility_host_->StartBatchMode(); | |
| 210 | |
| 211 if (!icon_base64_data_.empty()) | |
| 212 utility_host_->Send( | |
| 213 new ChromeUtilityMsg_DecodeImageBase64(icon_base64_data_)); | |
| 214 | |
| 215 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); | |
| 216 } | |
| 217 | |
| 218 // Implementing the URLFetcher::Delegate interface. | |
| 219 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE { | |
| 220 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 221 CHECK(source == url_fetcher_.get()); | |
| 222 if (source->status().status() != net::URLRequestStatus::SUCCESS || | |
| 223 source->response_code() != 200) { | |
| 224 BrowserThread::PostTask( | |
| 225 BrowserThread::IO, | |
| 226 FROM_HERE, | |
| 227 NewRunnableMethod(this, | |
| 228 &SafeBeginInstallHelper::OnDecodeImageFailed)); | |
| 229 } else { | |
| 230 std::string response_data; | |
| 231 source->GetResponseAsString(&response_data); | |
| 232 fetched_icon_data_.insert(fetched_icon_data_.begin(), | |
| 233 response_data.begin(), | |
| 234 response_data.end()); | |
| 235 BrowserThread::PostTask( | |
| 236 BrowserThread::IO, | |
| 237 FROM_HERE, | |
| 238 NewRunnableMethod(this, | |
| 239 &SafeBeginInstallHelper::StartFetchedImageDecode)); | |
| 240 } | |
| 241 url_fetcher_.reset(); | |
| 242 } | |
| 243 | |
| 244 void StartFetchedImageDecode() { | |
| 245 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 246 CHECK(utility_host_); | |
| 247 utility_host_->Send(new ChromeUtilityMsg_DecodeImage(fetched_icon_data_)); | |
| 248 } | |
| 249 | |
| 250 // Implementing pieces of the UtilityProcessHost::Client interface. | |
| 251 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | |
| 252 bool handled = true; | |
| 253 IPC_BEGIN_MESSAGE_MAP(SafeBeginInstallHelper, message) | |
| 254 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, | |
| 255 OnDecodeImageSucceeded) | |
| 256 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, | |
| 257 OnDecodeImageFailed) | |
| 258 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, | |
| 259 OnJSONParseSucceeded) | |
| 260 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, | |
| 261 OnJSONParseFailed) | |
| 262 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 263 IPC_END_MESSAGE_MAP() | |
| 264 return handled; | |
| 265 } | |
| 266 | |
| 267 void OnDecodeImageSucceeded(const SkBitmap& decoded_image) { | |
| 268 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 269 icon_ = decoded_image; | |
| 270 icon_decode_complete_ = true; | |
| 271 ReportResultsIfComplete(); | |
| 272 } | |
| 273 | |
| 274 void OnDecodeImageFailed() { | |
| 275 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 276 icon_decode_complete_ = true; | |
| 277 error_ = std::string(kImageDecodeError); | |
| 278 parse_error_ = BeginInstallWithManifestFunction::ICON_ERROR; | |
| 279 ReportResultsIfComplete(); | |
| 280 } | |
| 281 | |
| 282 void OnJSONParseSucceeded(const ListValue& wrapper) { | |
| 283 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 284 manifest_parse_complete_ = true; | |
| 285 Value* value = NULL; | |
| 286 CHECK(wrapper.Get(0, &value)); | |
| 287 if (value->IsType(Value::TYPE_DICTIONARY)) { | |
| 288 parsed_manifest_.reset( | |
| 289 static_cast<DictionaryValue*>(value)->DeepCopy()); | |
| 290 } else { | |
| 291 parse_error_ = BeginInstallWithManifestFunction::MANIFEST_ERROR; | |
| 292 } | |
| 293 ReportResultsIfComplete(); | |
| 294 } | |
| 295 | |
| 296 virtual void OnJSONParseFailed(const std::string& error_message) { | |
| 297 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 298 manifest_parse_complete_ = true; | |
| 299 error_ = error_message; | |
| 300 parse_error_ = BeginInstallWithManifestFunction::MANIFEST_ERROR; | |
| 301 ReportResultsIfComplete(); | |
| 302 } | |
| 303 | |
| 304 void ReportResultsIfComplete() { | |
| 305 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 306 | |
| 307 if (!icon_decode_complete_ || !manifest_parse_complete_) | |
| 308 return; | |
| 309 | |
| 310 // The utility_host_ will take care of deleting itself after this call. | |
| 311 utility_host_->EndBatchMode(); | |
| 312 utility_host_ = NULL; | |
| 313 | |
| 314 BrowserThread::PostTask( | |
| 315 BrowserThread::UI, | |
| 316 FROM_HERE, | |
| 317 NewRunnableMethod(this, | |
| 318 &SafeBeginInstallHelper::ReportResultFromUIThread)); | |
| 319 } | |
| 320 | |
| 321 void ReportResultFromUIThread() { | |
| 322 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 323 if (error_.empty() && parsed_manifest_.get()) | |
| 324 client_->OnParseSuccess(icon_, parsed_manifest_.release()); | |
| 325 else | |
| 326 client_->OnParseFailure(parse_error_, error_); | |
| 327 } | |
| 328 | |
| 329 private: | |
| 330 ~SafeBeginInstallHelper() {} | |
| 331 | |
| 332 // The client who we'll report results back to. | |
| 333 BeginInstallWithManifestFunction* client_; | |
| 334 | |
| 335 // The manifest to parse. | |
| 336 std::string manifest_; | |
| 337 | |
| 338 // Only one of these should be non-empty. If |icon_base64_data_| is non-emtpy, | |
| 339 // it's a base64-encoded string that needs to be parsed into an SkBitmap. If | |
| 340 // |icon_url_| is non-empty, it needs to be fetched and decoded into an | |
| 341 // SkBitmap. | |
| 342 std::string icon_base64_data_; | |
| 343 GURL icon_url_; | |
| 344 std::vector<unsigned char> fetched_icon_data_; | |
| 345 | |
| 346 // For fetching the icon, if needed. | |
| 347 scoped_ptr<URLFetcher> url_fetcher_; | |
| 348 net::URLRequestContextGetter* context_getter_; // Only usable on UI thread. | |
| 349 | |
| 350 UtilityProcessHost* utility_host_; | |
| 351 | |
| 352 // Flags for whether we're done doing icon decoding and manifest parsing. | |
| 353 bool icon_decode_complete_; | |
| 354 bool manifest_parse_complete_; | |
| 355 | |
| 356 // The results of succesful decoding/parsing. | |
| 357 SkBitmap icon_; | |
| 358 scoped_ptr<DictionaryValue> parsed_manifest_; | |
| 359 | |
| 360 // A details string for keeping track of any errors. | |
| 361 std::string error_; | |
| 362 | |
| 363 // A code to distinguish between an error with the icon, and an error with the | |
| 364 // manifest. | |
| 365 BeginInstallWithManifestFunction::ResultCode parse_error_; | |
| 366 }; | |
| 367 | |
| 368 BeginInstallWithManifestFunction::BeginInstallWithManifestFunction() | 154 BeginInstallWithManifestFunction::BeginInstallWithManifestFunction() |
| 369 : use_app_installed_bubble_(false) {} | 155 : use_app_installed_bubble_(false) {} |
| 370 | 156 |
| 371 BeginInstallWithManifestFunction::~BeginInstallWithManifestFunction() {} | 157 BeginInstallWithManifestFunction::~BeginInstallWithManifestFunction() {} |
| 372 | 158 |
| 373 bool BeginInstallWithManifestFunction::RunImpl() { | 159 bool BeginInstallWithManifestFunction::RunImpl() { |
| 374 if (!IsWebStoreURL(profile_, source_url())) { | 160 if (!IsWebStoreURL(profile_, source_url())) { |
| 375 SetResult(PERMISSION_DENIED); | 161 SetResult(PERMISSION_DENIED); |
| 376 return false; | 162 return false; |
| 377 } | 163 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 &localized_name_)); | 207 &localized_name_)); |
| 422 | 208 |
| 423 if (details->HasKey(kAppInstallBubbleKey)) | 209 if (details->HasKey(kAppInstallBubbleKey)) |
| 424 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean( | 210 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean( |
| 425 kAppInstallBubbleKey, &use_app_installed_bubble_)); | 211 kAppInstallBubbleKey, &use_app_installed_bubble_)); |
| 426 | 212 |
| 427 net::URLRequestContextGetter* context_getter = NULL; | 213 net::URLRequestContextGetter* context_getter = NULL; |
| 428 if (!icon_url.is_empty()) | 214 if (!icon_url.is_empty()) |
| 429 context_getter = profile()->GetRequestContext(); | 215 context_getter = profile()->GetRequestContext(); |
| 430 | 216 |
| 431 scoped_refptr<SafeBeginInstallHelper> helper = new SafeBeginInstallHelper( | 217 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( |
| 432 this, manifest_, icon_data_, icon_url, context_getter); | 218 this, manifest_, icon_data_, icon_url, context_getter); |
| 433 | 219 |
| 434 // The helper will call us back via OnParseSuccess or OnParseFailure. | 220 // The helper will call us back via OnWebstoreParseSuccess or |
| 221 // OnWebstoreParseFailure. |
| 435 helper->Start(); | 222 helper->Start(); |
| 436 | 223 |
| 437 // Matched with a Release in OnParseSuccess/OnParseFailure. | 224 // Matched with a Release in OnWebstoreParseSuccess/OnWebstoreParseFailure. |
| 438 AddRef(); | 225 AddRef(); |
| 439 | 226 |
| 440 // The response is sent asynchronously in OnParseSuccess/OnParseFailure. | 227 // The response is sent asynchronously in OnWebstoreParseSuccess/ |
| 228 // OnWebstoreParseFailure. |
| 441 return true; | 229 return true; |
| 442 } | 230 } |
| 443 | 231 |
| 444 | 232 |
| 445 void BeginInstallWithManifestFunction::SetResult(ResultCode code) { | 233 void BeginInstallWithManifestFunction::SetResult(ResultCode code) { |
| 446 switch (code) { | 234 switch (code) { |
| 447 case ERROR_NONE: | 235 case ERROR_NONE: |
| 448 result_.reset(Value::CreateStringValue("")); | 236 result_.reset(Value::CreateStringValue("")); |
| 449 break; | 237 break; |
| 450 case UNKNOWN_ERROR: | 238 case UNKNOWN_ERROR: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 480 void BeginInstallWithManifestFunction::SetIgnoreUserGestureForTests( | 268 void BeginInstallWithManifestFunction::SetIgnoreUserGestureForTests( |
| 481 bool ignore) { | 269 bool ignore) { |
| 482 ignore_user_gesture_for_tests = ignore; | 270 ignore_user_gesture_for_tests = ignore; |
| 483 } | 271 } |
| 484 | 272 |
| 485 void BeginInstallWithManifestFunction::SetAutoConfirmForTests( | 273 void BeginInstallWithManifestFunction::SetAutoConfirmForTests( |
| 486 bool should_proceed) { | 274 bool should_proceed) { |
| 487 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT; | 275 auto_confirm_for_tests = should_proceed ? PROCEED : ABORT; |
| 488 } | 276 } |
| 489 | 277 |
| 490 void BeginInstallWithManifestFunction::OnParseSuccess( | 278 void BeginInstallWithManifestFunction::OnWebstoreParseSuccess( |
| 491 const SkBitmap& icon, DictionaryValue* parsed_manifest) { | 279 const SkBitmap& icon, DictionaryValue* parsed_manifest) { |
| 492 CHECK(parsed_manifest); | 280 CHECK(parsed_manifest); |
| 493 icon_ = icon; | 281 icon_ = icon; |
| 494 parsed_manifest_.reset(parsed_manifest); | 282 parsed_manifest_.reset(parsed_manifest); |
| 495 | 283 |
| 496 // If we were passed a localized name to use in the dialog, create a copy | 284 // If we were passed a localized name to use in the dialog, create a copy |
| 497 // of the original manifest and replace the name in it. | 285 // of the original manifest and replace the name in it. |
| 498 scoped_ptr<DictionaryValue> localized_manifest; | 286 scoped_ptr<DictionaryValue> localized_manifest; |
| 499 if (!localized_name_.empty()) { | 287 if (!localized_name_.empty()) { |
| 500 localized_manifest.reset(parsed_manifest->DeepCopy()); | 288 localized_manifest.reset(parsed_manifest->DeepCopy()); |
| 501 localized_manifest->SetString(extension_manifest_keys::kName, | 289 localized_manifest->SetString(extension_manifest_keys::kName, |
| 502 localized_name_); | 290 localized_name_); |
| 503 } | 291 } |
| 504 | 292 |
| 505 // Create a dummy extension and show the extension install confirmation | 293 // Create a dummy extension and show the extension install confirmation |
| 506 // dialog. | 294 // dialog. |
| 507 std::string init_errors; | 295 std::string init_errors; |
| 508 dummy_extension_ = Extension::CreateWithId( | 296 dummy_extension_ = Extension::CreateWithId( |
| 509 FilePath(), | 297 FilePath(), |
| 510 Extension::INTERNAL, | 298 Extension::INTERNAL, |
| 511 localized_manifest.get() ? *localized_manifest.get() : *parsed_manifest, | 299 localized_manifest.get() ? *localized_manifest.get() : *parsed_manifest, |
| 512 Extension::NO_FLAGS, | 300 Extension::NO_FLAGS, |
| 513 id_, | 301 id_, |
| 514 &init_errors); | 302 &init_errors); |
| 515 if (!dummy_extension_.get()) { | 303 if (!dummy_extension_.get()) { |
| 516 OnParseFailure(MANIFEST_ERROR, std::string(kInvalidManifestError)); | 304 OnWebstoreParseFailure(WebstoreInstallHelper::Delegate::MANIFEST_ERROR, |
| 305 kInvalidManifestError); |
| 517 return; | 306 return; |
| 518 } | 307 } |
| 519 | 308 |
| 520 if (icon_.empty()) | 309 if (icon_.empty()) |
| 521 icon_ = Extension::GetDefaultIcon(dummy_extension_->is_app()); | 310 icon_ = Extension::GetDefaultIcon(dummy_extension_->is_app()); |
| 522 | 311 |
| 523 // In tests, we may have setup to proceed or abort without putting up the real | 312 // In tests, we may have setup to proceed or abort without putting up the real |
| 524 // confirmation dialog. | 313 // confirmation dialog. |
| 525 if (auto_confirm_for_tests != DO_NOT_SKIP) { | 314 if (auto_confirm_for_tests != DO_NOT_SKIP) { |
| 526 if (auto_confirm_for_tests == PROCEED) | 315 if (auto_confirm_for_tests == PROCEED) |
| 527 this->InstallUIProceed(); | 316 this->InstallUIProceed(); |
| 528 else | 317 else |
| 529 this->InstallUIAbort(true); | 318 this->InstallUIAbort(true); |
| 530 return; | 319 return; |
| 531 } | 320 } |
| 532 | 321 |
| 533 ShowExtensionInstallDialog(profile(), | 322 ShowExtensionInstallDialog(profile(), |
| 534 this, | 323 this, |
| 535 dummy_extension_.get(), | 324 dummy_extension_.get(), |
| 536 &icon_, | 325 &icon_, |
| 537 dummy_extension_->GetPermissionMessageStrings(), | 326 dummy_extension_->GetPermissionMessageStrings(), |
| 538 ExtensionInstallUI::INSTALL_PROMPT); | 327 ExtensionInstallUI::INSTALL_PROMPT); |
| 539 | 328 |
| 540 // Control flow finishes up in InstallUIProceed or InstallUIAbort. | 329 // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| 541 } | 330 } |
| 542 | 331 |
| 543 void BeginInstallWithManifestFunction::OnParseFailure( | 332 void BeginInstallWithManifestFunction::OnWebstoreParseFailure( |
| 544 ResultCode result_code, const std::string& error_message) { | 333 WebstoreInstallHelper::Delegate::InstallHelperResultCode result_code, |
| 545 SetResult(result_code); | 334 const std::string& error_message) { |
| 335 // Map from WebstoreInstallHelper's result codes to ours. |
| 336 switch (result_code) { |
| 337 case WebstoreInstallHelper::Delegate::UNKNOWN_ERROR: |
| 338 SetResult(UNKNOWN_ERROR); |
| 339 break; |
| 340 case WebstoreInstallHelper::Delegate::ICON_ERROR: |
| 341 SetResult(ICON_ERROR); |
| 342 break; |
| 343 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR: |
| 344 SetResult(MANIFEST_ERROR); |
| 345 break; |
| 346 default: |
| 347 CHECK(false); |
| 348 } |
| 546 error_ = error_message; | 349 error_ = error_message; |
| 547 SendResponse(false); | 350 SendResponse(false); |
| 548 | 351 |
| 549 // Matches the AddRef in RunImpl(). | 352 // Matches the AddRef in RunImpl(). |
| 550 Release(); | 353 Release(); |
| 551 } | 354 } |
| 552 | 355 |
| 553 void BeginInstallWithManifestFunction::InstallUIProceed() { | 356 void BeginInstallWithManifestFunction::InstallUIProceed() { |
| 554 CrxInstaller::WhitelistEntry* entry = new CrxInstaller::WhitelistEntry; | 357 CrxInstaller::WhitelistEntry* entry = new CrxInstaller::WhitelistEntry; |
| 555 entry->parsed_manifest.reset(parsed_manifest_.release()); | 358 entry->parsed_manifest.reset(parsed_manifest_.release()); |
| 556 entry->localized_name = localized_name_; | 359 entry->localized_name = localized_name_; |
| 557 entry->use_app_installed_bubble = use_app_installed_bubble_; | 360 entry->use_app_installed_bubble = use_app_installed_bubble_; |
| 558 CrxInstaller::SetWhitelistEntry(id_, entry); | 361 CrxInstaller::SetWhitelistEntry(id_, entry); |
| 559 SetResult(ERROR_NONE); | 362 SetResult(ERROR_NONE); |
| 560 SendResponse(true); | 363 SendResponse(true); |
| 561 | 364 |
| 562 // The Permissions_Install histogram is recorded from the ExtensionService | 365 // The Permissions_Install histogram is recorded from the ExtensionService |
| 563 // for all extension installs, so we only need to record the web store | 366 // for all extension installs, so we only need to record the web store |
| 564 // specific histogram here. | 367 // specific histogram here. |
| 565 ExtensionService::RecordPermissionMessagesHistogram( | 368 ExtensionService::RecordPermissionMessagesHistogram( |
| 566 dummy_extension_, "Extensions.Permissions_WebStoreInstall"); | 369 dummy_extension_, "Extensions.Permissions_WebStoreInstall"); |
| 567 | 370 |
| 568 // Matches the AddRef in RunImpl(). | 371 // Matches the AddRef in RunImpl(). |
| 569 Release(); | 372 Release(); |
| 570 } | 373 } |
| 571 | 374 |
| 572 void BeginInstallWithManifestFunction::InstallUIAbort(bool user_initiated) { | 375 void BeginInstallWithManifestFunction::InstallUIAbort(bool user_initiated) { |
| 573 error_ = std::string(kUserCancelledError); | 376 error_ = kUserCancelledError; |
| 574 SetResult(USER_CANCELLED); | 377 SetResult(USER_CANCELLED); |
| 575 SendResponse(false); | 378 SendResponse(false); |
| 576 | 379 |
| 577 // The web store install histograms are a subset of the install histograms. | 380 // The web store install histograms are a subset of the install histograms. |
| 578 // We need to record both histograms here since CrxInstaller::InstallUIAbort | 381 // We need to record both histograms here since CrxInstaller::InstallUIAbort |
| 579 // is never called for web store install cancellations | 382 // is never called for web store install cancellations |
| 580 std::string histogram_name = user_initiated ? | 383 std::string histogram_name = user_initiated ? |
| 581 "Extensions.Permissions_WebStoreInstallCancel" : | 384 "Extensions.Permissions_WebStoreInstallCancel" : |
| 582 "Extensions.Permissions_WebStoreInstallAbort"; | 385 "Extensions.Permissions_WebStoreInstallAbort"; |
| 583 ExtensionService::RecordPermissionMessagesHistogram( | 386 ExtensionService::RecordPermissionMessagesHistogram( |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 } | 569 } |
| 767 | 570 |
| 768 DCHECK(waiting_for_token_); | 571 DCHECK(waiting_for_token_); |
| 769 | 572 |
| 770 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); | 573 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); |
| 771 SendResponse(true); | 574 SendResponse(true); |
| 772 | 575 |
| 773 // Matches the AddRef in RunImpl(). | 576 // Matches the AddRef in RunImpl(). |
| 774 Release(); | 577 Release(); |
| 775 } | 578 } |
| OLD | NEW |