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