OLD | NEW |
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 Loading... |
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_ |
OLD | NEW |