1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "BusDeviceProvider.h"
16
17 #include <algorithm>
18
19 namespace audio_proxy {
20 namespace service {
21
22 class BusDeviceProvider::DeathRecipient : public hidl_death_recipient {
23 public:
DeathRecipient(BusDeviceProvider & owner)24 explicit DeathRecipient(BusDeviceProvider& owner) : mOwner(owner) {}
25 ~DeathRecipient() override = default;
26
serviceDied(uint64_t token,const android::wp<::android::hidl::base::V1_0::IBase> & who)27 void serviceDied(
28 uint64_t token,
29 const android::wp<::android::hidl::base::V1_0::IBase>& who) override {
30 mOwner.removeByToken(token);
31 }
32
33 private:
34 BusDeviceProvider& mOwner;
35 };
36
BusDeviceProvider()37 BusDeviceProvider::BusDeviceProvider()
38 : mDeathRecipient(new DeathRecipient(*this)) {}
39 BusDeviceProvider::~BusDeviceProvider() = default;
40
add(const hidl_string & address,sp<IBusDevice> device)41 bool BusDeviceProvider::add(const hidl_string& address, sp<IBusDevice> device) {
42 std::lock_guard<std::mutex> guard(mDevicesLock);
43 auto it = std::find_if(mBusDevices.begin(), mBusDevices.end(),
44 [&address](const BusDeviceHolder& holder) {
45 return holder.address == address;
46 });
47
48 if (it != mBusDevices.end()) {
49 return false;
50 }
51
52 uint64_t token = mNextToken++;
53
54 mBusDevices.push_back({device, address, token});
55
56 device->linkToDeath(mDeathRecipient, token);
57
58 return true;
59 }
60
get(const hidl_string & address)61 sp<IBusDevice> BusDeviceProvider::get(const hidl_string& address) {
62 std::lock_guard<std::mutex> guard(mDevicesLock);
63 auto it = std::find_if(mBusDevices.begin(), mBusDevices.end(),
64 [&address](const BusDeviceHolder& holder) {
65 return holder.address == address;
66 });
67
68 if (it == mBusDevices.end()) {
69 return nullptr;
70 }
71
72 return it->device;
73 }
74
removeAll()75 void BusDeviceProvider::removeAll() {
76 std::lock_guard<std::mutex> guard(mDevicesLock);
77 mBusDevices.clear();
78 }
79
removeByToken(uint64_t token)80 void BusDeviceProvider::removeByToken(uint64_t token) {
81 std::lock_guard<std::mutex> guard(mDevicesLock);
82 mBusDevices.erase(std::find_if(mBusDevices.begin(), mBusDevices.end(),
83 [token](const BusDeviceHolder& holder) {
84 return holder.token == token;
85 }));
86 }
87
88 } // namespace service
89 } // namespace audio_proxy