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_IMPL_H_ | 5 #ifndef CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ |
| 6 #define CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ | 6 #define CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ |
| 7 | 7 |
| 8 #include "base/containers/hash_tables.h" | 8 #include "base/containers/hash_tables.h" |
| 9 #include "base/observer_list.h" | 9 #include "base/macros.h" |
| 10 #include "base/threading/thread_checker.h" | 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "base/observer_list_threadsafe.h" | |
| 13 #include "base/synchronization/lock.h" | |
| 11 #include "chromecast/base/device_capabilities.h" | 14 #include "chromecast/base/device_capabilities.h" |
| 12 | 15 |
| 16 namespace base { | |
| 17 class SingleThreadTaskRunner; | |
| 18 } | |
| 19 | |
| 13 namespace chromecast { | 20 namespace chromecast { |
| 14 | 21 |
| 15 class DeviceCapabilitiesImpl : public DeviceCapabilities { | 22 class DeviceCapabilitiesImpl : public DeviceCapabilities { |
| 16 public: | 23 public: |
| 17 ~DeviceCapabilitiesImpl() override; | 24 ~DeviceCapabilitiesImpl() override; |
| 18 | 25 |
| 19 // DeviceCapabilities implementation: | 26 // DeviceCapabilities implementation: |
| 20 void Register(const std::string& key, Validator* validator) override; | 27 void Register(const std::string& key, Validator* validator) override; |
| 21 void Unregister(const std::string& key, const Validator* validator) override; | 28 void Unregister(const std::string& key, const Validator* validator) override; |
| 22 Validator* GetValidator(const std::string& key) const override; | 29 Validator* GetValidator(const std::string& key) const override; |
| 23 bool BluetoothSupported() const override; | 30 bool BluetoothSupported() const override; |
| 24 bool DisplaySupported() const override; | 31 bool DisplaySupported() const override; |
| 25 bool GetCapability(const std::string& path, | 32 scoped_ptr<base::Value> GetCapability(const std::string& path) const override; |
| 26 const base::Value** out_value) const override; | 33 std::string GetCapabilitiesString() const override; |
| 27 const std::string& GetCapabilitiesString() const override; | 34 scoped_ptr<base::DictionaryValue> GetCapabilities() const override; |
| 28 const base::DictionaryValue* GetCapabilities() const override; | |
| 29 void SetCapability(const std::string& path, | 35 void SetCapability(const std::string& path, |
| 30 scoped_ptr<base::Value> proposed_value) override; | 36 scoped_ptr<base::Value> proposed_value) override; |
| 31 void MergeDictionary(const base::DictionaryValue& dict_value) override; | 37 void MergeDictionary(const base::DictionaryValue& dict_value) override; |
| 32 void AddCapabilitiesObserver(Observer* observer) override; | 38 void AddCapabilitiesObserver(Observer* observer) override; |
| 33 void RemoveCapabilitiesObserver(Observer* observer) override; | 39 void RemoveCapabilitiesObserver(Observer* observer) override; |
| 34 | 40 |
| 35 private: | 41 private: |
| 42 // Customized wrapper class to make capabilities-related members immutable | |
| 43 // and RefCountedThreadSafe. Not using RefCountedData class since it requires | |
| 44 // a copy-constructable template parameter, which DictionaryValue does not | |
| 45 // meet. | |
| 46 class ImmutableCapabilitiesData | |
| 47 : public base::RefCountedThreadSafe<ImmutableCapabilitiesData> { | |
| 48 public: | |
| 49 ImmutableCapabilitiesData(); | |
| 50 explicit ImmutableCapabilitiesData( | |
| 51 scoped_ptr<const base::DictionaryValue> dictionary); | |
| 52 | |
| 53 const base::DictionaryValue* dictionary() const { | |
| 54 return dictionary_.get(); | |
| 55 } | |
| 56 | |
| 57 const std::string* json_string() const { return json_string_.get(); } | |
|
byungchul
2015/10/28 01:09:43
Can they be null? Otherwise, const&
esum
2015/10/28 04:16:27
Done.
| |
| 58 | |
| 59 private: | |
| 60 friend class base::RefCountedThreadSafe<ImmutableCapabilitiesData>; | |
| 61 | |
| 62 ~ImmutableCapabilitiesData(); | |
| 63 | |
| 64 const scoped_ptr<const base::DictionaryValue> dictionary_; | |
| 65 const scoped_ptr<const std::string> json_string_; | |
| 66 | |
| 67 DISALLOW_COPY_AND_ASSIGN(ImmutableCapabilitiesData); | |
| 68 }; | |
| 69 | |
| 70 class ValidatorInfo : public base::SupportsWeakPtr<ValidatorInfo> { | |
| 71 public: | |
| 72 explicit ValidatorInfo(Validator* validator); | |
| 73 ~ValidatorInfo(); | |
| 74 | |
| 75 Validator* validator() const { return validator_; } | |
| 76 | |
| 77 base::SingleThreadTaskRunner* task_runner() const { | |
|
byungchul
2015/10/28 01:09:43
Please comment why it is not a scoped_refptr
esum
2015/10/28 04:16:27
Done. Was just trying to avoid a call to AddRef(),
byungchul
2015/10/28 16:04:18
It depends. Sometimes returning ref-counted object
| |
| 78 return task_runner_.get(); | |
| 79 } | |
| 80 | |
| 81 void Validate(const std::string& path, | |
| 82 scoped_ptr<base::Value> proposed_value) const; | |
| 83 | |
| 84 private: | |
| 85 Validator* const validator_; | |
| 86 // TaskRunner of thread that validator_ was registered on | |
| 87 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
| 88 | |
| 89 DISALLOW_COPY_AND_ASSIGN(ValidatorInfo); | |
| 90 }; | |
| 91 | |
| 36 // For DeviceCapabilitiesImpl() | 92 // For DeviceCapabilitiesImpl() |
| 37 friend class DeviceCapabilities; | 93 friend class DeviceCapabilities; |
| 38 // For SetValidatedValueInternal() | 94 // For SetValidatedValueInternal() |
| 39 friend class DeviceCapabilities::Validator; | 95 friend class DeviceCapabilities::Validator; |
| 40 | 96 |
| 41 // Map from capability key to corresponding Validator. Gets updated | 97 // Map from capability key to corresponding ValidatorInfo. Gets updated |
| 42 // in Register()/Unregister(). | 98 // in Register()/Unregister(). A ValidatorInfo* is used because |
| 43 typedef base::hash_map<std::string, Validator*> ValidatorMap; | 99 // SupportsWeakPtr does not allow ValidatorInfo to be copyable. This means |
| 100 // that the code is responsible for deleting the ValidatorInfo* before an | |
| 101 // entry is removed. | |
| 102 typedef base::hash_map<std::string, ValidatorInfo*> ValidatorMap; | |
| 44 | 103 |
| 45 // Internal constructor used by static DeviceCapabilities::Create*() methods. | 104 // Internal constructor used by static DeviceCapabilities::Create*() methods. |
| 46 DeviceCapabilitiesImpl(); | 105 DeviceCapabilitiesImpl(); |
| 47 | 106 |
| 48 void SetValidatedValueInternal(const std::string& path, | 107 void SetValidatedValue(const std::string& path, |
| 49 scoped_ptr<base::Value> new_value) override; | 108 scoped_ptr<base::Value> new_value) override; |
| 50 void UpdateStrAndNotifyChanged(const std::string& path); | 109 scoped_refptr<ImmutableCapabilitiesData> GetCapabilitiesDataReference() const; |
| 51 | 110 |
| 52 scoped_ptr<base::DictionaryValue> capabilities_; | 111 // Defined locking order if acquiring both locks at same time from a thread |
| 53 scoped_ptr<const std::string> capabilities_str_; | 112 // to prevent deadlocks: |
| 113 // 1) validation_lock_ | |
| 114 // 2) capabilities_lock_ | |
|
byungchul
2015/10/28 01:09:43
Any chances to lock both at a time?
esum
2015/10/28 04:16:27
Not currently. Just put this here as precaution/re
| |
| 115 | |
| 116 // Lock for all access to capabilities related members (capabilities_data_) | |
| 117 mutable base::Lock capabilities_lock_; | |
| 118 // Lock for all access to validation members (validator_map_) | |
| 119 mutable base::Lock validation_lock_; | |
| 120 | |
| 121 scoped_refptr<ImmutableCapabilitiesData> capabilities_data_; | |
| 122 // TaskRunner for capability writes. All internal writes to | |
| 123 // capabilities_data_ must occur on task_runner_for_writes_'s thread. | |
| 124 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_writes_; | |
| 54 | 125 |
| 55 ValidatorMap validator_map_; | 126 ValidatorMap validator_map_; |
| 56 base::ObserverList<Observer> observer_list_; | 127 const scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; |
| 57 base::ThreadChecker thread_checker_; | |
| 58 | 128 |
| 59 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilitiesImpl); | 129 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilitiesImpl); |
| 60 }; | 130 }; |
| 61 | 131 |
| 62 } // namespace chromecast | 132 } // namespace chromecast |
| 63 | 133 |
| 64 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ | 134 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ |
| OLD | NEW |