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 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 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 164 BpBluetooth::BpBluetooth(const sp<IBinder>& impl) 165 : BpInterface<IBluetooth>(impl) { 166 } 167 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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