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/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