• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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