blob: e3c99e943d7ba3122a2b70670d3d11dc15128a05 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/services/app_service/public/cpp/permission.h"
#include <sstream>
#include <variant>
#include "base/containers/to_value_list.h"
#include "base/strings/to_string.h"
namespace apps {
namespace {
const char kPermissionTypeKey[] = "permission_type";
const char kValueKey[] = "value";
const char kIsManagedKey[] = "is_managed";
const char kDetailsKey[] = "details";
} // namespace
APP_ENUM_TO_STRING(PermissionType,
kUnknown,
kCamera,
kLocation,
kMicrophone,
kNotifications,
kContacts,
kStorage,
kPrinting,
kFileHandling)
APP_ENUM_TO_STRING(TriState, kAllow, kBlock, kAsk)
Permission::Permission(PermissionType permission_type,
PermissionValue value,
bool is_managed,
std::optional<std::string> details)
: permission_type(permission_type),
value(std::move(value)),
is_managed(is_managed),
details(std::move(details)) {}
Permission::~Permission() = default;
PermissionPtr Permission::Clone() const {
return std::make_unique<Permission>(permission_type, value, is_managed,
details);
}
bool Permission::IsPermissionEnabled() const {
if (std::holds_alternative<bool>(value)) {
return std::get<bool>(value);
}
if (std::holds_alternative<TriState>(value)) {
return std::get<TriState>(value) == TriState::kAllow;
}
return false;
}
std::string Permission::ToString() const {
std::stringstream out;
out << " permission type: " << EnumToString(permission_type) << std::endl;
if (std::holds_alternative<bool>(value)) {
out << " bool_value: " << base::ToString(std::get<bool>(value));
} else if (std::holds_alternative<TriState>(value)) {
out << " tristate_value: " << EnumToString(std::get<TriState>(value));
}
out << std::endl;
if (details.has_value()) {
out << " details: " << details.value() << std::endl;
}
out << " is_managed: " << base::ToString(is_managed) << std::endl;
return out.str();
}
Permissions ClonePermissions(const Permissions& source_permissions) {
Permissions permissions;
for (const auto& permission : source_permissions) {
permissions.push_back(permission->Clone());
}
return permissions;
}
bool IsEqual(const Permissions& source, const Permissions& target) {
if (source.size() != target.size()) {
return false;
}
for (int i = 0; i < static_cast<int>(source.size()); i++) {
if (*source[i] != *target[i]) {
return false;
}
}
return true;
}
base::Value::Dict ConvertPermissionToDict(const PermissionPtr& permission) {
base::Value::Dict dict;
if (!permission) {
return dict;
}
dict.Set(kPermissionTypeKey, static_cast<int>(permission->permission_type));
if (std::holds_alternative<bool>(permission->value)) {
dict.Set(kValueKey, std::get<bool>(permission->value));
} else if (std::holds_alternative<TriState>(permission->value)) {
dict.Set(kValueKey,
static_cast<int>(std::get<TriState>(permission->value)));
}
dict.Set(kIsManagedKey, permission->is_managed);
if (permission->details.has_value()) {
dict.Set(kDetailsKey, permission->details.value());
}
return dict;
}
PermissionPtr ConvertDictToPermission(const base::Value::Dict& dict) {
std::optional<int> permission_type = dict.FindInt(kPermissionTypeKey);
if (!permission_type.has_value() ||
permission_type.value() < static_cast<int>(PermissionType::kUnknown) ||
permission_type.value() > static_cast<int>(PermissionType::kMaxValue)) {
return nullptr;
}
Permission::PermissionValue permission_value;
std::optional<bool> value = dict.FindBool(kValueKey);
if (value.has_value()) {
permission_value = value.value();
} else {
std::optional<int> tri_state = dict.FindInt(kValueKey);
if (tri_state.has_value() &&
tri_state.value() >= static_cast<int>(TriState::kAllow) &&
tri_state.value() <= static_cast<int>(TriState::kMaxValue)) {
permission_value = static_cast<TriState>(tri_state.value());
} else {
return nullptr;
}
}
std::optional<bool> is_managed = dict.FindBool(kIsManagedKey);
if (!is_managed.has_value()) {
return nullptr;
}
const std::string* details = dict.FindString(kDetailsKey);
return std::make_unique<Permission>(
static_cast<PermissionType>(permission_type.value()), permission_value,
is_managed.value(),
details ? std::optional<std::string>(*details) : std::nullopt);
}
base::Value::List ConvertPermissionsToList(const Permissions& permissions) {
return base::ToValueList(permissions, &ConvertPermissionToDict);
}
Permissions ConvertListToPermissions(const base::Value::List* list) {
Permissions permissions;
if (!list) {
return permissions;
}
for (const base::Value& permission : *list) {
PermissionPtr parsed_permission =
ConvertDictToPermission(permission.GetDict());
if (parsed_permission) {
permissions.push_back(std::move(parsed_permission));
}
}
return permissions;
}
} // namespace apps