blob: 613ca1e1777faeda3c54e3ece7ae79c3e3f2f9bd [file] [log] [blame]
// Copyright 2022 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 <vector>
#include "chrome/browser/ash/crosapi/parent_access_ash.h"
#include "chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace crosapi {
crosapi::mojom::ParentAccessResultPtr DialogResultToParentAccessResult(
std::unique_ptr<ash::ParentAccessDialog::Result> result) {
crosapi::mojom::ParentAccessResultPtr parent_access_result;
switch (result->status) {
case ash::ParentAccessDialog::Result::Status::kApproved:
parent_access_result = mojom::ParentAccessResult::NewApproved(
crosapi::mojom::ParentAccessApprovedResult::New(
result->parent_access_token,
result->parent_access_token_expire_timestamp));
break;
case ash::ParentAccessDialog::Result::Status::kDeclined:
parent_access_result = mojom::ParentAccessResult::NewDeclined(
crosapi::mojom::ParentAccessDeclinedResult::New());
break;
case ash::ParentAccessDialog::Result::Status::kCanceled:
parent_access_result = mojom::ParentAccessResult::NewCanceled(
crosapi::mojom::ParentAccessCanceledResult::New());
break;
case ash::ParentAccessDialog::Result::Status::kError:
parent_access_result = mojom::ParentAccessResult::NewError(
crosapi::mojom::ParentAccessErrorResult::New(
crosapi::mojom::ParentAccessErrorResult::Type::kUnknown));
break;
case ash::ParentAccessDialog::Result::Status::kDisabled:
// TODO(b/262450337): Implement disabled case when extension approvals is
// implemented. Disabled state is not possible for the current callers of
// ParentAccessAsh.
NOTREACHED_NORETURN();
}
return parent_access_result;
}
crosapi::mojom::ParentAccessResultPtr ShowErrorToParentAccessResultError(
ash::ParentAccessDialogProvider::ShowError show_dialog_result) {
crosapi::mojom::ParentAccessResultPtr parent_access_result;
// This result indicates basic errors that can occur synchronously.
switch (show_dialog_result) {
case ash::ParentAccessDialogProvider::ShowError::kDialogAlreadyVisible:
parent_access_result = mojom::ParentAccessResult::NewError(
crosapi::mojom::ParentAccessErrorResult::New(
crosapi::mojom::ParentAccessErrorResult::Type::kAlreadyVisible));
break;
case ash::ParentAccessDialogProvider::ShowError::kNotAChildUser:
parent_access_result = mojom::ParentAccessResult::NewError(
crosapi::mojom::ParentAccessErrorResult::New(
crosapi::mojom::ParentAccessErrorResult::Type::kNotAChildUser));
break;
case ash::ParentAccessDialogProvider::ShowError::kNone:
// The dialog is showing successfully. Wait until we get the result from
// the dialog before running the crosapi callback. This will be handled
// in OnParentAccessDialogClosed.
break;
}
return parent_access_result;
}
ParentAccessAsh::ParentAccessAsh() = default;
ParentAccessAsh::~ParentAccessAsh() = default;
void ParentAccessAsh::BindReceiver(
mojo::PendingReceiver<mojom::ParentAccess> receiver) {
receivers_.Add(this, std::move(receiver));
}
// crosapi::mojom::ParentAccess:
void ParentAccessAsh::GetWebsiteParentApproval(
const GURL& url,
const std::u16string& child_display_name,
const gfx::ImageSkia& favicon,
GetWebsiteParentApprovalCallback callback) {
// Encode the favicon as a PNG bitmap.
std::vector<uint8_t> favicon_bitmap;
gfx::PNGCodec::FastEncodeBGRASkBitmap(*favicon.bitmap(), false,
&favicon_bitmap);
// Assemble the parameters for a website access request.
parent_access_ui::mojom::ParentAccessParamsPtr params =
parent_access_ui::mojom::ParentAccessParams::New(
parent_access_ui::mojom::ParentAccessParams::FlowType::kWebsiteAccess,
parent_access_ui::mojom::FlowTypeParams::NewWebApprovalsParams(
parent_access_ui::mojom::WebApprovalsParams::New(
url, child_display_name, favicon_bitmap)),
/* is_disabled= */ false);
ShowParentAccessDialog(std::move(params), std::move(callback));
}
ash::ParentAccessDialogProvider* ParentAccessAsh::GetDialogProvider() {
if (!dialog_provider_)
dialog_provider_ = std::make_unique<ash::ParentAccessDialogProvider>();
return dialog_provider_.get();
}
void ParentAccessAsh::ShowParentAccessDialog(
parent_access_ui::mojom::ParentAccessParamsPtr params,
ParentAccessAsh::ParentAccessCallback callback) {
ash::ParentAccessDialogProvider::ShowError show_error =
GetDialogProvider()->Show(
std::move(params),
base::BindOnce(&ParentAccessAsh::OnParentAccessDialogClosed,
base::Unretained(this)));
crosapi::mojom::ParentAccessResultPtr show_error_result =
ShowErrorToParentAccessResultError(show_error);
if (show_error_result) {
// This result indicates basic errors that can occur synchronously.
std::move(callback).Run(std::move(show_error_result));
return;
} else {
// No show-error, so save the callback so we can use it to respond when the
// dialog completes.
DCHECK(!callback_);
callback_ = std::move(callback);
}
}
ash::ParentAccessDialogProvider* ParentAccessAsh::SetDialogProviderForTest(
std::unique_ptr<ash::ParentAccessDialogProvider> provider) {
dialog_provider_ = std::move(provider);
return dialog_provider_.get();
}
void ParentAccessAsh::OnParentAccessDialogClosed(
std::unique_ptr<ash::ParentAccessDialog::Result> result) {
if (callback_) {
std::move(callback_).Run(
DialogResultToParentAccessResult(std::move(result)));
}
}
} // namespace crosapi