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(webstore_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( |
| 87 webstore_install::Result result, |
| 88 const std::string& error) { |
| 89 if (!callback_.is_null()) |
| 90 callback_.Run(result == webstore_install::SUCCESS, error); |
| 91 Release(); // Matches the AddRef in BeginInstall. |
| 92 } |
| 93 |
| 94 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { |
| 95 install_prompt_ = CreateInstallPrompt(); |
| 96 if (install_prompt_) { |
| 97 ShowInstallUI(); |
| 98 // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| 99 } else { |
| 100 InstallUIProceed(); |
| 101 } |
| 102 } |
| 103 |
| 104 scoped_refptr<const Extension> |
| 105 WebstoreStandaloneInstaller::GetLocalizedExtensionForDisplay() { |
| 106 if (!localized_extension_for_display_.get()) { |
| 107 DCHECK(manifest_.get()); |
| 108 if (!manifest_.get()) |
| 109 return NULL; |
| 110 |
| 111 std::string error; |
| 112 localized_extension_for_display_ = |
| 113 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( |
| 114 manifest_.get(), |
| 115 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, |
| 116 id_, |
| 117 localized_name_, |
| 118 localized_description_, |
| 119 &error); |
| 120 } |
| 121 return localized_extension_for_display_.get(); |
| 122 } |
| 123 |
| 124 void WebstoreStandaloneInstaller::OnManifestParsed() { |
| 125 ProceedWithInstallPrompt(); |
79 } | 126 } |
80 | 127 |
81 scoped_ptr<ExtensionInstallPrompt> | 128 scoped_ptr<ExtensionInstallPrompt> |
82 WebstoreStandaloneInstaller::CreateInstallUI() { | 129 WebstoreStandaloneInstaller::CreateInstallUI() { |
83 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); | 130 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); |
84 } | 131 } |
85 | 132 |
86 scoped_ptr<WebstoreInstaller::Approval> | 133 scoped_ptr<WebstoreInstaller::Approval> |
87 WebstoreStandaloneInstaller::CreateApproval() const { | 134 WebstoreStandaloneInstaller::CreateApproval() const { |
88 scoped_ptr<WebstoreInstaller::Approval> approval( | 135 scoped_ptr<WebstoreInstaller::Approval> approval( |
89 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( | 136 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
90 profile_, | 137 profile_, |
91 id_, | 138 id_, |
92 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), | 139 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), |
93 true)); | 140 true)); |
94 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); | 141 approval->skip_post_install_ui = !ShouldShowPostInstallUI(); |
95 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); | 142 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); |
96 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); | 143 approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); |
97 return approval.Pass(); | 144 return approval.Pass(); |
98 } | 145 } |
99 | 146 |
100 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { | 147 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { |
101 OnWebStoreDataFetcherDone(); | 148 OnWebStoreDataFetcherDone(); |
102 CompleteInstall(kWebstoreRequestError); | 149 CompleteInstall(webstore_install::WEBSTORE_REQUEST_ERROR, |
| 150 kWebstoreRequestError); |
103 } | 151 } |
104 | 152 |
105 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( | 153 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( |
106 scoped_ptr<base::DictionaryValue> webstore_data) { | 154 scoped_ptr<base::DictionaryValue> webstore_data) { |
107 OnWebStoreDataFetcherDone(); | 155 OnWebStoreDataFetcherDone(); |
108 | 156 |
109 if (!CheckRequestorAlive()) { | 157 if (!CheckRequestorAlive()) { |
110 CompleteInstall(std::string()); | 158 CompleteInstall(webstore_install::ABORTED, std::string()); |
111 return; | 159 return; |
112 } | 160 } |
113 | 161 |
114 std::string error; | 162 std::string error; |
115 | 163 |
116 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { | 164 if (!CheckInlineInstallPermitted(*webstore_data, &error)) { |
117 CompleteInstall(error); | 165 CompleteInstall(webstore_install::NOT_PERMITTED, error); |
118 return; | 166 return; |
119 } | 167 } |
120 | 168 |
121 if (!CheckRequestorPermitted(*webstore_data, &error)) { | 169 if (!CheckRequestorPermitted(*webstore_data, &error)) { |
122 CompleteInstall(error); | 170 CompleteInstall(webstore_install::NOT_PERMITTED, error); |
123 return; | 171 return; |
124 } | 172 } |
125 | 173 |
126 // Manifest, number of users, average rating and rating count are required. | 174 // Manifest, number of users, average rating and rating count are required. |
127 std::string manifest; | 175 std::string manifest; |
128 if (!webstore_data->GetString(kManifestKey, &manifest) || | 176 if (!webstore_data->GetString(kManifestKey, &manifest) || |
129 !webstore_data->GetString(kUsersKey, &localized_user_count_) || | 177 !webstore_data->GetString(kUsersKey, &localized_user_count_) || |
130 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || | 178 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || |
131 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { | 179 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { |
132 CompleteInstall(kInvalidWebstoreResponseError); | 180 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 181 kInvalidWebstoreResponseError); |
133 return; | 182 return; |
134 } | 183 } |
135 | 184 |
136 // Optional. | 185 // Optional. |
137 show_user_count_ = true; | 186 show_user_count_ = true; |
138 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); | 187 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); |
139 | 188 |
140 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || | 189 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || |
141 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { | 190 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { |
142 CompleteInstall(kInvalidWebstoreResponseError); | 191 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 192 kInvalidWebstoreResponseError); |
143 return; | 193 return; |
144 } | 194 } |
145 | 195 |
146 // Localized name and description are optional. | 196 // Localized name and description are optional. |
147 if ((webstore_data->HasKey(kLocalizedNameKey) && | 197 if ((webstore_data->HasKey(kLocalizedNameKey) && |
148 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || | 198 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || |
149 (webstore_data->HasKey(kLocalizedDescriptionKey) && | 199 (webstore_data->HasKey(kLocalizedDescriptionKey) && |
150 !webstore_data->GetString( | 200 !webstore_data->GetString( |
151 kLocalizedDescriptionKey, &localized_description_))) { | 201 kLocalizedDescriptionKey, &localized_description_))) { |
152 CompleteInstall(kInvalidWebstoreResponseError); | 202 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 203 kInvalidWebstoreResponseError); |
153 return; | 204 return; |
154 } | 205 } |
155 | 206 |
156 // Icon URL is optional. | 207 // Icon URL is optional. |
157 GURL icon_url; | 208 GURL icon_url; |
158 if (webstore_data->HasKey(kIconUrlKey)) { | 209 if (webstore_data->HasKey(kIconUrlKey)) { |
159 std::string icon_url_string; | 210 std::string icon_url_string; |
160 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { | 211 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { |
161 CompleteInstall(kInvalidWebstoreResponseError); | 212 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 213 kInvalidWebstoreResponseError); |
162 return; | 214 return; |
163 } | 215 } |
164 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( | 216 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( |
165 icon_url_string); | 217 icon_url_string); |
166 if (!icon_url.is_valid()) { | 218 if (!icon_url.is_valid()) { |
167 CompleteInstall(kInvalidWebstoreResponseError); | 219 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, |
| 220 kInvalidWebstoreResponseError); |
168 return; | 221 return; |
169 } | 222 } |
170 } | 223 } |
171 | 224 |
172 // Assume ownership of webstore_data. | 225 // Assume ownership of webstore_data. |
173 webstore_data_ = webstore_data.Pass(); | 226 webstore_data_ = webstore_data.Pass(); |
174 | 227 |
175 scoped_refptr<WebstoreInstallHelper> helper = | 228 scoped_refptr<WebstoreInstallHelper> helper = |
176 new WebstoreInstallHelper(this, | 229 new WebstoreInstallHelper(this, |
177 id_, | 230 id_, |
178 manifest, | 231 manifest, |
179 std::string(), // We don't have any icon data. | 232 std::string(), // We don't have any icon data. |
180 icon_url, | 233 icon_url, |
181 profile_->GetRequestContext()); | 234 profile_->GetRequestContext()); |
182 // The helper will call us back via OnWebstoreParseSucces or | 235 // The helper will call us back via OnWebstoreParseSucces or |
183 // OnWebstoreParseFailure. | 236 // OnWebstoreParseFailure. |
184 helper->Start(); | 237 helper->Start(); |
185 } | 238 } |
186 | 239 |
187 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( | 240 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( |
188 const std::string& error) { | 241 const std::string& error) { |
189 OnWebStoreDataFetcherDone(); | 242 OnWebStoreDataFetcherDone(); |
190 CompleteInstall(error); | 243 CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, error); |
191 } | 244 } |
192 | 245 |
193 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( | 246 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( |
194 const std::string& id, | 247 const std::string& id, |
195 const SkBitmap& icon, | 248 const SkBitmap& icon, |
196 base::DictionaryValue* manifest) { | 249 base::DictionaryValue* manifest) { |
197 CHECK_EQ(id_, id); | 250 CHECK_EQ(id_, id); |
198 | 251 |
199 if (!CheckRequestorAlive()) { | 252 if (!CheckRequestorAlive()) { |
200 CompleteInstall(std::string()); | 253 CompleteInstall(webstore_install::ABORTED, std::string()); |
201 return; | 254 return; |
202 } | 255 } |
203 | 256 |
204 manifest_.reset(manifest); | 257 manifest_.reset(manifest); |
205 icon_ = icon; | 258 icon_ = icon; |
206 | 259 |
207 std::string error; | 260 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 } | 261 } |
222 | 262 |
223 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( | 263 void WebstoreStandaloneInstaller::OnWebstoreParseFailure( |
224 const std::string& id, | 264 const std::string& id, |
225 InstallHelperResultCode result_code, | 265 InstallHelperResultCode result_code, |
226 const std::string& error_message) { | 266 const std::string& error_message) { |
227 CompleteInstall(error_message); | 267 webstore_install::Result install_result = webstore_install::UNKNOWN_ERROR; |
| 268 switch (result_code) { |
| 269 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR: |
| 270 install_result = webstore_install::INVALID_MANIFEST; |
| 271 break; |
| 272 case WebstoreInstallHelper::Delegate::ICON_ERROR: |
| 273 install_result = webstore_install::ICON_ERROR; |
| 274 break; |
| 275 default: |
| 276 break; |
| 277 } |
| 278 |
| 279 CompleteInstall(install_result, error_message); |
228 } | 280 } |
229 | 281 |
230 void WebstoreStandaloneInstaller::InstallUIProceed() { | 282 void WebstoreStandaloneInstaller::InstallUIProceed() { |
231 if (!CheckRequestorAlive()) { | 283 if (!CheckRequestorAlive()) { |
232 CompleteInstall(std::string()); | 284 CompleteInstall(webstore_install::ABORTED, std::string()); |
233 return; | 285 return; |
234 } | 286 } |
235 | 287 |
236 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); | 288 scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); |
237 | 289 |
238 ExtensionService* extension_service = | 290 ExtensionService* extension_service = |
239 ExtensionSystem::Get(profile_)->extension_service(); | 291 ExtensionSystem::Get(profile_)->extension_service(); |
240 const Extension* extension = | 292 const Extension* installed_extension = |
241 extension_service->GetExtensionById(id_, true /* include disabled */); | 293 extension_service->GetExtensionById(id_, true /* include disabled */); |
242 if (extension) { | 294 if (installed_extension) { |
243 std::string install_result; // Empty string for install success. | 295 std::string install_message; |
| 296 webstore_install::Result install_result = webstore_install::SUCCESS; |
| 297 bool done = true; |
244 | 298 |
245 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { | 299 if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { |
246 // Don't install a blacklisted extension. | 300 // Don't install a blacklisted extension. |
247 install_result = kExtensionIsBlacklisted; | 301 install_result = webstore_install::BLACKLISTED; |
248 } else if (util::IsEphemeralApp(extension->id(), profile_) && | 302 install_message = kExtensionIsBlacklisted; |
| 303 } else if (util::IsEphemeralApp(installed_extension->id(), profile_) && |
249 !approval->is_ephemeral) { | 304 !approval->is_ephemeral) { |
250 // If the target extension has already been installed ephemerally, it can | 305 // If the target extension has already been installed ephemerally and is |
251 // be promoted to a regular installed extension and downloading from the | 306 // up to date, it can be promoted to a regular installed extension and |
252 // Web Store is not necessary. | 307 // downloading from the Web Store is not necessary. |
253 extension_service->PromoteEphemeralApp(extension, false); | 308 const Extension* extension_to_install = GetLocalizedExtensionForDisplay(); |
| 309 if (!extension_to_install) { |
| 310 CompleteInstall(webstore_install::INVALID_MANIFEST, |
| 311 kInvalidManifestError); |
| 312 return; |
| 313 } |
| 314 |
| 315 if (installed_extension->version()->CompareTo( |
| 316 *extension_to_install->version()) < 0) { |
| 317 // If the existing extension is out of date, proceed with the install |
| 318 // to update the extension. |
| 319 done = false; |
| 320 } else { |
| 321 extension_service->PromoteEphemeralApp(installed_extension, false); |
| 322 } |
254 } else if (!extension_service->IsExtensionEnabled(id_)) { | 323 } else if (!extension_service->IsExtensionEnabled(id_)) { |
255 // If the extension is installed but disabled, and not blacklisted, | 324 // If the extension is installed but disabled, and not blacklisted, |
256 // enable it. | 325 // enable it. |
257 extension_service->EnableExtension(id_); | 326 extension_service->EnableExtension(id_); |
258 } // else extension is installed and enabled; no work to be done. | 327 } // else extension is installed and enabled; no work to be done. |
259 | 328 |
260 CompleteInstall(install_result); | 329 if (done) { |
261 return; | 330 CompleteInstall(install_result, install_message); |
| 331 return; |
| 332 } |
262 } | 333 } |
263 | 334 |
264 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 335 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
265 profile_, | 336 profile_, |
266 this, | 337 this, |
267 GetWebContents(), | 338 GetWebContents(), |
268 id_, | 339 id_, |
269 approval.Pass(), | 340 approval.Pass(), |
270 install_source_); | 341 install_source_); |
271 installer->Start(); | 342 installer->Start(); |
272 } | 343 } |
273 | 344 |
274 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { | 345 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { |
275 CompleteInstall(kUserCancelledError); | 346 CompleteInstall(webstore_install::USER_CANCELLED, kUserCancelledError); |
276 } | 347 } |
277 | 348 |
278 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( | 349 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( |
279 const std::string& id) { | 350 const std::string& id) { |
280 CHECK_EQ(id_, id); | 351 CHECK_EQ(id_, id); |
281 CompleteInstall(std::string()); | 352 CompleteInstall(webstore_install::SUCCESS, std::string()); |
282 } | 353 } |
283 | 354 |
284 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( | 355 void WebstoreStandaloneInstaller::OnExtensionInstallFailure( |
285 const std::string& id, | 356 const std::string& id, |
286 const std::string& error, | 357 const std::string& error, |
287 WebstoreInstaller::FailureReason cancelled) { | 358 WebstoreInstaller::FailureReason reason) { |
288 CHECK_EQ(id_, id); | 359 CHECK_EQ(id_, id); |
289 CompleteInstall(error); | |
290 } | |
291 | 360 |
292 void WebstoreStandaloneInstaller::AbortInstall() { | 361 webstore_install::Result install_result = webstore_install::UNKNOWN_ERROR; |
293 callback_.Reset(); | 362 switch (reason) { |
294 // Abort any in-progress fetches. | 363 case WebstoreInstaller::FAILURE_REASON_CANCELLED: |
295 if (webstore_data_fetcher_) { | 364 install_result = webstore_install::USER_CANCELLED; |
296 webstore_data_fetcher_.reset(); | 365 break; |
297 Release(); // Matches the AddRef in BeginInstall. | 366 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_FOUND: |
| 367 case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE: |
| 368 install_result = webstore_install::MISSING_DEPENDENCIES; |
| 369 break; |
| 370 default: |
| 371 break; |
298 } | 372 } |
299 } | |
300 | 373 |
301 void WebstoreStandaloneInstaller::InvokeCallback(const std::string& error) { | 374 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 } | 375 } |
310 | 376 |
311 void WebstoreStandaloneInstaller::ShowInstallUI() { | 377 void WebstoreStandaloneInstaller::ShowInstallUI() { |
312 std::string error; | 378 const Extension* localized_extension = GetLocalizedExtensionForDisplay(); |
313 localized_extension_for_display_ = | 379 if (!localized_extension) { |
314 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( | 380 CompleteInstall(webstore_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; | 381 return; |
324 } | 382 } |
325 | 383 |
326 install_ui_ = CreateInstallUI(); | 384 install_ui_ = CreateInstallUI(); |
327 install_ui_->ConfirmStandaloneInstall( | 385 install_ui_->ConfirmStandaloneInstall( |
328 this, localized_extension_for_display_.get(), &icon_, install_prompt_); | 386 this, localized_extension, &icon_, install_prompt_); |
329 } | 387 } |
330 | 388 |
331 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 389 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
332 // An instance of this class is passed in as a delegate for the | 390 // An instance of this class is passed in as a delegate for the |
333 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 391 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
334 // therefore needs to remain alive until they are done. Clear the webstore | 392 // 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 | 393 // data fetcher to avoid calling Release in AbortInstall while any of these |
336 // operations are in progress. | 394 // operations are in progress. |
337 webstore_data_fetcher_.reset(); | 395 webstore_data_fetcher_.reset(); |
338 } | 396 } |
339 | 397 |
340 } // namespace extensions | 398 } // namespace extensions |
OLD | NEW |