blob: a51bcdbe4d87994de5aa245c198eb946f3be3d88 [file] [log] [blame]
// Copyright 2015 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/dashboard_private/dashboard_private_api.h"
#include <utility>
#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/profiles/profile.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/common/extension.h"
#include "net/base/load_flags.h"
#include "url/gurl.h"
namespace extensions {
namespace ShowPermissionPromptForDelegatedInstall =
api::dashboard_private::ShowPermissionPromptForDelegatedInstall;
namespace {
// Error messages that can be returned by the API.
const char kDashboardInvalidIconUrlError[] = "Invalid icon url";
const char kDashboardInvalidIdError[] = "Invalid id";
const char kDashboardInvalidManifestError[] = "Invalid manifest";
const char kDashboardUserCancelledError[] = "User cancelled install";
api::dashboard_private::Result WebstoreInstallHelperResultToDashboardApiResult(
WebstoreInstallHelper::Delegate::InstallHelperResultCode result) {
switch (result) {
case WebstoreInstallHelper::Delegate::UNKNOWN_ERROR:
return api::dashboard_private::RESULT_UNKNOWN_ERROR;
case WebstoreInstallHelper::Delegate::ICON_ERROR:
return api::dashboard_private::RESULT_ICON_ERROR;
case WebstoreInstallHelper::Delegate::MANIFEST_ERROR:
return api::dashboard_private::RESULT_MANIFEST_ERROR;
}
NOTREACHED();
return api::dashboard_private::RESULT_NONE;
}
} // namespace
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction() {
}
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
~DashboardPrivateShowPermissionPromptForDelegatedInstallFunction() {
}
ExtensionFunction::ResponseAction
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::Run() {
params_ = Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(params_);
if (!crx_file::id_util::IdIsValid(params_->details.id)) {
return RespondNow(BuildResponse(api::dashboard_private::RESULT_INVALID_ID,
kDashboardInvalidIdError));
}
GURL icon_url;
if (params_->details.icon_url) {
icon_url = source_url().Resolve(*params_->details.icon_url);
if (!icon_url.is_valid()) {
return RespondNow(
BuildResponse(api::dashboard_private::RESULT_INVALID_ICON_URL,
kDashboardInvalidIconUrlError));
}
}
network::mojom::URLLoaderFactory* loader_factory = nullptr;
if (!icon_url.is_empty()) {
loader_factory =
content::BrowserContext::GetDefaultStoragePartition(browser_context())
->GetURLLoaderFactoryForBrowserProcess()
.get();
}
auto helper = base::MakeRefCounted<WebstoreInstallHelper>(
this, params_->details.id, params_->details.manifest, icon_url);
// The helper will call us back via OnWebstoreParseSuccess or
// OnWebstoreParseFailure.
helper->Start(loader_factory);
// Matched with a Release in OnWebstoreParseSuccess/OnWebstoreParseFailure.
AddRef();
// The response is sent asynchronously in OnWebstoreParseSuccess/
// OnWebstoreParseFailure.
return RespondLater();
}
void DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
OnWebstoreParseSuccess(
const std::string& id,
const SkBitmap& icon,
std::unique_ptr<base::DictionaryValue> parsed_manifest) {
CHECK_EQ(params_->details.id, id);
CHECK(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,
kDashboardInvalidManifestError);
return;
}
content::WebContents* web_contents = GetSenderWebContents();
if (!web_contents) {
// The browser window has gone away.
Respond(BuildResponse(api::dashboard_private::RESULT_USER_CANCELLED,
kDashboardUserCancelledError));
// Matches the AddRef in Run().
Release();
return;
}
std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt(
new ExtensionInstallPrompt::Prompt(
ExtensionInstallPrompt::DELEGATED_PERMISSIONS_PROMPT));
prompt->set_delegated_username(details().delegated_user);
install_prompt_.reset(new ExtensionInstallPrompt(web_contents));
install_prompt_->ShowDialog(
base::Bind(
&DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
OnInstallPromptDone,
this),
dummy_extension_.get(), &icon, std::move(prompt),
ExtensionInstallPrompt::GetDefaultShowDialogCallback());
// Control flow finishes up in OnInstallPromptDone().
}
void DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
OnWebstoreParseFailure(
const std::string& id,
WebstoreInstallHelper::Delegate::InstallHelperResultCode result,
const std::string& error_message) {
CHECK_EQ(params_->details.id, id);
Respond(BuildResponse(WebstoreInstallHelperResultToDashboardApiResult(result),
error_message));
// Matches the AddRef in Run().
Release();
}
void DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::
OnInstallPromptDone(ExtensionInstallPrompt::Result result) {
bool accepted = (result == ExtensionInstallPrompt::Result::ACCEPTED);
Respond(
BuildResponse(accepted ? api::dashboard_private::RESULT_EMPTY_STRING
: api::dashboard_private::RESULT_USER_CANCELLED,
accepted ? std::string() : kDashboardUserCancelledError));
Release(); // Matches the AddRef in Run().
}
ExtensionFunction::ResponseValue
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::BuildResponse(
api::dashboard_private::Result result, const std::string& error) {
// The web store expects an empty string on success.
if (result == api::dashboard_private::RESULT_EMPTY_STRING)
return ArgumentList(CreateResults(result));
return ErrorWithArguments(CreateResults(result), error);
}
std::unique_ptr<base::ListValue>
DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::CreateResults(
api::dashboard_private::Result result) const {
return ShowPermissionPromptForDelegatedInstall::Results::Create(result);
}
} // namespace extensions