| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h" |
| |
| #include "apps/app_launcher.h" |
| #include "base/bind_helpers.h" |
| #include "base/command_line.h" |
| #include "base/lazy_instance.h" |
| #include "base/memory/scoped_vector.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "chrome/browser/about_flags.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/crx_installer.h" |
| #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| #include "chrome/browser/extensions/extension_prefs.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_system.h" |
| #include "chrome/browser/extensions/webstore_installer.h" |
| #include "chrome/browser/gpu/gpu_feature_checker.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/signin/signin_manager.h" |
| #include "chrome/browser/signin/signin_manager_factory.h" |
| #include "chrome/browser/sync/profile_sync_service.h" |
| #include "chrome/browser/sync/profile_sync_service_factory.h" |
| #include "chrome/browser/ui/app_list/app_list_service.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/extensions/extension_l10n_util.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/public/browser/gpu_data_manager.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/web_contents.h" |
| #include "extensions/common/error_utils.h" |
| #include "grit/chromium_strings.h" |
| #include "grit/generated_resources.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| using content::GpuDataManager; |
| |
| namespace extensions { |
| |
| namespace BeginInstallWithManifest3 = |
| api::webstore_private::BeginInstallWithManifest3; |
| namespace CompleteInstall = api::webstore_private::CompleteInstall; |
| namespace GetBrowserLogin = api::webstore_private::GetBrowserLogin; |
| namespace GetIsLauncherEnabled = api::webstore_private::GetIsLauncherEnabled; |
| namespace GetStoreLogin = api::webstore_private::GetStoreLogin; |
| namespace GetWebGLStatus = api::webstore_private::GetWebGLStatus; |
| namespace InstallBundle = api::webstore_private::InstallBundle; |
| namespace IsInIncognitoMode = api::webstore_private::IsInIncognitoMode; |
| namespace SetStoreLogin = api::webstore_private::SetStoreLogin; |
| |
| namespace { |
| |
| // Holds the Approvals between the time we prompt and start the installs. |
| class PendingApprovals { |
| public: |
| PendingApprovals(); |
| ~PendingApprovals(); |
| |
| void PushApproval(scoped_ptr<WebstoreInstaller::Approval> approval); |
| scoped_ptr<WebstoreInstaller::Approval> PopApproval( |
| Profile* profile, const std::string& id); |
| private: |
| typedef ScopedVector<WebstoreInstaller::Approval> ApprovalList; |
| |
| ApprovalList approvals_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PendingApprovals); |
| }; |
| |
| PendingApprovals::PendingApprovals() {} |
| PendingApprovals::~PendingApprovals() {} |
| |
| void PendingApprovals::PushApproval( |
| scoped_ptr<WebstoreInstaller::Approval> approval) { |
| approvals_.push_back(approval.release()); |
| } |
| |
| scoped_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval( |
| Profile* profile, const std::string& id) { |
| for (size_t i = 0; i < approvals_.size(); ++i) { |
| WebstoreInstaller::Approval* approval = approvals_[i]; |
| if (approval->extension_id == id && |
| profile->IsSameProfile(approval->profile)) { |
| approvals_.weak_erase(approvals_.begin() + i); |
| return scoped_ptr<WebstoreInstaller::Approval>(approval); |
| } |
| } |
| return scoped_ptr<WebstoreInstaller::Approval>(); |
| } |
| |
| // Uniquely holds the profile and extension id of an install between the time we |
| // prompt and complete the installs. |
| class PendingInstalls { |
| public: |
| PendingInstalls(); |
| ~PendingInstalls(); |
| |
| bool InsertInstall(Profile* profile, const std::string& id); |
| void EraseInstall(Profile* profile, const std::string& id); |
| private: |
| typedef std::pair<Profile*, std::string> ProfileAndExtensionId; |
| typedef std::vector<ProfileAndExtensionId> InstallList; |
| |
| InstallList::iterator FindInstall(Profile* profile, const std::string& id); |
| |
| InstallList installs_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PendingInstalls); |
| }; |
| |
| PendingInstalls::PendingInstalls() {} |
| PendingInstalls::~PendingInstalls() {} |
| |
| // Returns true and inserts the profile/id pair if it is not present. Otherwise |
| // returns false. |
| bool PendingInstalls::InsertInstall(Profile* profile, const std::string& id) { |
| if (FindInstall(profile, id) != installs_.end()) |
| return false; |
| installs_.push_back(make_pair(profile, id)); |
| return true; |
| } |
| |
| // Removes the given profile/id pair. |
| void PendingInstalls::EraseInstall(Profile* profile, const std::string& id) { |
| InstallList::iterator it = FindInstall(profile, id); |
| if (it != installs_.end()) |
| installs_.erase(it); |
| } |
| |
| PendingInstalls::InstallList::iterator PendingInstalls::FindInstall( |
| Profile* profile, |
| const std::string& id) { |
| for (size_t i = 0; i < installs_.size(); ++i) { |
| ProfileAndExtensionId install = installs_[i]; |
| if (install.second == id && profile->IsSameProfile(install.first)) |
| return (installs_.begin() + i); |
| } |
| return installs_.end(); |
| } |
| |
| static base::LazyInstance<PendingApprovals> g_pending_approvals = |
| LAZY_INSTANCE_INITIALIZER; |
| static base::LazyInstance<PendingInstalls> g_pending_installs = |
| LAZY_INSTANCE_INITIALIZER; |
| |
| // A preference set by the web store to indicate login information for |
| // purchased apps. |
| const char kWebstoreLogin[] = "extensions.webstore_login"; |
| const char kAlreadyInstalledError[] = "This item is already installed"; |
| const char kCannotSpecifyIconDataAndUrlError[] = |
| "You cannot specify both icon data and an icon url"; |
| const char kInvalidIconUrlError[] = "Invalid icon url"; |
| const char kInvalidIdError[] = "Invalid id"; |
| const char kInvalidManifestError[] = "Invalid manifest"; |
| const char kNoPreviousBeginInstallWithManifestError[] = |
| "* does not match a previous call to beginInstallWithManifest3"; |
| const char kUserCancelledError[] = "User cancelled install"; |
| |
| WebstoreInstaller::Delegate* test_webstore_installer_delegate = NULL; |
| |
| // We allow the web store to set a string containing login information when a |
| // purchase is made, so that when a user logs into sync with a different |
| // account we can recognize the situation. The Get function returns the login if |
| // there was previously stored data, or an empty string otherwise. The Set will |
| // overwrite any previous login. |
| std::string GetWebstoreLogin(Profile* profile) { |
| if (profile->GetPrefs()->HasPrefPath(kWebstoreLogin)) |
| return profile->GetPrefs()->GetString(kWebstoreLogin); |
| return std::string(); |
| } |
| |
| void SetWebstoreLogin(Profile* profile, const std::string& login) { |
| profile->GetPrefs()->SetString(kWebstoreLogin, login); |
| } |
| |
| } // namespace |
| |
| // static |
| void WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting( |
| WebstoreInstaller::Delegate* delegate) { |
| test_webstore_installer_delegate = delegate; |
| } |
| |
| // static |
| scoped_ptr<WebstoreInstaller::Approval> |
| WebstorePrivateApi::PopApprovalForTesting( |
| Profile* profile, const std::string& extension_id) { |
| return g_pending_approvals.Get().PopApproval(profile, extension_id); |
| } |
| |
| WebstorePrivateInstallBundleFunction::WebstorePrivateInstallBundleFunction() {} |
| WebstorePrivateInstallBundleFunction::~WebstorePrivateInstallBundleFunction() {} |
| |
| bool WebstorePrivateInstallBundleFunction::RunImpl() { |
| scoped_ptr<InstallBundle::Params> params( |
| InstallBundle::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params); |
| |
| BundleInstaller::ItemList items; |
| if (!ReadBundleInfo(*params, &items)) |
| return false; |
| |
| bundle_ = new BundleInstaller(GetCurrentBrowser(), items); |
| |
| AddRef(); // Balanced in OnBundleInstallCompleted / OnBundleInstallCanceled. |
| |
| bundle_->PromptForApproval(this); |
| return true; |
| } |
| |
| bool WebstorePrivateInstallBundleFunction:: |
| ReadBundleInfo(const InstallBundle::Params& params, |
| BundleInstaller::ItemList* items) { |
| for (size_t i = 0; i < params.details.size(); ++i) { |
| BundleInstaller::Item item; |
| item.id = params.details[i]->id; |
| item.manifest = params.details[i]->manifest; |
| item.localized_name = params.details[i]->localized_name; |
| items->push_back(item); |
| } |
| |
| return true; |
| } |
| |
| void WebstorePrivateInstallBundleFunction::OnBundleInstallApproved() { |
| bundle_->CompleteInstall( |
| &(dispatcher()->delegate()->GetAssociatedWebContents()->GetController()), |
| this); |
| } |
| |
| void WebstorePrivateInstallBundleFunction::OnBundleInstallCanceled( |
| bool user_initiated) { |
| if (user_initiated) |
| error_ = "user_canceled"; |
| else |
| error_ = "unknown_error"; |
| |
| SendResponse(false); |
| |
| Release(); // Balanced in RunImpl(). |
| } |
| |
| void WebstorePrivateInstallBundleFunction::OnBundleInstallCompleted() { |
| SendResponse(true); |
| |
| Release(); // Balanced in RunImpl(). |
| } |
| |
| WebstorePrivateBeginInstallWithManifest3Function:: |
| WebstorePrivateBeginInstallWithManifest3Function() {} |
| |
| WebstorePrivateBeginInstallWithManifest3Function:: |
| ~WebstorePrivateBeginInstallWithManifest3Function() {} |
| |
| bool WebstorePrivateBeginInstallWithManifest3Function::RunImpl() { |
| params_ = BeginInstallWithManifest3::Params::Create(*args_); |
| EXTENSION_FUNCTION_VALIDATE(params_); |
| |
| if (!extensions::Extension::IdIsValid(params_->details.id)) { |
| SetResultCode(INVALID_ID); |
| error_ = kInvalidIdError; |
| return false; |
| } |
| |
| if (params_->details.icon_data && params_->details.icon_url) { |
| SetResultCode(ICON_ERROR); |
| error_ = kCannotSpecifyIconDataAndUrlError; |
| return false; |
| } |
| |
| GURL icon_url; |
| if (params_->details.icon_url) { |
| std::string tmp_url; |
| icon_url = source_url().Resolve(*params_->details.icon_url); |
| if (!icon_url.is_valid()) { |
| SetResultCode(INVALID_ICON_URL); |
| error_ = kInvalidIconUrlError; |
| return false; |
| } |
| } |
| |
| std::string icon_data = params_->details.icon_data ? |
| *params_->details.icon_data : std::string(); |
| |
| ExtensionService* service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| if (service->GetInstalledExtension(params_->details.id) || |
| !g_pending_installs.Get().InsertInstall(profile_, params_->details.id)) { |
| SetResultCode(ALREADY_INSTALLED); |
| error_ = kAlreadyInstalledError; |
| return false; |
| } |
| |
| net::URLRequestContextGetter* context_getter = NULL; |
| if (!icon_url.is_empty()) |
| context_getter = profile()->GetRequestContext(); |
| |
| scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( |
| this, params_->details.id, params_->details.manifest, icon_data, icon_url, |
| context_getter); |
| |
| // The helper will call us back via OnWebstoreParseSuccess or |
| // OnWebstoreParseFailure. |
| helper->Start(); |
| |
| // Matched with a Release in OnWebstoreParseSuccess/OnWebstoreParseFailure. |
| AddRef(); |
| |
| // The response is sent asynchronously in OnWebstoreParseSuccess/ |
| // OnWebstoreParseFailure. |
| return true; |
| } |
| |
| const char* WebstorePrivateBeginInstallWithManifest3Function:: |
| ResultCodeToString(ResultCode code) { |
| switch (code) { |
| case ERROR_NONE: |
| return ""; |
| case UNKNOWN_ERROR: |
| return "unknown_error"; |
| case USER_CANCELLED: |
| return "user_cancelled"; |
| case MANIFEST_ERROR: |
| return "manifest_error"; |
| case ICON_ERROR: |
| return "icon_error"; |
| case INVALID_ID: |
| return "invalid_id"; |
| case PERMISSION_DENIED: |
| return "permission_denied"; |
| case INVALID_ICON_URL: |
| return "invalid_icon_url"; |
| case SIGNIN_FAILED: |
| return "signin_failed"; |
| case ALREADY_INSTALLED: |
| return "already_installed"; |
| } |
| NOTREACHED(); |
| return ""; |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::SetResultCode( |
| ResultCode code) { |
| results_ = BeginInstallWithManifest3::Results::Create( |
| ResultCodeToString(code)); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseSuccess( |
| const std::string& id, |
| const SkBitmap& icon, |
| base::DictionaryValue* parsed_manifest) { |
| CHECK_EQ(params_->details.id, id); |
| CHECK(parsed_manifest); |
| icon_ = icon; |
| parsed_manifest_.reset(parsed_manifest); |
| |
| std::string localized_name = params_->details.localized_name ? |
| *params_->details.localized_name : std::string(); |
| |
| std::string error; |
| dummy_extension_ = ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( |
| parsed_manifest_.get(), |
| Extension::FROM_WEBSTORE, |
| id, |
| localized_name, |
| std::string(), |
| &error); |
| |
| if (!dummy_extension_.get()) { |
| OnWebstoreParseFailure(params_->details.id, |
| WebstoreInstallHelper::Delegate::MANIFEST_ERROR, |
| kInvalidManifestError); |
| return; |
| } |
| |
| SigninManagerBase* signin_manager = |
| SigninManagerFactory::GetForProfile(profile()); |
| if (dummy_extension_->is_platform_app() && |
| signin_manager && |
| signin_manager->GetAuthenticatedUsername().empty() && |
| signin_manager->AuthInProgress()) { |
| signin_tracker_.reset(new SigninTracker(profile(), this)); |
| return; |
| } |
| |
| SigninCompletedOrNotNeeded(); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseFailure( |
| const std::string& id, |
| WebstoreInstallHelper::Delegate::InstallHelperResultCode result_code, |
| const std::string& error_message) { |
| CHECK_EQ(params_->details.id, id); |
| |
| // Map from WebstoreInstallHelper's result codes to ours. |
| switch (result_code) { |
| case WebstoreInstallHelper::Delegate::UNKNOWN_ERROR: |
| SetResultCode(UNKNOWN_ERROR); |
| break; |
| case WebstoreInstallHelper::Delegate::ICON_ERROR: |
| SetResultCode(ICON_ERROR); |
| break; |
| case WebstoreInstallHelper::Delegate::MANIFEST_ERROR: |
| SetResultCode(MANIFEST_ERROR); |
| break; |
| default: |
| CHECK(false); |
| } |
| error_ = error_message; |
| g_pending_installs.Get().EraseInstall(profile_, id); |
| SendResponse(false); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::SigninFailed( |
| const GoogleServiceAuthError& error) { |
| signin_tracker_.reset(); |
| |
| SetResultCode(SIGNIN_FAILED); |
| error_ = error.ToString(); |
| g_pending_installs.Get().EraseInstall(profile_, params_->details.id); |
| SendResponse(false); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::SigninSuccess() { |
| signin_tracker_.reset(); |
| |
| SigninCompletedOrNotNeeded(); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function:: |
| SigninCompletedOrNotNeeded() { |
| content::WebContents* web_contents = GetAssociatedWebContents(); |
| if (!web_contents) // The browser window has gone away. |
| return; |
| install_prompt_.reset(new ExtensionInstallPrompt(web_contents)); |
| install_prompt_->ConfirmWebstoreInstall( |
| this, |
| dummy_extension_.get(), |
| &icon_, |
| ExtensionInstallPrompt::GetDefaultShowDialogCallback()); |
| // Control flow finishes up in InstallUIProceed or InstallUIAbort. |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::InstallUIProceed() { |
| // This gets cleared in CrxInstaller::ConfirmInstall(). TODO(asargent) - in |
| // the future we may also want to add time-based expiration, where a whitelist |
| // entry is only valid for some number of minutes. |
| scoped_ptr<WebstoreInstaller::Approval> approval( |
| WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
| profile(), params_->details.id, parsed_manifest_.Pass(), false)); |
| approval->use_app_installed_bubble = params_->details.app_install_bubble; |
| approval->enable_launcher = params_->details.enable_launcher; |
| // If we are enabling the launcher, we should not show the app list in order |
| // to train the user to open it themselves at least once. |
| approval->skip_post_install_ui = params_->details.enable_launcher; |
| approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); |
| g_pending_approvals.Get().PushApproval(approval.Pass()); |
| |
| SetResultCode(ERROR_NONE); |
| SendResponse(true); |
| |
| // The Permissions_Install histogram is recorded from the ExtensionService |
| // for all extension installs, so we only need to record the web store |
| // specific histogram here. |
| ExtensionService::RecordPermissionMessagesHistogram( |
| dummy_extension_.get(), "Extensions.Permissions_WebStoreInstall"); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| void WebstorePrivateBeginInstallWithManifest3Function::InstallUIAbort( |
| bool user_initiated) { |
| error_ = kUserCancelledError; |
| SetResultCode(USER_CANCELLED); |
| g_pending_installs.Get().EraseInstall(profile_, params_->details.id); |
| SendResponse(false); |
| |
| // The web store install histograms are a subset of the install histograms. |
| // We need to record both histograms here since CrxInstaller::InstallUIAbort |
| // is never called for web store install cancellations. |
| std::string histogram_name = user_initiated ? |
| "Extensions.Permissions_WebStoreInstallCancel" : |
| "Extensions.Permissions_WebStoreInstallAbort"; |
| ExtensionService::RecordPermissionMessagesHistogram(dummy_extension_.get(), |
| histogram_name.c_str()); |
| |
| histogram_name = user_initiated ? |
| "Extensions.Permissions_InstallCancel" : |
| "Extensions.Permissions_InstallAbort"; |
| ExtensionService::RecordPermissionMessagesHistogram(dummy_extension_.get(), |
| histogram_name.c_str()); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| WebstorePrivateCompleteInstallFunction:: |
| WebstorePrivateCompleteInstallFunction() {} |
| |
| WebstorePrivateCompleteInstallFunction:: |
| ~WebstorePrivateCompleteInstallFunction() {} |
| |
| bool WebstorePrivateCompleteInstallFunction::RunImpl() { |
| scoped_ptr<CompleteInstall::Params> params( |
| CompleteInstall::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params); |
| if (!extensions::Extension::IdIsValid(params->expected_id)) { |
| error_ = kInvalidIdError; |
| return false; |
| } |
| |
| approval_ = g_pending_approvals.Get().PopApproval(profile(), |
| params->expected_id).Pass(); |
| if (!approval_) { |
| error_ = ErrorUtils::FormatErrorMessage( |
| kNoPreviousBeginInstallWithManifestError, params->expected_id); |
| return false; |
| } |
| |
| // Balanced in OnExtensionInstallSuccess() or OnExtensionInstallFailure(). |
| AddRef(); |
| |
| if (approval_->enable_launcher) |
| AppListService::Get()->EnableAppList(profile()); |
| |
| if (apps::IsAppLauncherEnabled() && approval_->manifest->is_app()) { |
| // Show the app list to show download is progressing. Don't show the app |
| // list on first app install so users can be trained to open it themselves. |
| if (approval_->enable_launcher) |
| AppListService::Get()->CreateForProfile(profile()); |
| else |
| AppListService::Get()->ShowForProfile(profile()); |
| } |
| |
| // The extension will install through the normal extension install flow, but |
| // the whitelist entry will bypass the normal permissions install dialog. |
| scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| profile(), this, |
| &(dispatcher()->delegate()->GetAssociatedWebContents()->GetController()), |
| params->expected_id, approval_.Pass(), |
| WebstoreInstaller::INSTALL_SOURCE_OTHER); |
| installer->Start(); |
| |
| return true; |
| } |
| |
| void WebstorePrivateCompleteInstallFunction::OnExtensionInstallSuccess( |
| const std::string& id) { |
| if (test_webstore_installer_delegate) |
| test_webstore_installer_delegate->OnExtensionInstallSuccess(id); |
| |
| LOG(INFO) << "Install success, sending response"; |
| g_pending_installs.Get().EraseInstall(profile_, id); |
| SendResponse(true); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| void WebstorePrivateCompleteInstallFunction::OnExtensionInstallFailure( |
| const std::string& id, |
| const std::string& error, |
| WebstoreInstaller::FailureReason reason) { |
| if (test_webstore_installer_delegate) { |
| test_webstore_installer_delegate->OnExtensionInstallFailure( |
| id, error, reason); |
| } |
| |
| error_ = error; |
| LOG(INFO) << "Install failed, sending response"; |
| g_pending_installs.Get().EraseInstall(profile_, id); |
| SendResponse(false); |
| |
| // Matches the AddRef in RunImpl(). |
| Release(); |
| } |
| |
| WebstorePrivateEnableAppLauncherFunction:: |
| WebstorePrivateEnableAppLauncherFunction() {} |
| |
| WebstorePrivateEnableAppLauncherFunction:: |
| ~WebstorePrivateEnableAppLauncherFunction() {} |
| |
| bool WebstorePrivateEnableAppLauncherFunction::RunImpl() { |
| AppListService::Get()->EnableAppList(profile()); |
| return true; |
| } |
| |
| bool WebstorePrivateGetBrowserLoginFunction::RunImpl() { |
| GetBrowserLogin::Results::Info info; |
| info.login = profile_->GetOriginalProfile()->GetPrefs()->GetString( |
| prefs::kGoogleServicesUsername); |
| results_ = GetBrowserLogin::Results::Create(info); |
| return true; |
| } |
| |
| bool WebstorePrivateGetStoreLoginFunction::RunImpl() { |
| results_ = GetStoreLogin::Results::Create(GetWebstoreLogin(profile_)); |
| return true; |
| } |
| |
| bool WebstorePrivateSetStoreLoginFunction::RunImpl() { |
| scoped_ptr<SetStoreLogin::Params> params( |
| SetStoreLogin::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params); |
| SetWebstoreLogin(profile_, params->login); |
| return true; |
| } |
| |
| WebstorePrivateGetWebGLStatusFunction::WebstorePrivateGetWebGLStatusFunction() { |
| feature_checker_ = new GPUFeatureChecker( |
| gpu::GPU_FEATURE_TYPE_WEBGL, |
| base::Bind(&WebstorePrivateGetWebGLStatusFunction::OnFeatureCheck, |
| base::Unretained(this))); |
| } |
| |
| WebstorePrivateGetWebGLStatusFunction:: |
| ~WebstorePrivateGetWebGLStatusFunction() {} |
| |
| void WebstorePrivateGetWebGLStatusFunction::CreateResult(bool webgl_allowed) { |
| results_ = GetWebGLStatus::Results::Create(GetWebGLStatus::Results:: |
| ParseWebgl_status(webgl_allowed ? "webgl_allowed" : "webgl_blocked")); |
| } |
| |
| bool WebstorePrivateGetWebGLStatusFunction::RunImpl() { |
| feature_checker_->CheckGPUFeatureAvailability(); |
| return true; |
| } |
| |
| void WebstorePrivateGetWebGLStatusFunction:: |
| OnFeatureCheck(bool feature_allowed) { |
| CreateResult(feature_allowed); |
| SendResponse(true); |
| } |
| |
| bool WebstorePrivateGetIsLauncherEnabledFunction::RunImpl() { |
| results_ = GetIsLauncherEnabled::Results::Create( |
| apps::IsAppLauncherEnabled()); |
| return true; |
| } |
| |
| bool WebstorePrivateIsInIncognitoModeFunction::RunImpl() { |
| results_ = IsInIncognitoMode::Results::Create( |
| profile_ != profile_->GetOriginalProfile()); |
| return true; |
| } |
| |
| } // namespace extensions |