Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: chromecast/base/device_capabilities.h

Issue 1409173006: Making DeviceCapabilities threadsafe with locking. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Just changing unit test assertions to new format. No other changes. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chromecast/base/device_capabilities_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROMECAST_BASE_DEVICE_CAPABILITIES_H_ 5 #ifndef CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
6 #define CHROMECAST_BASE_DEVICE_CAPABILITIES_H_ 6 #define CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
7 7
8 #include <string> 8 #include <string>
9 9
10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
11 13
12 namespace base { 14 namespace base {
13 class DictionaryValue; 15 class DictionaryValue;
14 class Value; 16 class Value;
15 } 17 }
16 18
17 namespace chromecast { 19 namespace chromecast {
18 20
19 // Device capabilities are a set of features used to determine what operations 21 // Device capabilities are a set of features used to determine what operations
20 // are available on the device. They are identified by a key (string) and a 22 // are available on the device. They are identified by a key (string) and a
21 // value (base::Value). The class serves 2 main purposes: 23 // value (base::Value). The class serves 2 main purposes:
22 // 24 //
23 // 1) Provide an interface for updating default capabilities and querying their 25 // 1) Provide an interface for updating default capabilities and querying their
24 // current value. Default capabilities are known to the system beforehand 26 // current value. Default capabilities are known to the system beforehand
25 // and used by modules throughout Chromecast to control behavior of operations. 27 // and used by modules throughout Chromecast to control behavior of operations.
26 // 28 //
27 // 2) Store dynamic capabilities. Dynamic capabilities are not known to the 29 // 2) Store dynamic capabilities. Dynamic capabilities are not known to the
28 // system beforehand and are introduced by external parties. These capabilites 30 // system beforehand and are introduced by external parties. These capabilites
29 // are stored and then forwarded to app servers that use them to determine how 31 // are stored and then forwarded to app servers that use them to determine how
30 // to interact with the device. 32 // to interact with the device.
33 //
34 // Thread Safety:
35 // Observers can be added from any thread. Each Observer is guaranteed to be
36 // notified on same thread that it was added on and must be removed on the same
37 // thread that it was added on.
38 //
39 // Validators can be registered from any thread. Each Validator's Validate()
40 // method is guaranteed to be called on same thread that the Validator was
41 // registered on. The Validator must be unregistered on the same thread
42 // that it was registered on.
43 //
44 // All other methods can be called safely from any thread.
31 45
32 // TODO(esum): 46 // TODO(esum):
33 // 1) A pure virtual interface with implementation files is no longer needed 47 // 1) Add WifiSupported, HotspotSupported, and MultizoneSupported capabilities.
34 // now that this file resides in chromecast/base. Change it such that there 48 // 2) It's not ideal to have the accessors (BluetoothSupported(), etc.) not
35 // is just device_capabilities.h/cc.
36 // 2) Make class thread-safe with locking.
37 // 3) Add WifiSupported, HotspotSupported, and MultizoneSupported capabilities.
38 // 4) It's not ideal to have the accessors (BluetoothSupported(), etc.) not
39 // be valid initially until the capability gets registered. We might want 49 // be valid initially until the capability gets registered. We might want
40 // to use some kind of builder class to solve this. 50 // to use some kind of builder class to solve this.
41 class DeviceCapabilities { 51 class DeviceCapabilities {
42 public: 52 public:
43 class Observer { 53 class Observer {
44 public: 54 public:
45 // Called when DeviceCapabilities gets written to in any way. |path| 55 // Called when DeviceCapabilities gets written to in any way. |path|
46 // is full path to capability that has been updated. 56 // is full path to capability that has been updated.
47 virtual void OnCapabilitiesChanged(const std::string& path) = 0; 57 virtual void OnCapabilitiesChanged(const std::string& path) = 0;
48 58
(...skipping 30 matching lines...) Expand all
79 // DeviceCapabilities, where |path| is updated internally to |new_value|. 89 // DeviceCapabilities, where |path| is updated internally to |new_value|.
80 void SetValidatedValue(const std::string& path, 90 void SetValidatedValue(const std::string& path,
81 scoped_ptr<base::Value> new_value) const; 91 scoped_ptr<base::Value> new_value) const;
82 92
83 private: 93 private:
84 DeviceCapabilities* const capabilities_; 94 DeviceCapabilities* const capabilities_;
85 95
86 DISALLOW_COPY_AND_ASSIGN(Validator); 96 DISALLOW_COPY_AND_ASSIGN(Validator);
87 }; 97 };
88 98
99 // Class used to store/own capabilities-related data. It is immutable and
100 // RefCountedThreadSafe, so client code can freely query it throughout its
101 // lifetime without worrying about the data getting invalidated in any way.
102 class Data : public base::RefCountedThreadSafe<Data> {
103 public:
104 // Accessor for complete capabilities in dictionary format.
105 const base::DictionaryValue& dictionary() const {
106 return *dictionary_.get();
107 }
108
109 // Accessor for complete capabilities string in JSON format.
110 const std::string& json_string() const { return *json_string_.get(); }
111
112 private:
113 friend class base::RefCountedThreadSafe<Data>;
114 // DeviceCapabilities should be the only one responsible for Data
115 // construction. See CreateData() methods.
116 friend class DeviceCapabilities;
117
118 // Constructs empty dictionary with no capabilities.
119 Data();
120 // Uses |dictionary| as capabilities dictionary.
121 explicit Data(scoped_ptr<const base::DictionaryValue> dictionary);
122 ~Data();
123
124 const scoped_ptr<const base::DictionaryValue> dictionary_;
125 const scoped_ptr<const std::string> json_string_;
126
127 DISALLOW_COPY_AND_ASSIGN(Data);
128 };
129
89 // Default Capability keys 130 // Default Capability keys
90 static const char kKeyBluetoothSupported[]; 131 static const char kKeyBluetoothSupported[];
91 static const char kKeyDisplaySupported[]; 132 static const char kKeyDisplaySupported[];
92 133
134 // This class should get destroyed after all Validators have been
135 // unregistered, all Observers have been removed, and the class is no longer
136 // being accessed.
93 virtual ~DeviceCapabilities() {} 137 virtual ~DeviceCapabilities() {}
94 138
95 // Create empty instance with no capabilities. Although the class is not 139 // Create empty instance with no capabilities. Although the class is not
96 // singleton, there is meant to be a single instance owned by another module. 140 // singleton, there is meant to be a single instance owned by another module.
97 // The instance should be created early enough for all managers to register 141 // The instance should be created early enough for all managers to register
98 // themselves, and then live long enough for all managers to unregister. 142 // themselves, and then live long enough for all managers to unregister.
99 static scoped_ptr<DeviceCapabilities> Create(); 143 static scoped_ptr<DeviceCapabilities> Create();
100 // Creates an instance where all the default capabilities are initialized 144 // Creates an instance where all the default capabilities are initialized
101 // to a predefined default value, and no Validators are registered. For use 145 // to a predefined default value, and no Validators are registered. For use
102 // only in unit tests. 146 // only in unit tests.
103 static scoped_ptr<DeviceCapabilities> CreateForTesting(); 147 static scoped_ptr<DeviceCapabilities> CreateForTesting();
104 148
105 // Registers a Validator for a capability. A given key must only be 149 // Registers a Validator for a capability. A given key must only be
106 // registered once, and must be unregistered before calling Register() again. 150 // registered once, and must be unregistered before calling Register() again.
107 // If the capability has a value of Dictionary type, |key| must be just 151 // If the capability has a value of Dictionary type, |key| must be just
108 // the capability's top-level key and not include path expansions to levels 152 // the capability's top-level key and not include path expansions to levels
109 // farther down. For example, "foo" is a valid value for |key|, but "foo.bar" 153 // farther down. For example, "foo" is a valid value for |key|, but "foo.bar"
110 // is not. Note that if "foo.bar" is updated in SetCapability(), the 154 // is not. Note that if "foo.bar" is updated in SetCapability(), the
111 // Validate() method for "foo"'s Validator will be called, with a |path| of 155 // Validate() method for "foo"'s Validator will be called, with a |path| of
112 // "foo.bar". Both Register() and Unregister() must be called on cast 156 // "foo.bar". Note that this method does not add or modify the capability.
113 // receiver main thread; the Validator provided will also be called on cast 157 // To do this, SetCapability() should be called, or Validators can call
114 // receiver main thread. Note that this method does not add or modify 158 // SetValidatedValue(). This method is synchronous to ensure Validators know
115 // the capability. To do this, SetCapability() should be called, or 159 // exactly when they may start receiving validation requests.
116 // Validators can call SetValidatedValue().
117 virtual void Register(const std::string& key, 160 virtual void Register(const std::string& key,
118 Validator* validator) = 0; 161 Validator* validator) = 0;
119 // Unregisters Validator for |key|. |validator| argument must match 162 // Unregisters Validator for |key|. |validator| argument must match
120 // |validator| argument that was passed in to Register() for |key|. Note that 163 // |validator| argument that was passed in to Register() for |key|. Note that
121 // the capability and its value remain untouched. 164 // the capability and its value remain untouched. This method is synchronous
165 // to ensure Validators know exactly when they will stop receiving validation
166 // requests.
122 virtual void Unregister(const std::string& key, 167 virtual void Unregister(const std::string& key,
123 const Validator* validator) = 0; 168 const Validator* validator) = 0;
124 // Gets the Validator currently registered for |key|. Returns nullptr if 169 // Gets the Validator currently registered for |key|. Returns nullptr if
125 // no Validator is registered. 170 // no Validator is registered.
126 virtual Validator* GetValidator(const std::string& key) const = 0; 171 virtual Validator* GetValidator(const std::string& key) const = 0;
127 172
128 // Accessors for default capabilities. Note that the capability must be added 173 // Accessors for default capabilities. Note that the capability must be added
129 // through SetCapability() or SetValidatedValue() (for Validators) before 174 // through SetCapability() or SetValidatedValue() (for Validators) before
130 // accessors are called. 175 // accessors are called.
131 virtual bool BluetoothSupported() const = 0; 176 virtual bool BluetoothSupported() const = 0;
132 virtual bool DisplaySupported() const = 0; 177 virtual bool DisplaySupported() const = 0;
133 178
134 // Gets the value of |path|. If capability at |path| does not exist, 179 // Returns a deep copy of the value at |path|. If the capability at |path|
135 // |out_value| remains untouched. Returns true if the capability has been 180 // does not exist, a null scoped_ptr is returned.
136 // successfully retrieved. Note that this does NOT perform a deep copy, and 181 virtual scoped_ptr<base::Value> GetCapability(
137 // DeviceCapabilities still owns the memory returned through |out_value|. 182 const std::string& path) const = 0;
138 virtual bool GetCapability(const std::string& path,
139 const base::Value** out_value) const = 0;
140 183
141 // Returns the complete capability string (JSON format). 184 // Use this method to access dictionary and JSON string. No deep copying is
142 virtual const std::string& GetCapabilitiesString() const = 0; 185 // performed, so this method is inexpensive. Note that any capability updates
143 186 // that occur after GetData() has been called will not be reflected in the
144 // Returns the capabilities dictionary. 187 // returned scoped_refptr. You can think of this method as taking a snapshot
145 virtual const base::DictionaryValue* GetCapabilities() const = 0; 188 // of the capabilities when it gets called.
189 virtual scoped_refptr<Data> GetData() const = 0;
146 190
147 // Updates the value at |path| to |proposed_value| if |path| already exists 191 // Updates the value at |path| to |proposed_value| if |path| already exists
148 // and adds new capability if |path| doesn't. Note that if a key has been 192 // and adds new capability if |path| doesn't. Note that if a key has been
149 // registered that is at the beginning of |path|, then the Validator will be 193 // registered that is at the beginning of |path|, then the Validator will be
150 // used to determine if |proposed_value| is accepted. 194 // used to determine if |proposed_value| is accepted.
151 // Ex: If "foo" has a Validator registered, a |path| of "foo.bar" 195 // Ex: If "foo" has a Validator registered, a |path| of "foo.bar"
152 // will cause |proposed_value| to go through the Validator's Validate() 196 // will cause |proposed_value| to go through the Validator's Validate()
153 // method. Client code may use the Observer interface to determine the 197 // method. Client code may use the Observer interface to determine the
154 // ultimate value used. 198 // ultimate value used. This method is asynchronous.
155 virtual void SetCapability(const std::string& path, 199 virtual void SetCapability(const std::string& path,
156 scoped_ptr<base::Value> proposed_value) = 0; 200 scoped_ptr<base::Value> proposed_value) = 0;
157 // Iterates through entries in |dict_value| and calls SetCapability() for 201 // Iterates through entries in |dict_value| and calls SetCapability() for
158 // each one. 202 // each one. This method is asynchronous.
159 virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0; 203 virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0;
160 204
161 // Adds/removes an observer. It doesn't take the ownership of |observer|. 205 // Adds/removes an observer. It doesn't take the ownership of |observer|.
162 virtual void AddCapabilitiesObserver(Observer* observer) = 0; 206 virtual void AddCapabilitiesObserver(Observer* observer) = 0;
163 virtual void RemoveCapabilitiesObserver(Observer* observer) = 0; 207 virtual void RemoveCapabilitiesObserver(Observer* observer) = 0;
164 208
165 protected: 209 protected:
166 DeviceCapabilities() {} 210 DeviceCapabilities() {}
167 211
212 // For derived implementation classes to create Data instances since they do
213 // not have access to Data constructors.
214 // Creates empty dictionary with no capabilities.
215 static scoped_refptr<Data> CreateData();
216 // Uses |dictionary| as capabilities dictionary.
217 static scoped_refptr<Data> CreateData(
218 scoped_ptr<const base::DictionaryValue> dictionary);
219
168 private: 220 private:
169 // Does actual internal update of |path| to |new_value|. 221 // Does actual internal update of |path| to |new_value|.
170 virtual void SetValidatedValueInternal(const std::string& path, 222 virtual void SetValidatedValue(const std::string& path,
171 scoped_ptr<base::Value> new_value) = 0; 223 scoped_ptr<base::Value> new_value) = 0;
172 224
173 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities); 225 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities);
174 }; 226 };
175 227
176 } // namespace chromecast 228 } // namespace chromecast
177 229
178 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_H_ 230 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
OLDNEW
« no previous file with comments | « no previous file | chromecast/base/device_capabilities_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698