blob: 58067cbcf73a58ce37b318e05b1bee36bc2d1530 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/web_applications/isolated_web_apps/isolation_data.h"
#include "base/containers/to_value_list.h"
#include "base/values.h"
#include "components/webapps/isolated_web_apps/types/update_channel.h"
namespace web_app {
namespace {
void PersistFieldsForUpdateImpl(IsolationData::Builder& builder,
const IsolationData& isolation_data) {
builder.SetControlledFramePartitions(
isolation_data.controlled_frame_partitions());
if (isolation_data.update_manifest_url()) {
builder.SetUpdateManifestUrl(*isolation_data.update_manifest_url());
}
if (isolation_data.update_channel()) {
builder.SetUpdateChannel(*isolation_data.update_channel());
}
}
} // namespace
IsolationData::IsolationData(
IsolatedWebAppStorageLocation location,
IwaVersion version,
std::set<std::string> controlled_frame_partitions,
std::optional<PendingUpdateInfo> pending_update_info,
std::optional<IsolatedWebAppIntegrityBlockData> integrity_block_data,
std::optional<GURL> update_manifest_url,
std::optional<UpdateChannel> update_channel,
std::optional<OpenedTabsCounterNotificationState>
opened_tabs_counter_notification_state)
: location_(std::move(location)),
version_(std::move(version)),
controlled_frame_partitions_(std::move(controlled_frame_partitions)),
pending_update_info_(std::move(pending_update_info)),
integrity_block_data_(std::move(integrity_block_data)),
update_manifest_url_(std::move(update_manifest_url)),
opened_tabs_counter_notification_state_(
std::move(opened_tabs_counter_notification_state)),
update_channel_(std::move(update_channel)) {
CHECK(!update_manifest_url_.has_value() || update_manifest_url_->is_valid(),
base::NotFatalUntil::M138);
}
IsolationData::~IsolationData() = default;
IsolationData::IsolationData(const IsolationData&) = default;
IsolationData& IsolationData::operator=(const IsolationData&) = default;
IsolationData::IsolationData(IsolationData&&) = default;
IsolationData& IsolationData::operator=(IsolationData&&) = default;
base::Value IsolationData::AsDebugValue() const {
auto debug_dict =
base::Value::Dict()
.Set("isolated_web_app_location", location_.ToDebugValue())
.Set("version", version_.GetString())
.Set("controlled_frame_partitions (on-disk)",
base::ToValueList(controlled_frame_partitions_))
.Set("pending_update_info", pending_update_info_
? pending_update_info_->AsDebugValue()
: base::Value())
.Set("integrity_block_data",
integrity_block_data_ ? integrity_block_data_->AsDebugValue()
: base::Value())
.Set("opened_tabs_counter_notification_state",
opened_tabs_counter_notification_state_
? base::Value(
opened_tabs_counter_notification_state_->GetState()
.DebugString())
: base::Value());
if (update_manifest_url_) {
debug_dict.Set("update_manifest_url", update_manifest_url_->spec());
}
if (update_channel_) {
debug_dict.Set("update_channel", update_channel_->ToString());
}
return base::Value(std::move(debug_dict));
}
IsolationData::PendingUpdateInfo::PendingUpdateInfo(
IsolatedWebAppStorageLocation location,
IwaVersion version,
std::optional<IsolatedWebAppIntegrityBlockData> integrity_block_data)
: location(std::move(location)),
version(std::move(version)),
integrity_block_data(std::move(integrity_block_data)) {}
IsolationData::PendingUpdateInfo::~PendingUpdateInfo() = default;
IsolationData::PendingUpdateInfo::PendingUpdateInfo(const PendingUpdateInfo&) =
default;
IsolationData::PendingUpdateInfo& IsolationData::PendingUpdateInfo::operator=(
const PendingUpdateInfo&) = default;
base::Value IsolationData::PendingUpdateInfo::AsDebugValue() const {
return base::Value(
base::Value::Dict()
.Set("isolated_web_app_location", location.ToDebugValue())
.Set("version", version.GetString())
.Set("integrity_block_data",
integrity_block_data ? integrity_block_data->AsDebugValue()
: base::Value()));
}
IsolationData::OpenedTabsCounterNotificationState::
OpenedTabsCounterNotificationState(
proto::IsolationData::OpenedTabsCounterNotificationState state)
: proto_state_(std::move(state)) {
CHECK(proto_state_.has_acknowledged());
CHECK(proto_state_.has_times_shown());
}
IsolationData::OpenedTabsCounterNotificationState::
OpenedTabsCounterNotificationState(bool acknowledged,
uint32_t times_shown) {
proto_state_.set_acknowledged(acknowledged);
proto_state_.set_times_shown(times_shown);
}
const proto::IsolationData::OpenedTabsCounterNotificationState&
IsolationData::OpenedTabsCounterNotificationState::GetState() const {
return proto_state_;
}
IsolationData::Builder::Builder(IsolatedWebAppStorageLocation location,
IwaVersion version)
: location_(std::move(location)), version_(std::move(version)) {}
IsolationData::Builder::Builder(const IsolationData& isolation_data)
: location_(isolation_data.location()),
version_(isolation_data.version()),
controlled_frame_partitions_(
isolation_data.controlled_frame_partitions()),
pending_update_info_(isolation_data.pending_update_info()),
integrity_block_data_(isolation_data.integrity_block_data()),
update_manifest_url_(isolation_data.update_manifest_url()),
update_channel_(isolation_data.update_channel()) {}
IsolationData::Builder::~Builder() = default;
IsolationData::Builder::Builder(const IsolationData::Builder&) = default;
IsolationData::Builder& IsolationData::Builder::operator=(
const IsolationData::Builder&) = default;
IsolationData::Builder::Builder(IsolationData::Builder&&) = default;
IsolationData::Builder& IsolationData::Builder::operator=(
IsolationData::Builder&&) = default;
IsolationData::Builder& IsolationData::Builder::SetControlledFramePartitions(
std::set<std::string> controlled_frame_partitions) & {
controlled_frame_partitions_ = std::move(controlled_frame_partitions);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::SetControlledFramePartitions(
std::set<std::string> controlled_frame_partitions) && {
controlled_frame_partitions_ = std::move(controlled_frame_partitions);
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::SetPendingUpdateInfo(
IsolationData::PendingUpdateInfo pending_update_info) & {
CHECK_EQ(pending_update_info.location.dev_mode(), location_.dev_mode());
pending_update_info_ = std::move(pending_update_info);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::SetPendingUpdateInfo(
IsolationData::PendingUpdateInfo pending_update_info) && {
CHECK_EQ(pending_update_info.location.dev_mode(), location_.dev_mode());
pending_update_info_ = std::move(pending_update_info);
return std::move(*this);
}
IsolationData::Builder&
IsolationData::Builder::SetOpenedTabsCounterNotificationState(
IsolationData::OpenedTabsCounterNotificationState notification_state) & {
opened_tabs_counter_notification_state_ = std::move(notification_state);
return *this;
}
IsolationData::Builder&&
IsolationData::Builder::SetOpenedTabsCounterNotificationState(
IsolationData::OpenedTabsCounterNotificationState notification_state) && {
opened_tabs_counter_notification_state_ = std::move(notification_state);
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::ClearPendingUpdateInfo() & {
pending_update_info_ = std::nullopt;
return *this;
}
IsolationData::Builder&& IsolationData::Builder::ClearPendingUpdateInfo() && {
pending_update_info_ = std::nullopt;
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::SetIntegrityBlockData(
IsolatedWebAppIntegrityBlockData integrity_block_data) & {
integrity_block_data_ = std::move(integrity_block_data);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::SetIntegrityBlockData(
IsolatedWebAppIntegrityBlockData integrity_block_data) && {
integrity_block_data_ = std::move(integrity_block_data);
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::SetUpdateManifestUrl(
GURL update_manifest_url) & {
CHECK(location_.dev_mode())
<< "This field is supposed to be used only with dev mode installs via "
"chrome://web-app-internals.";
CHECK(update_manifest_url.is_valid(), base::NotFatalUntil::M138);
update_manifest_url_ = std::move(update_manifest_url);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::SetUpdateManifestUrl(
GURL update_manifest_url) && {
CHECK(location_.dev_mode())
<< "This field is supposed to be used only with dev mode installs via "
"chrome://web-app-internals.";
CHECK(update_manifest_url.is_valid(), base::NotFatalUntil::M138);
update_manifest_url_ = std::move(update_manifest_url);
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::SetUpdateChannel(
UpdateChannel update_channel) & {
CHECK(location_.dev_mode())
<< "This field is supposed to be used only with dev mode installs via "
"chrome://web-app-internals.";
update_channel_ = std::move(update_channel);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::SetUpdateChannel(
UpdateChannel update_channel) && {
CHECK(location_.dev_mode())
<< "This field is supposed to be used only with dev mode installs via "
"chrome://web-app-internals.";
update_channel_ = std::move(update_channel);
return std::move(*this);
}
IsolationData::Builder& IsolationData::Builder::PersistFieldsForUpdate(
const IsolationData& isolation_data) & {
PersistFieldsForUpdateImpl(*this, isolation_data);
return *this;
}
IsolationData::Builder&& IsolationData::Builder::PersistFieldsForUpdate(
const IsolationData& isolation_data) && {
PersistFieldsForUpdateImpl(*this, isolation_data);
return std::move(*this);
}
IsolationData IsolationData::Builder::Build() && {
return IsolationData(
std::move(location_), std::move(version_),
std::move(controlled_frame_partitions_), std::move(pending_update_info_),
std::move(integrity_block_data_), std::move(update_manifest_url_),
std::move(update_channel_),
std::move(opened_tabs_counter_notification_state_));
}
} // namespace web_app