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

Side by Side Diff: chrome/browser/extensions/api/webstore_private/webstore_private_api.cc

Issue 850283003: Add a new webstorePrivate API to show a permission prompt for delegated installs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@testext_permission_prompt
Patch Set: rebase Created 5 years, 10 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/api/webstore_private/webstore_private_api.h" 5 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
6 6
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 28 matching lines...) Expand all
39 namespace CompleteInstall = api::webstore_private::CompleteInstall; 39 namespace CompleteInstall = api::webstore_private::CompleteInstall;
40 namespace GetBrowserLogin = api::webstore_private::GetBrowserLogin; 40 namespace GetBrowserLogin = api::webstore_private::GetBrowserLogin;
41 namespace GetEphemeralAppsEnabled = 41 namespace GetEphemeralAppsEnabled =
42 api::webstore_private::GetEphemeralAppsEnabled; 42 api::webstore_private::GetEphemeralAppsEnabled;
43 namespace GetIsLauncherEnabled = api::webstore_private::GetIsLauncherEnabled; 43 namespace GetIsLauncherEnabled = api::webstore_private::GetIsLauncherEnabled;
44 namespace GetStoreLogin = api::webstore_private::GetStoreLogin; 44 namespace GetStoreLogin = api::webstore_private::GetStoreLogin;
45 namespace GetWebGLStatus = api::webstore_private::GetWebGLStatus; 45 namespace GetWebGLStatus = api::webstore_private::GetWebGLStatus;
46 namespace IsInIncognitoMode = api::webstore_private::IsInIncognitoMode; 46 namespace IsInIncognitoMode = api::webstore_private::IsInIncognitoMode;
47 namespace LaunchEphemeralApp = api::webstore_private::LaunchEphemeralApp; 47 namespace LaunchEphemeralApp = api::webstore_private::LaunchEphemeralApp;
48 namespace SetStoreLogin = api::webstore_private::SetStoreLogin; 48 namespace SetStoreLogin = api::webstore_private::SetStoreLogin;
49 namespace ShowPermissionPromptForDelegatedInstall =
50 api::webstore_private::ShowPermissionPromptForDelegatedInstall;
49 51
50 namespace { 52 namespace {
51 53
52 // Holds the Approvals between the time we prompt and start the installs. 54 // Holds the Approvals between the time we prompt and start the installs.
53 class PendingApprovals { 55 class PendingApprovals {
54 public: 56 public:
55 PendingApprovals(); 57 PendingApprovals();
56 ~PendingApprovals(); 58 ~PendingApprovals();
57 59
58 void PushApproval(scoped_ptr<WebstoreInstaller::Approval> approval); 60 void PushApproval(scoped_ptr<WebstoreInstaller::Approval> approval);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return api::webstore_private::RESULT_UNSUPPORTED_EXTENSION_TYPE; 128 return api::webstore_private::RESULT_UNSUPPORTED_EXTENSION_TYPE;
127 case webstore_install::INSTALL_IN_PROGRESS: 129 case webstore_install::INSTALL_IN_PROGRESS:
128 return api::webstore_private::RESULT_INSTALL_IN_PROGRESS; 130 return api::webstore_private::RESULT_INSTALL_IN_PROGRESS;
129 case webstore_install::LAUNCH_IN_PROGRESS: 131 case webstore_install::LAUNCH_IN_PROGRESS:
130 return api::webstore_private::RESULT_LAUNCH_IN_PROGRESS; 132 return api::webstore_private::RESULT_LAUNCH_IN_PROGRESS;
131 } 133 }
132 NOTREACHED(); 134 NOTREACHED();
133 return api::webstore_private::RESULT_NONE; 135 return api::webstore_private::RESULT_NONE;
134 } 136 }
135 137
138 api::webstore_private::Result WebstoreInstallHelperResultToApiResult(
139 WebstoreInstallHelper::Delegate::InstallHelperResultCode result) {
140 switch (result) {
141 case WebstoreInstallHelper::Delegate::UNKNOWN_ERROR:
142 return api::webstore_private::RESULT_UNKNOWN_ERROR;
143 case WebstoreInstallHelper::Delegate::ICON_ERROR:
144 return api::webstore_private::RESULT_ICON_ERROR;
145 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR:
146 return api::webstore_private::RESULT_MANIFEST_ERROR;
147 }
148 NOTREACHED();
149 return api::webstore_private::RESULT_NONE;
150 }
151
136 static base::LazyInstance<PendingApprovals> g_pending_approvals = 152 static base::LazyInstance<PendingApprovals> g_pending_approvals =
137 LAZY_INSTANCE_INITIALIZER; 153 LAZY_INSTANCE_INITIALIZER;
138 154
139 // A preference set by the web store to indicate login information for 155 // A preference set by the web store to indicate login information for
140 // purchased apps. 156 // purchased apps.
141 const char kWebstoreLogin[] = "extensions.webstore_login"; 157 const char kWebstoreLogin[] = "extensions.webstore_login";
142 const char kAlreadyInstalledError[] = "This item is already installed"; 158 const char kAlreadyInstalledError[] = "This item is already installed";
143 const char kCannotSpecifyIconDataAndUrlError[] = 159 const char kCannotSpecifyIconDataAndUrlError[] =
144 "You cannot specify both icon data and an icon url"; 160 "You cannot specify both icon data and an icon url";
145 const char kInvalidIconUrlError[] = "Invalid icon url"; 161 const char kInvalidIconUrlError[] = "Invalid icon url";
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); 315 ExtensionInstallPrompt::GetDefaultShowDialogCallback());
300 // Control flow finishes up in InstallUIProceed or InstallUIAbort. 316 // Control flow finishes up in InstallUIProceed or InstallUIAbort.
301 } 317 }
302 318
303 void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseFailure( 319 void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseFailure(
304 const std::string& id, 320 const std::string& id,
305 WebstoreInstallHelper::Delegate::InstallHelperResultCode result, 321 WebstoreInstallHelper::Delegate::InstallHelperResultCode result,
306 const std::string& error_message) { 322 const std::string& error_message) {
307 CHECK_EQ(params_->details.id, id); 323 CHECK_EQ(params_->details.id, id);
308 324
309 // Map from WebstoreInstallHelper's result codes to ours. 325 Respond(BuildResponseForError(WebstoreInstallHelperResultToApiResult(result),
310 api::webstore_private::Result api_result = 326 error_message));
311 api::webstore_private::RESULT_NONE;
312 switch (result) {
313 case WebstoreInstallHelper::Delegate::UNKNOWN_ERROR:
314 api_result = api::webstore_private::RESULT_UNKNOWN_ERROR;
315 break;
316 case WebstoreInstallHelper::Delegate::ICON_ERROR:
317 api_result = api::webstore_private::RESULT_ICON_ERROR;
318 break;
319 case WebstoreInstallHelper::Delegate::MANIFEST_ERROR:
320 api_result = api::webstore_private::RESULT_MANIFEST_ERROR;
321 break;
322 }
323 DCHECK_NE(api_result, api::webstore_private::RESULT_NONE);
324 Respond(BuildResponseForError(api_result, error_message));
325 327
326 // Matches the AddRef in Run(). 328 // Matches the AddRef in Run().
327 Release(); 329 Release();
328 } 330 }
329 331
330 void WebstorePrivateBeginInstallWithManifest3Function::InstallUIProceed() { 332 void WebstorePrivateBeginInstallWithManifest3Function::InstallUIProceed() {
331 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in 333 // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in
332 // the future we may also want to add time-based expiration, where a whitelist 334 // the future we may also want to add time-based expiration, where a whitelist
333 // entry is only valid for some number of minutes. 335 // entry is only valid for some number of minutes.
334 scoped_ptr<WebstoreInstaller::Approval> approval( 336 scoped_ptr<WebstoreInstaller::Approval> approval(
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 // Matches the AddRef in Run(). 511 // Matches the AddRef in Run().
510 Release(); 512 Release();
511 } 513 }
512 514
513 void WebstorePrivateCompleteInstallFunction::OnInstallSuccess( 515 void WebstorePrivateCompleteInstallFunction::OnInstallSuccess(
514 const std::string& id) { 516 const std::string& id) {
515 if (test_webstore_installer_delegate) 517 if (test_webstore_installer_delegate)
516 test_webstore_installer_delegate->OnExtensionInstallSuccess(id); 518 test_webstore_installer_delegate->OnExtensionInstallSuccess(id);
517 } 519 }
518 520
521 WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
522 WebstorePrivateShowPermissionPromptForDelegatedInstallFunction() {
523 }
524
525 WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
526 ~WebstorePrivateShowPermissionPromptForDelegatedInstallFunction() {
527 }
528
529 ExtensionFunction::ResponseAction
530 WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::Run() {
not at google - send to devlin 2015/02/24 18:30:00 Is there a nice way to factor this that shares the
Marc Treib 2015/02/25 13:38:47 Done (not sure on the "nice" part, though). I've e
531 params_ = ShowPermissionPromptForDelegatedInstall::Params::Create(*args_);
532 EXTENSION_FUNCTION_VALIDATE(params_);
533
534 if (!crx_file::id_util::IdIsValid(params_->details.id)) {
535 return RespondNow(BuildResponse(api::webstore_private::RESULT_INVALID_ID,
536 kInvalidIdError));
537 }
538
539 if (params_->details.icon_data && params_->details.icon_url) {
540 return RespondNow(BuildResponse(api::webstore_private::RESULT_ICON_ERROR,
541 kCannotSpecifyIconDataAndUrlError));
542 }
543
544 GURL icon_url;
545 if (params_->details.icon_url) {
546 std::string tmp_url;
not at google - send to devlin 2015/02/24 18:30:00 Unused? (also unused above)
Marc Treib 2015/02/25 13:38:47 Done, thanks! (copy&paste ftl)
547 icon_url = source_url().Resolve(*params_->details.icon_url);
548 if (!icon_url.is_valid()) {
549 return RespondNow(BuildResponse(
550 api::webstore_private::RESULT_INVALID_ICON_URL,
551 kInvalidIconUrlError));
552 }
553 }
554
555 std::string icon_data = params_->details.icon_data ?
556 *params_->details.icon_data : std::string();
557
558 net::URLRequestContextGetter* context_getter = NULL;
559 if (!icon_url.is_empty())
560 context_getter = browser_context()->GetRequestContext();
561
562 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper(
563 this, params_->details.id, params_->details.manifest, icon_data, icon_url,
564 context_getter);
565
566 // The helper will call us back via OnWebstoreParseSuccess or
567 // OnWebstoreParseFailure.
568 helper->Start();
569
570 // Matched with a Release in OnWebstoreParseSuccess/OnWebstoreParseFailure.
571 AddRef();
572
573 // The response is sent asynchronously in OnWebstoreParseSuccess/
574 // OnWebstoreParseFailure.
575 return RespondLater();
576 }
577
578 void WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
579 OnWebstoreParseSuccess(const std::string& id,
580 const SkBitmap& icon,
581 base::DictionaryValue* parsed_manifest) {
582 CHECK_EQ(params_->details.id, id);
583 CHECK(parsed_manifest);
584 icon_ = icon;
585 parsed_manifest_.reset(parsed_manifest);
586
587 std::string localized_name = params_->details.localized_name ?
588 *params_->details.localized_name : std::string();
589
590 std::string error;
591 dummy_extension_ = ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
592 parsed_manifest_.get(),
593 Extension::FROM_WEBSTORE,
594 id,
595 localized_name,
596 std::string(),
597 &error);
598
599 if (!dummy_extension_.get()) {
600 OnWebstoreParseFailure(params_->details.id,
601 WebstoreInstallHelper::Delegate::MANIFEST_ERROR,
602 kInvalidManifestError);
603 return;
604 }
605
606 content::WebContents* web_contents = GetAssociatedWebContents();
607 if (!web_contents) {
608 // The browser window has gone away.
609 Respond(BuildResponse(api::webstore_private::RESULT_USER_CANCELLED,
610 kUserCancelledError));
611 // Matches the AddRef in Run().
612 Release();
613 return;
614 }
615 install_prompt_.reset(new ExtensionInstallPrompt(web_contents));
616 install_prompt_->ConfirmPermissionsForDelegatedInstall(
617 this, dummy_extension_.get(), params_->details.delegated_user, &icon_);
618 // Control flow finishes up in InstallUIProceed or InstallUIAbort.
619 }
620
621 void WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
622 OnWebstoreParseFailure(
623 const std::string& id,
624 WebstoreInstallHelper::Delegate::InstallHelperResultCode result,
625 const std::string& error_message) {
626 CHECK_EQ(params_->details.id, id);
627
628 Respond(BuildResponse(WebstoreInstallHelperResultToApiResult(result),
629 error_message));
630
631 // Matches the AddRef in Run().
632 Release();
633 }
634
635 void WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
636 InstallUIProceed() {
637 Respond(BuildResponse(api::webstore_private::RESULT_SUCCESS, std::string()));
638
639 // Matches the AddRef in Run().
640 Release();
641 }
642
643 void WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::
644 InstallUIAbort(bool user_initiated) {
645 Respond(BuildResponse(api::webstore_private::RESULT_USER_CANCELLED,
646 kUserCancelledError));
647
648 // Matches the AddRef in Run().
649 Release();
650 }
651
652 ExtensionFunction::ResponseValue
653 WebstorePrivateShowPermissionPromptForDelegatedInstallFunction::BuildResponse(
654 api::webstore_private::Result result, const std::string& error) {
655 if (result != api::webstore_private::RESULT_SUCCESS) {
656 return ErrorWithArguments(
657 ShowPermissionPromptForDelegatedInstall::Results::Create(result),
658 error);
659 }
660 return ArgumentList(
661 ShowPermissionPromptForDelegatedInstall::Results::Create(result));
662 }
663
519 WebstorePrivateEnableAppLauncherFunction:: 664 WebstorePrivateEnableAppLauncherFunction::
520 WebstorePrivateEnableAppLauncherFunction() : chrome_details_(this) {} 665 WebstorePrivateEnableAppLauncherFunction() : chrome_details_(this) {}
521 666
522 WebstorePrivateEnableAppLauncherFunction:: 667 WebstorePrivateEnableAppLauncherFunction::
523 ~WebstorePrivateEnableAppLauncherFunction() {} 668 ~WebstorePrivateEnableAppLauncherFunction() {}
524 669
525 ExtensionFunction::ResponseAction 670 ExtensionFunction::ResponseAction
526 WebstorePrivateEnableAppLauncherFunction::Run() { 671 WebstorePrivateEnableAppLauncherFunction::Run() {
527 AppListService* app_list_service = AppListService::Get( 672 AppListService* app_list_service = AppListService::Get(
528 GetHostDesktopTypeForWebContents( 673 GetHostDesktopTypeForWebContents(
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 WebstorePrivateGetEphemeralAppsEnabledFunction:: 834 WebstorePrivateGetEphemeralAppsEnabledFunction::
690 ~WebstorePrivateGetEphemeralAppsEnabledFunction() {} 835 ~WebstorePrivateGetEphemeralAppsEnabledFunction() {}
691 836
692 ExtensionFunction::ResponseAction 837 ExtensionFunction::ResponseAction
693 WebstorePrivateGetEphemeralAppsEnabledFunction::Run() { 838 WebstorePrivateGetEphemeralAppsEnabledFunction::Run() {
694 return RespondNow(ArgumentList(GetEphemeralAppsEnabled::Results::Create( 839 return RespondNow(ArgumentList(GetEphemeralAppsEnabled::Results::Create(
695 EphemeralAppLauncher::IsFeatureEnabled()))); 840 EphemeralAppLauncher::IsFeatureEnabled())));
696 } 841 }
697 842
698 } // namespace extensions 843 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698