summaryrefslogtreecommitdiffstats
path: root/extensions/common/extension_set.h
blob: 3bcc1f35fef1b7f477cd969bf5a93bf4c93c0f2e (plain)
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
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_COMMON_EXTENSION_SET_H_
#define EXTENSIONS_COMMON_EXTENSION_SET_H_

#include <stddef.h>

#include <iterator>
#include <map>
#include <string>

#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "extensions/common/extension.h"
#include "url/gurl.h"

namespace extensions {

// The one true extension container. Extensions are identified by their id.
// Only one extension can be in the set with a given ID.
class ExtensionSet {
 public:
  typedef std::pair<base::FilePath, std::string> ExtensionPathAndDefaultLocale;
  typedef std::map<std::string, scoped_refptr<const Extension> > ExtensionMap;
  typedef base::Callback<void(const ExtensionIdSet&)>
      ModificationCallback;

  // Iteration over the values of the map (given that it's an ExtensionSet,
  // it should iterate like a set iterator).
  class const_iterator : public std::iterator<std::input_iterator_tag,
                                              scoped_refptr<const Extension> > {
   public:
    const_iterator();
    const_iterator(const const_iterator& other);
    explicit const_iterator(ExtensionMap::const_iterator it);
    ~const_iterator();
    const_iterator& operator++() {
      ++it_;
      return *this;
    }
    const_iterator operator++(int) {
      const const_iterator old(*this);
      ++it_;
      return old;
    }
    const scoped_refptr<const Extension>& operator*() const {
      return it_->second;
    }
    const scoped_refptr<const Extension>* operator->() const {
      return &it_->second;
    }
    bool operator!=(const const_iterator& other) const {
      return it_ != other.it_;
    }
    bool operator==(const const_iterator& other) const {
      return it_ == other.it_;
    }

   private:
    ExtensionMap::const_iterator it_;
  };

  ExtensionSet();
  ~ExtensionSet();

  size_t size() const;
  bool is_empty() const;

  // Iteration support.
  const_iterator begin() const { return const_iterator(extensions_.begin()); }
  const_iterator end() const { return const_iterator(extensions_.end()); }

  // Returns true if the set contains the specified extension.
  bool Contains(const std::string& id) const;

  // Adds the specified extension to the set. The set becomes an owner. Any
  // previous extension with the same ID is removed.
  // Returns true if there is no previous extension.
  bool Insert(const scoped_refptr<const Extension>& extension);

  // Copies different items from |extensions| to the current set and returns
  // whether anything changed.
  bool InsertAll(const ExtensionSet& extensions);

  // Removes the specified extension.
  // Returns true if the set contained the specified extnesion.
  bool Remove(const std::string& id);

  // Removes all extensions.
  void Clear();

  // Returns the extension ID, or empty if none. This includes web URLs that
  // are part of an extension's web extent.
  std::string GetExtensionOrAppIDByURL(const GURL& url) const;

  // Returns the Extension, or NULL if none.  This includes web URLs that are
  // part of an extension's web extent.
  // NOTE: This can return NULL if called before UpdateExtensions receives
  // bulk extension data (e.g. if called from
  // EventBindings::HandleContextCreated)
  const Extension* GetExtensionOrAppByURL(const GURL& url) const;

  // Returns the app specified by the given |url|, if one exists. This will
  // return NULL if there is no entry with |url|, or if the extension with
  // |url| is not an app.
  const Extension* GetAppByURL(const GURL& url) const;

  // Returns the hosted app whose web extent contains the URL.
  const Extension* GetHostedAppByURL(const GURL& url) const;

  // Returns a hosted app that contains any URL that overlaps with the given
  // extent, if one exists.
  const Extension* GetHostedAppByOverlappingWebExtent(
      const URLPatternSet& extent) const;

  // Returns true if |new_url| is in the extent of the same extension as
  // |old_url|.  Also returns true if neither URL is in an app.
  bool InSameExtent(const GURL& old_url, const GURL& new_url) const;

  // Look up an Extension object by id.
  const Extension* GetByID(const std::string& id) const;

  // Gets the IDs of all extensions in the set.
  ExtensionIdSet GetIDs() const;

  // Returns true if |info| should get extension api bindings and be permitted
  // to make api calls. Note that this is independent of what extension
  // permissions the given extension has been granted.
  bool ExtensionBindingsAllowed(const GURL& url) const;

  void set_modification_callback(
      const ModificationCallback& modification_callback) {
    modification_callback_ = modification_callback;
  }

 private:
  FRIEND_TEST_ALL_PREFIXES(ExtensionSetTest, ExtensionSet);

  ExtensionMap extensions_;

  // If non-null, called with the extension ids in this set after a modification
  // occurred. This is not called on Clear() which is typically used when
  // discarding the set (e.g., on shutdown) and we do not want to track that as
  // a real modification.
  ModificationCallback modification_callback_;

  DISALLOW_COPY_AND_ASSIGN(ExtensionSet);
};

}  // namespace extensions

#endif  // EXTENSIONS_COMMON_EXTENSION_SET_H_