blob: c7d8abdb46062716f111493aea2d46ba7223a9d6 [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/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 "net/url_request/url_request.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 kInvalidIconUrlError[] = "Invalid icon url";
const char kInvalidIdError[] = "Invalid id";
const char kInvalidManifestError[] = "Invalid manifest";
const char kUserCancelledError[] = "User cancelled install";
api::dashboard_private::Result WebstoreInstallHelperResultToApiResult(
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,
kInvalidIdError));
}
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,
kInvalidIconUrlError));
}
}
network::mojom::URLLoaderFactory* loader_factory = nullptr;
if (!icon_url.is_empty()) {
loader_factory =
content::BrowserContext::GetDefaultStoragePartition(browser_context())
->GetURLLoaderFactoryForBrowserProcess();
}
scoped_refptr<WebstoreInstallHelper> helper = new 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,
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,
Extension::FROM_WEBSTORE,
id,
localized_name,
std::string(),
&error);
if (!dummy_extension_.get()) {
OnWebstoreParseFailure(params_->details.id,
WebstoreInstallHelper::Delegate::MANIFEST_ERROR,
kInvalidManifestError);
return;
}
content::WebContents* web_contents = GetAssociatedWebContents();
if (!web_contents) {
// The browser window has gone away.
Respond(BuildResponse(api::dashboard_private::RESULT_USER_CANCELLED,
kUserCancelledError));
// 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(WebstoreInstallHelperResultToApiResult(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() : kUserCancelledError));
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