Chromium Code Reviews| 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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 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 Loading... | |
| 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; |
|
byungchul
2015/10/28 01:09:43
Can we avoid deep copy? Why not use ref-count here
esum
2015/10/28 04:16:27
Hmm. We can, but I can't think of a way to do that
byungchul
2015/10/28 16:04:18
Can you check how capabilities are used? If deep c
esum
2015/10/28 17:58:50
GetCapabilities() gets called in EndPointWithAppli
byungchul
2015/10/28 18:37:16
It would be nice to mention that these api are not
esum
2015/10/28 18:44:30
Hmm, I'm not happy leaving a comment like that. Le
esum
2015/10/28 19:58:42
I can think there are 2 straightforward ways of do
| |
| 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_ |
| OLD | NEW |