1 // Copyright 2017 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_RENDERER_FEATURE_CACHE_H_
6 #define EXTENSIONS_RENDERER_FEATURE_CACHE_H_
7 
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/macros.h"
14 #include "extensions/common/extension_id.h"
15 #include "extensions/common/features/feature.h"
16 #include "url/gurl.h"
17 
18 namespace extensions {
19 class Extension;
20 
21 // Caches features available to different extensions in different context types,
22 // and returns features available to a given context. Note: currently, this is
23 // only used for non-webpage contexts.
24 // TODO(devlin): Use it for all context types?
25 // Note: This could actually go in extensions/common/, if there was any need for
26 // it browser-side.
27 class FeatureCache {
28  public:
29   using FeatureNameVector = std::vector<std::string>;
30 
31   FeatureCache();
32   ~FeatureCache();
33 
34   // Returns the names of features available to the given set of |context_type|,
35   // |extension|, and |url| in a lexicographically sorted vector.
36   // Note: these contexts should be valid, so WebUI contexts should have no
37   // extensions, extension should be non-null for extension contexts, etc.
38   FeatureNameVector GetAvailableFeatures(Feature::Context context_type,
39                                          const Extension* extension,
40                                          const GURL& url);
41 
42   // Invalidates the cache for the specified extension.
43   void InvalidateExtension(const ExtensionId& extension_id);
44 
45  private:
46   using FeatureVector = std::vector<const Feature*>;
47   // Note: We use a key of ExtensionId, Feature::Context to maximize cache hits.
48   // Unfortunately, this won't always be perfectly accurate, since some features
49   // may have other context-dependent restrictions (such as URLs), but caching
50   // by extension id + context + url would result in significantly fewer hits.
51   using ExtensionCacheMapKey = std::pair<ExtensionId, Feature::Context>;
52   using ExtensionCacheMap = std::map<ExtensionCacheMapKey, FeatureVector>;
53 
54   // Cache by origin.
55   using WebUICacheMap = std::map<GURL, FeatureVector>;
56 
57   // Returns the features available to the given context from the cache,
58   // creating a new entry if one doesn't exist.
59   const FeatureVector& GetFeaturesFromCache(Feature::Context context_type,
60                                             const Extension* extension,
61                                             const GURL& origin);
62 
63   // Creates a FeatureVector to be entered into a cache for the specified
64   // context data.
65   FeatureVector CreateCacheEntry(Feature::Context context_type,
66                                  const Extension* extension,
67                                  const GURL& origin);
68 
69   // The cache of extension-related contexts. These may be invalidated, since
70   // extension permissions change.
71   ExtensionCacheMap extension_cache_;
72 
73   // The cache of WebUI-related features. These shouldn't need to be
74   // invalidated (since WebUI permissions don't change), and are cached by
75   // origin. These covers chrome:// and chrome-untrusted:// URLs.
76   WebUICacheMap webui_cache_;
77 
78   DISALLOW_COPY_AND_ASSIGN(FeatureCache);
79 };
80 
81 }  // namespace extensions
82 
83 #endif  // EXTENSIONS_RENDERER_FEATURE_CACHE_H_
84