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 "AudioProxyManager.h"
16 
17 #include <aidl/device/google/atv/audio_proxy/IAudioProxy.h>
18 #include <android-base/logging.h>
19 #include <android-base/thread_annotations.h>
20 #include <android/binder_manager.h>
21 
22 #include <mutex>
23 
24 #include "AudioProxyDevice.h"
25 #include "StreamProviderImpl.h"
26 
27 using aidl::device::google::atv::audio_proxy::IAudioProxy;
28 using android::sp;
29 using android::status_t;
30 
31 namespace audio_proxy {
32 namespace {
33 
checkDevice(audio_proxy_device_t * device)34 bool checkDevice(audio_proxy_device_t* device) {
35   return device && device->get_address && device->open_output_stream &&
36          device->close_output_stream &&
37          // Check v2 extension. Currently only MediaShell uses this library and
38          // we'll make sure the MediaShell will update to use the new API.
39          device->v2 && device->v2->get_service_name &&
40          device->v2->open_output_stream;
41 }
42 
getAudioProxyService(const std::string & serviceName)43 std::shared_ptr<IAudioProxy> getAudioProxyService(
44     const std::string& serviceName) {
45   std::string instanceName =
46       std::string(IAudioProxy::descriptor) + "/" + serviceName;
47   return IAudioProxy::fromBinder(
48       ndk::SpAIBinder(AServiceManager_getService(instanceName.c_str())));
49 }
50 
51 class AudioProxyManagerImpl : public AudioProxyManager {
52  public:
53   AudioProxyManagerImpl();
54   ~AudioProxyManagerImpl() override = default;
55 
56   bool registerDevice(audio_proxy_device_t* device) override;
57 
58 
59  private:
60   static void onServiceDied(void* cookie);
61   bool reconnectService();
62   bool reconnectService_Locked() REQUIRES(mLock);
63 
64   ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
65 
66   std::mutex mLock;
67   std::shared_ptr<IAudioProxy> mService GUARDED_BY(mLock);
68   std::unique_ptr<AudioProxyDevice> mDevice GUARDED_BY(mLock);
69 };
70 
AudioProxyManagerImpl()71 AudioProxyManagerImpl::AudioProxyManagerImpl()
72     : mDeathRecipient(
73           AIBinder_DeathRecipient_new(AudioProxyManagerImpl::onServiceDied)) {}
74 
registerDevice(audio_proxy_device_t * device)75 bool AudioProxyManagerImpl::registerDevice(audio_proxy_device_t* device) {
76   if (!checkDevice(device)) {
77     LOG(ERROR) << "Invalid device.";
78     return false;
79   }
80 
81   std::scoped_lock<std::mutex> lock(mLock);
82   if (mDevice) {
83     DCHECK(mService);
84     LOG(ERROR) << "Device already registered!";
85     return false;
86   }
87   mDevice = std::make_unique<AudioProxyDevice>(device);
88 
89   DCHECK(!mService);
90   return reconnectService_Locked();
91 }
92 
reconnectService()93 bool AudioProxyManagerImpl::reconnectService() {
94   std::scoped_lock<std::mutex> lock(mLock);
95   return reconnectService_Locked();
96 }
97 
reconnectService_Locked()98 bool AudioProxyManagerImpl::reconnectService_Locked() {
99   DCHECK(mDevice);
100 
101   auto service = getAudioProxyService(mDevice->getServiceName());
102   if (!service) {
103     LOG(ERROR) << "Failed to reconnect service";
104     return false;
105   }
106 
107   binder_status_t binder_status = AIBinder_linkToDeath(
108       service->asBinder().get(), mDeathRecipient.get(), this);
109   if (binder_status != STATUS_OK) {
110     LOG(ERROR) << "Failed to linkToDeath " << static_cast<int>(binder_status);
111     return false;
112   }
113 
114   ndk::ScopedAStatus status = service->start(
115       ndk::SharedRefBase::make<StreamProviderImpl>(mDevice.get()));
116   if (!status.isOk()) {
117     LOG(ERROR) << "Failed to start service.";
118     return false;
119   }
120 
121   mService = std::move(service);
122   return true;
123 }
124 
125 // static
onServiceDied(void * cookie)126 void AudioProxyManagerImpl::onServiceDied(void* cookie) {
127   auto* manager = static_cast<AudioProxyManagerImpl*>(cookie);
128   manager->reconnectService();
129 }
130 
131 }  // namespace
132 
createAudioProxyManager()133 std::unique_ptr<AudioProxyManager> createAudioProxyManager() {
134   return std::make_unique<AudioProxyManagerImpl>();
135 }
136 
137 }  // namespace audio_proxy
138