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
BluetoothLeAdvertiserBinderServer(bluetooth::Adapter * adapter)34 BluetoothLeAdvertiserBinderServer::BluetoothLeAdvertiserBinderServer(
35 bluetooth::Adapter* adapter)
36 : adapter_(adapter) {
37 CHECK(adapter_);
38 }
39
~BluetoothLeAdvertiserBinderServer()40 BluetoothLeAdvertiserBinderServer::~BluetoothLeAdvertiserBinderServer() {}
41
RegisterAdvertiser(const android::sp<IBluetoothLeAdvertiserCallback> & callback,bool * _aidl_return)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
UnregisterAdvertiser(int advertiser_id)53 Status BluetoothLeAdvertiserBinderServer::UnregisterAdvertiser(
54 int advertiser_id) {
55 VLOG(2) << __func__;
56 UnregisterInstanceBase(advertiser_id);
57 return Status::ok();
58 }
59
UnregisterAll()60 Status BluetoothLeAdvertiserBinderServer::UnregisterAll() {
61 VLOG(2) << __func__;
62 UnregisterAllBase();
63 return Status::ok();
64 }
65
StartMultiAdvertising(int advertiser_id,const android::bluetooth::AdvertiseData & advertise_data,const android::bluetooth::AdvertiseData & scan_response,const android::bluetooth::AdvertiseSettings & settings,bool * _aidl_return)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
StopMultiAdvertising(int advertiser_id,bool * _aidl_return)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>
GetLECallback(int advertiser_id)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>
GetLEAdvertiser(int advertiser_id)166 BluetoothLeAdvertiserBinderServer::GetLEAdvertiser(int advertiser_id) {
167 return std::static_pointer_cast<bluetooth::LowEnergyAdvertiser>(
168 GetInstance(advertiser_id));
169 }
170
OnRegisterInstanceImpl(bluetooth::BLEStatus status,android::sp<IInterface> callback,bluetooth::BluetoothInstance * instance)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