extension_builder.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
  5. #define EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
  6. #include <initializer_list>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include "base/files/file_path.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/strings/string_piece.h"
  13. #include "extensions/common/api/extension_action/action_info.h"
  14. #include "extensions/common/manifest.h"
  15. #include "extensions/common/mojom/manifest.mojom-shared.h"
  16. #include "extensions/common/value_builder.h"
  17. namespace extensions {
  18. class Extension;
  19. // An easier way to create extensions than Extension::Create. The
  20. // constructor sets up some defaults which are customized using the
  21. // methods.
  22. // This class can be used in two ways:
  23. // Aided Manifest Construction
  24. // The easy way. Use the constructor that takes a name and use helper methods
  25. // like AddPermission() to customize the extension without needing to
  26. // construct the manifest dictionary by hand. For more customization, you can
  27. // use MergeManifest() to add additional keys (which will take precedence over
  28. // others).
  29. // Custom Manifest Construction
  30. // The hard way. Use the default constructor. SetManifest() *must* be called
  31. // with a valid manifest dictionary.
  32. // TODO(devlin): My suspicion is that this is almost always less readable and
  33. // useful, but it came first and is used in many places. It'd be nice to maybe
  34. // get rid of it.
  35. // These are not interchangable - calling SetManifest() with aided manifest
  36. // construction or e.g. AddPermissions() with custom manifest construction will
  37. // crash.
  38. class ExtensionBuilder {
  39. public:
  40. enum class Type {
  41. EXTENSION,
  42. PLATFORM_APP,
  43. };
  44. enum class BackgroundContext {
  45. BACKGROUND_PAGE,
  46. EVENT_PAGE,
  47. SERVICE_WORKER,
  48. };
  49. static constexpr char kServiceWorkerScriptFile[] = "sw.js";
  50. // Initializes an ExtensionBuilder that can be used with SetManifest() for
  51. // complete customization.
  52. ExtensionBuilder();
  53. // Initializes an ExtensionBuilder that can be used with various utility
  54. // methods to automatically construct a manifest. |name| will be the name of
  55. // the extension and used to generate a stable ID.
  56. ExtensionBuilder(const std::string& name, Type type = Type::EXTENSION);
  57. ExtensionBuilder(const ExtensionBuilder&) = delete;
  58. ExtensionBuilder& operator=(const ExtensionBuilder&) = delete;
  59. ~ExtensionBuilder();
  60. // Move constructor and operator=.
  61. ExtensionBuilder(ExtensionBuilder&& other);
  62. ExtensionBuilder& operator=(ExtensionBuilder&& other);
  63. // Returns the base::Value for the manifest, rather than constructing a full
  64. // extension. This is useful if you want to then use this in a ManifestTest or
  65. // to write a manifest with a TestExtensionDir.
  66. base::Value BuildManifest();
  67. // Can only be called once, after which it's invalid to use the builder.
  68. // CHECKs that the extension was created successfully.
  69. scoped_refptr<const Extension> Build();
  70. //////////////////////////////////////////////////////////////////////////////
  71. // Utility methods for use with aided manifest construction.
  72. // Add one or more permissions to the extension.
  73. ExtensionBuilder& AddPermission(const std::string& permission);
  74. ExtensionBuilder& AddPermissions(const std::vector<std::string>& permissions);
  75. // Sets an action type for the extension to have. By default, no action will
  76. // be set (though note that we synthesize a page action for most extensions).
  77. ExtensionBuilder& SetAction(ActionInfo::Type type);
  78. // Sets a background context for the extension. By default, none will be set.
  79. ExtensionBuilder& SetBackgroundContext(BackgroundContext background_context);
  80. // Adds a content script to the extension, with a script with the specified
  81. // |script_name| that matches the given |match_patterns|.
  82. ExtensionBuilder& AddContentScript(
  83. const std::string& script_name,
  84. const std::vector<std::string>& match_patterns);
  85. // Shortcuts for extremely popular keys.
  86. // Typically we'd use SetManifestKey() or SetManifestPath() for these, but
  87. // provide a faster route for these, since they're so central.
  88. ExtensionBuilder& SetVersion(const std::string& version);
  89. ExtensionBuilder& SetManifestVersion(int manifest_version);
  90. // Shortcuts to setting values on the manifest dictionary without needing to
  91. // go all the way through MergeManifest(). Sample usage:
  92. // ExtensionBuilder("name").SetManifestKey("version", "0.2").Build();
  93. // Can be used in conjuction with ListBuilder and DictionaryBuilder for more
  94. // complex types.
  95. template <typename T>
  96. ExtensionBuilder& SetManifestKey(base::StringPiece key, T&& value) {
  97. SetManifestKeyImpl(key, base::Value(std::forward<T>(value)));
  98. return *this;
  99. }
  100. template <typename T>
  101. ExtensionBuilder& SetManifestPath(
  102. std::initializer_list<base::StringPiece> path,
  103. T&& value) {
  104. SetManifestPathImpl(path, base::Value(std::forward<T>(value)));
  105. return *this;
  106. }
  107. // Specializations for unique_ptr<> to allow passing unique_ptr<base::Value>.
  108. // All other types will fail to compile.
  109. template <typename T>
  110. ExtensionBuilder& SetManifestKey(base::StringPiece key,
  111. std::unique_ptr<T> value) {
  112. SetManifestKeyImpl(key, std::move(*value));
  113. return *this;
  114. }
  115. template <typename T>
  116. ExtensionBuilder& SetManifestPath(
  117. std::initializer_list<base::StringPiece> path,
  118. std::unique_ptr<T> value) {
  119. SetManifestPathImpl(path, std::move(*value));
  120. return *this;
  121. }
  122. // A shortcut for adding raw JSON to the extension manifest. Useful if
  123. // constructing the values with a ValueBuilder is more painful than seeing
  124. // them with a string.
  125. // This JSON should be what you would add at the root node of the manifest;
  126. // for instance:
  127. // builder.AddJSON(R"("content_scripts": [...], "action": {})");
  128. // Keys specified in `json` take precedence over previously-set values.
  129. ExtensionBuilder& AddJSON(base::StringPiece json);
  130. //////////////////////////////////////////////////////////////////////////////
  131. // Utility methods for use with custom manifest construction.
  132. // Assigns the extension's manifest to |manifest|.
  133. ExtensionBuilder& SetManifest(
  134. std::unique_ptr<base::DictionaryValue> manifest);
  135. //////////////////////////////////////////////////////////////////////////////
  136. // Common utility methods (usable with both aided and custom manifest
  137. // creation).
  138. // Defaults to FilePath().
  139. ExtensionBuilder& SetPath(const base::FilePath& path);
  140. // Defaults to mojom::ManifestLocation::kUnpacked.
  141. ExtensionBuilder& SetLocation(mojom::ManifestLocation location);
  142. // Merge another manifest into the current manifest, with new keys taking
  143. // precedence.
  144. ExtensionBuilder& MergeManifest(const base::Value& manifest);
  145. ExtensionBuilder& MergeManifest(
  146. std::unique_ptr<base::DictionaryValue> manifest);
  147. // Add flags to the extension. Default is no flags.
  148. ExtensionBuilder& AddFlags(int init_from_value_flags);
  149. // Defaults to the default extension ID created in Extension::Create or to an
  150. // ID generated from the extension's name, if aided manifest construction is
  151. // used.
  152. ExtensionBuilder& SetID(const std::string& id);
  153. private:
  154. struct ManifestData;
  155. void SetManifestKeyImpl(base::StringPiece key, base::Value value);
  156. void SetManifestPathImpl(std::initializer_list<base::StringPiece> path,
  157. base::Value value);
  158. // Information for constructing the manifest; either metadata about the
  159. // manifest which will be used to construct it, or the dictionary itself. Only
  160. // one will be present.
  161. std::unique_ptr<ManifestData> manifest_data_;
  162. std::unique_ptr<base::DictionaryValue> manifest_value_;
  163. base::FilePath path_;
  164. mojom::ManifestLocation location_;
  165. int flags_;
  166. std::string id_;
  167. };
  168. } // namespace extensions
  169. #endif // EXTENSIONS_COMMON_EXTENSION_BUILDER_H_