Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: chrome/browser/extensions/webstore_standalone_installer.cc

Issue 339103002: Update the EphemeralAppLauncher for use by the webstorePrivate API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Self nit Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698