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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
#define EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
#include <initializer_list>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include "base/files/file_path.h"
#include "base/memory/scoped_refptr.h"
#include "base/values.h"
#include "extensions/common/api/extension_action/action_info.h"
#include "extensions/common/manifest.h"
#include "extensions/common/mojom/manifest.mojom-shared.h"
namespace extensions {
class Extension;
// An easier way to create extensions than Extension::Create. The
// constructor sets up some defaults which are customized using the
// methods.
// This class can be used in two ways:
// Aided Manifest Construction
// The easy way. Use the constructor that takes a name and use helper methods
// like AddAPIPermission() to customize the extension without needing to
// construct the manifest dictionary by hand. For more customization, you can
// use MergeManifest() to add additional keys (which will take precedence over
// others).
// Custom Manifest Construction
// The hard way. Use the default constructor. SetManifest() *must* be called
// with a valid manifest dictionary.
// TODO(devlin): My suspicion is that this is almost always less readable and
// useful, but it came first and is used in many places. It'd be nice to maybe
// get rid of it.
// These are not interchangeable - calling SetManifest() with aided manifest
// construction or e.g. AddAPIPermissions() with custom manifest construction
// will crash.
class ExtensionBuilder {
public:
enum class Type {
EXTENSION,
PLATFORM_APP,
};
enum class BackgroundContext {
BACKGROUND_PAGE,
EVENT_PAGE,
SERVICE_WORKER,
};
static constexpr char kServiceWorkerScriptFile[] = "sw.js";
// Initializes an ExtensionBuilder that can be used with SetManifest() for
// complete customization.
ExtensionBuilder();
// Initializes an ExtensionBuilder that can be used with various utility
// methods to automatically construct a manifest. `name` will be the name of
// the extension and used to generate a stable ID.
explicit ExtensionBuilder(const std::string& name,
Type type = Type::EXTENSION);
ExtensionBuilder(const ExtensionBuilder&) = delete;
ExtensionBuilder& operator=(const ExtensionBuilder&) = delete;
~ExtensionBuilder();
// Move constructor and operator=.
ExtensionBuilder(ExtensionBuilder&& other);
ExtensionBuilder& operator=(ExtensionBuilder&& other);
// Returns the base::Value for the manifest, rather than constructing a full
// extension. This is useful if you want to then use this in a ManifestTest or
// to write a manifest with a TestExtensionDir.
base::Value BuildManifest();
// Can only be called once, after which it's invalid to use the builder.
// CHECKs that the extension was created successfully.
scoped_refptr<const Extension> Build();
//////////////////////////////////////////////////////////////////////////////
// Utility methods for use with aided manifest construction.
// Adds one or more API permissions to the extension.
ExtensionBuilder& AddAPIPermission(const std::string& permission);
ExtensionBuilder& AddAPIPermissions(
const std::vector<std::string>& permissions);
// Adds one or more optional API permissions to the extension.
ExtensionBuilder& AddOptionalAPIPermission(const std::string& permission);
ExtensionBuilder& AddOptionalAPIPermissions(
const std::vector<std::string>& permissions);
// Adds one or more host permissions to the extension.
ExtensionBuilder& AddHostPermission(const std::string& permission);
ExtensionBuilder& AddHostPermissions(
const std::vector<std::string>& permissions);
// Adds one or more optional host permissions to the extension.
ExtensionBuilder& AddOptionalHostPermission(const std::string& permission);
ExtensionBuilder& AddOptionalHostPermissions(
const std::vector<std::string>& permissions);
// Sets an action type for the extension to have. By default, no action will
// be set (though note that we synthesize a page action for most extensions).
ExtensionBuilder& SetAction(ActionInfo::Type type);
// Sets a background context for the extension. By default, none will be set.
ExtensionBuilder& SetBackgroundContext(BackgroundContext background_context);
// Adds a content script to the extension, with a script with the specified
// `script_name` that matches the given `match_patterns`.
ExtensionBuilder& AddContentScript(
const std::string& script_name,
const std::vector<std::string>& match_patterns);
// Shortcuts for extremely popular keys.
// Typically we'd use SetManifestKey() or SetManifestPath() for these, but
// provide a faster route for these, since they're so central.
ExtensionBuilder& SetVersion(const std::string& version);
ExtensionBuilder& SetManifestVersion(int manifest_version);
// Shortcuts to setting values on the manifest dictionary without needing to
// go all the way through MergeManifest(). Sample usage:
// ExtensionBuilder("name").SetManifestKey("version", "0.2").Build();
// Can be used in conjunction with chained base::Value::List and
// base::Value::Dict to create complex values.
template <typename T>
ExtensionBuilder& SetManifestKey(std::string_view key, T&& value) {
SetManifestKeyImpl(key, base::Value(std::forward<T>(value)));
return *this;
}
template <typename T>
ExtensionBuilder& SetManifestPath(std::string_view path, T&& value) {
SetManifestPathImpl(path, base::Value(std::forward<T>(value)));
return *this;
}
// A shortcut for adding raw JSON to the extension manifest. Useful if
// constructing the values with a ValueBuilder is more painful than seeing
// them with a string.
// This JSON should be what you would add at the root node of the manifest;
// for instance:
// builder.AddJSON(R"("content_scripts": [...], "action": {})");
// Keys specified in `json` take precedence over previously-set values.
ExtensionBuilder& AddJSON(std::string_view json);
//////////////////////////////////////////////////////////////////////////////
// Utility methods for use with custom manifest construction.
// Assigns the extension's manifest to `manifest`.
ExtensionBuilder& SetManifest(base::Value::Dict manifest);
//////////////////////////////////////////////////////////////////////////////
// Common utility methods (usable with both aided and custom manifest
// creation).
// Defaults to FilePath().
ExtensionBuilder& SetPath(const base::FilePath& path);
// Defaults to mojom::ManifestLocation::kUnpacked.
ExtensionBuilder& SetLocation(mojom::ManifestLocation location);
// Merge another manifest into the current manifest, with new keys taking
// precedence.
ExtensionBuilder& MergeManifest(base::Value::Dict manifest);
// Add flags to the extension. Default is no flags.
ExtensionBuilder& AddFlags(int init_from_value_flags);
// Defaults to the default extension ID created in Extension::Create or to an
// ID generated from the extension's name, if aided manifest construction is
// used.
ExtensionBuilder& SetID(const std::string& id);
private:
struct ManifestData;
void SetManifestKeyImpl(std::string_view key, base::Value value);
void SetManifestPathImpl(std::string_view path, base::Value value);
// Information for constructing the manifest; either metadata about the
// manifest which will be used to construct it, or the dictionary itself. Only
// one will be present.
std::unique_ptr<ManifestData> manifest_data_;
std::optional<base::Value::Dict> manifest_value_;
base::FilePath path_;
mojom::ManifestLocation location_;
int flags_;
std::string id_;
};
} // namespace extensions
#endif // EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
|