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

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

Issue 7735001: Add a iconUrl parameter to webstorePrivate.beginInstallWithManifest2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/extension_webstore_private_api.h" 5 #include "chrome/browser/extensions/extension_webstore_private_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/scoped_temp_dir.h" 10 #include "base/scoped_temp_dir.h"
(...skipping 12 matching lines...) Expand all
23 #include "chrome/common/chrome_notification_types.h" 23 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/chrome_utility_messages.h" 25 #include "chrome/common/chrome_utility_messages.h"
26 #include "chrome/common/extensions/extension_constants.h" 26 #include "chrome/common/extensions/extension_constants.h"
27 #include "chrome/common/extensions/extension_error_utils.h" 27 #include "chrome/common/extensions/extension_error_utils.h"
28 #include "chrome/common/extensions/extension_l10n_util.h" 28 #include "chrome/common/extensions/extension_l10n_util.h"
29 #include "chrome/common/net/gaia/gaia_constants.h" 29 #include "chrome/common/net/gaia/gaia_constants.h"
30 #include "content/browser/tab_contents/tab_contents.h" 30 #include "content/browser/tab_contents/tab_contents.h"
31 #include "content/common/notification_details.h" 31 #include "content/common/notification_details.h"
32 #include "content/common/notification_source.h" 32 #include "content/common/notification_source.h"
33 #include "content/common/url_fetcher.h"
33 #include "grit/chromium_strings.h" 34 #include "grit/chromium_strings.h"
34 #include "grit/generated_resources.h" 35 #include "grit/generated_resources.h"
36 #include "net/url_request/url_request_status.h"
35 #include "ui/base/l10n/l10n_util.h" 37 #include "ui/base/l10n/l10n_util.h"
36 38
37 namespace { 39 namespace {
38 40
39 const char kAppInstallBubbleKey[] = "appInstallBubble"; 41 const char kAppInstallBubbleKey[] = "appInstallBubble";
40 const char kIconDataKey[] = "iconData"; 42 const char kIconDataKey[] = "iconData";
43 const char kIconUrlKey[] = "iconUrl";
41 const char kIdKey[] = "id"; 44 const char kIdKey[] = "id";
42 const char kLocalizedNameKey[] = "localizedName"; 45 const char kLocalizedNameKey[] = "localizedName";
43 const char kLoginKey[] = "login"; 46 const char kLoginKey[] = "login";
44 const char kManifestKey[] = "manifest"; 47 const char kManifestKey[] = "manifest";
45 const char kTokenKey[] = "token"; 48 const char kTokenKey[] = "token";
46 49
50 const char kCannotSpecifyIconDataAndUrlError[] =
51 "You cannot specify both icon data and an icon url";
47 const char kImageDecodeError[] = "Image decode failed"; 52 const char kImageDecodeError[] = "Image decode failed";
53 const char kInvalidIconUrlError[] = "Invalid icon url";
48 const char kInvalidIdError[] = "Invalid id"; 54 const char kInvalidIdError[] = "Invalid id";
49 const char kInvalidManifestError[] = "Invalid manifest"; 55 const char kInvalidManifestError[] = "Invalid manifest";
50 const char kNoPreviousBeginInstallError[] = 56 const char kNoPreviousBeginInstallError[] =
51 "* does not match a previous call to beginInstall"; 57 "* does not match a previous call to beginInstall";
52 const char kUserCancelledError[] = "User cancelled install"; 58 const char kUserCancelledError[] = "User cancelled install";
53 const char kUserGestureRequiredError[] = 59 const char kUserGestureRequiredError[] =
54 "This function must be called during a user gesture"; 60 "This function must be called during a user gesture";
55 61
56 ProfileSyncService* test_sync_service = NULL; 62 ProfileSyncService* test_sync_service = NULL;
57 BrowserSignin* test_signin = NULL; 63 BrowserSignin* test_signin = NULL;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 151 }
146 152
147 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in 153 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in
148 // the future we may also want to add time-based expiration, where a whitelist 154 // the future we may also want to add time-based expiration, where a whitelist
149 // entry is only valid for some number of minutes. 155 // entry is only valid for some number of minutes.
150 CrxInstaller::SetWhitelistedInstallId(id); 156 CrxInstaller::SetWhitelistedInstallId(id);
151 return true; 157 return true;
152 } 158 }
153 159
154 // This is a class to help BeginInstallWithManifestFunction manage sending 160 // This is a class to help BeginInstallWithManifestFunction manage sending
155 // JSON manifests and base64-encoded icon data to the utility process for 161 // work to the utility process for parsing manifests and fetching/decoding
156 // parsing. 162 // icon data.
157 class SafeBeginInstallHelper : public UtilityProcessHost::Client { 163 class SafeBeginInstallHelper : public UtilityProcessHost::Client,
164 public URLFetcher::Delegate {
158 public: 165 public:
166 // Only one of icon_data or icon_url should be non-empty. If icon_url is
167 // non-empty, context_getter should be filled in, but otherwise NULL.
159 SafeBeginInstallHelper(BeginInstallWithManifestFunction* client, 168 SafeBeginInstallHelper(BeginInstallWithManifestFunction* client,
169 const std::string& manifest,
160 const std::string& icon_data, 170 const std::string& icon_data,
161 const std::string& manifest) 171 const GURL& icon_url,
172 net::URLRequestContextGetter* context_getter)
162 : client_(client), 173 : client_(client),
163 icon_data_(icon_data),
164 manifest_(manifest), 174 manifest_(manifest),
175 icon_base64_data_(icon_data),
176 icon_url_(icon_url),
177 context_getter_(context_getter),
165 utility_host_(NULL), 178 utility_host_(NULL),
166 icon_decode_complete_(false), 179 icon_decode_complete_(false),
167 manifest_parse_complete_(false), 180 manifest_parse_complete_(false),
168 parse_error_(BeginInstallWithManifestFunction::UNKNOWN_ERROR) {} 181 parse_error_(BeginInstallWithManifestFunction::UNKNOWN_ERROR) {}
169 182
170 void Start() { 183 void Start() {
171 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185 CHECK(icon_base64_data_.empty() || icon_url_.is_empty());
186
187 if (icon_base64_data_.empty() && icon_url_.is_empty())
188 icon_decode_complete_ = true;
189
172 BrowserThread::PostTask( 190 BrowserThread::PostTask(
173 BrowserThread::IO, 191 BrowserThread::IO,
174 FROM_HERE, 192 FROM_HERE,
175 NewRunnableMethod(this, 193 NewRunnableMethod(this,
176 &SafeBeginInstallHelper::StartWorkOnIOThread)); 194 &SafeBeginInstallHelper::StartWorkOnIOThread));
195
196 if (!icon_url_.is_empty()) {
197 CHECK(context_getter_);
198 url_fetcher_.reset(new URLFetcher(icon_url_, URLFetcher::GET, this));
199 url_fetcher_->set_request_context(context_getter_);
200
201 url_fetcher_->Start();
202 // We'll get called back in OnURLFetchComplete.
203 }
177 } 204 }
178 205
179 void StartWorkOnIOThread() { 206 void StartWorkOnIOThread() {
180 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 207 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
181 utility_host_ = new UtilityProcessHost(this, BrowserThread::IO); 208 utility_host_ = new UtilityProcessHost(this, BrowserThread::IO);
182 utility_host_->StartBatchMode(); 209 utility_host_->StartBatchMode();
183 if (icon_data_.empty()) 210
184 icon_decode_complete_ = true; 211 if (!icon_base64_data_.empty())
185 else 212 utility_host_->Send(
186 utility_host_->Send(new ChromeUtilityMsg_DecodeImageBase64(icon_data_)); 213 new ChromeUtilityMsg_DecodeImageBase64(icon_base64_data_));
214
187 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); 215 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_));
188 } 216 }
189 217
218 // Implementing the URLFetcher::Delegate interface.
219 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE {
220 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
221 CHECK(source == url_fetcher_.get());
222 if (source->status().status() != net::URLRequestStatus::SUCCESS ||
223 source->response_code() != 200) {
224 BrowserThread::PostTask(
225 BrowserThread::IO,
226 FROM_HERE,
227 NewRunnableMethod(this,
228 &SafeBeginInstallHelper::OnDecodeImageFailed));
229 } else {
230 std::string response_data;
231 source->GetResponseAsString(&response_data);
232 fetched_icon_data_.insert(fetched_icon_data_.begin(),
233 response_data.begin(),
234 response_data.end());
235 BrowserThread::PostTask(
236 BrowserThread::IO,
237 FROM_HERE,
238 NewRunnableMethod(this,
239 &SafeBeginInstallHelper::StartFetchedImageDecode));
240 }
241 url_fetcher_.reset();
242 }
243
244 void StartFetchedImageDecode() {
245 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
246 CHECK(utility_host_);
247 utility_host_->Send(new ChromeUtilityMsg_DecodeImage(fetched_icon_data_));
248 }
249
190 // Implementing pieces of the UtilityProcessHost::Client interface. 250 // Implementing pieces of the UtilityProcessHost::Client interface.
191 virtual bool OnMessageReceived(const IPC::Message& message) { 251 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
192 bool handled = true; 252 bool handled = true;
193 IPC_BEGIN_MESSAGE_MAP(SafeBeginInstallHelper, message) 253 IPC_BEGIN_MESSAGE_MAP(SafeBeginInstallHelper, message)
194 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, 254 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded,
195 OnDecodeImageSucceeded) 255 OnDecodeImageSucceeded)
196 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, 256 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed,
197 OnDecodeImageFailed) 257 OnDecodeImageFailed)
198 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, 258 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
199 OnJSONParseSucceeded) 259 OnJSONParseSucceeded)
200 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, 260 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
201 OnJSONParseFailed) 261 OnJSONParseFailed)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 else 325 else
266 client_->OnParseFailure(parse_error_, error_); 326 client_->OnParseFailure(parse_error_, error_);
267 } 327 }
268 328
269 private: 329 private:
270 ~SafeBeginInstallHelper() {} 330 ~SafeBeginInstallHelper() {}
271 331
272 // The client who we'll report results back to. 332 // The client who we'll report results back to.
273 BeginInstallWithManifestFunction* client_; 333 BeginInstallWithManifestFunction* client_;
274 334
275 // The data to parse. 335 // The manifest to parse.
276 std::string icon_data_;
277 std::string manifest_; 336 std::string manifest_;
278 337
338 // Only one of these should be non-empty. If |icon_base64_data_| is non-emtpy,
339 // it's a base64-encoded string that needs to be parsed into an SkBitmap. If
340 // |icon_url_| is non-empty, it needs to be fetched and decoded into an
341 // SkBitmap.
342 std::string icon_base64_data_;
343 GURL icon_url_;
344 std::vector<unsigned char> fetched_icon_data_;
345
346 // For fetching the icon, if needed.
347 scoped_ptr<URLFetcher> url_fetcher_;
348 net::URLRequestContextGetter* context_getter_; // Only usable on UI thread.
349
279 UtilityProcessHost* utility_host_; 350 UtilityProcessHost* utility_host_;
280 351
281 // Flags for whether we're done doing icon decoding and manifest parsing. 352 // Flags for whether we're done doing icon decoding and manifest parsing.
282 bool icon_decode_complete_; 353 bool icon_decode_complete_;
283 bool manifest_parse_complete_; 354 bool manifest_parse_complete_;
284 355
285 // The results of succesful decoding/parsing. 356 // The results of succesful decoding/parsing.
286 SkBitmap icon_; 357 SkBitmap icon_;
287 scoped_ptr<DictionaryValue> parsed_manifest_; 358 scoped_ptr<DictionaryValue> parsed_manifest_;
288 359
(...skipping 28 matching lines...) Expand all
317 388
318 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_)); 389 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_));
319 if (!Extension::IdIsValid(id_)) { 390 if (!Extension::IdIsValid(id_)) {
320 SetResult(INVALID_ID); 391 SetResult(INVALID_ID);
321 error_ = kInvalidIdError; 392 error_ = kInvalidIdError;
322 return false; 393 return false;
323 } 394 }
324 395
325 EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); 396 EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_));
326 397
398 if (details->HasKey(kIconDataKey) && details->HasKey(kIconUrlKey)) {
399 SetResult(ICON_ERROR);
400 error_ = kCannotSpecifyIconDataAndUrlError;
401 return false;
402 }
403
327 if (details->HasKey(kIconDataKey)) 404 if (details->HasKey(kIconDataKey))
328 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconDataKey, &icon_data_)); 405 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconDataKey, &icon_data_));
329 406
407 GURL icon_url;
408 if (details->HasKey(kIconUrlKey)) {
409 std::string tmp_url;
410 EXTENSION_FUNCTION_VALIDATE(details->GetString(kIconUrlKey, &tmp_url));
411 icon_url = source_url().Resolve(tmp_url);
412 if (!icon_url.is_valid()) {
413 SetResult(INVALID_ICON_URL);
414 error_ = kInvalidIconUrlError;
415 return false;
416 }
417 }
418
330 if (details->HasKey(kLocalizedNameKey)) 419 if (details->HasKey(kLocalizedNameKey))
331 EXTENSION_FUNCTION_VALIDATE(details->GetString(kLocalizedNameKey, 420 EXTENSION_FUNCTION_VALIDATE(details->GetString(kLocalizedNameKey,
332 &localized_name_)); 421 &localized_name_));
333 422
334 if (details->HasKey(kAppInstallBubbleKey)) 423 if (details->HasKey(kAppInstallBubbleKey))
335 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean( 424 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(
336 kAppInstallBubbleKey, &use_app_installed_bubble_)); 425 kAppInstallBubbleKey, &use_app_installed_bubble_));
337 426
338 scoped_refptr<SafeBeginInstallHelper> helper = 427 net::URLRequestContextGetter* context_getter = NULL;
339 new SafeBeginInstallHelper(this, icon_data_, manifest_); 428 if (!icon_url.is_empty())
340 // The helper will call us back via OnParseSucces or OnParseFailure. 429 context_getter = profile()->GetRequestContext();
430
431 scoped_refptr<SafeBeginInstallHelper> helper = new SafeBeginInstallHelper(
432 this, manifest_, icon_data_, icon_url, context_getter);
433
434 // The helper will call us back via OnParseSuccess or OnParseFailure.
341 helper->Start(); 435 helper->Start();
342 436
343 // Matched with a Release in OnSuccess/OnFailure. 437 // Matched with a Release in OnParseSuccess/OnParseFailure.
344 AddRef(); 438 AddRef();
345 439
346 // The response is sent asynchronously in OnSuccess/OnFailure. 440 // The response is sent asynchronously in OnParseSuccess/OnParseFailure.
347 return true; 441 return true;
348 } 442 }
349 443
350 444
351 void BeginInstallWithManifestFunction::SetResult(ResultCode code) { 445 void BeginInstallWithManifestFunction::SetResult(ResultCode code) {
352 switch (code) { 446 switch (code) {
353 case ERROR_NONE: 447 case ERROR_NONE:
354 result_.reset(Value::CreateStringValue("")); 448 result_.reset(Value::CreateStringValue(""));
355 break; 449 break;
356 case UNKNOWN_ERROR: 450 case UNKNOWN_ERROR:
(...skipping 10 matching lines...) Expand all
367 break; 461 break;
368 case INVALID_ID: 462 case INVALID_ID:
369 result_.reset(Value::CreateStringValue("invalid_id")); 463 result_.reset(Value::CreateStringValue("invalid_id"));
370 break; 464 break;
371 case PERMISSION_DENIED: 465 case PERMISSION_DENIED:
372 result_.reset(Value::CreateStringValue("permission_denied")); 466 result_.reset(Value::CreateStringValue("permission_denied"));
373 break; 467 break;
374 case NO_GESTURE: 468 case NO_GESTURE:
375 result_.reset(Value::CreateStringValue("no_gesture")); 469 result_.reset(Value::CreateStringValue("no_gesture"));
376 break; 470 break;
471 case INVALID_ICON_URL:
472 result_.reset(Value::CreateStringValue("invalid_icon_url"));
473 break;
377 default: 474 default:
378 CHECK(false); 475 CHECK(false);
379 } 476 }
380 } 477 }
381 478
382 // static 479 // static
383 void BeginInstallWithManifestFunction::SetIgnoreUserGestureForTests( 480 void BeginInstallWithManifestFunction::SetIgnoreUserGestureForTests(
384 bool ignore) { 481 bool ignore) {
385 ignore_user_gesture_for_tests = ignore; 482 ignore_user_gesture_for_tests = ignore;
386 } 483 }
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 } 766 }
670 767
671 DCHECK(waiting_for_token_); 768 DCHECK(waiting_for_token_);
672 769
673 result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); 770 result_.reset(CreateLoginResult(profile_->GetOriginalProfile()));
674 SendResponse(true); 771 SendResponse(true);
675 772
676 // Matches the AddRef in RunImpl(). 773 // Matches the AddRef in RunImpl().
677 Release(); 774 Release();
678 } 775 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698