blob: ac48462288b7c2d0bfd2dc83812edc47a2f826ef [file] [log] [blame]
yucliu616c55f2020-05-11 17:48:57 -07001// 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
yucliu2ca85ac2020-09-22 17:50:47 -070022#include PATH(device/google/atv/audio_proxy/AUDIO_PROXY_FILE_VERSION/IAudioProxyDevicesManager.h)
yucliu616c55f2020-05-11 17:48:57 -070023// 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
34using ::android::sp;
35using ::android::status_t;
36using ::android::hardware::hidl_death_recipient;
37using ::android::hardware::Return;
yucliu2ca85ac2020-09-22 17:50:47 -070038using ::device::google::atv::audio_proxy::AUDIO_PROXY_CPP_VERSION::
yucliu616c55f2020-05-11 17:48:57 -070039 IAudioProxyDevicesManager;
40
41namespace audio_proxy {
yucliu2ca85ac2020-09-22 17:50:47 -070042namespace AUDIO_PROXY_CPP_VERSION {
yucliu616c55f2020-05-11 17:48:57 -070043namespace {
44
45bool checkDevice(audio_proxy_device_t* device) {
yucliu77f096a2020-05-11 18:44:19 -070046 return device && device->get_address && device->open_output_stream &&
47 device->close_output_stream;
yucliu616c55f2020-05-11 17:48:57 -070048}
49
50class DeathRecipient;
51
52class 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
69class DeathRecipient : public hidl_death_recipient {
70 public:
71 explicit DeathRecipient(AudioProxyManagerImpl& manager) : mManager(manager) {}
72 ~DeathRecipient() override = default;
73
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
84AudioProxyManagerImpl::AudioProxyManagerImpl(
85 const sp<IAudioProxyDevicesManager>& manager)
86 : mService(manager), mDeathRecipient(new DeathRecipient(*this)) {
87 mService->linkToDeath(mDeathRecipient, 1234);
88}
89
90bool 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
108void 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
125std::unique_ptr<AudioProxyManager> createAudioProxyManager() {
126 auto service = IAudioProxyDevicesManager::getService();
127 if (!service) {
128 return nullptr;
129 }
130
yucliu2ca85ac2020-09-22 17:50:47 -0700131 ALOGI("Connect to audio proxy service %s", TO_STR(AUDIO_PROXY_FILE_VERSION));
yucliu616c55f2020-05-11 17:48:57 -0700132 return std::make_unique<AudioProxyManagerImpl>(service);
133}
134
yucliu2ca85ac2020-09-22 17:50:47 -0700135} // namespace AUDIO_PROXY_CPP_VERSION
yucliu616c55f2020-05-11 17:48:57 -0700136} // namespace audio_proxy