From 03c549e0392f92c02536d3f86d5e1d8dfa3435ac Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 1 Sep 2021 11:08:40 +0200 Subject: BASELINE: Update Chromium to 91.0.4472.160 Change-Id: I0def1f08a2412aeed79a9ab95dd50eb5c3f65f31 Reviewed-by: Allan Sandfeld Jensen --- chromium/components/component_updater/BUILD.gn | 2 + .../components/component_updater/android/BUILD.gn | 40 +++- .../android/component_loader_policy.cc | 192 +++++++++++++++++ .../android/component_loader_policy.h | 131 +++++++++++ .../android/component_loader_policy_forward.h | 19 ++ .../android/component_loader_policy_unittests.cc | 240 +++++++++++++++++++++ .../android/embedded_component_loader.cc | 150 ------------- .../android/embedded_component_loader.h | 100 --------- .../android/embedded_component_loader_unittests.cc | 234 -------------------- ...oken_key_commitments_component_loader_policy.cc | 88 ++++++++ ...token_key_commitments_component_loader_policy.h | 56 +++++ .../component_updater/component_installer.cc | 18 +- .../component_updater/component_installer.h | 10 +- .../component_updater/component_updater_service.cc | 13 +- .../component_updater/component_updater_service.h | 4 +- .../component_updater_service_internal.h | 3 +- .../component_updater/component_updater_utils.cc | 35 +++ .../component_updater/component_updater_utils.h | 31 +++ .../origin_trials_component_installer.cc | 24 ++- .../origin_trials_component_installer.h | 1 + ...n_key_commitments_component_installer_policy.cc | 57 +++-- ...en_key_commitments_component_installer_policy.h | 20 ++ 22 files changed, 933 insertions(+), 535 deletions(-) create mode 100644 chromium/components/component_updater/android/component_loader_policy.cc create mode 100644 chromium/components/component_updater/android/component_loader_policy.h create mode 100644 chromium/components/component_updater/android/component_loader_policy_forward.h create mode 100644 chromium/components/component_updater/android/component_loader_policy_unittests.cc delete mode 100644 chromium/components/component_updater/android/embedded_component_loader.cc delete mode 100644 chromium/components/component_updater/android/embedded_component_loader.h delete mode 100644 chromium/components/component_updater/android/embedded_component_loader_unittests.cc create mode 100644 chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc create mode 100644 chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h create mode 100644 chromium/components/component_updater/component_updater_utils.cc create mode 100644 chromium/components/component_updater/component_updater_utils.h (limited to 'chromium/components/component_updater') diff --git a/chromium/components/component_updater/BUILD.gn b/chromium/components/component_updater/BUILD.gn index 612b86c1d68..cdd4003b544 100644 --- a/chromium/components/component_updater/BUILD.gn +++ b/chromium/components/component_updater/BUILD.gn @@ -17,6 +17,8 @@ static_library("component_updater") { "component_updater_switches.h", "component_updater_url_constants.cc", "component_updater_url_constants.h", + "component_updater_utils.cc", + "component_updater_utils.h", "configurator_impl.cc", "configurator_impl.h", "pref_names.cc", diff --git a/chromium/components/component_updater/android/BUILD.gn b/chromium/components/component_updater/android/BUILD.gn index 979bac15a90..21e34fc8e07 100644 --- a/chromium/components/component_updater/android/BUILD.gn +++ b/chromium/components/component_updater/android/BUILD.gn @@ -13,7 +13,6 @@ android_library("background_task_update_scheduler_java") { deps = [ ":background_task_update_scheduler_jni_headers", "//base:base_java", - "//base:jni_java", "//components/background_task_scheduler:background_task_scheduler_java", "//components/background_task_scheduler:background_task_scheduler_task_ids_java", "//third_party/android_deps:chromium_play_services_availability_java", @@ -48,12 +47,31 @@ android_library("component_provider_service_aidl_java") { srcjar_deps = [ ":component_provider_service_aidl" ] } +android_library("embedded_component_loader_java") { + sources = [ + "java/src/org/chromium/components/component_updater/ComponentLoaderPolicyBridge.java", + "java/src/org/chromium/components/component_updater/EmbeddedComponentLoader.java", + ] + deps = [ + ":component_provider_service_aidl_java", + ":embedded_component_loader_jni_headers", + "//base:base_java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] +} + +generate_jni("embedded_component_loader_jni_headers") { + sources = [ "java/src/org/chromium/components/component_updater/ComponentLoaderPolicyBridge.java" ] +} + static_library("embedded_component_loader") { sources = [ - "embedded_component_loader.cc", - "embedded_component_loader.h", + "component_loader_policy.cc", + "component_loader_policy.h", + "component_loader_policy_forward.h", ] deps = [ + ":embedded_component_loader_jni_headers", "//base", "//components/component_updater", "//components/update_client", @@ -62,7 +80,7 @@ static_library("embedded_component_loader") { source_set("embedded_component_loader_unittests") { testonly = true - sources = [ "embedded_component_loader_unittests.cc" ] + sources = [ "component_loader_policy_unittests.cc" ] deps = [ ":embedded_component_loader", "//base", @@ -71,3 +89,17 @@ source_set("embedded_component_loader_unittests") { "//testing/gtest", ] } + +static_library("loader_policies") { + sources = [ + "loader_policies/trust_token_key_commitments_component_loader_policy.cc", + "loader_policies/trust_token_key_commitments_component_loader_policy.h", + ] + + deps = [ + ":embedded_component_loader", + "//base", + "//components/component_updater", + "//components/component_updater/installer_policies", + ] +} diff --git a/chromium/components/component_updater/android/component_loader_policy.cc b/chromium/components/component_updater/android/component_loader_policy.cc new file mode 100644 index 00000000000..67acfb31c9a --- /dev/null +++ b/chromium/components/component_updater/android/component_loader_policy.cc @@ -0,0 +1,192 @@ +// Copyright 2021 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 "components/component_updater/android/component_loader_policy.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/check.h" +#include "base/containers/flat_map.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_file.h" +#include "base/json/json_string_value_serializer.h" +#include "base/location.h" +#include "base/memory/scoped_refptr.h" +#include "base/sequence_checker.h" +#include "base/task/post_task.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "base/values.h" +#include "base/version.h" +#include "components/component_updater/android/component_loader_policy_forward.h" +#include "components/component_updater/android/embedded_component_loader_jni_headers/ComponentLoaderPolicyBridge_jni.h" +#include "components/update_client/utils.h" + +namespace component_updater { +namespace { + +constexpr char kManifestFileName[] = "manifest.json"; + +// TODO(crbug.com/1180964) move to base/file_util.h +bool ReadFdToString(int fd, std::string* contents) { + base::ScopedFILE file_stream(fdopen(fd, "r")); + return file_stream.get() + ? base::ReadStreamToString(file_stream.get(), contents) + : false; +} + +std::unique_ptr ReadManifest( + const std::string& manifest_content) { + JSONStringValueDeserializer deserializer(manifest_content); + std::string error; + std::unique_ptr root = deserializer.Deserialize(nullptr, &error); + return (root && root->is_dict()) + ? std::unique_ptr( + static_cast(root.release())) + : nullptr; +} + +std::unique_ptr ReadManifestFromFd(int fd) { + std::string content; + if (!ReadFdToString(fd, &content)) { + return nullptr; + } + return ReadManifest(content); +} + +} // namespace + +ComponentLoaderPolicy::~ComponentLoaderPolicy() = default; + +AndroidComponentLoaderPolicy::AndroidComponentLoaderPolicy( + std::unique_ptr loader_policy) + : loader_policy_(std::move(loader_policy)) { + JNIEnv* env = base::android::AttachCurrentThread(); + obj_.Reset(env, Java_ComponentLoaderPolicyBridge_Constructor( + env, reinterpret_cast(this)) + .obj()); +} + +AndroidComponentLoaderPolicy::~AndroidComponentLoaderPolicy() = default; + +base::android::ScopedJavaLocalRef +AndroidComponentLoaderPolicy::GetJavaObject() { + return base::android::ScopedJavaLocalRef(obj_); +} + +void AndroidComponentLoaderPolicy::ComponentLoaded( + JNIEnv* env, + const base::android::JavaRef& jfile_names, + const base::android::JavaRef& jfds) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::vector file_names; + std::vector fds; + base::android::AppendJavaStringArrayToStringVector(env, jfile_names, + &file_names); + base::android::JavaIntArrayToIntVector(env, jfds, &fds); + DCHECK_EQ(file_names.size(), fds.size()); + + // Construct the file_name->file_descriptor map excluding the manifest file + // as it's parsed and passed separately. + base::flat_map fd_map; + int manifest_fd = -1; + for (size_t i = 0; i < file_names.size(); ++i) { + const std::string& file_name = file_names[i]; + if (file_name == kManifestFileName) { + manifest_fd = fds[i]; + } else { + fd_map[file_name] = fds[i]; + } + } + if (manifest_fd == -1) { + CloseFdsAndFail(fd_map); + return; + } + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce(ReadManifestFromFd, manifest_fd), + base::BindOnce(&AndroidComponentLoaderPolicy::NotifyNewVersion, + base::Owned(this), fd_map)); +} + +void AndroidComponentLoaderPolicy::ComponentLoadFailed(JNIEnv* env) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + loader_policy_->ComponentLoadFailed(); + delete this; +} + +base::android::ScopedJavaLocalRef +AndroidComponentLoaderPolicy::GetComponentId(JNIEnv* env) { + std::vector hash; + loader_policy_->GetHash(&hash); + return base::android::ConvertUTF8ToJavaString( + env, update_client::GetCrxIdFromPublicKeyHash(hash)); +} + +void AndroidComponentLoaderPolicy::NotifyNewVersion( + const base::flat_map& fd_map, + std::unique_ptr manifest) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!manifest) { + CloseFdsAndFail(fd_map); + return; + } + std::string version_ascii; + manifest->GetStringASCII("version", &version_ascii); + base::Version version(version_ascii); + if (!version.IsValid()) { + CloseFdsAndFail(fd_map); + return; + } + loader_policy_->ComponentLoaded(version, fd_map, std::move(manifest)); +} + +void AndroidComponentLoaderPolicy::CloseFdsAndFail( + const base::flat_map& fd_map) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (auto& iter : fd_map) { + close(iter.second); + } + loader_policy_->ComponentLoadFailed(); +} + +// static +base::android::ScopedJavaLocalRef +AndroidComponentLoaderPolicy::ToJavaArrayOfAndroidComponentLoaderPolicy( + JNIEnv* env, + ComponentLoaderPolicyVector policies) { + base::android::ScopedJavaLocalRef policy_array = + Java_ComponentLoaderPolicyBridge_createNewArray(env, policies.size()); + + for (size_t i = 0; i < policies.size(); ++i) { + // The `AndroidComponentLoaderPolicy` object is owned by the java + // ComponentLoaderPolicy object which manages its life time and will triger + // deletion. + auto* android_policy = + new AndroidComponentLoaderPolicy(std::move(policies[i])); + Java_ComponentLoaderPolicyBridge_setArrayElement( + env, policy_array, i, android_policy->GetJavaObject()); + } + return policy_array; +} + +} // namespace component_updater diff --git a/chromium/components/component_updater/android/component_loader_policy.h b/chromium/components/component_updater/android/component_loader_policy.h new file mode 100644 index 00000000000..ab66fc4803d --- /dev/null +++ b/chromium/components/component_updater/android/component_loader_policy.h @@ -0,0 +1,131 @@ +// Copyright 2021 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. + +#ifndef COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_H_ +#define COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_H_ + +#include +#include + +#include +#include +#include + +#include "base/android/scoped_java_ref.h" +#include "base/containers/flat_map.h" +#include "base/memory/scoped_refptr.h" +#include "base/sequence_checker.h" +#include "components/component_updater/android/component_loader_policy_forward.h" + +namespace base { +class Version; +class DictionaryValue; +} // namespace base + +namespace component_updater { + +// Components should use `AndroidComponentLoaderPolicy` by defining a class that +// implements the members of `ComponentLoaderPolicy`, and then registering a +// `AndroidComponentLoaderPolicy` that has been constructed with an instance of +// that class in an instance of embedded WebView or WebLayer with the Java +// AndroidComponentLoaderPolicy. The `AndroidComponentLoaderPolicy` will fetch +// the components files from the Android `ComponentsProviderService` and invoke +// the callbacks defined in this class. +// +// Ideally, the implementation of this class should share implementation with +// its component `ComponentInstallerPolicy` counterpart. +// +// Used on the UI thread, should post any non-user-visible tasks to a background +// runner. +class ComponentLoaderPolicy { + public: + virtual ~ComponentLoaderPolicy(); + + // ComponentLoaded is called when the loader successfully gets file + // descriptors for all files in the component from the + // ComponentsProviderService. + // + // Will be called at most once. This is mutually exclusive with + // ComponentLoadFailed; if this is called then ComponentLoadFailed won't be + // called. + // + // Overriders must close all file descriptors after using them. + // + // `version` is the version of the component. + // `fd_map` maps file relative paths in the install directory to its file + // descriptor. + // `manifest` is the manifest for this version of the component. + virtual void ComponentLoaded( + const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) = 0; + + // Called if connection to the service fails, components files are not found + // or if the manifest file is missing or invalid. + // + // Will be called at most once. This is mutually exclusive with + // ComponentLoaded; if this is called then ComponentLoaded won't be called. + // + // TODO(crbug.com/1180966) accept error code for different types of errors. + virtual void ComponentLoadFailed() = 0; + + // Returns the component's SHA2 hash as raw bytes, the hash value is used as + // the unique id of the component and will be used to request components files + // from the ComponentsProviderService. + virtual void GetHash(std::vector* hash) const = 0; +}; + +// Provides a bridge from Java to native to receive callbacks from the Java +// loader and pass it to the wrapped ComponentLoaderPolicy instance. +// +// The object is single use only, it will be deleted when ComponentLoaded or +// ComponentLoadedFailed is called once. +// +// Called on the UI thread, should post any non-user-visible tasks to a +// background runner. +class AndroidComponentLoaderPolicy { + public: + explicit AndroidComponentLoaderPolicy( + std::unique_ptr loader_policy); + ~AndroidComponentLoaderPolicy(); + + AndroidComponentLoaderPolicy(const AndroidComponentLoaderPolicy&) = delete; + AndroidComponentLoaderPolicy& operator=(const AndroidComponentLoaderPolicy&) = + delete; + + // A utility method that returns an array of Java objects of + // `org.chromium.components.component_updater.ComponentLoaderPolicy`. + static base::android::ScopedJavaLocalRef + ToJavaArrayOfAndroidComponentLoaderPolicy( + JNIEnv* env, + ComponentLoaderPolicyVector policies); + + // JNI overrides: + void ComponentLoaded(JNIEnv* env, + const base::android::JavaRef& jfile_names, + const base::android::JavaRef& jfds); + void ComponentLoadFailed(JNIEnv* env); + base::android::ScopedJavaLocalRef GetComponentId(JNIEnv* env); + + private: + // Returns a Java object of + // `org.chromium.components.component_updater.ComponentLoaderPolicy`. + base::android::ScopedJavaLocalRef GetJavaObject(); + + void NotifyNewVersion(const base::flat_map& fd_map, + std::unique_ptr manifest); + void CloseFdsAndFail(const base::flat_map& fd_map); + + SEQUENCE_CHECKER(sequence_checker_); + + // A Java object of + // `org.chromium.components.component_updater.ComponentLoaderPolicy`. + base::android::ScopedJavaGlobalRef obj_; + + std::unique_ptr loader_policy_; +}; + +} // namespace component_updater + +#endif // COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_H_ \ No newline at end of file diff --git a/chromium/components/component_updater/android/component_loader_policy_forward.h b/chromium/components/component_updater/android/component_loader_policy_forward.h new file mode 100644 index 00000000000..f6f87535b66 --- /dev/null +++ b/chromium/components/component_updater/android/component_loader_policy_forward.h @@ -0,0 +1,19 @@ +// Copyright 2021 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. + +#ifndef COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_FORWARD_H_ +#define COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_FORWARD_H_ + +#include +#include + +namespace component_updater { +class ComponentLoaderPolicy; + +using ComponentLoaderPolicyVector = + std::vector>; + +} // namespace component_updater + +#endif // COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_FORWARD_H_ diff --git a/chromium/components/component_updater/android/component_loader_policy_unittests.cc b/chromium/components/component_updater/android/component_loader_policy_unittests.cc new file mode 100644 index 00000000000..b5547f1a78f --- /dev/null +++ b/chromium/components/component_updater/android/component_loader_policy_unittests.cc @@ -0,0 +1,240 @@ +// Copyright 2021 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 "components/component_updater/android/component_loader_policy.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/containers/flat_map.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/values.h" +#include "base/version.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace component_updater { + +namespace { + +constexpr char kComponentId[] = "jebgalgnebhfojomionfpkfelancnnkf"; +// This hash corresponds to kComponentId. +constexpr uint8_t kSha256Hash[] = { + 0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 0x8e, 0xd5, 0xfa, + 0x54, 0xb0, 0xd2, 0xdd, 0xa5, 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, + 0xf6, 0xc4, 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; + +void GetPkHash(std::vector* hash) { + hash->assign(std::begin(kSha256Hash), std::end(kSha256Hash)); +} + +std::vector OpenFileFds(const base::FilePath& base, + const std::vector& files) { + std::vector fds; + for (const std::string& file : files) { + base::FilePath path = base.AppendASCII(file); + fds.push_back(open(path.MaybeAsASCII().c_str(), O_RDONLY)); + } + return fds; +} + +using OnLoadedTestCallBack = + base::OnceCallback&, + std::unique_ptr)>; + +class MockLoaderPolicy : public ComponentLoaderPolicy { + public: + explicit MockLoaderPolicy(OnLoadedTestCallBack on_loaded, + base::OnceClosure on_failed) + : on_loaded_(std::move(on_loaded)), on_failed_(std::move(on_failed)) {} + + MockLoaderPolicy() + : on_loaded_( + base::DoNothing::Once&, + std::unique_ptr>()), + on_failed_(base::DoNothing::Once()) {} + + ~MockLoaderPolicy() override = default; + + MockLoaderPolicy(const MockLoaderPolicy&) = delete; + MockLoaderPolicy& operator=(const MockLoaderPolicy&) = delete; + + void ComponentLoaded( + const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) override { + std::move(on_loaded_).Run(version, fd_map, std::move(manifest)); + } + + void ComponentLoadFailed() override { std::move(on_failed_).Run(); } + + void GetHash(std::vector* hash) const override { GetPkHash(hash); } + + private: + OnLoadedTestCallBack on_loaded_; + base::OnceClosure on_failed_; +}; + +void VerifyComponentLoaded(base::OnceClosure on_done, + const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) { + EXPECT_EQ(version.GetString(), "123.456.789"); + EXPECT_EQ(fd_map.size(), 2u); + EXPECT_NE(fd_map.find("file1.txt"), fd_map.end()); + EXPECT_NE(fd_map.find("file2.txt"), fd_map.end()); + + std::move(on_done).Run(); +} + +} // namespace + +class AndroidComponentLoaderPolicyTest : public testing::Test { + public: + AndroidComponentLoaderPolicyTest() = default; + ~AndroidComponentLoaderPolicyTest() override = default; + + AndroidComponentLoaderPolicyTest(const AndroidComponentLoaderPolicyTest&) = + delete; + AndroidComponentLoaderPolicyTest& operator=( + const AndroidComponentLoaderPolicyTest&) = delete; + + void SetUp() override { + env_ = base::android::AttachCurrentThread(); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + } + + protected: + void WriteFile(const std::string& file_name, const std::string& content) { + ASSERT_TRUE( + base::WriteFile(temp_dir_.GetPath().AppendASCII(file_name), content)); + files_.push_back(file_name); + } + + std::vector GetFileFds() const { + return OpenFileFds(temp_dir_.GetPath(), files_); + } + + JNIEnv* env_ = nullptr; + std::vector files_; + + private: + base::ScopedTempDir temp_dir_; +}; + +TEST_F(AndroidComponentLoaderPolicyTest, TestValidManifest) { + base::test::TaskEnvironment task_environment; + + WriteFile("file1.txt", "1"); + WriteFile("file2.txt", "2"); + WriteFile("manifest.json", + "{\n\"manifest_version\": 2,\n\"version\": \"123.456.789\"\n}"); + + base::RunLoop run_loop; + auto* android_policy = + new AndroidComponentLoaderPolicy(std::make_unique( + base::BindOnce(&VerifyComponentLoaded, run_loop.QuitClosure()), + base::BindOnce([]() { FAIL(); }))); + + android_policy->ComponentLoaded( + env_, base::android::ToJavaArrayOfStrings(env_, files_), + base::android::ToJavaIntArray(env_, GetFileFds())); + run_loop.Run(); +} + +TEST_F(AndroidComponentLoaderPolicyTest, TestMissingManifest) { + base::test::TaskEnvironment task_environment; + + WriteFile("file.txt", "test"); + + base::RunLoop run_loop; + auto* android_policy = + new AndroidComponentLoaderPolicy(std::make_unique( + base::BindOnce( + [](const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) { FAIL(); }), + run_loop.QuitClosure())); + + android_policy->ComponentLoaded( + env_, base::android::ToJavaArrayOfStrings(env_, files_), + base::android::ToJavaIntArray(env_, GetFileFds())); + run_loop.Run(); +} + +TEST_F(AndroidComponentLoaderPolicyTest, TestInvalidVersion) { + base::test::TaskEnvironment task_environment; + + WriteFile("file.txt", "test"); + WriteFile("manifest.json", + "{\n\"manifest_version\": 2,\n\"version\": \"\"\n}"); + + base::RunLoop run_loop; + auto* android_policy = + new AndroidComponentLoaderPolicy(std::make_unique( + base::BindOnce( + [](const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) { FAIL(); }), + run_loop.QuitClosure())); + + android_policy->ComponentLoaded( + env_, base::android::ToJavaArrayOfStrings(env_, files_), + base::android::ToJavaIntArray(env_, GetFileFds())); + run_loop.Run(); +} + +TEST_F(AndroidComponentLoaderPolicyTest, TestInvalidManifest) { + base::test::TaskEnvironment task_environment; + + WriteFile("file.txt", "test"); + WriteFile("manifest.json", "{\n\"manifest_version\":}"); + + base::RunLoop run_loop; + auto* android_policy = + new AndroidComponentLoaderPolicy(std::make_unique( + base::BindOnce( + [](const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) { FAIL(); }), + run_loop.QuitClosure())); + + android_policy->ComponentLoaded( + env_, base::android::ToJavaArrayOfStrings(env_, files_), + base::android::ToJavaIntArray(env_, GetFileFds())); + run_loop.Run(); +} + +TEST_F(AndroidComponentLoaderPolicyTest, TestGetComponentId) { + base::test::TaskEnvironment task_environment; + + auto* android_policy = + new AndroidComponentLoaderPolicy(std::make_unique()); + + base::android::ScopedJavaLocalRef jcomponentId = + android_policy->GetComponentId(env_); + + EXPECT_EQ(base::android::ConvertJavaStringToUTF8(jcomponentId), kComponentId); +} + +} // namespace component_updater \ No newline at end of file diff --git a/chromium/components/component_updater/android/embedded_component_loader.cc b/chromium/components/component_updater/android/embedded_component_loader.cc deleted file mode 100644 index db4ca30fe26..00000000000 --- a/chromium/components/component_updater/android/embedded_component_loader.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2021 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 "components/component_updater/android/embedded_component_loader.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/bind.h" -#include "base/callback.h" -#include "base/check.h" -#include "base/containers/flat_map.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/json/json_string_value_serializer.h" -#include "base/location.h" -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/task/post_task.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "base/values.h" -#include "base/version.h" -#include "components/update_client/utils.h" - -namespace component_updater { -namespace { - -constexpr char kManifestFileName[] = "manifest.json"; - -// TODO(crbug.com/1180964) move to base/file_util.h -bool ReadFdToString(int fd, std::string* contents) { - base::ScopedFILE file_stream(fdopen(fd, "r")); - return file_stream.get() - ? base::ReadStreamToString(file_stream.get(), contents) - : false; -} - -std::unique_ptr ReadManifest( - const std::string& manifest_content) { - JSONStringValueDeserializer deserializer(manifest_content); - std::string error; - std::unique_ptr root = deserializer.Deserialize(nullptr, &error); - return (root && root->is_dict()) - ? std::unique_ptr( - static_cast(root.release())) - : nullptr; -} - -std::unique_ptr ReadManifestFromFd(int fd) { - std::string content; - if (!ReadFdToString(fd, &content)) { - return nullptr; - } - return ReadManifest(content); -} - -} // namespace - -ComponentLoaderPolicy::~ComponentLoaderPolicy() = default; - -EmbeddedComponentLoader::EmbeddedComponentLoader( - std::unique_ptr loader_policy) - : loader_policy_(std::move(loader_policy)) {} - -EmbeddedComponentLoader::~EmbeddedComponentLoader() = default; - -void EmbeddedComponentLoader::ComponentLoaded( - JNIEnv* env, - const base::android::JavaRef& jfile_names, - const base::android::JavaRef& jfds) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - std::vector file_names; - std::vector fds; - base::android::AppendJavaStringArrayToStringVector(env, jfile_names, - &file_names); - base::android::JavaIntArrayToIntVector(env, jfds, &fds); - DCHECK_EQ(file_names.size(), fds.size()); - - // Construct the file_name->file_descriptor map excluding the manifest file - // as it's parsed and passed separately. - base::flat_map fd_map; - int manifest_fd = -1; - for (size_t i = 0; i < file_names.size(); ++i) { - const std::string& file_name = file_names[i]; - if (file_name == kManifestFileName) { - manifest_fd = fds[i]; - } else { - fd_map[file_name] = fds[i]; - } - } - if (manifest_fd == -1) { - loader_policy_->ComponentLoadFailed(); - return; - } - - base::PostTaskAndReplyWithResult( - FROM_HERE, - {base::ThreadPool(), base::MayBlock(), - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(ReadManifestFromFd, manifest_fd), - base::BindOnce(&EmbeddedComponentLoader::NotifyNewVersion, - weak_ptr_factory_.GetWeakPtr(), fd_map)); -} - -void EmbeddedComponentLoader::ComponentLoadFailed(JNIEnv* env) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - loader_policy_->ComponentLoadFailed(); -} - -base::android::ScopedJavaLocalRef -EmbeddedComponentLoader::GetComponentId(JNIEnv* env) { - std::vector hash; - loader_policy_->GetHash(&hash); - return base::android::ConvertUTF8ToJavaString( - env, update_client::GetCrxIdFromPublicKeyHash(hash)); -} - -void EmbeddedComponentLoader::NotifyNewVersion( - const base::flat_map& fd_map, - std::unique_ptr manifest) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (!manifest) { - loader_policy_->ComponentLoadFailed(); - return; - } - std::string version_ascii; - manifest->GetStringASCII("version", &version_ascii); - base::Version version(version_ascii); - if (!version.IsValid()) { - loader_policy_->ComponentLoadFailed(); - return; - } - loader_policy_->ComponentLoaded(version, fd_map, std::move(manifest)); -} - -} // namespace component_updater diff --git a/chromium/components/component_updater/android/embedded_component_loader.h b/chromium/components/component_updater/android/embedded_component_loader.h deleted file mode 100644 index f70c922fd06..00000000000 --- a/chromium/components/component_updater/android/embedded_component_loader.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2021 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. - -#ifndef COMPONENTS_COMPONENT_UPDATER_ANDROID_EMBEDDED_COMPONENT_LOADER_H_ -#define COMPONENTS_COMPONENT_UPDATER_ANDROID_EMBEDDED_COMPONENT_LOADER_H_ - -#include -#include - -#include -#include -#include - -#include "base/android/scoped_java_ref.h" -#include "base/containers/flat_map.h" -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" - -namespace base { -class Version; -class DictionaryValue; -} // namespace base - -namespace component_updater { - -// Components should use `EmbeddedComponentLoader` by defining a class that -// implements the members of `ComponentLoaderPolicy`, and then registering a -// `EmbeddedComponentLoader` that has been constructed with an instance of that -// class in an instance of embedded WebView or WebLayer with the Java -// EmbeddedComponentLoader. The `EmbeddedComponentLoader` will fetch the -// components files from the Android `ComponentsProviderService` and invoke the -// callbacks defined in this class. -// -// Ideally, the implementation of this class should share implementation with -// its component `ComponentInstallerPolicy` counterpart. -class ComponentLoaderPolicy { - public: - virtual ~ComponentLoaderPolicy(); - - // ComponentLoaded is called when the loader successfully gets file - // descriptors for all files in the component from the - // ComponentsProviderService. - // - // Must close all file descriptors after using them. Can be called multiple - // times in the same run. - // - // `version` is the version of the component. - // `fd_map` maps file relative paths in the install directory to its file - // descriptor. - // `manifest` is the manifest for this version of the component. - virtual void ComponentLoaded( - const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) = 0; - - // Called if connection to the service fails, components files are not found - // or if the manifest file is missing or invalid. Can - // be called multiple times in the same run. - // - // TODO(crbug.com/1180966) accept error code for different types of errors. - virtual void ComponentLoadFailed() = 0; - - // Returns the component's SHA2 hash as raw bytes, the hash value is used as - // the unique id of the component and will be used to request components files - // from the ComponentsProviderService. - virtual void GetHash(std::vector* hash) const = 0; -}; - -// Provides a bridge from Java to native to receive callbacks from the Java -// loader and pass it to the wrapped ComponentLoaderPolicy instance. -// -// Must only be created and used on the same thread. -class EmbeddedComponentLoader { - public: - explicit EmbeddedComponentLoader( - std::unique_ptr loader_policy); - ~EmbeddedComponentLoader(); - - // JNI overrides: - void ComponentLoaded(JNIEnv* env, - const base::android::JavaRef& jfile_names, - const base::android::JavaRef& jfds); - void ComponentLoadFailed(JNIEnv* env); - base::android::ScopedJavaLocalRef GetComponentId(JNIEnv* env); - - void NotifyNewVersion(const base::flat_map& fd_map, - std::unique_ptr manifest); - - private: - SEQUENCE_CHECKER(sequence_checker_); - - std::unique_ptr loader_policy_; - base::WeakPtrFactory weak_ptr_factory_{this}; -}; - -} // namespace component_updater - -#endif // COMPONENTS_COMPONENT_UPDATER_ANDROID_EMBEDDED_COMPONENT_LOADER_H_ \ No newline at end of file diff --git a/chromium/components/component_updater/android/embedded_component_loader_unittests.cc b/chromium/components/component_updater/android/embedded_component_loader_unittests.cc deleted file mode 100644 index e17849f5603..00000000000 --- a/chromium/components/component_updater/android/embedded_component_loader_unittests.cc +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2021 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 "components/component_updater/android/embedded_component_loader.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "base/callback.h" -#include "base/callback_helpers.h" -#include "base/containers/flat_map.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/run_loop.h" -#include "base/test/task_environment.h" -#include "base/values.h" -#include "base/version.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace component_updater { - -namespace { - -constexpr char kComponentId[] = "jebgalgnebhfojomionfpkfelancnnkf"; -// This hash corresponds to kComponentId. -constexpr uint8_t kSha256Hash[] = { - 0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 0x8e, 0xd5, 0xfa, - 0x54, 0xb0, 0xd2, 0xdd, 0xa5, 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, - 0xf6, 0xc4, 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; - -void GetPkHash(std::vector* hash) { - hash->assign(std::begin(kSha256Hash), std::end(kSha256Hash)); -} - -std::vector OpenFileFds(const base::FilePath& base, - const std::vector& files) { - std::vector fds; - for (const std::string& file : files) { - base::FilePath path = base.AppendASCII(file); - fds.push_back(open(path.MaybeAsASCII().c_str(), O_RDONLY)); - } - return fds; -} - -using OnLoadedTestCallBack = - base::OnceCallback&, - std::unique_ptr)>; - -class MockLoaderPolicy : public ComponentLoaderPolicy { - public: - explicit MockLoaderPolicy(OnLoadedTestCallBack on_loaded, - base::OnceClosure on_failed) - : on_loaded_(std::move(on_loaded)), on_failed_(std::move(on_failed)) {} - - MockLoaderPolicy() - : on_loaded_( - base::DoNothing::Once&, - std::unique_ptr>()), - on_failed_(base::DoNothing::Once()) {} - - ~MockLoaderPolicy() override = default; - - MockLoaderPolicy(const MockLoaderPolicy&) = delete; - MockLoaderPolicy& operator=(const MockLoaderPolicy&) = delete; - - void ComponentLoaded( - const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) override { - std::move(on_loaded_).Run(version, fd_map, std::move(manifest)); - } - - void ComponentLoadFailed() override { std::move(on_failed_).Run(); } - - void GetHash(std::vector* hash) const override { GetPkHash(hash); } - - private: - OnLoadedTestCallBack on_loaded_; - base::OnceClosure on_failed_; -}; - -void VerifyComponentLoaded(base::OnceClosure on_done, - const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) { - EXPECT_EQ(version.GetString(), "123.456.789"); - EXPECT_EQ(fd_map.size(), 2u); - EXPECT_NE(fd_map.find("file1.txt"), fd_map.end()); - EXPECT_NE(fd_map.find("file2.txt"), fd_map.end()); - - std::move(on_done).Run(); -} - -} // namespace - -class EmbeddedComponentLoaderTest : public testing::Test { - public: - EmbeddedComponentLoaderTest() = default; - ~EmbeddedComponentLoaderTest() override = default; - - EmbeddedComponentLoaderTest(const EmbeddedComponentLoaderTest&) = delete; - EmbeddedComponentLoaderTest& operator=(const EmbeddedComponentLoaderTest&) = - delete; - - void SetUp() override { - env_ = base::android::AttachCurrentThread(); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - } - - protected: - void WriteFile(const std::string& file_name, const std::string& content) { - ASSERT_TRUE( - base::WriteFile(temp_dir_.GetPath().AppendASCII(file_name), content)); - files_.push_back(file_name); - } - - std::vector GetFileFds() const { - return OpenFileFds(temp_dir_.GetPath(), files_); - } - - JNIEnv* env_ = nullptr; - std::vector files_; - - private: - base::ScopedTempDir temp_dir_; -}; - -TEST_F(EmbeddedComponentLoaderTest, TestValidManifest) { - base::test::TaskEnvironment task_environment; - - WriteFile("file1.txt", "1"); - WriteFile("file2.txt", "2"); - WriteFile("manifest.json", - "{\n\"manifest_version\": 2,\n\"version\": \"123.456.789\"\n}"); - - base::RunLoop run_loop; - EmbeddedComponentLoader loader(std::make_unique( - base::BindOnce(&VerifyComponentLoaded, run_loop.QuitClosure()), - base::BindOnce([]() { FAIL(); }))); - - loader.ComponentLoaded(env_, - base::android::ToJavaArrayOfStrings(env_, files_), - base::android::ToJavaIntArray(env_, GetFileFds())); - run_loop.Run(); -} - -TEST_F(EmbeddedComponentLoaderTest, TestMissingManifest) { - base::test::TaskEnvironment task_environment; - - WriteFile("file.txt", "test"); - - base::RunLoop run_loop; - EmbeddedComponentLoader loader(std::make_unique( - base::BindOnce( - [](const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) { FAIL(); }), - run_loop.QuitClosure())); - - loader.ComponentLoaded(env_, - base::android::ToJavaArrayOfStrings(env_, files_), - base::android::ToJavaIntArray(env_, GetFileFds())); - run_loop.Run(); -} - -TEST_F(EmbeddedComponentLoaderTest, TestInvalidVersion) { - base::test::TaskEnvironment task_environment; - - WriteFile("file.txt", "test"); - WriteFile("manifest.json", - "{\n\"manifest_version\": 2,\n\"version\": \"\"\n}"); - - base::RunLoop run_loop; - EmbeddedComponentLoader loader(std::make_unique( - base::BindOnce( - [](const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) { FAIL(); }), - run_loop.QuitClosure())); - - loader.ComponentLoaded(env_, - base::android::ToJavaArrayOfStrings(env_, files_), - base::android::ToJavaIntArray(env_, GetFileFds())); - run_loop.Run(); -} - -TEST_F(EmbeddedComponentLoaderTest, TestInvalidManifest) { - base::test::TaskEnvironment task_environment; - - WriteFile("file.txt", "test"); - WriteFile("manifest.json", "{\n\"manifest_version\":}"); - - base::RunLoop run_loop; - EmbeddedComponentLoader loader(std::make_unique( - base::BindOnce( - [](const base::Version& version, - const base::flat_map& fd_map, - std::unique_ptr manifest) { FAIL(); }), - run_loop.QuitClosure())); - - loader.ComponentLoaded(env_, - base::android::ToJavaArrayOfStrings(env_, files_), - base::android::ToJavaIntArray(env_, GetFileFds())); - run_loop.Run(); -} - -TEST_F(EmbeddedComponentLoaderTest, TestGetComponentId) { - base::test::TaskEnvironment task_environment; - - EmbeddedComponentLoader loader(std::make_unique()); - - base::android::ScopedJavaLocalRef jcomponentId = - loader.GetComponentId(env_); - - EXPECT_EQ(base::android::ConvertJavaStringToUTF8(jcomponentId), kComponentId); -} - -} // namespace component_updater \ No newline at end of file diff --git a/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc b/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc new file mode 100644 index 00000000000..cd55c8d544f --- /dev/null +++ b/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc @@ -0,0 +1,88 @@ +// Copyright 2021 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 "components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "base/bind.h" +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/optional.h" +#include "base/values.h" +#include "base/version.h" +#include "components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h" + +namespace { + +// Attempts to load key commitments as raw JSON from their storage file, +// returning the loaded commitments on success and nullopt on failure. +// TODO(crbug.com/1180964) move reading string from fd to base/file_util.h +base::Optional LoadKeyCommitmentsFromDisk(int fd) { + base::ScopedFILE file_stream(fdopen(fd, "r")); + if (!file_stream.get()) { + return base::nullopt; + } + std::string commitments; + if (!base::ReadStreamToString(file_stream.get(), &commitments)) + return base::nullopt; + + return commitments; +} + +} // namespace + +namespace component_updater { + +TrustTokenKeyCommitmentsComponentLoaderPolicy:: + TrustTokenKeyCommitmentsComponentLoaderPolicy( + base::RepeatingCallback on_commitments_ready) + : on_commitments_ready_(std::move(on_commitments_ready)) {} + +TrustTokenKeyCommitmentsComponentLoaderPolicy:: + ~TrustTokenKeyCommitmentsComponentLoaderPolicy() = default; + +void TrustTokenKeyCommitmentsComponentLoaderPolicy::ComponentLoaded( + const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) { + int keys_fd = -1; + for (auto& key_value : fd_map) { + if (key_value.first == kTrustTokenKeyCommitmentsFileName) { + keys_fd = key_value.second; + } else { + // Close unused fds. + close(key_value.second); + } + } + if (keys_fd == -1) { + VLOG(1) << "TrustTokenKeyCommitmentsComponentLoaderPolicy#ComponentLoaded " + "failed because keys.json is not found in the fd map"; + ComponentLoadFailed(); + return; + } + component_updater::TrustTokenKeyCommitmentsComponentInstallerPolicy:: + LoadTrustTokensFromString( + base::BindOnce(&LoadKeyCommitmentsFromDisk, keys_fd), + on_commitments_ready_); +} + +void TrustTokenKeyCommitmentsComponentLoaderPolicy::ComponentLoadFailed() {} + +void TrustTokenKeyCommitmentsComponentLoaderPolicy::GetHash( + std::vector* hash) const { + component_updater::TrustTokenKeyCommitmentsComponentInstallerPolicy:: + GetPublicKeyHash(hash); +} + +} // namespace component_updater diff --git a/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h b/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h new file mode 100644 index 00000000000..9652cdb17cb --- /dev/null +++ b/chromium/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h @@ -0,0 +1,56 @@ +// Copyright 2021 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. + +#ifndef COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_TRUST_TOKEN_KEY_COMMITMENTS_COMPONENT_LOADER_POLICY_H_ +#define COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_TRUST_TOKEN_KEY_COMMITMENTS_COMPONENT_LOADER_POLICY_H_ + +#include + +#include +#include +#include + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "components/component_updater/android/component_loader_policy.h" + +namespace base { +class DictionaryValue; +class Version; +} // namespace base + +namespace component_updater { + +// TrustTokenKeyCommitmentsComponentLoaderPolicy defines a loader responsible +// for receiving updated Trust Tokens key commitments config and passing them to +// the network service via Mojo. +class TrustTokenKeyCommitmentsComponentLoaderPolicy + : public ComponentLoaderPolicy { + public: + // |on_commitments_ready| will be called on the UI thread when + // key commitments become ready. + explicit TrustTokenKeyCommitmentsComponentLoaderPolicy( + base::RepeatingCallback on_commitments_ready); + ~TrustTokenKeyCommitmentsComponentLoaderPolicy() override; + + TrustTokenKeyCommitmentsComponentLoaderPolicy( + const TrustTokenKeyCommitmentsComponentLoaderPolicy&) = delete; + TrustTokenKeyCommitmentsComponentLoaderPolicy& operator=( + const TrustTokenKeyCommitmentsComponentLoaderPolicy&) = delete; + + private: + // The following methods override ComponentLoaderPolicy. + void ComponentLoaded( + const base::Version& version, + const base::flat_map& fd_map, + std::unique_ptr manifest) override; + void ComponentLoadFailed() override; + void GetHash(std::vector* hash) const override; + + base::RepeatingCallback on_commitments_ready_; +}; + +} // namespace component_updater + +#endif // COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_TRUST_TOKEN_KEY_COMMITMENTS_COMPONENT_LOADER_POLICY_H_ diff --git a/chromium/components/component_updater/component_installer.cc b/chromium/components/component_updater/component_installer.cc index 4195384e110..bc82389f170 100644 --- a/chromium/components/component_updater/component_installer.cc +++ b/chromium/components/component_updater/component_installer.cc @@ -7,6 +7,7 @@ #include #include "base/bind.h" +#include "base/callback.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -20,6 +21,7 @@ #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" +#include "base/threading/thread_checker.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "base/version.h" @@ -66,6 +68,15 @@ ComponentInstaller::~ComponentInstaller() = default; void ComponentInstaller::Register(ComponentUpdateService* cus, base::OnceClosure callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(cus); + Register(base::BindOnce(&ComponentUpdateService::RegisterComponent, + base::Unretained(cus)), + std::move(callback)); +} + +void ComponentInstaller::Register(RegisterCallback register_callback, + base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Some components may affect user visible features, hence USER_VISIBLE. task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( @@ -84,7 +95,8 @@ void ComponentInstaller::Register(ComponentUpdateService* cus, base::BindOnce(&ComponentInstaller::StartRegistration, this, registration_info), base::BindOnce(&ComponentInstaller::FinishRegistration, this, - registration_info, cus, std::move(callback))); + registration_info, std::move(register_callback), + std::move(callback))); } void ComponentInstaller::OnUpdateError(int error) { @@ -394,7 +406,7 @@ void ComponentInstaller::UninstallOnTaskRunner() { void ComponentInstaller::FinishRegistration( scoped_refptr registration_info, - ComponentUpdateService* cus, + RegisterCallback register_callback, base::OnceClosure callback) { VLOG(1) << __func__ << " for " << installer_policy_->GetName(); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -419,7 +431,7 @@ void ComponentInstaller::FinishRegistration( crx.supports_group_policy_enable_component_updates = installer_policy_->SupportsGroupPolicyEnabledComponentUpdates(); - if (!cus->RegisterComponent(crx)) { + if (!std::move(register_callback).Run(crx)) { LOG(ERROR) << "Component registration failed for " << installer_policy_->GetName(); if (!callback.is_null()) diff --git a/chromium/components/component_updater/component_installer.h b/chromium/components/component_updater/component_installer.h index 59acccf579b..bedc9e02130 100644 --- a/chromium/components/component_updater/component_installer.h +++ b/chromium/components/component_updater/component_installer.h @@ -26,6 +26,8 @@ class SingleThreadTaskRunner; } // namespace base namespace component_updater { +using RegisterCallback = + base::OnceCallback; class ComponentUpdateService; @@ -113,10 +115,16 @@ class ComponentInstaller final : public update_client::CrxInstaller { scoped_refptr action_handler = nullptr); // Registers the component for update checks and installs. + // |cus| provides the registration logic. // The passed |callback| will be called once the initial check for installed // versions is done and the component has been registered. void Register(ComponentUpdateService* cus, base::OnceClosure callback); + // Registers the component for update checks and installs. + // |register_callback| is called to do the registration. + // |callback| is called when registration finishes. + void Register(RegisterCallback register_callback, base::OnceClosure callback); + // Overrides from update_client::CrxInstaller. void OnUpdateError(int error) override; @@ -163,7 +171,7 @@ class ComponentInstaller final : public update_client::CrxInstaller { base::FilePath* install_path); void StartRegistration(scoped_refptr registration_info); void FinishRegistration(scoped_refptr registration_info, - ComponentUpdateService* cus, + RegisterCallback register_callback, base::OnceClosure callback); void ComponentReady(std::unique_ptr manifest); void UninstallOnTaskRunner(); diff --git a/chromium/components/component_updater/component_updater_service.cc b/chromium/components/component_updater/component_updater_service.cc index f76eb12049b..94e48b56e36 100644 --- a/chromium/components/component_updater/component_updater_service.cc +++ b/chromium/components/component_updater/component_updater_service.cc @@ -24,6 +24,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "components/component_updater/component_updater_service_internal.h" +#include "components/component_updater/component_updater_utils.h" #include "components/update_client/configurator.h" #include "components/update_client/crx_update_item.h" #include "components/update_client/update_client.h" @@ -48,7 +49,7 @@ namespace component_updater { ComponentInfo::ComponentInfo(const std::string& id, const std::string& fingerprint, - const base::string16& name, + const std::u16string& name, const base::Version& version) : id(id), fingerprint(fingerprint), name(name), version(version) {} ComponentInfo::ComponentInfo(const ComponentInfo& other) = default; @@ -212,10 +213,7 @@ OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { base::Optional CrxUpdateService::GetComponent( const std::string& id) const { DCHECK(thread_checker_.CalledOnValidThread()); - const auto it = components_.find(id); - if (it != components_.end()) - return it->second; - return base::nullopt; + return component_updater::GetComponent(components_, id); } const CrxUpdateItem* CrxUpdateService::GetComponentState( @@ -379,10 +377,7 @@ bool CrxUpdateService::GetComponentDetails(const std::string& id, std::vector> CrxUpdateService::GetCrxComponents( const std::vector& ids) { DCHECK(thread_checker_.CalledOnValidThread()); - std::vector> components; - for (const auto& id : ids) - components.push_back(GetComponent(id)); - return components; + return component_updater::GetCrxComponents(components_, ids); } void CrxUpdateService::OnUpdateComplete(Callback callback, diff --git a/chromium/components/component_updater/component_updater_service.h b/chromium/components/component_updater/component_updater_service.h index d8790667654..b4693bbeaf5 100644 --- a/chromium/components/component_updater/component_updater_service.h +++ b/chromium/components/component_updater/component_updater_service.h @@ -53,7 +53,7 @@ using CrxUpdateItem = update_client::CrxUpdateItem; struct ComponentInfo { ComponentInfo(const std::string& id, const std::string& fingerprint, - const base::string16& name, + const std::u16string& name, const base::Version& version); ComponentInfo(const ComponentInfo& other); ComponentInfo(ComponentInfo&& other); @@ -61,7 +61,7 @@ struct ComponentInfo { const std::string id; const std::string fingerprint; - const base::string16 name; + const std::u16string name; const base::Version version; }; diff --git a/chromium/components/component_updater/component_updater_service_internal.h b/chromium/components/component_updater/component_updater_service_internal.h index 19d92ea76fc..e27044e3842 100644 --- a/chromium/components/component_updater/component_updater_service_internal.h +++ b/chromium/components/component_updater/component_updater_service_internal.h @@ -10,6 +10,7 @@ #include #include +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/optional.h" @@ -94,7 +95,7 @@ class CrxUpdateService : public ComponentUpdateService, scoped_refptr update_client_; // A collection of every registered component. - using Components = std::map; + using Components = base::flat_map; Components components_; // Maintains the order in which components have been registered. The position diff --git a/chromium/components/component_updater/component_updater_utils.cc b/chromium/components/component_updater/component_updater_utils.cc new file mode 100644 index 00000000000..2def469b88a --- /dev/null +++ b/chromium/components/component_updater/component_updater_utils.cc @@ -0,0 +1,35 @@ +// Copyright 2021 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 "components/component_updater/component_updater_utils.h" + +#include +#include + +#include "base/containers/flat_map.h" +#include "base/optional.h" +#include "components/update_client/update_client.h" + +namespace component_updater { + +base::Optional GetComponent( + const base::flat_map& components, + const std::string& id) { + const auto it = components.find(id); + if (it != components.end()) + return it->second; + return base::nullopt; +} + +std::vector> GetCrxComponents( + const base::flat_map& + registered_components, + const std::vector& ids) { + std::vector> components; + for (const auto& id : ids) + components.push_back(GetComponent(registered_components, id)); + return components; +} + +} // namespace component_updater diff --git a/chromium/components/component_updater/component_updater_utils.h b/chromium/components/component_updater/component_updater_utils.h new file mode 100644 index 00000000000..d65639e9455 --- /dev/null +++ b/chromium/components/component_updater/component_updater_utils.h @@ -0,0 +1,31 @@ +// Copyright 2021 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. + +#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_UTILS_H_ +#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_UTILS_H_ + +#include +#include + +#include "base/containers/flat_map.h" +#include "base/optional.h" + +namespace update_client { +struct CrxComponent; +} // namespace update_client + +namespace component_updater { + +base::Optional GetComponent( + const base::flat_map& components, + const std::string& id); + +std::vector> GetCrxComponents( + const base::flat_map& + registered_components, + const std::vector& ids); + +} // namespace component_updater + +#endif // COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_UTILS_H_ diff --git a/chromium/components/component_updater/installer_policies/origin_trials_component_installer.cc b/chromium/components/component_updater/installer_policies/origin_trials_component_installer.cc index 713c2e3e8d5..6122093307d 100644 --- a/chromium/components/component_updater/installer_policies/origin_trials_component_installer.cc +++ b/chromium/components/component_updater/installer_policies/origin_trials_component_installer.cc @@ -4,7 +4,9 @@ #include "components/component_updater/installer_policies/origin_trials_component_installer.h" +#include #include +#include #include "base/bind.h" #include "base/callback.h" @@ -48,6 +50,20 @@ const uint8_t kOriginTrialSha2Hash[] = { } // namespace +// static +void OriginTrialsComponentInstallerPolicy::GetComponentHash( + std::vector* hash) { + if (!hash) + return; + hash->assign(std::begin(kOriginTrialSha2Hash), + std::end(kOriginTrialSha2Hash)); +} + +void OriginTrialsComponentInstallerPolicy::GetHash( + std::vector* hash) const { + GetComponentHash(hash); +} + bool OriginTrialsComponentInstallerPolicy::VerifyInstallation( const base::DictionaryValue& manifest, const base::FilePath& install_dir) const { @@ -83,14 +99,6 @@ base::FilePath OriginTrialsComponentInstallerPolicy::GetRelativeInstallDir() return base::FilePath(FILE_PATH_LITERAL("OriginTrials")); } -void OriginTrialsComponentInstallerPolicy::GetHash( - std::vector* hash) const { - if (!hash) - return; - hash->assign(kOriginTrialSha2Hash, - kOriginTrialSha2Hash + base::size(kOriginTrialSha2Hash)); -} - std::string OriginTrialsComponentInstallerPolicy::GetName() const { return "Origin Trials"; } diff --git a/chromium/components/component_updater/installer_policies/origin_trials_component_installer.h b/chromium/components/component_updater/installer_policies/origin_trials_component_installer.h index 9e81f42326c..1d682b82251 100644 --- a/chromium/components/component_updater/installer_policies/origin_trials_component_installer.h +++ b/chromium/components/component_updater/installer_policies/origin_trials_component_installer.h @@ -21,6 +21,7 @@ namespace component_updater { class OriginTrialsComponentInstallerPolicy : public ComponentInstallerPolicy { public: + static void GetComponentHash(std::vector* hash); OriginTrialsComponentInstallerPolicy() = default; ~OriginTrialsComponentInstallerPolicy() override = default; OriginTrialsComponentInstallerPolicy( diff --git a/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.cc b/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.cc index 8b56f9ac77b..87295372536 100644 --- a/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.cc +++ b/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.cc @@ -19,6 +19,7 @@ #include "base/path_service.h" #include "base/stl_util.h" #include "base/task/post_task.h" +#include "base/task/thread_pool.h" #include "base/version.h" #include "components/component_updater/component_updater_paths.h" #include "components/component_updater/component_updater_switches.h" @@ -27,11 +28,6 @@ using component_updater::ComponentUpdateService; namespace { -// This file name must be in sync with the server-side configuration, or updates -// will fail. -const base::FilePath::CharType kTrustTokenKeyCommitmentsFileName[] = - FILE_PATH_LITERAL("keys.json"); - // The SHA256 of the SubjectPublicKeyInfo used to sign the extension. // The extension id is: kiabhabjdbkjdpjbpigfodbdjmbglcoo const uint8_t kTrustTokenKeyCommitmentsPublicKeySHA256[32] = { @@ -115,21 +111,9 @@ void TrustTokenKeyCommitmentsComponentInstallerPolicy::ComponentReady( VLOG(1) << "Component ready, version " << version.GetString() << " in " << install_dir.value(); - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&LoadKeyCommitmentsFromDisk, - GetInstalledPath(install_dir)), - base::BindOnce( - // Only bother sending commitments to the network service if we loaded - // them successfully. - [](base::RepeatingCallback - on_commitments_ready, - base::Optional loaded_commitments) { - if (loaded_commitments.has_value()) { - on_commitments_ready.Run(*loaded_commitments); - } - }, - on_commitments_ready_)); + LoadTrustTokensFromString(base::BindOnce(&LoadKeyCommitmentsFromDisk, + GetInstalledPath(install_dir)), + on_commitments_ready_); } // Called during startup and installation before ComponentReady(). @@ -149,9 +133,7 @@ TrustTokenKeyCommitmentsComponentInstallerPolicy::GetRelativeInstallDir() void TrustTokenKeyCommitmentsComponentInstallerPolicy::GetHash( std::vector* hash) const { - hash->assign(kTrustTokenKeyCommitmentsPublicKeySHA256, - kTrustTokenKeyCommitmentsPublicKeySHA256 + - base::size(kTrustTokenKeyCommitmentsPublicKeySHA256)); + GetPublicKeyHash(hash); } std::string TrustTokenKeyCommitmentsComponentInstallerPolicy::GetName() const { @@ -164,4 +146,33 @@ TrustTokenKeyCommitmentsComponentInstallerPolicy::GetInstallerAttributes() return update_client::InstallerAttributes(); } +// static +void TrustTokenKeyCommitmentsComponentInstallerPolicy::GetPublicKeyHash( + std::vector* hash) { + DCHECK(hash); + hash->assign(kTrustTokenKeyCommitmentsPublicKeySHA256, + kTrustTokenKeyCommitmentsPublicKeySHA256 + + base::size(kTrustTokenKeyCommitmentsPublicKeySHA256)); +} + +// static +void TrustTokenKeyCommitmentsComponentInstallerPolicy:: + LoadTrustTokensFromString( + base::OnceCallback()> load_keys_from_disk, + base::OnceCallback on_commitments_ready) { + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + std::move(load_keys_from_disk), + base::BindOnce( + // Only bother sending commitments to the network service if we loaded + // them successfully. + [](base::OnceCallback on_commitments_ready, + base::Optional loaded_commitments) { + if (loaded_commitments.has_value()) { + std::move(on_commitments_ready).Run(loaded_commitments.value()); + } + }, + std::move(on_commitments_ready))); +} + } // namespace component_updater diff --git a/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h b/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h index 897cbdb70e8..c6e31982c62 100644 --- a/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h +++ b/chromium/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h @@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" +#include "base/optional.h" #include "base/values.h" #include "components/component_updater/component_installer.h" @@ -23,6 +24,11 @@ class FilePath; namespace component_updater { +// This file name must be in sync with the server-side configuration, or updates +// will fail. +const base::FilePath::CharType kTrustTokenKeyCommitmentsFileName[] = + FILE_PATH_LITERAL("keys.json"); + // TrustTokenKeyCommitmentsComponentInstallerPolicy defines an installer // responsible for receiving updated Trust Tokens // (https://github.com/wicg/trust-token-api) key commitments and passing them to @@ -41,6 +47,20 @@ class TrustTokenKeyCommitmentsComponentInstallerPolicy TrustTokenKeyCommitmentsComponentInstallerPolicy& operator=( const TrustTokenKeyCommitmentsComponentInstallerPolicy&) = delete; + // Returns the component's SHA2 hash as raw bytes. + static void GetPublicKeyHash(std::vector* hash); + + // Loads trust tokens from string using the given `load_keys_from_disk` call. + // + // static to allow sharing with the Android `ComponentLoaderPolicy`. + // + // `load_keys_from_disk` a callback that read trust tokens from file and + // return them as an optional string. `on_commitments_ready` loads trust + // tokens in network service. + static void LoadTrustTokensFromString( + base::OnceCallback()> load_keys_from_disk, + base::OnceCallback on_commitments_ready); + protected: void GetHash(std::vector* hash) const override; -- cgit v1.2.1