Fixes bug in html_viewer that could lead to dropping interface requests
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_media_client.cc
blob592275307695a89a2d97a22bab0aa2df8d0d6aab
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/bluetooth_media_client.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/observer_list.h"
11 #include "dbus/bus.h"
12 #include "dbus/message.h"
13 #include "dbus/object_manager.h"
14 #include "dbus/object_proxy.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
17 namespace {
19 // Since there is no property associated with Media objects, an empty callback
20 // is used.
21 void DoNothing(const std::string& property_name) {
24 // TODO(mcchou): Add these service constants into dbus/service_constants.h
25 // later.
26 const char kBluetoothMediaInterface[] = "org.bluez.Media1";
28 // Method names supported by Media Interface.
29 const char kRegisterEndpoint[] = "RegisterEndpoint";
30 const char kUnregisterEndpoint[] = "UnregisterEndpoint";
32 // The set of properties which are used to register a media endpoint.
33 const char kUUIDEndpointProperty[] = "UUID";
34 const char kCodecEndpointProperty[] = "Codec";
35 const char kCapabilitiesEndpointProperty[] = "Capabilities";
37 } // namespace
39 namespace chromeos {
41 // static
42 const char BluetoothMediaClient::kNoResponseError[] =
43 "org.chromium.Error.NoResponse";
45 // static
46 const char BluetoothMediaClient::kBluetoothAudioSinkUUID[] =
47 "0000110b-0000-1000-8000-00805f9b34fb";
49 BluetoothMediaClient::EndpointProperties::EndpointProperties() : codec(0x00) {
52 BluetoothMediaClient::EndpointProperties::~EndpointProperties() {
55 class BluetoothMediaClientImpl
56 : public BluetoothMediaClient, dbus::ObjectManager::Interface {
57 public:
58 BluetoothMediaClientImpl()
59 : object_manager_(nullptr), weak_ptr_factory_(this) {}
61 ~BluetoothMediaClientImpl() override {
62 object_manager_->UnregisterInterface(kBluetoothMediaInterface);
65 // dbus::ObjectManager::Interface overrides.
67 dbus::PropertySet* CreateProperties(
68 dbus::ObjectProxy* object_proxy,
69 const dbus::ObjectPath& object_path,
70 const std::string& interface_name) override {
71 return new dbus::PropertySet(object_proxy, interface_name,
72 base::Bind(&DoNothing));
75 void ObjectAdded(const dbus::ObjectPath& object_path,
76 const std::string& interface_name) override {
77 VLOG(1) << "Remote Media added: " << object_path.value();
78 FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_,
79 MediaAdded(object_path));
82 void ObjectRemoved(const dbus::ObjectPath& object_path,
83 const std::string& interface_name) override {
84 VLOG(1) << "Remote Media removed: " << object_path.value();
85 FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_,
86 MediaRemoved(object_path));
89 // BluetoothMediaClient overrides.
91 void AddObserver(BluetoothMediaClient::Observer* observer) override {
92 DCHECK(observer);
93 observers_.AddObserver(observer);
96 void RemoveObserver(BluetoothMediaClient::Observer* observer) override {
97 DCHECK(observer);
98 observers_.RemoveObserver(observer);
101 void RegisterEndpoint(const dbus::ObjectPath& object_path,
102 const dbus::ObjectPath& endpoint_path,
103 const EndpointProperties& properties,
104 const base::Closure& callback,
105 const ErrorCallback& error_callback) override {
106 VLOG(1) << "RegisterEndpoint - endpoint: " << endpoint_path.value();
108 dbus::MethodCall method_call(kBluetoothMediaInterface, kRegisterEndpoint);
110 dbus::MessageWriter writer(&method_call);
111 dbus::MessageWriter array_writer(nullptr);
112 dbus::MessageWriter dict_entry_writer(nullptr);
114 // Send the path to the endpoint.
115 writer.AppendObjectPath(endpoint_path);
117 writer.OpenArray("{sv}", &array_writer);
119 // Send UUID.
120 array_writer.OpenDictEntry(&dict_entry_writer);
121 dict_entry_writer.AppendString(kUUIDEndpointProperty);
122 dict_entry_writer.AppendVariantOfString(properties.uuid);
123 array_writer.CloseContainer(&dict_entry_writer);
125 // Send Codec.
126 array_writer.OpenDictEntry(&dict_entry_writer);
127 dict_entry_writer.AppendString(kCodecEndpointProperty);
128 dict_entry_writer.AppendVariantOfByte(properties.codec);
129 array_writer.CloseContainer(&dict_entry_writer);
131 // Send Capabilities.
132 dbus::MessageWriter variant_writer(nullptr);
133 array_writer.OpenDictEntry(&dict_entry_writer);
134 dict_entry_writer.AppendString(kCapabilitiesEndpointProperty);
135 dict_entry_writer.OpenVariant("ay", &variant_writer);
136 variant_writer.AppendArrayOfBytes(properties.capabilities.data(),
137 properties.capabilities.size());
138 dict_entry_writer.CloseContainer(&variant_writer);
139 array_writer.CloseContainer(&dict_entry_writer);
141 writer.CloseContainer(&array_writer);
143 // Get Object Proxy based on the service name and the service path and call
144 // RegisterEndpoint medthod.
145 scoped_refptr<dbus::ObjectProxy> object_proxy(
146 object_manager_->GetObjectProxy(object_path));
147 object_proxy->CallMethodWithErrorCallback(
148 &method_call,
149 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
150 base::Bind(&BluetoothMediaClientImpl::OnSuccess,
151 weak_ptr_factory_.GetWeakPtr(), callback),
152 base::Bind(&BluetoothMediaClientImpl::OnError,
153 weak_ptr_factory_.GetWeakPtr(), error_callback));
156 void UnregisterEndpoint(const dbus::ObjectPath& object_path,
157 const dbus::ObjectPath& endpoint_path,
158 const base::Closure& callback,
159 const ErrorCallback& error_callback) override {
160 VLOG(1) << "UnregisterEndpoint - endpoint: " << endpoint_path.value();
162 dbus::MethodCall method_call(kBluetoothMediaInterface, kUnregisterEndpoint);
164 // Send the path to the endpoint.
165 dbus::MessageWriter writer(&method_call);
166 writer.AppendObjectPath(endpoint_path);
168 // Get Object Proxy based on the service name and the service path and call
169 // RegisterEndpoint medthod.
170 scoped_refptr<dbus::ObjectProxy> object_proxy(
171 object_manager_->GetObjectProxy(object_path));
172 object_proxy->CallMethodWithErrorCallback(
173 &method_call,
174 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
175 base::Bind(&BluetoothMediaClientImpl::OnSuccess,
176 weak_ptr_factory_.GetWeakPtr(), callback),
177 base::Bind(&BluetoothMediaClientImpl::OnError,
178 weak_ptr_factory_.GetWeakPtr(), error_callback));
181 protected:
182 void Init(dbus::Bus* bus) override {
183 DCHECK(bus);
184 object_manager_ = bus->GetObjectManager(
185 bluetooth_object_manager::kBluetoothObjectManagerServiceName,
186 dbus::ObjectPath(
187 bluetooth_object_manager::kBluetoothObjectManagerServicePath));
188 object_manager_->RegisterInterface(kBluetoothMediaInterface, this);
191 private:
192 // Called when a response for successful method call is received.
193 void OnSuccess(const base::Closure& callback,
194 dbus::Response* response) {
195 DCHECK(response);
196 callback.Run();
199 // Called when a response for a failed method call is received.
200 void OnError(const ErrorCallback& error_callback,
201 dbus::ErrorResponse* response) {
202 // Error response has an optional error message argument.
203 std::string error_name;
204 std::string error_message;
205 if (response) {
206 dbus::MessageReader reader(response);
207 error_name = response->GetErrorName();
208 reader.PopString(&error_message);
209 } else {
210 error_name = kNoResponseError;
212 error_callback.Run(error_name, error_message);
215 dbus::ObjectManager* object_manager_;
217 // List of observers interested in event notifications from us.
218 base::ObserverList<BluetoothMediaClient::Observer> observers_;
220 base::WeakPtrFactory<BluetoothMediaClientImpl> weak_ptr_factory_;
222 DISALLOW_COPY_AND_ASSIGN(BluetoothMediaClientImpl);
225 BluetoothMediaClient::BluetoothMediaClient() {
228 BluetoothMediaClient::~BluetoothMediaClient() {
231 BluetoothMediaClient* BluetoothMediaClient::Create() {
232 return new BluetoothMediaClientImpl();
235 } // namespace chromeos