1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// Copyright 2021 The Chromium Authors
// 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 <jni.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/android/scoped_java_ref.h"
#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/values.h"
#include "components/component_updater/android/component_loader_policy_forward.h"
namespace base {
class Version;
} // namespace base
namespace component_updater {
// Errors that cause failure when loading a component. These values are
// persisted to logs. Entries should not be renumbered and numeric values should
// never be reused.
//
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.component_updater
enum class ComponentLoadResult {
kComponentLoaded = 0,
kFailedToConnectToComponentsProviderService = 1,
kRemoteException = 2,
kComponentsProviderServiceError = 3,
kMissingManifest = 4,
kMalformedManifest = 5,
kInvalidVersion = 6,
kMaxValue = kInvalidVersion,
};
inline constexpr char kManifestFileName[] = "manifest.json";
inline constexpr char kMetadataFileName[] = "aw_extra_component_metadata.json";
inline constexpr char kMetadataFileCohortIdKey[] = "cohortId";
inline constexpr char kComponentsCrashKeyName[] = "crx-components";
inline constexpr char kCohortHashCrashKeyName[] =
"crx-components-cohort-hashes";
// 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,
base::flat_map<std::string, base::ScopedFD>& fd_map,
base::Value::Dict 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.
virtual void ComponentLoadFailed(ComponentLoadResult error) = 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<uint8_t>* hash) const = 0;
// Returns a Human readable string that can be used as a suffix for recorded
// UMA metrics. New suffixes should be added to
// "ComponentUpdater.AndroidComponentLoader.ComponentName" in
// tools/metrics/histograms/metadata/histogram_suffixes_list.xml.
virtual std::string GetMetricsSuffix() 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<ComponentLoaderPolicy> 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<jobjectArray>
ToJavaArrayOfAndroidComponentLoaderPolicy(
JNIEnv* env,
ComponentLoaderPolicyVector policies);
// JNI overrides:
void ComponentLoaded(JNIEnv* env,
const base::android::JavaRef<jobjectArray>& jfile_names,
const base::android::JavaRef<jintArray>& jfds);
void ComponentLoadFailed(JNIEnv* env, jint error_code);
base::android::ScopedJavaLocalRef<jstring> GetComponentId(JNIEnv* env);
private:
// Returns a Java object of
// `org.chromium.components.component_updater.ComponentLoaderPolicy`.
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
std::string GetComponentId() const;
void NotifyNewVersion(
base::flat_map<std::string, base::ScopedFD>& fd_map,
std::pair<std::optional<base::Value::Dict>,
std::optional<base::Value::Dict>> component_files);
void ComponentLoadFailedInternal(ComponentLoadResult error);
SEQUENCE_CHECKER(sequence_checker_);
// A Java object of
// `org.chromium.components.component_updater.ComponentLoaderPolicy`.
base::android::ScopedJavaGlobalRef<jobject> obj_;
std::unique_ptr<ComponentLoaderPolicy> loader_policy_;
};
} // namespace component_updater
#endif // COMPONENTS_COMPONENT_UPDATER_ANDROID_COMPONENT_LOADER_POLICY_H_
|