| // 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 |