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 |