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

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: Clean up unit test. 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
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/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 10 matching lines...) Expand all
21 // value (base::Value). The class serves 2 main purposes: 21 // value (base::Value). The class serves 2 main purposes:
22 // 22 //
23 // 1) Provide an interface for updating default capabilities and querying their 23 // 1) Provide an interface for updating default capabilities and querying their
24 // current value. Default capabilities are known to the system beforehand 24 // current value. Default capabilities are known to the system beforehand
25 // and used by modules throughout Chromecast to control behavior of operations. 25 // and used by modules throughout Chromecast to control behavior of operations.
26 // 26 //
27 // 2) Store dynamic capabilities. Dynamic capabilities are not known to the 27 // 2) Store dynamic capabilities. Dynamic capabilities are not known to the
28 // system beforehand and are introduced by external parties. These capabilites 28 // 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 29 // are stored and then forwarded to app servers that use them to determine how
30 // to interact with the device. 30 // to interact with the device.
31 //
32 // Thread Safety:
33 // Observers can be added from any thread. Each Observer is guaranteed to be
34 // notified on same thread that it was added on and must be removed on the same
35 // thread that it was added on.
36 //
37 // Validators can be registered from any thread. Each Validator's Validate()
38 // method is guaranteed to be called on same thread that the Validator was
39 // registered on. The Validator must be unregistered on the same thread
40 // that it was registered on.
41 //
42 // All other methods can be called safely from any thread.
31 43
32 // TODO(esum): 44 // TODO(esum):
33 // 1) A pure virtual interface with implementation files is no longer needed 45 // 1) Add WifiSupported, HotspotSupported, and MultizoneSupported capabilities.
34 // now that this file resides in chromecast/base. Change it such that there 46 // 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 47 // be valid initially until the capability gets registered. We might want
40 // to use some kind of builder class to solve this. 48 // to use some kind of builder class to solve this.
41 class DeviceCapabilities { 49 class DeviceCapabilities {
42 public: 50 public:
43 class Observer { 51 class Observer {
44 public: 52 public:
45 // Called when DeviceCapabilities gets written to in any way. |path| 53 // Called when DeviceCapabilities gets written to in any way. |path|
46 // is full path to capability that has been updated. 54 // is full path to capability that has been updated.
47 virtual void OnCapabilitiesChanged(const std::string& path) = 0; 55 virtual void OnCapabilitiesChanged(const std::string& path) = 0;
48 56
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 private: 91 private:
84 DeviceCapabilities* const capabilities_; 92 DeviceCapabilities* const capabilities_;
85 93
86 DISALLOW_COPY_AND_ASSIGN(Validator); 94 DISALLOW_COPY_AND_ASSIGN(Validator);
87 }; 95 };
88 96
89 // Default Capability keys 97 // Default Capability keys
90 static const char kKeyBluetoothSupported[]; 98 static const char kKeyBluetoothSupported[];
91 static const char kKeyDisplaySupported[]; 99 static const char kKeyDisplaySupported[];
92 100
101 // This class should get destroyed after all Validators have been
102 // unregistered, all Observers have been removed, and the class is no longer
103 // being accessed.
93 virtual ~DeviceCapabilities() {} 104 virtual ~DeviceCapabilities() {}
94 105
95 // Create empty instance with no capabilities. Although the class is not 106 // 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. 107 // 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 108 // The instance should be created early enough for all managers to register
98 // themselves, and then live long enough for all managers to unregister. 109 // themselves, and then live long enough for all managers to unregister.
99 static scoped_ptr<DeviceCapabilities> Create(); 110 static scoped_ptr<DeviceCapabilities> Create();
100 // Creates an instance where all the default capabilities are initialized 111 // Creates an instance where all the default capabilities are initialized
101 // to a predefined default value, and no Validators are registered. For use 112 // to a predefined default value, and no Validators are registered. For use
102 // only in unit tests. 113 // only in unit tests.
103 static scoped_ptr<DeviceCapabilities> CreateForTesting(); 114 static scoped_ptr<DeviceCapabilities> CreateForTesting();
104 115
105 // Registers a Validator for a capability. A given key must only be 116 // Registers a Validator for a capability. A given key must only be
106 // registered once, and must be unregistered before calling Register() again. 117 // registered once, and must be unregistered before calling Register() again.
107 // If the capability has a value of Dictionary type, |key| must be just 118 // 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 119 // 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" 120 // 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 121 // 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 122 // 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 123 // "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 124 // To do this, SetCapability() should be called, or Validators can call
114 // receiver main thread. Note that this method does not add or modify 125 // SetValidatedValue(). This method is synchronous to ensure Validators know
115 // the capability. To do this, SetCapability() should be called, or 126 // exactly when they may start receiving validation requests.
116 // Validators can call SetValidatedValue().
117 virtual void Register(const std::string& key, 127 virtual void Register(const std::string& key,
118 Validator* validator) = 0; 128 Validator* validator) = 0;
119 // Unregisters Validator for |key|. |validator| argument must match 129 // Unregisters Validator for |key|. |validator| argument must match
120 // |validator| argument that was passed in to Register() for |key|. Note that 130 // |validator| argument that was passed in to Register() for |key|. Note that
121 // the capability and its value remain untouched. 131 // the capability and its value remain untouched. This method is synchronous
132 // to ensure Validators know exactly when they will stop receiving validation
133 // requests.
122 virtual void Unregister(const std::string& key, 134 virtual void Unregister(const std::string& key,
123 const Validator* validator) = 0; 135 const Validator* validator) = 0;
124 // Gets the Validator currently registered for |key|. Returns nullptr if 136 // Gets the Validator currently registered for |key|. Returns nullptr if
125 // no Validator is registered. 137 // no Validator is registered.
126 virtual Validator* GetValidator(const std::string& key) const = 0; 138 virtual Validator* GetValidator(const std::string& key) const = 0;
127 139
128 // Accessors for default capabilities. Note that the capability must be added 140 // Accessors for default capabilities. Note that the capability must be added
129 // through SetCapability() or SetValidatedValue() (for Validators) before 141 // through SetCapability() or SetValidatedValue() (for Validators) before
130 // accessors are called. 142 // accessors are called.
131 virtual bool BluetoothSupported() const = 0; 143 virtual bool BluetoothSupported() const = 0;
132 virtual bool DisplaySupported() const = 0; 144 virtual bool DisplaySupported() const = 0;
133 145
134 // Gets the value of |path|. If capability at |path| does not exist, 146 // 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 147 // does not exist, a null scoped_ptr is returned.
136 // successfully retrieved. Note that this does NOT perform a deep copy, and 148 virtual scoped_ptr<base::Value> GetCapability(
137 // DeviceCapabilities still owns the memory returned through |out_value|. 149 const std::string& path) const = 0;
138 virtual bool GetCapability(const std::string& path,
139 const base::Value** out_value) const = 0;
140 150
141 // Returns the complete capability string (JSON format). 151 // Returns the complete capability string (JSON format).
142 virtual const std::string& GetCapabilitiesString() const = 0; 152 virtual std::string GetCapabilitiesString() const = 0;
143 153
144 // Returns the capabilities dictionary. 154 // Returns deep copy of the capabilities dictionary.
145 virtual const base::DictionaryValue* GetCapabilities() const = 0; 155 virtual scoped_ptr<base::DictionaryValue> GetCapabilities() const = 0;
146 156
147 // Updates the value at |path| to |proposed_value| if |path| already exists 157 // 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 158 // 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 159 // registered that is at the beginning of |path|, then the Validator will be
150 // used to determine if |proposed_value| is accepted. 160 // used to determine if |proposed_value| is accepted.
151 // Ex: If "foo" has a Validator registered, a |path| of "foo.bar" 161 // Ex: If "foo" has a Validator registered, a |path| of "foo.bar"
152 // will cause |proposed_value| to go through the Validator's Validate() 162 // will cause |proposed_value| to go through the Validator's Validate()
153 // method. Client code may use the Observer interface to determine the 163 // method. Client code may use the Observer interface to determine the
154 // ultimate value used. 164 // ultimate value used. This method is asynchronous.
155 virtual void SetCapability(const std::string& path, 165 virtual void SetCapability(const std::string& path,
156 scoped_ptr<base::Value> proposed_value) = 0; 166 scoped_ptr<base::Value> proposed_value) = 0;
157 // Iterates through entries in |dict_value| and calls SetCapability() for 167 // Iterates through entries in |dict_value| and calls SetCapability() for
158 // each one. 168 // each one. This method is asynchronous.
159 virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0; 169 virtual void MergeDictionary(const base::DictionaryValue& dict_value) = 0;
160 170
161 // Adds/removes an observer. It doesn't take the ownership of |observer|. 171 // Adds/removes an observer. It doesn't take the ownership of |observer|.
162 virtual void AddCapabilitiesObserver(Observer* observer) = 0; 172 virtual void AddCapabilitiesObserver(Observer* observer) = 0;
163 virtual void RemoveCapabilitiesObserver(Observer* observer) = 0; 173 virtual void RemoveCapabilitiesObserver(Observer* observer) = 0;
164 174
165 protected: 175 protected:
166 DeviceCapabilities() {} 176 DeviceCapabilities() {}
167 177
168 private: 178 private:
169 // Does actual internal update of |path| to |new_value|. 179 // Does actual internal update of |path| to |new_value|.
170 virtual void SetValidatedValueInternal(const std::string& path, 180 virtual void SetValidatedValue(const std::string& path,
171 scoped_ptr<base::Value> new_value) = 0; 181 scoped_ptr<base::Value> new_value) = 0;
172 182
173 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities); 183 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilities);
174 }; 184 };
175 185
176 } // namespace chromecast 186 } // namespace chromecast
177 187
178 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_H_ 188 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_H_
OLDNEW
« no previous file with comments | « no previous file | chromecast/base/device_capabilities_impl.h » ('j') | chromecast/base/device_capabilities_impl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698