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 |