| 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 "base/version.h" |
| 9 #include "chrome/browser/extensions/crx_installer.h" | 9 #include "chrome/browser/extensions/crx_installer.h" |
| 10 #include "chrome/browser/extensions/extension_install_prompt.h" | 10 #include "chrome/browser/extensions/extension_install_prompt.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 namespace extensions { | 25 namespace extensions { |
| 26 | 26 |
| 27 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; | 27 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; |
| 28 const char kWebstoreRequestError[] = | 28 const char kWebstoreRequestError[] = |
| 29 "Could not fetch data from the Chrome Web Store"; | 29 "Could not fetch data from the Chrome Web Store"; |
| 30 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; | 30 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; |
| 31 const char kInvalidManifestError[] = "Invalid manifest"; | 31 const char kInvalidManifestError[] = "Invalid manifest"; |
| 32 const char kUserCancelledError[] = "User cancelled install"; | 32 const char kUserCancelledError[] = "User cancelled install"; |
| 33 const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; | 33 const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; |
| 34 const char kInstallInProgressError[] = "An install is already in progress"; |
| 35 const char kLaunchInProgressError[] = "A launch is already in progress"; |
| 34 | 36 |
| 35 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( | 37 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( |
| 36 const std::string& webstore_item_id, | 38 const std::string& webstore_item_id, |
| 37 Profile* profile, | 39 Profile* profile, |
| 38 const Callback& callback) | 40 const Callback& callback) |
| 39 : id_(webstore_item_id), | 41 : id_(webstore_item_id), |
| 40 callback_(callback), | 42 callback_(callback), |
| 41 profile_(profile), | 43 profile_(profile), |
| 42 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), | 44 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), |
| 43 show_user_count_(true), | 45 show_user_count_(true), |
| 44 average_rating_(0.0), | 46 average_rating_(0.0), |
| 45 rating_count_(0) { | 47 rating_count_(0), |
| 48 install_registered_(false) { |
| 46 } | 49 } |
| 47 | 50 |
| 48 void WebstoreStandaloneInstaller::BeginInstall() { | 51 void WebstoreStandaloneInstaller::BeginInstall() { |
| 49 // Add a ref to keep this alive for WebstoreDataFetcher. | 52 // Add a ref to keep this alive for WebstoreDataFetcher. |
| 50 // All code paths from here eventually lead to either CompleteInstall or | 53 // All code paths from here eventually lead to either CompleteInstall or |
| 51 // AbortInstall, which both release this ref. | 54 // AbortInstall, which both release this ref. |
| 52 AddRef(); | 55 AddRef(); |
| 53 | 56 |
| 54 if (!Extension::IdIsValid(id_)) { | 57 if (!Extension::IdIsValid(id_)) { |
| 55 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); | 58 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); |
| 56 return; | 59 return; |
| 57 } | 60 } |
| 58 | 61 |
| 62 webstore_install::Result result = webstore_install::UNKNOWN_ERROR; |
| 63 std::string error; |
| 64 if (!EnsureUniqueInstall(&result, &error)) { |
| 65 CompleteInstall(result, error); |
| 66 return; |
| 67 } |
| 68 |
| 59 // Use the requesting page as the referrer both since that is more correct | 69 // Use the requesting page as the referrer both since that is more correct |
| 60 // (it is the page that caused this request to happen) and so that we can | 70 // (it is the page that caused this request to happen) and so that we can |
| 61 // track top sites that trigger inline install requests. | 71 // track top sites that trigger inline install requests. |
| 62 webstore_data_fetcher_.reset(new WebstoreDataFetcher( | 72 webstore_data_fetcher_.reset(new WebstoreDataFetcher( |
| 63 this, | 73 this, |
| 64 profile_->GetRequestContext(), | 74 profile_->GetRequestContext(), |
| 65 GetRequestorURL(), | 75 GetRequestorURL(), |
| 66 id_)); | 76 id_)); |
| 67 webstore_data_fetcher_->Start(); | 77 webstore_data_fetcher_->Start(); |
| 68 } | 78 } |
| 69 | 79 |
| 70 // | 80 // |
| 71 // Private interface implementation. | 81 // Private interface implementation. |
| 72 // | 82 // |
| 73 | 83 |
| 74 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() { | 84 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() { |
| 75 } | 85 } |
| 76 | 86 |
| 77 void WebstoreStandaloneInstaller::AbortInstall() { | 87 void WebstoreStandaloneInstaller::AbortInstall() { |
| 78 callback_.Reset(); | 88 callback_.Reset(); |
| 79 // Abort any in-progress fetches. | 89 // Abort any in-progress fetches. |
| 80 if (webstore_data_fetcher_) { | 90 if (webstore_data_fetcher_) { |
| 81 webstore_data_fetcher_.reset(); | 91 webstore_data_fetcher_.reset(); |
| 92 DeregisterActiveInstall(); |
| 82 Release(); // Matches the AddRef in BeginInstall. | 93 Release(); // Matches the AddRef in BeginInstall. |
| 83 } | 94 } |
| 84 } | 95 } |
| 85 | 96 |
| 97 bool WebstoreStandaloneInstaller::EnsureUniqueInstall( |
| 98 webstore_install::Result* reason, |
| 99 std::string* error) { |
| 100 InstallTracker* tracker = InstallTracker::Get(profile_); |
| 101 DCHECK(tracker); |
| 102 |
| 103 const InstallTracker::InstallProgressData* existing_install_data = |
| 104 tracker->GetActiveInstall(id_); |
| 105 if (existing_install_data) { |
| 106 if (existing_install_data->is_ephemeral) { |
| 107 *reason = webstore_install::LAUNCH_IN_PROGRESS; |
| 108 *error = kLaunchInProgressError; |
| 109 } else { |
| 110 *reason = webstore_install::INSTALL_IN_PROGRESS; |
| 111 *error = kInstallInProgressError; |
| 112 } |
| 113 return false; |
| 114 } |
| 115 |
| 116 InstallTracker::InstallProgressData install_data(id_); |
| 117 InitInstallData(&install_data); |
| 118 tracker->AddActiveInstall(install_data); |
| 119 install_registered_ = true; |
| 120 return true; |
| 121 } |
| 122 |
| 86 void WebstoreStandaloneInstaller::CompleteInstall( | 123 void WebstoreStandaloneInstaller::CompleteInstall( |
| 87 webstore_install::Result result, | 124 webstore_install::Result result, |
| 88 const std::string& error) { | 125 const std::string& error) { |
| 126 DeregisterActiveInstall(); |
| 89 if (!callback_.is_null()) | 127 if (!callback_.is_null()) |
| 90 callback_.Run(result == webstore_install::SUCCESS, error); | 128 callback_.Run(result == webstore_install::SUCCESS, error); |
| 91 Release(); // Matches the AddRef in BeginInstall. | 129 Release(); // Matches the AddRef in BeginInstall. |
| 92 } | 130 } |
| 93 | 131 |
| 94 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { | 132 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { |
| 95 install_prompt_ = CreateInstallPrompt(); | 133 install_prompt_ = CreateInstallPrompt(); |
| 96 if (install_prompt_) { | 134 if (install_prompt_) { |
| 97 ShowInstallUI(); | 135 ShowInstallUI(); |
| 98 // Control flow finishes up in InstallUIProceed or InstallUIAbort. | 136 // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 114 manifest_.get(), | 152 manifest_.get(), |
| 115 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, | 153 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, |
| 116 id_, | 154 id_, |
| 117 localized_name_, | 155 localized_name_, |
| 118 localized_description_, | 156 localized_description_, |
| 119 &error); | 157 &error); |
| 120 } | 158 } |
| 121 return localized_extension_for_display_.get(); | 159 return localized_extension_for_display_.get(); |
| 122 } | 160 } |
| 123 | 161 |
| 162 void WebstoreStandaloneInstaller::InitInstallData( |
| 163 InstallTracker::InstallProgressData* install_data) const { |
| 164 // Default implementation sets no properties. |
| 165 } |
| 166 |
| 124 void WebstoreStandaloneInstaller::OnManifestParsed() { | 167 void WebstoreStandaloneInstaller::OnManifestParsed() { |
| 125 ProceedWithInstallPrompt(); | 168 ProceedWithInstallPrompt(); |
| 126 } | 169 } |
| 127 | 170 |
| 128 scoped_ptr<ExtensionInstallPrompt> | 171 scoped_ptr<ExtensionInstallPrompt> |
| 129 WebstoreStandaloneInstaller::CreateInstallUI() { | 172 WebstoreStandaloneInstaller::CreateInstallUI() { |
| 130 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); | 173 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); |
| 131 } | 174 } |
| 132 | 175 |
| 133 scoped_ptr<WebstoreInstaller::Approval> | 176 scoped_ptr<WebstoreInstaller::Approval> |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 | 431 |
| 389 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 432 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
| 390 // An instance of this class is passed in as a delegate for the | 433 // An instance of this class is passed in as a delegate for the |
| 391 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 434 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
| 392 // therefore needs to remain alive until they are done. Clear the webstore | 435 // therefore needs to remain alive until they are done. Clear the webstore |
| 393 // data fetcher to avoid calling Release in AbortInstall while any of these | 436 // data fetcher to avoid calling Release in AbortInstall while any of these |
| 394 // operations are in progress. | 437 // operations are in progress. |
| 395 webstore_data_fetcher_.reset(); | 438 webstore_data_fetcher_.reset(); |
| 396 } | 439 } |
| 397 | 440 |
| 441 void WebstoreStandaloneInstaller::DeregisterActiveInstall() { |
| 442 if (!install_registered_) |
| 443 return; |
| 444 |
| 445 InstallTracker* tracker = InstallTracker::Get(profile_); |
| 446 DCHECK(tracker); |
| 447 tracker->RemoveActiveInstall(id_); |
| 448 } |
| 449 |
| 398 } // namespace extensions | 450 } // namespace extensions |
| OLD | NEW |