Home | History | Annotate | Download | only in binder
      1 //
      2 //  Copyright 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/ipc/binder/bluetooth_le_advertiser_binder_server.h"
     18 
     19 #include <base/logging.h>
     20 
     21 #include "service/adapter.h"
     22 
     23 using android::String8;
     24 using android::String16;
     25 using android::binder::Status;
     26 
     27 namespace ipc {
     28 namespace binder {
     29 
     30 namespace {
     31 const int kInvalidInstanceId = -1;
     32 }  // namespace
     33 
     34 BluetoothLeAdvertiserBinderServer::BluetoothLeAdvertiserBinderServer(
     35     bluetooth::Adapter* adapter)
     36     : adapter_(adapter) {
     37   CHECK(adapter_);
     38 }
     39 
     40 BluetoothLeAdvertiserBinderServer::~BluetoothLeAdvertiserBinderServer() {}
     41 
     42 Status BluetoothLeAdvertiserBinderServer::RegisterAdvertiser(
     43     const android::sp<IBluetoothLeAdvertiserCallback>& callback,
     44     bool* _aidl_return) {
     45   VLOG(2) << __func__;
     46   bluetooth::LowEnergyAdvertiserFactory* adv_factory =
     47       adapter_->GetLeAdvertiserFactory();
     48 
     49   *_aidl_return = RegisterInstanceBase(callback, adv_factory);
     50   return Status::ok();
     51 }
     52 
     53 Status BluetoothLeAdvertiserBinderServer::UnregisterAdvertiser(
     54     int advertiser_id) {
     55   VLOG(2) << __func__;
     56   UnregisterInstanceBase(advertiser_id);
     57   return Status::ok();
     58 }
     59 
     60 Status BluetoothLeAdvertiserBinderServer::UnregisterAll() {
     61   VLOG(2) << __func__;
     62   UnregisterAllBase();
     63   return Status::ok();
     64 }
     65 
     66 Status BluetoothLeAdvertiserBinderServer::StartMultiAdvertising(
     67     int advertiser_id, const android::bluetooth::AdvertiseData& advertise_data,
     68     const android::bluetooth::AdvertiseData& scan_response,
     69     const android::bluetooth::AdvertiseSettings& settings, bool* _aidl_return) {
     70   VLOG(2) << __func__ << " advertiser_id: " << advertiser_id;
     71   std::lock_guard<std::mutex> lock(*maps_lock());
     72 
     73   auto advertiser = GetLEAdvertiser(advertiser_id);
     74   if (!advertiser) {
     75     LOG(ERROR) << "Unknown advertiser_id: " << advertiser_id;
     76     *_aidl_return = false;
     77     return Status::ok();
     78   }
     79 
     80   // Create a weak pointer and pass that to the callback to prevent a potential
     81   // use after free.
     82   android::wp<BluetoothLeAdvertiserBinderServer> weak_ptr_to_this(this);
     83   auto settings_copy = settings;
     84   auto callback = [=](bluetooth::BLEStatus status) {
     85     auto sp_to_this = weak_ptr_to_this.promote();
     86     if (!sp_to_this.get()) {
     87       VLOG(2) << "BluetoothLeAdvertiserBinderServer was deleted";
     88       return;
     89     }
     90 
     91     std::lock_guard<std::mutex> lock(*maps_lock());
     92 
     93     auto cb = GetLECallback(advertiser_id);
     94     if (!cb.get()) {
     95       VLOG(1) << "Advertiser was removed before callback: " << advertiser_id;
     96       return;
     97     }
     98 
     99     cb->OnMultiAdvertiseCallback(status, true /* is_start */, settings_copy);
    100   };
    101 
    102   if (!advertiser->StartAdvertising(settings, advertise_data, scan_response,
    103                                     callback)) {
    104     LOG(ERROR) << "Failed to initiate call to start advertising";
    105     *_aidl_return = false;
    106     return Status::ok();
    107   }
    108 
    109   *_aidl_return = true;
    110   return Status::ok();
    111 }
    112 
    113 Status BluetoothLeAdvertiserBinderServer::StopMultiAdvertising(
    114     int advertiser_id, bool* _aidl_return) {
    115   VLOG(2) << __func__;
    116   std::lock_guard<std::mutex> lock(*maps_lock());
    117 
    118   auto advertiser = GetLEAdvertiser(advertiser_id);
    119   if (!advertiser) {
    120     LOG(ERROR) << "Unknown advertiser_id: " << advertiser_id;
    121     *_aidl_return = false;
    122     return Status::ok();
    123   }
    124 
    125   // Create a weak pointer and pass that to the callback to prevent a potential
    126   // use after free.
    127   android::wp<BluetoothLeAdvertiserBinderServer> weak_ptr_to_this(this);
    128   auto settings_copy = advertiser->advertise_settings();
    129   auto callback = [=](bluetooth::BLEStatus status) {
    130     auto sp_to_this = weak_ptr_to_this.promote();
    131     if (!sp_to_this.get()) {
    132       VLOG(2) << "BluetoothLeAdvertiserBinderServer was deleted";
    133       return;
    134     }
    135 
    136     auto cb = GetLECallback(advertiser_id);
    137     if (!cb.get()) {
    138       VLOG(2) << "Advertiser was unregistered - advertiser_id: "
    139               << advertiser_id;
    140       return;
    141     }
    142 
    143     std::lock_guard<std::mutex> lock(*maps_lock());
    144 
    145     cb->OnMultiAdvertiseCallback(status, false /* is_start */, settings_copy);
    146   };
    147 
    148   if (!advertiser->StopAdvertising(callback)) {
    149     LOG(ERROR) << "Failed to initiate call to start advertising";
    150     *_aidl_return = false;
    151     return Status::ok();
    152   }
    153 
    154   *_aidl_return = true;
    155   return Status::ok();
    156 }
    157 
    158 android::sp<IBluetoothLeAdvertiserCallback>
    159 BluetoothLeAdvertiserBinderServer::GetLECallback(int advertiser_id) {
    160   auto cb = GetCallback(advertiser_id);
    161   return android::sp<IBluetoothLeAdvertiserCallback>(
    162       static_cast<IBluetoothLeAdvertiserCallback*>(cb.get()));
    163 }
    164 
    165 std::shared_ptr<bluetooth::LowEnergyAdvertiser>
    166 BluetoothLeAdvertiserBinderServer::GetLEAdvertiser(int advertiser_id) {
    167   return std::static_pointer_cast<bluetooth::LowEnergyAdvertiser>(
    168       GetInstance(advertiser_id));
    169 }
    170 
    171 void BluetoothLeAdvertiserBinderServer::OnRegisterInstanceImpl(
    172     bluetooth::BLEStatus status, android::sp<IInterface> callback,
    173     bluetooth::BluetoothInstance* instance) {
    174   VLOG(1) << __func__ << " status: " << status;
    175 
    176   android::sp<IBluetoothLeAdvertiserCallback> cb(
    177       static_cast<IBluetoothLeAdvertiserCallback*>(callback.get()));
    178   cb->OnAdvertiserRegistered(status, (status == bluetooth::BLE_STATUS_SUCCESS)
    179                                          ? instance->GetInstanceId()
    180                                          : kInvalidInstanceId);
    181 }
    182 
    183 }  // namespace binder
    184 }  // namespace ipc
    185