1 //
2 // Copyright (C) 2015 Google, Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "service/common/bluetooth/binder/IBluetooth.h"
18
19 #include <base/logging.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/Parcel.h>
22
23 using android::defaultServiceManager;
24 using android::IBinder;
25 using android::interface_cast;
26 using android::IServiceManager;
27 using android::Parcel;
28 using android::PERMISSION_DENIED;
29 using android::sp;
30 using android::status_t;
31 using android::String16;
32
33 namespace ipc {
34 namespace binder {
35
36 // static
37 const char IBluetooth::kServiceName[] = "bluetooth-service";
38
39 // static
getClientInterface()40 sp<IBluetooth> IBluetooth::getClientInterface() {
41 sp<IServiceManager> sm = defaultServiceManager();
42 if (!sm.get()) {
43 LOG(ERROR) << "Failed to obtain a handle to the default Service Manager";
44 return nullptr;
45 }
46
47 sp<IBinder> binder = sm->getService(String16(kServiceName));
48 if (!binder.get()) {
49 LOG(ERROR) << "Failed to obtain a handle to the Bluetooth service";
50 return nullptr;
51 }
52
53 sp<IBluetooth> bt_iface = interface_cast<IBluetooth>(binder);
54 if (!bt_iface.get()) {
55 LOG(ERROR) << "Obtained invalid IBinder handle";
56 return nullptr;
57 }
58
59 return bt_iface;
60 }
61
62 // BnBluetooth (server) implementation
63 // ========================================================
64
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)65 status_t BnBluetooth::onTransact(
66 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
67 VLOG(2) << "IBluetooth transaction: " << code;
68
69 switch (code) {
70 case IS_ENABLED_TRANSACTION: {
71 CHECK_INTERFACE(IBluetooth, data, reply);
72 bool is_enabled = IsEnabled();
73 reply->writeInt32(is_enabled);
74 return android::NO_ERROR;
75 }
76 case GET_STATE_TRANSACTION: {
77 CHECK_INTERFACE(IBluetooth, data, reply);
78 int state = GetState();
79 reply->writeInt32(state);
80 return android::NO_ERROR;
81 }
82 case ENABLE_TRANSACTION: {
83 CHECK_INTERFACE(IBluetooth, data, reply);
84 bool start_restricted = data.readBool();
85 bool result = Enable(start_restricted);
86 reply->writeInt32(result);
87 return android::NO_ERROR;
88 }
89 case DISABLE_TRANSACTION: {
90 CHECK_INTERFACE(IBluetooth, data, reply);
91 bool result = Disable();
92 reply->writeInt32(result);
93 return android::NO_ERROR;
94 }
95 case GET_ADDRESS_TRANSACTION: {
96 CHECK_INTERFACE(IBluetooth, data, reply);
97 std::string address = GetAddress();
98 reply->writeCString(address.c_str());
99 return android::NO_ERROR;
100 }
101 case GET_UUIDS_TRANSACTION:
102 CHECK_INTERFACE(IBluetooth, data, reply);
103 // TODO(armansito): Figure out how to handle a Java "ParcelUuid" natively.
104 // (see http://b/23316698).
105 return android::INVALID_OPERATION;
106
107 case SET_NAME_TRANSACTION: {
108 CHECK_INTERFACE(IBluetooth, data, reply);
109 std::string name(data.readCString());
110 bool result = SetName(name);
111 reply->writeInt32(result);
112 return android::NO_ERROR;
113 }
114 case GET_NAME_TRANSACTION: {
115 CHECK_INTERFACE(IBluetooth, data, reply);
116 std::string name = GetName();
117 reply->writeCString(name.c_str());
118 return android::NO_ERROR;
119 }
120 case REGISTER_CALLBACK_TRANSACTION: {
121 CHECK_INTERFACE(IBluetooth, data, reply);
122 sp<IBinder> callback = data.readStrongBinder();
123 RegisterCallback(interface_cast<IBluetoothCallback>(callback));
124 return android::NO_ERROR;
125 }
126 case UNREGISTER_CALLBACK_TRANSACTION: {
127 CHECK_INTERFACE(IBluetooth, data, reply);
128 sp<IBinder> callback = data.readStrongBinder();
129 UnregisterCallback(interface_cast<IBluetoothCallback>(callback));
130 return android::NO_ERROR;
131 }
132 case IS_MULTI_ADVERTISEMENT_SUPPORTED_TRANSACTION: {
133 CHECK_INTERFACE(IBluetooth, data, reply);
134 bool result = IsMultiAdvertisementSupported();
135 reply->writeInt32(result);
136 return android::NO_ERROR;
137 }
138 case GET_LOW_ENERGY_INTERFACE_TRANSACTION: {
139 CHECK_INTERFACE(IBluetooth, data, reply);
140 sp<IBluetoothLowEnergy> ble_iface = GetLowEnergyInterface();
141 reply->writeStrongBinder(IInterface::asBinder(ble_iface.get()));
142 return android::NO_ERROR;
143 }
144 case GET_GATT_CLIENT_INTERFACE_TRANSACTION: {
145 CHECK_INTERFACE(IBluetooth, data, reply);
146 sp<IBluetoothGattClient> gatt_client_iface = GetGattClientInterface();
147 reply->writeStrongBinder(IInterface::asBinder(gatt_client_iface.get()));
148 return android::NO_ERROR;
149 }
150 case GET_GATT_SERVER_INTERFACE_TRANSACTION: {
151 CHECK_INTERFACE(IBluetooth, data, reply);
152 sp<IBluetoothGattServer> gatt_server_iface = GetGattServerInterface();
153 reply->writeStrongBinder(IInterface::asBinder(gatt_server_iface.get()));
154 return android::NO_ERROR;
155 }
156 default:
157 return BBinder::onTransact(code, data, reply, flags);
158 }
159 }
160
161 // BpBluetooth (client) implementation
162 // ========================================================
163
BpBluetooth(const sp<IBinder> & impl)164 BpBluetooth::BpBluetooth(const sp<IBinder>& impl)
165 : BpInterface<IBluetooth>(impl) {
166 }
167
IsEnabled()168 bool BpBluetooth::IsEnabled() {
169 Parcel data, reply;
170
171 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
172 remote()->transact(IBluetooth::IS_ENABLED_TRANSACTION, data, &reply);
173
174 return reply.readInt32();
175 }
176
GetState()177 int BpBluetooth::GetState() {
178 Parcel data, reply;
179
180 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
181 remote()->transact(IBluetooth::GET_STATE_TRANSACTION, data, &reply);
182
183 return reply.readInt32();
184 }
185
Enable(bool start_restricted)186 bool BpBluetooth::Enable(bool start_restricted) {
187 Parcel data, reply;
188
189 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
190 data.writeBool(start_restricted);
191 remote()->transact(IBluetooth::ENABLE_TRANSACTION, data, &reply);
192
193 return reply.readInt32();
194 }
195
EnableNoAutoConnect()196 bool BpBluetooth::EnableNoAutoConnect() {
197 Parcel data, reply;
198
199 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
200 remote()->transact(IBluetooth::ENABLE_NO_AUTO_CONNECT_TRANSACTION,
201 data, &reply);
202
203 return reply.readInt32();
204 }
205
Disable()206 bool BpBluetooth::Disable() {
207 Parcel data, reply;
208
209 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
210 remote()->transact(IBluetooth::DISABLE_TRANSACTION, data, &reply);
211
212 return reply.readInt32();
213 }
214
GetAddress()215 std::string BpBluetooth::GetAddress() {
216 Parcel data, reply;
217
218 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
219 remote()->transact(IBluetooth::GET_ADDRESS_TRANSACTION, data, &reply);
220
221 return reply.readCString();
222 }
223
GetUUIDs()224 std::vector<bluetooth::UUID> BpBluetooth::GetUUIDs() {
225 // TODO(armansito): need to deserialize a parceled java.util.ParcelUUID[] to
226 // std::vector<bluetooth::UUID> here (see http://b/23316698).
227 return std::vector<bluetooth::UUID>();
228 }
229
SetName(const std::string & name)230 bool BpBluetooth::SetName(const std::string& name) {
231 Parcel data, reply;
232
233 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
234 data.writeCString(name.c_str());
235 remote()->transact(IBluetooth::SET_NAME_TRANSACTION, data, &reply);
236
237 return reply.readInt32();
238 }
239
GetName()240 std::string BpBluetooth::GetName() {
241 Parcel data, reply;
242
243 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
244 remote()->transact(IBluetooth::GET_NAME_TRANSACTION, data, &reply);
245
246 return reply.readCString();
247 }
248
RegisterCallback(const sp<IBluetoothCallback> & callback)249 void BpBluetooth::RegisterCallback(const sp<IBluetoothCallback>& callback) {
250 Parcel data, reply;
251
252 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
253 data.writeStrongBinder(IInterface::asBinder(callback.get()));
254
255 remote()->transact(IBluetooth::REGISTER_CALLBACK_TRANSACTION, data, &reply);
256 }
257
UnregisterCallback(const sp<IBluetoothCallback> & callback)258 void BpBluetooth::UnregisterCallback(const sp<IBluetoothCallback>& callback) {
259 Parcel data, reply;
260
261 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
262 data.writeStrongBinder(IInterface::asBinder(callback.get()));
263
264 remote()->transact(IBluetooth::UNREGISTER_CALLBACK_TRANSACTION, data, &reply);
265 }
266
IsMultiAdvertisementSupported()267 bool BpBluetooth::IsMultiAdvertisementSupported() {
268 Parcel data, reply;
269
270 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
271
272 remote()->transact(IBluetooth::IS_MULTI_ADVERTISEMENT_SUPPORTED_TRANSACTION,
273 data, &reply);
274
275 return reply.readInt32();
276 }
277
GetLowEnergyInterface()278 sp<IBluetoothLowEnergy> BpBluetooth::GetLowEnergyInterface() {
279 Parcel data, reply;
280
281 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
282
283 remote()->transact(IBluetooth::GET_LOW_ENERGY_INTERFACE_TRANSACTION,
284 data, &reply);
285
286 return interface_cast<IBluetoothLowEnergy>(reply.readStrongBinder());
287 }
288
GetGattClientInterface()289 sp<IBluetoothGattClient> BpBluetooth::GetGattClientInterface() {
290 Parcel data, reply;
291
292 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
293
294 remote()->transact(IBluetooth::GET_GATT_CLIENT_INTERFACE_TRANSACTION,
295 data, &reply);
296
297 return interface_cast<IBluetoothGattClient>(reply.readStrongBinder());
298 }
299
GetGattServerInterface()300 sp<IBluetoothGattServer> BpBluetooth::GetGattServerInterface() {
301 Parcel data, reply;
302
303 data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
304
305 remote()->transact(IBluetooth::GET_GATT_SERVER_INTERFACE_TRANSACTION,
306 data, &reply);
307
308 return interface_cast<IBluetoothGattServer>(reply.readStrongBinder());
309 }
310
311 IMPLEMENT_META_INTERFACE(Bluetooth, IBluetooth::kServiceName);
312
313 } // namespace binder
314 } // namespace ipc
315