File: feature.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (228 lines) | stat: -rw-r--r-- 8,649 bytes parent folder | download | duplicates (3)
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// 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_FEATURES_FEATURE_H_
#define EXTENSIONS_COMMON_FEATURES_FEATURE_H_

#include <map>
#include <set>
#include <string>
#include <string_view>

#include "extensions/common/context_data.h"
#include "extensions/common/hashed_extension_id.h"
#include "extensions/common/manifest.h"
#include "extensions/common/mojom/context_type.mojom-forward.h"
#include "extensions/common/mojom/manifest.mojom-shared.h"

class GURL;

namespace extensions {

inline constexpr int kUnspecifiedContextId = -1;

class Extension;

// Represents a single feature accessible to an extension developer, such as a
// top-level manifest key, a permission, or a programmatic API. A feature can
// express requirements for where it can be accessed, and supports testing
// support for those requirements. If platforms are not specified, then feature
// is available on all platforms.
//
// See //chrome/common/extensions/api/_features.md for a description of feature
// usage and types.
class Feature {
 public:
  // The platforms the feature is supported in.
  enum Platform {
    UNSPECIFIED_PLATFORM,
    CHROMEOS_PLATFORM,
    LINUX_PLATFORM,
    MACOSX_PLATFORM,
    WIN_PLATFORM,
    FUCHSIA_PLATFORM,
    DESKTOP_ANDROID_PLATFORM,
  };

  // Whether a feature is available in a given situation or not, and if not,
  // why not.
  enum AvailabilityResult {
    IS_AVAILABLE,
    NOT_FOUND_IN_ALLOWLIST,
    INVALID_URL,
    INVALID_TYPE,
    INVALID_CONTEXT,
    INVALID_LOCATION,
    INVALID_PLATFORM,
    INVALID_MIN_MANIFEST_VERSION,
    INVALID_MAX_MANIFEST_VERSION,
    INVALID_SESSION_TYPE,
    NOT_PRESENT,
    UNSUPPORTED_CHANNEL,
    FOUND_IN_BLOCKLIST,
    MISSING_COMMAND_LINE_SWITCH,
    FEATURE_FLAG_DISABLED,
    REQUIRES_DEVELOPER_MODE,
    MISSING_DELEGATED_AVAILABILITY_CHECK,
    FAILED_DELEGATED_AVAILABILITY_CHECK,
  };

  // Shorthand for delegated availability check handler function signature. The
  // function signature's arguments should contain all of the arguments passed
  // into IsAvailableToContextImpl().
  using DelegatedAvailabilityCheckHandler =
      base::RepeatingCallback<bool(const std::string& api_full_name,
                                   const Extension* extension,
                                   mojom::ContextType context,
                                   const GURL& url,
                                   Platform platform,
                                   int context_id,
                                   bool check_developer_mode,
                                   const ContextData& context_data)>;

  // Mapping Feature::name() to override function.
  using FeatureDelegatedAvailabilityCheckMap =
      std::map<std::string, DelegatedAvailabilityCheckHandler>;

  // Container for AvailabilityResult that also exposes a user-visible error
  // message in cases where the feature is not available.
  class Availability {
   public:
    Availability(AvailabilityResult result, const std::string& message)
        : result_(result), message_(message) {}

    AvailabilityResult result() const { return result_; }
    bool is_available() const { return result_ == IS_AVAILABLE; }
    const std::string& message() const { return message_; }

   private:
    friend class SimpleFeature;
    friend class Feature;

    const AvailabilityResult result_;
    const std::string message_;
  };

  Feature();
  virtual ~Feature();

  const std::string& name() const { return name_; }
  // Note that this arg is passed as a string_view to avoid a lot of bloat from
  // inlined std::string code.
  void set_name(std::string_view name);
  const std::string& alias() const { return alias_; }
  void set_alias(std::string_view alias);
  const std::string& source() const { return source_; }
  void set_source(std::string_view source);
  bool no_parent() const { return no_parent_; }

  // Gets the platform the code is currently running on.
  static Platform GetCurrentPlatform();

  // Tests whether this is an internal API or not.
  virtual bool IsInternal() const = 0;

  // Returns if this feature's availability requires a delegated availability
  // check.
  virtual bool RequiresDelegatedAvailabilityCheck() const = 0;

  // Sets the feature availability override handler to use.
  virtual void SetDelegatedAvailabilityCheckHandler(
      DelegatedAvailabilityCheckHandler handler) = 0;

  // Returns true if the feature is available to be parsed into a new extension
  // manifest.
  Availability IsAvailableToManifest(const HashedExtensionId& hashed_id,
                                     Manifest::Type type,
                                     mojom::ManifestLocation location,
                                     int manifest_version,
                                     int context_id) const {
    return IsAvailableToManifest(hashed_id, type, location, manifest_version,
                                 GetCurrentPlatform(), context_id);
  }
  virtual Availability IsAvailableToManifest(const HashedExtensionId& hashed_id,
                                             Manifest::Type type,
                                             mojom::ManifestLocation location,
                                             int manifest_version,
                                             Platform platform,
                                             int context_id) const = 0;

  // Returns true if the feature is available to `extension`.
  Availability IsAvailableToExtension(const Extension* extension) const;

  // Returns true if the feature is available to be used in the specified
  // extension and context.
  Availability IsAvailableToContext(const Extension* extension,
                                    mojom::ContextType context,
                                    const GURL& url,
                                    int context_id,
                                    const ContextData& context_data) const {
    return IsAvailableToContext(extension, context, url, GetCurrentPlatform(),
                                context_id, context_data);
  }

  Availability IsAvailableToContext(const Extension* extension,
                                    mojom::ContextType context,
                                    const GURL& url,
                                    Platform platform,
                                    int context_id,
                                    const ContextData& context_data) const {
    return IsAvailableToContextImpl(extension, context, url, platform,
                                    context_id, true, context_data);
  }

  Availability IsAvailableToContextIgnoringDevMode(
      const Extension* extension,
      mojom::ContextType context,
      const GURL& url,
      Platform platform,
      int context_id,
      const ContextData& context_data) const {
    return IsAvailableToContextImpl(
        extension, context, url, platform, context_id,
        /*check_developer_mode=*/false, context_data);
  }
  // Returns true if the feature is available to the current environment,
  // without needing to know information about an Extension or any other
  // contextual information. Typically used when the Feature is purely
  // configured by command line flags and/or Chrome channel.
  //
  // Generally try not to use this function. Even if you don't think a Feature
  // relies on an Extension now - maybe it will, one day, so if there's an
  // Extension available (or a runtime context, etc) then use the more targeted
  // method instead.
  virtual Availability IsAvailableToEnvironment(int context_id) const = 0;

  virtual bool IsIdInBlocklist(const HashedExtensionId& hashed_id) const = 0;
  virtual bool IsIdInAllowlist(const HashedExtensionId& hashed_id) const = 0;

  bool HasDelegatedAvailabilityCheckHandlerForTesting() const;

 protected:
  friend class SimpleFeature;
  friend class ComplexFeature;

  // These parameters should be kept in sync with
  // DelegatedAvailabilityCheckHandler.
  virtual Availability IsAvailableToContextImpl(
      const Extension* extension,
      mojom::ContextType context,
      const GURL& url,
      Platform platform,
      int context_id,
      bool check_developer_mode,
      const ContextData& context_data) const = 0;

  // Gets whether a feature availability override handler has been set.
  virtual bool HasDelegatedAvailabilityCheckHandler() const = 0;

  std::string name_;
  std::string alias_;
  std::string source_;
  bool no_parent_;
};

}  // namespace extensions

#endif  // EXTENSIONS_COMMON_FEATURES_FEATURE_H_