| 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_inline_installer.h" | 5 #include "chrome/browser/extensions/webstore_inline_installer.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 private: | 140 private: |
| 141 virtual ~SafeWebstoreResponseParser() {} | 141 virtual ~SafeWebstoreResponseParser() {} |
| 142 | 142 |
| 143 WebstoreInlineInstaller* client_; | 143 WebstoreInlineInstaller* client_; |
| 144 | 144 |
| 145 std::string webstore_data_; | 145 std::string webstore_data_; |
| 146 std::string error_; | 146 std::string error_; |
| 147 scoped_ptr<DictionaryValue> parsed_webstore_data_; | 147 scoped_ptr<DictionaryValue> parsed_webstore_data_; |
| 148 }; | 148 }; |
| 149 | 149 |
| 150 WebstoreInlineInstaller::WebstoreInlineInstaller(WebContents* web_contents, | 150 WebstoreInlineInstaller::WebstoreInlineInstaller( |
| 151 int install_id, | 151 WebContents* web_contents, |
| 152 int return_route_id, | 152 std::string webstore_item_id, |
| 153 std::string webstore_item_id, | 153 VerifiedSiteRequired require_verified_site, |
| 154 GURL requestor_url, | 154 GURL requestor_url, |
| 155 Delegate* delegate) | 155 Callback callback) |
| 156 : content::WebContentsObserver(web_contents), | 156 : content::WebContentsObserver(web_contents), |
| 157 install_id_(install_id), | |
| 158 return_route_id_(return_route_id), | |
| 159 id_(webstore_item_id), | 157 id_(webstore_item_id), |
| 158 require_verified_site_(require_verified_site == REQUIRE_VERIFIED_SITE), |
| 160 requestor_url_(requestor_url), | 159 requestor_url_(requestor_url), |
| 161 delegate_(delegate), | 160 callback_(callback), |
| 161 skip_post_install_ui_(false), |
| 162 average_rating_(0.0), | 162 average_rating_(0.0), |
| 163 rating_count_(0) { | 163 rating_count_(0) { |
| 164 CHECK(!callback.is_null()); |
| 164 } | 165 } |
| 165 | 166 |
| 166 void WebstoreInlineInstaller::BeginInstall() { | 167 void WebstoreInlineInstaller::BeginInstall() { |
| 167 AddRef(); // Balanced in CompleteInstall or WebContentsDestroyed. | 168 AddRef(); // Balanced in CompleteInstall or WebContentsDestroyed. |
| 168 | 169 |
| 169 if (!Extension::IdIsValid(id_)) { | 170 if (!Extension::IdIsValid(id_)) { |
| 170 CompleteInstall(kInvalidWebstoreItemId); | 171 CompleteInstall(kInvalidWebstoreItemId); |
| 171 return; | 172 return; |
| 172 } | 173 } |
| 173 | 174 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 return; | 288 return; |
| 288 } | 289 } |
| 289 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( | 290 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( |
| 290 icon_url_string); | 291 icon_url_string); |
| 291 if (!icon_url.is_valid()) { | 292 if (!icon_url.is_valid()) { |
| 292 CompleteInstall(kInvalidWebstoreResponseError); | 293 CompleteInstall(kInvalidWebstoreResponseError); |
| 293 return; | 294 return; |
| 294 } | 295 } |
| 295 } | 296 } |
| 296 | 297 |
| 297 // Verified site is required | 298 // Check for a verified site if required. |
| 298 if (webstore_data->HasKey(kVerifiedSiteKey)) { | 299 if (require_verified_site_) { |
| 300 if (!webstore_data->HasKey(kVerifiedSiteKey)) { |
| 301 CompleteInstall(kNoVerifiedSiteError); |
| 302 return; |
| 303 } |
| 299 std::string verified_site; | 304 std::string verified_site; |
| 300 if (!webstore_data->GetString(kVerifiedSiteKey, &verified_site)) { | 305 if (!webstore_data->GetString(kVerifiedSiteKey, &verified_site)) { |
| 301 CompleteInstall(kInvalidWebstoreResponseError); | 306 CompleteInstall(kInvalidWebstoreResponseError); |
| 302 return; | 307 return; |
| 303 } | 308 } |
| 304 | |
| 305 if (!IsRequestorURLInVerifiedSite(requestor_url_, verified_site)) { | 309 if (!IsRequestorURLInVerifiedSite(requestor_url_, verified_site)) { |
| 306 CompleteInstall(kNotFromVerifiedSiteError); | 310 CompleteInstall(kNotFromVerifiedSiteError); |
| 307 return; | 311 return; |
| 308 } | 312 } |
| 309 } else { | |
| 310 CompleteInstall(kNoVerifiedSiteError); | |
| 311 return; | |
| 312 } | 313 } |
| 313 | 314 |
| 314 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( | 315 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( |
| 315 this, | 316 this, |
| 316 id_, | 317 id_, |
| 317 manifest, | 318 manifest, |
| 318 "", // We don't have any icon data. | 319 "", // We don't have any icon data. |
| 319 icon_url, | 320 icon_url, |
| 320 Profile::FromBrowserContext(web_contents()->GetBrowserContext())-> | 321 Profile::FromBrowserContext(web_contents()->GetBrowserContext())-> |
| 321 GetRequestContext()); | 322 GetRequestContext()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 id_, | 359 id_, |
| 359 localized_name_, | 360 localized_name_, |
| 360 localized_description_, | 361 localized_description_, |
| 361 &error); | 362 &error); |
| 362 if (!dummy_extension_) { | 363 if (!dummy_extension_) { |
| 363 OnWebstoreParseFailure(id_, WebstoreInstallHelper::Delegate::MANIFEST_ERROR, | 364 OnWebstoreParseFailure(id_, WebstoreInstallHelper::Delegate::MANIFEST_ERROR, |
| 364 kInvalidManifestError); | 365 kInvalidManifestError); |
| 365 return; | 366 return; |
| 366 } | 367 } |
| 367 | 368 |
| 368 install_ui_.reset( | 369 install_ui_.reset(new ExtensionInstallPrompt(NULL, web_contents(), profile)); |
| 369 ExtensionInstallUI::CreateInstallPromptWithWebContents(web_contents())); | |
| 370 install_ui_->ConfirmInlineInstall(this, dummy_extension_, &icon_, prompt); | 370 install_ui_->ConfirmInlineInstall(this, dummy_extension_, &icon_, prompt); |
| 371 // Control flow finishes up in InstallUIProceed or InstallUIAbort. | 371 // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| 372 } | 372 } |
| 373 | 373 |
| 374 void WebstoreInlineInstaller::OnWebstoreParseFailure( | 374 void WebstoreInlineInstaller::OnWebstoreParseFailure( |
| 375 const std::string& id, | 375 const std::string& id, |
| 376 InstallHelperResultCode result_code, | 376 InstallHelperResultCode result_code, |
| 377 const std::string& error_message) { | 377 const std::string& error_message) { |
| 378 CompleteInstall(error_message); | 378 CompleteInstall(error_message); |
| 379 } | 379 } |
| 380 | 380 |
| 381 void WebstoreInlineInstaller::InstallUIProceed() { | 381 void WebstoreInlineInstaller::InstallUIProceed() { |
| 382 // Check if the tab has gone away in the meantime. | 382 // Check if the tab has gone away in the meantime. |
| 383 if (!web_contents()) { | 383 if (!web_contents()) { |
| 384 CompleteInstall(""); | 384 CompleteInstall(""); |
| 385 return; | 385 return; |
| 386 } | 386 } |
| 387 | 387 |
| 388 Profile* profile = Profile::FromBrowserContext( | 388 Profile* profile = Profile::FromBrowserContext( |
| 389 web_contents()->GetBrowserContext()); | 389 web_contents()->GetBrowserContext()); |
| 390 | 390 |
| 391 scoped_ptr<WebstoreInstaller::Approval> approval( | 391 scoped_ptr<WebstoreInstaller::Approval> approval( |
| 392 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( | 392 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
| 393 profile, | 393 profile, |
| 394 id_, | 394 id_, |
| 395 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()))); | 395 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()))); |
| 396 approval->use_app_installed_bubble = true; | 396 if (skip_post_install_ui_) |
| 397 approval->skip_post_install_ui = true; |
| 398 else |
| 399 approval->use_app_installed_bubble = true; |
| 397 | 400 |
| 398 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 401 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| 399 profile, this, &(web_contents()->GetController()), id_, approval.Pass(), | 402 profile, this, &(web_contents()->GetController()), id_, approval.Pass(), |
| 400 WebstoreInstaller::FLAG_INLINE_INSTALL); | 403 WebstoreInstaller::FLAG_INLINE_INSTALL); |
| 401 installer->Start(); | 404 installer->Start(); |
| 402 } | 405 } |
| 403 | 406 |
| 404 void WebstoreInlineInstaller::InstallUIAbort(bool user_initiated) { | 407 void WebstoreInlineInstaller::InstallUIAbort(bool user_initiated) { |
| 405 CompleteInstall(kUserCancelledError); | 408 CompleteInstall(kUserCancelledError); |
| 406 } | 409 } |
| 407 | 410 |
| 408 void WebstoreInlineInstaller::WebContentsDestroyed(WebContents* web_contents) { | 411 void WebstoreInlineInstaller::WebContentsDestroyed(WebContents* web_contents) { |
| 412 callback_.Reset(); |
| 409 // Abort any in-progress fetches. | 413 // Abort any in-progress fetches. |
| 410 if (webstore_data_url_fetcher_.get()) { | 414 if (webstore_data_url_fetcher_.get()) { |
| 411 webstore_data_url_fetcher_.reset(); | 415 webstore_data_url_fetcher_.reset(); |
| 412 Release(); // Matches the AddRef in BeginInstall. | 416 Release(); // Matches the AddRef in BeginInstall. |
| 413 } | 417 } |
| 414 } | 418 } |
| 415 | 419 |
| 416 void WebstoreInlineInstaller::OnExtensionInstallSuccess(const std::string& id) { | 420 void WebstoreInlineInstaller::OnExtensionInstallSuccess(const std::string& id) { |
| 417 CHECK_EQ(id_, id); | 421 CHECK_EQ(id_, id); |
| 418 CompleteInstall(""); | 422 CompleteInstall(""); |
| 419 } | 423 } |
| 420 | 424 |
| 421 void WebstoreInlineInstaller::OnExtensionInstallFailure( | 425 void WebstoreInlineInstaller::OnExtensionInstallFailure( |
| 422 const std::string& id, const std::string& error) { | 426 const std::string& id, const std::string& error) { |
| 423 CHECK_EQ(id_, id); | 427 CHECK_EQ(id_, id); |
| 424 CompleteInstall(error); | 428 CompleteInstall(error); |
| 425 } | 429 } |
| 426 | 430 |
| 427 void WebstoreInlineInstaller::CompleteInstall(const std::string& error) { | 431 void WebstoreInlineInstaller::CompleteInstall(const std::string& error) { |
| 428 // Only bother responding if there's still a tab contents to send back the | 432 if (!callback_.is_null()) |
| 429 // response to. | 433 callback_.Run(error.empty(), error); |
| 430 if (web_contents()) { | |
| 431 if (error.empty()) { | |
| 432 delegate_->OnInlineInstallSuccess(install_id_, return_route_id_); | |
| 433 } else { | |
| 434 delegate_->OnInlineInstallFailure(install_id_, return_route_id_, error); | |
| 435 } | |
| 436 } | |
| 437 | 434 |
| 438 Release(); // Matches the AddRef in BeginInstall. | 435 Release(); // Matches the AddRef in BeginInstall. |
| 439 } | 436 } |
| 440 | 437 |
| 441 // static | 438 // static |
| 442 bool WebstoreInlineInstaller::IsRequestorURLInVerifiedSite( | 439 bool WebstoreInlineInstaller::IsRequestorURLInVerifiedSite( |
| 443 const GURL& requestor_url, | 440 const GURL& requestor_url, |
| 444 const std::string& verified_site) { | 441 const std::string& verified_site) { |
| 445 // Turn the verified site (which may be a bare domain, or have a port and/or a | 442 // Turn the verified site (which may be a bare domain, or have a port and/or a |
| 446 // path) into a URL that can be parsed by URLPattern. | 443 // path) into a URL that can be parsed by URLPattern. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 457 DLOG(WARNING) << "Could not parse " << verified_site_url << | 454 DLOG(WARNING) << "Could not parse " << verified_site_url << |
| 458 " as URL pattern " << parse_result; | 455 " as URL pattern " << parse_result; |
| 459 return false; | 456 return false; |
| 460 } | 457 } |
| 461 verified_site_pattern.SetScheme("*"); | 458 verified_site_pattern.SetScheme("*"); |
| 462 | 459 |
| 463 return verified_site_pattern.MatchesURL(requestor_url); | 460 return verified_site_pattern.MatchesURL(requestor_url); |
| 464 } | 461 } |
| 465 | 462 |
| 466 } // namespace extensions | 463 } // namespace extensions |
| OLD | NEW |