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/observer_list_threadsafe.h" | |
12 #include "base/synchronization/lock.h" | |
11 #include "chromecast/base/device_capabilities.h" | 13 #include "chromecast/base/device_capabilities.h" |
12 | 14 |
15 namespace base { | |
16 class SingleThreadTaskRunner; | |
17 } | |
18 | |
13 namespace chromecast { | 19 namespace chromecast { |
14 | 20 |
15 class DeviceCapabilitiesImpl : public DeviceCapabilities { | 21 class DeviceCapabilitiesImpl : public DeviceCapabilities { |
16 public: | 22 public: |
17 ~DeviceCapabilitiesImpl() override; | 23 ~DeviceCapabilitiesImpl() override; |
18 | 24 |
19 // DeviceCapabilities implementation: | 25 // DeviceCapabilities implementation: |
20 void Register(const std::string& key, Validator* validator) override; | 26 void Register(const std::string& key, Validator* validator) override; |
21 void Unregister(const std::string& key, const Validator* validator) override; | 27 void Unregister(const std::string& key, const Validator* validator) override; |
22 Validator* GetValidator(const std::string& key) const override; | 28 Validator* GetValidator(const std::string& key) const override; |
23 bool BluetoothSupported() const override; | 29 bool BluetoothSupported() const override; |
24 bool DisplaySupported() const override; | 30 bool DisplaySupported() const override; |
25 bool GetCapability(const std::string& path, | 31 scoped_ptr<base::Value> GetCapability(const std::string& path) const override; |
26 const base::Value** out_value) const override; | 32 std::string GetCapabilitiesString() const override; |
27 const std::string& GetCapabilitiesString() const override; | 33 scoped_ptr<base::DictionaryValue> GetCapabilities() const override; |
28 const base::DictionaryValue* GetCapabilities() const override; | |
29 void SetCapability(const std::string& path, | 34 void SetCapability(const std::string& path, |
30 scoped_ptr<base::Value> proposed_value) override; | 35 scoped_ptr<base::Value> proposed_value) override; |
31 void MergeDictionary(const base::DictionaryValue& dict_value) override; | 36 void MergeDictionary(const base::DictionaryValue& dict_value) override; |
32 void AddCapabilitiesObserver(Observer* observer) override; | 37 void AddCapabilitiesObserver(Observer* observer) override; |
33 void RemoveCapabilitiesObserver(Observer* observer) override; | 38 void RemoveCapabilitiesObserver(Observer* observer) override; |
34 | 39 |
35 private: | 40 private: |
41 // Customized wrapper class to make capabilities-related members immutable | |
42 // and RefCountedThreadSafe. Not using RefCountedData class since it requires | |
43 // a copy-constructable template parameter, which DictionaryValue does not | |
44 // meet. | |
45 template <class T> | |
46 struct ImmutableRefCounted | |
47 : public base::RefCountedThreadSafe<ImmutableRefCounted<T>> { | |
48 public: | |
49 ImmutableRefCounted(); | |
50 explicit ImmutableRefCounted(scoped_ptr<const T> data_arg); | |
51 | |
52 // Using scoped_ptr instead of raw data member (T) because DictionaryValue | |
53 // and string usage in this class tends to get passed by scoped_ptr. | |
54 const scoped_ptr<const T> data; | |
byungchul
2015/10/27 20:38:22
This struct is not copyable. Please make this a cl
esum
2015/10/28 00:29:51
Done.
| |
55 | |
56 private: | |
57 friend class base::RefCountedThreadSafe<ImmutableRefCounted<T>>; | |
58 | |
59 ~ImmutableRefCounted() {} | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(ImmutableRefCounted); | |
62 }; | |
63 | |
64 struct ValidatorInfo { | |
65 explicit ValidatorInfo(Validator* validator_arg); | |
66 ~ValidatorInfo(); | |
67 | |
68 Validator* const validator; | |
69 // TaskRunner of thread that validator_ was registered on | |
70 const scoped_refptr<base::SingleThreadTaskRunner> task_runner; | |
71 }; | |
72 | |
36 // For DeviceCapabilitiesImpl() | 73 // For DeviceCapabilitiesImpl() |
37 friend class DeviceCapabilities; | 74 friend class DeviceCapabilities; |
38 // For SetValidatedValueInternal() | 75 // For SetValidatedValueInternal() |
39 friend class DeviceCapabilities::Validator; | 76 friend class DeviceCapabilities::Validator; |
40 | 77 |
41 // Map from capability key to corresponding Validator. Gets updated | 78 // Map from capability key to corresponding ValidatorInfo. Gets updated |
42 // in Register()/Unregister(). | 79 // in Register()/Unregister(). |
43 typedef base::hash_map<std::string, Validator*> ValidatorMap; | 80 typedef base::hash_map<std::string, ValidatorInfo> ValidatorMap; |
81 typedef ImmutableRefCounted<base::DictionaryValue> | |
82 ImmutableRefCountedDictionary; | |
83 typedef ImmutableRefCounted<std::string> ImmutableRefCountedString; | |
44 | 84 |
45 // Internal constructor used by static DeviceCapabilities::Create*() methods. | 85 // Internal constructor used by static DeviceCapabilities::Create*() methods. |
46 DeviceCapabilitiesImpl(); | 86 DeviceCapabilitiesImpl(); |
47 | 87 |
48 void SetValidatedValueInternal(const std::string& path, | 88 void SetValidatedValue(const std::string& path, |
49 scoped_ptr<base::Value> new_value) override; | 89 scoped_ptr<base::Value> new_value) override; |
50 void UpdateStrAndNotifyChanged(const std::string& path); | 90 void RunValidateOnCurrentThread(const std::string& path, |
91 scoped_ptr<base::Value> proposed_value, | |
92 Validator* validator); | |
93 scoped_refptr<ImmutableRefCountedDictionary> GetCapabilitiesReference() const; | |
94 scoped_refptr<ImmutableRefCountedString> GetCapabilitiesStrReference() const; | |
51 | 95 |
52 scoped_ptr<base::DictionaryValue> capabilities_; | 96 // Defined locking order if acquiring both locks at same time from a thread |
53 scoped_ptr<const std::string> capabilities_str_; | 97 // to prevent deadlocks: |
98 // 1) validation_lock_ | |
99 // 2) capabilities_lock_ | |
100 | |
101 // Lock for all access to capabilities related members (capabilities_ and | |
102 // capabilities_str_) | |
103 mutable base::Lock capabilities_lock_; | |
104 // Lock for all access to validation members (validator_map_) | |
105 mutable base::Lock validation_lock_; | |
106 | |
107 scoped_refptr<ImmutableRefCountedDictionary> capabilities_; | |
108 scoped_refptr<ImmutableRefCountedString> capabilities_str_; | |
109 // TaskRunner for capability writes. All internal writes to capabilities_ | |
110 // must occur on task_runner_for_writes_'s thread. | |
111 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_writes_; | |
54 | 112 |
55 ValidatorMap validator_map_; | 113 ValidatorMap validator_map_; |
56 base::ObserverList<Observer> observer_list_; | 114 const scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; |
57 base::ThreadChecker thread_checker_; | |
58 | 115 |
59 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilitiesImpl); | 116 DISALLOW_COPY_AND_ASSIGN(DeviceCapabilitiesImpl); |
60 }; | 117 }; |
61 | 118 |
62 } // namespace chromecast | 119 } // namespace chromecast |
63 | 120 |
64 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ | 121 #endif // CHROMECAST_BASE_DEVICE_CAPABILITIES_IMPL_H_ |
OLD | NEW |