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 #define LOG_TAG "audio_proxy_client"
16
17 #include "AudioProxyManager.h"
18
19 #include <mutex>
20
21 // clang-format off
22 #include PATH(device/google/atv/audio_proxy/AUDIO_PROXY_FILE_VERSION/IAudioProxyDevicesManager.h)
23 // clang-format on
24
25 #include <hidl/HidlTransportSupport.h>
26 #include <utils/Log.h>
27
28 #include "AudioProxyDevice.h"
29 #include "BusDeviceImpl.h"
30
31 #define QUOTE(s) #s
32 #define TO_STR(s) QUOTE(s)
33
34 using ::android::sp;
35 using ::android::status_t;
36 using ::android::hardware::hidl_death_recipient;
37 using ::android::hardware::Return;
38 using ::device::google::atv::audio_proxy::AUDIO_PROXY_CPP_VERSION::
39 IAudioProxyDevicesManager;
40
41 namespace audio_proxy {
42 namespace AUDIO_PROXY_CPP_VERSION {
43 namespace {
44
checkDevice(audio_proxy_device_t * device)45 bool checkDevice(audio_proxy_device_t* device) {
46 return device && device->get_address && device->open_output_stream &&
47 device->close_output_stream;
48 }
49
50 class DeathRecipient;
51
52 class AudioProxyManagerImpl : public AudioProxyManager {
53 public:
54 explicit AudioProxyManagerImpl(const sp<IAudioProxyDevicesManager>& manager);
55 ~AudioProxyManagerImpl() override = default;
56
57 bool registerDevice(audio_proxy_device_t* device) override;
58
59 void reconnectService();
60
61 private:
62 std::mutex mLock;
63 sp<IAudioProxyDevicesManager> mService;
64 std::unique_ptr<AudioProxyDevice> mDevice;
65
66 sp<DeathRecipient> mDeathRecipient;
67 };
68
69 class DeathRecipient : public hidl_death_recipient {
70 public:
DeathRecipient(AudioProxyManagerImpl & manager)71 explicit DeathRecipient(AudioProxyManagerImpl& manager) : mManager(manager) {}
72 ~DeathRecipient() override = default;
73
serviceDied(uint64_t cookie,const android::wp<::android::hidl::base::V1_0::IBase> & who)74 void serviceDied(
75 uint64_t cookie,
76 const android::wp<::android::hidl::base::V1_0::IBase>& who) override {
77 mManager.reconnectService();
78 }
79
80 private:
81 AudioProxyManagerImpl& mManager;
82 };
83
AudioProxyManagerImpl(const sp<IAudioProxyDevicesManager> & manager)84 AudioProxyManagerImpl::AudioProxyManagerImpl(
85 const sp<IAudioProxyDevicesManager>& manager)
86 : mService(manager), mDeathRecipient(new DeathRecipient(*this)) {
87 mService->linkToDeath(mDeathRecipient, 1234);
88 }
89
registerDevice(audio_proxy_device_t * device)90 bool AudioProxyManagerImpl::registerDevice(audio_proxy_device_t* device) {
91 if (!checkDevice(device)) {
92 ALOGE("Invalid device.");
93 return false;
94 }
95
96 std::lock_guard<std::mutex> guard(mLock);
97 if (mDevice) {
98 ALOGE("Device already registered!");
99 return false;
100 }
101
102 mDevice = std::make_unique<AudioProxyDevice>(device);
103
104 const char* address = mDevice->getAddress();
105 return mService->registerDevice(address, new BusDeviceImpl(mDevice.get()));
106 }
107
reconnectService()108 void AudioProxyManagerImpl::reconnectService() {
109 std::lock_guard<std::mutex> guard(mLock);
110 mService = IAudioProxyDevicesManager::getService();
111 if (!mService) {
112 ALOGE("Failed to reconnect service");
113 return;
114 }
115
116 if (mDevice) {
117 bool success = mService->registerDevice(mDevice->getAddress(),
118 new BusDeviceImpl(mDevice.get()));
119 ALOGE_IF(!success, "fail to register device after reconnect.");
120 }
121 }
122
123 } // namespace
124
createAudioProxyManager()125 std::unique_ptr<AudioProxyManager> createAudioProxyManager() {
126 auto service = IAudioProxyDevicesManager::getService();
127 if (!service) {
128 return nullptr;
129 }
130
131 ALOGI("Connect to audio proxy service %s", TO_STR(AUDIO_PROXY_FILE_VERSION));
132 return std::make_unique<AudioProxyManagerImpl>(service);
133 }
134
135 } // namespace AUDIO_PROXY_CPP_VERSION
136 } // namespace audio_proxy
137