Home | History | Annotate | Download | only in binder
      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