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_FEATURES_FEATURE_H_
6#define EXTENSIONS_COMMON_FEATURES_FEATURE_H_
7
8#include <set>
9#include <string>
10
11#include "base/strings/string_piece.h"
12#include "base/values.h"
13#include "extensions/common/hashed_extension_id.h"
14#include "extensions/common/manifest.h"
15
16class GURL;
17
18namespace extensions {
19
20class Extension;
21
22// Represents a single feature accessible to an extension developer, such as a
23// top-level manifest key, a permission, or a programmatic API. A feature can
24// express requirements for where it can be accessed, and supports testing
25// support for those requirements. If platforms are not specified, then feature
26// is available on all platforms.
27//
28// See //chrome/common/extensions/api/_features.md for a description of feature
29// usage and types.
30class Feature {
31 public:
32 // The JavaScript contexts the feature is supported in.
33 enum Context {
34 UNSPECIFIED_CONTEXT,
35 BLESSED_EXTENSION_CONTEXT,
36 UNBLESSED_EXTENSION_CONTEXT,
37 CONTENT_SCRIPT_CONTEXT,
38 WEB_PAGE_CONTEXT,
39 BLESSED_WEB_PAGE_CONTEXT,
40 WEBUI_CONTEXT,
41 SERVICE_WORKER_CONTEXT,
42 LOCK_SCREEN_EXTENSION_CONTEXT,
43 };
44
45 // The platforms the feature is supported in.
46 enum Platform {
47 UNSPECIFIED_PLATFORM,
48 CHROMEOS_PLATFORM,
49 LINUX_PLATFORM,
50 MACOSX_PLATFORM,
51 WIN_PLATFORM
52 };
53
54 // Whether a feature is available in a given situation or not, and if not,
55 // why not.
56 enum AvailabilityResult {
57 IS_AVAILABLE,
58 NOT_FOUND_IN_WHITELIST,
59 INVALID_URL,
60 INVALID_TYPE,
61 INVALID_CONTEXT,
62 INVALID_LOCATION,
63 INVALID_PLATFORM,
64 INVALID_MIN_MANIFEST_VERSION,
65 INVALID_MAX_MANIFEST_VERSION,
66 INVALID_SESSION_TYPE,
67 NOT_PRESENT,
68 UNSUPPORTED_CHANNEL,
69 FOUND_IN_BLACKLIST,
70 MISSING_COMMAND_LINE_SWITCH,
71 };
72
73 // Container for AvailabiltyResult that also exposes a user-visible error
74 // message in cases where the feature is not available.
75 class Availability {
76 public:
77 Availability(AvailabilityResult result, const std::string& message)
78 : result_(result), message_(message) {}
79
80 AvailabilityResult result() const { return result_; }
81 bool is_available() const { return result_ == IS_AVAILABLE; }
82 const std::string& message() const { return message_; }
83
84 private:
85 friend class SimpleFeature;
86 friend class Feature;
87
88 const AvailabilityResult result_;
89 const std::string message_;
90 };
91
92 Feature();
93 virtual ~Feature();
94
95 const std::string& name() const { return name_; }
96 // Note that this arg is passed as a StringPiece to avoid a lot of bloat from
97 // inlined std::string code.
98 void set_name(base::StringPiece name);
99 const std::string& alias() const { return alias_; }
100 void set_alias(base::StringPiece alias);
101 const std::string& source() const { return source_; }
102 void set_source(base::StringPiece source);
103 bool no_parent() const { return no_parent_; }
104
105 // Gets the platform the code is currently running on.
106 static Platform GetCurrentPlatform();
107
108 // Tests whether this is an internal API or not.
109 virtual bool IsInternal() const = 0;
110
111 // Returns true if the feature is available to be parsed into a new extension
112 // manifest.
113 Availability IsAvailableToManifest(const HashedExtensionId& hashed_id,
114 Manifest::Type type,
115 Manifest::Location location,
116 int manifest_version) const {
117 return IsAvailableToManifest(hashed_id, type, location, manifest_version,
118 GetCurrentPlatform());
119 }
120 virtual Availability IsAvailableToManifest(const HashedExtensionId& hashed_id,
121 Manifest::Type type,
122 Manifest::Location location,
123 int manifest_version,
124 Platform platform) const = 0;
125
126 // Returns true if the feature is available to |extension|.
127 Availability IsAvailableToExtension(const Extension* extension) const;
128
129 // Returns true if the feature is available to be used in the specified
130 // extension and context.
131 Availability IsAvailableToContext(const Extension* extension,
132 Context context,
133 const GURL& url) const {
134 return IsAvailableToContext(extension, context, url, GetCurrentPlatform());
135 }
136 virtual Availability IsAvailableToContext(const Extension* extension,
137 Context context,
138 const GURL& url,
139 Platform platform) const = 0;
140
141 // Returns true if the feature is available to the current environment,
142 // without needing to know information about an Extension or any other
143 // contextual information. Typically used when the Feature is purely
144 // configured by command line flags and/or Chrome channel.
145 //
146 // Generally try not to use this function. Even if you don't think a Feature
147 // relies on an Extension now - maybe it will, one day, so if there's an
148 // Extension available (or a runtime context, etc) then use the more targeted
149 // method instead.
150 virtual Availability IsAvailableToEnvironment() const = 0;
151
152 virtual bool IsIdInBlocklist(const HashedExtensionId& hashed_id) const = 0;
153 virtual bool IsIdInAllowlist(const HashedExtensionId& hashed_id) const = 0;
154
155 protected:
156 std::string name_;
157 std::string alias_;
158 std::string source_;
159 bool no_parent_;
160};
161
162} // namespace extensions
163
164#endif // EXTENSIONS_COMMON_FEATURES_FEATURE_H_
165