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
5#ifndef EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
6#define EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
7
8#include <initializer_list>
9#include <memory>
10#include <string>
11
12#include "base/files/file_path.h"
13#include "base/macros.h"
14#include "base/memory/ref_counted.h"
15#include "base/strings/string_piece.h"
16#include "extensions/common/manifest.h"
17#include "extensions/common/value_builder.h"
18
19namespace extensions {
20class Extension;
21
22// An easier way to create extensions than Extension::Create. The
23// constructor sets up some defaults which are customized using the
24// methods.
25// This class can be used in two ways:
26// Aided Manifest Construction
27// The easy way. Use the constructor that takes a name and use helper methods
28// like AddPermission() to customize the extension without needing to
29// construct the manifest dictionary by hand. For more customization, you can
30// use MergeManifest() to add additional keys (which will take precedence over
31// others).
32// Custom Manifest Construction
33// The hard way. Use the default constructor. SetManifest() *must* be called
34// with a valid manifest dictionary.
35// TODO(devlin): My suspicion is that this is almost always less readable and
36// useful, but it came first and is used in many places. It'd be nice to maybe
37// get rid of it.
38// These are not interchangable - calling SetManifest() with aided manifest
39// construction or e.g. AddPermissions() with custom manifest construction will
40// crash.
41class ExtensionBuilder {
42 public:
43 enum class Type {
44 EXTENSION,
45 PLATFORM_APP,
46 };
47
48 enum class ActionType {
49 PAGE_ACTION,
50 BROWSER_ACTION,
51 };
52
53 enum class BackgroundPage {
54 PERSISTENT,
55 EVENT,
56 };
57
58 // Initializes an ExtensionBuilder that can be used with SetManifest() for
59 // complete customization.
60 ExtensionBuilder();
61
62 // Initializes an ExtensionBuilder that can be used with various utility
63 // methods to automatically construct a manifest. |name| will be the name of
64 // the extension and used to generate a stable ID.
65 ExtensionBuilder(const std::string& name, Type type = Type::EXTENSION);
66
67 ~ExtensionBuilder();
68
69 // Move constructor and operator=.
70 ExtensionBuilder(ExtensionBuilder&& other);
71 ExtensionBuilder& operator=(ExtensionBuilder&& other);
72
73 // Can only be called once, after which it's invalid to use the builder.
74 // CHECKs that the extension was created successfully.
75 scoped_refptr<const Extension> Build();
76
77 //////////////////////////////////////////////////////////////////////////////
78 // Utility methods for use with aided manifest construction.
79
80 // Add one or more permissions to the extension.
81 ExtensionBuilder& AddPermission(const std::string& permission);
82 ExtensionBuilder& AddPermissions(const std::vector<std::string>& permissions);
83
84 // Sets an action type for the extension to have. By default, no action will
85 // be set (though note that we synthesize a page action for most extensions).
86 ExtensionBuilder& SetAction(ActionType action);
87
88 // Sets a background page for the extension to have. By default, no background
89 // page will be set.
90 ExtensionBuilder& SetBackgroundPage(BackgroundPage background_page);
91
92 // Adds a content script to the extension, with a script with the specified
93 // |script_name| that matches the given |match_patterns|.
94 ExtensionBuilder& AddContentScript(
95 const std::string& script_name,
96 const std::vector<std::string>& match_patterns);
97
98 // Shortcut for setting a specific manifest version. Typically we'd use
99 // SetManifestKey() or SetManifestPath() for these, but provide a faster
100 // route for version, since it's so central.
101 ExtensionBuilder& SetVersion(const std::string& version);
102
103 // Shortcuts to setting values on the manifest dictionary without needing to
104 // go all the way through MergeManifest(). Sample usage:
105 // ExtensionBuilder("name").SetManifestKey("version", "0.2").Build();
106 // Can be used in conjuction with ListBuilder and DictionaryBuilder for more
107 // complex types.
108 template <typename T>
109 ExtensionBuilder& SetManifestKey(base::StringPiece key, T value) {
110 SetManifestKeyImpl(key, base::Value(value));
111 return *this;
112 }
113 template <typename T>
114 ExtensionBuilder& SetManifestPath(
115 std::initializer_list<base::StringPiece> path,
116 T value) {
117 SetManifestPathImpl(path, base::Value(value));
118 return *this;
119 }
120 // Specializations for unique_ptr<> to allow passing unique_ptr<base::Value>.
121 // All other types will fail to compile.
122 template <typename T>
123 ExtensionBuilder& SetManifestKey(base::StringPiece key,
124 std::unique_ptr<T> value) {
125 SetManifestKeyImpl(key, std::move(*value));
126 return *this;
127 }
128 template <typename T>
129 ExtensionBuilder& SetManifestPath(
130 std::initializer_list<base::StringPiece> path,
131 std::unique_ptr<T> value) {
132 SetManifestPathImpl(path, std::move(*value));
133 return *this;
134 }
135
136 //////////////////////////////////////////////////////////////////////////////
137 // Utility methods for use with custom manifest construction.
138
139 // Assigns the extension's manifest to |manifest|.
140 ExtensionBuilder& SetManifest(
141 std::unique_ptr<base::DictionaryValue> manifest);
142
143 //////////////////////////////////////////////////////////////////////////////
144 // Common utility methods (usable with both aided and custom manifest
145 // creation).
146
147 // Defaults to FilePath().
148 ExtensionBuilder& SetPath(const base::FilePath& path);
149
150 // Defaults to Manifest::UNPACKED.
151 ExtensionBuilder& SetLocation(Manifest::Location location);
152
153 // Merge another manifest into the current manifest, with new keys taking
154 // precedence.
155 ExtensionBuilder& MergeManifest(
156 std::unique_ptr<base::DictionaryValue> manifest);
157
158 // Add flags to the extension. Default is no flags.
159 ExtensionBuilder& AddFlags(int init_from_value_flags);
160
161 // Defaults to the default extension ID created in Extension::Create or to an
162 // ID generated from the extension's name, if aided manifest construction is
163 // used.
164 ExtensionBuilder& SetID(const std::string& id);
165
166 private:
167 struct ManifestData;
168
169 void SetManifestKeyImpl(base::StringPiece key, base::Value value);
170 void SetManifestPathImpl(std::initializer_list<base::StringPiece> path,
171 base::Value value);
172
173 // Information for constructing the manifest; either metadata about the
174 // manifest which will be used to construct it, or the dictionary itself. Only
175 // one will be present.
176 std::unique_ptr<ManifestData> manifest_data_;
177 std::unique_ptr<base::DictionaryValue> manifest_value_;
178
179 base::FilePath path_;
180 Manifest::Location location_;
181 int flags_;
182 std::string id_;
183
184 DISALLOW_COPY_AND_ASSIGN(ExtensionBuilder);
185};
186
187} // namespace extensions
188
189#endif // EXTENSIONS_COMMON_EXTENSION_BUILDER_H_
190