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)34bool 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)43std::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()71AudioProxyManagerImpl::AudioProxyManagerImpl() 72 : mDeathRecipient( 73 AIBinder_DeathRecipient_new(AudioProxyManagerImpl::onServiceDied)) {} 74 registerDevice(audio_proxy_device_t * device)75bool 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()93bool AudioProxyManagerImpl::reconnectService() { 94 std::scoped_lock<std::mutex> lock(mLock); 95 return reconnectService_Locked(); 96 } 97 reconnectService_Locked()98bool 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)126void AudioProxyManagerImpl::onServiceDied(void* cookie) { 127 auto* manager = static_cast<AudioProxyManagerImpl*>(cookie); 128 manager->reconnectService(); 129 } 130 131 } // namespace 132 createAudioProxyManager()133std::unique_ptr<AudioProxyManager> createAudioProxyManager() { 134 return std::make_unique<AudioProxyManagerImpl>(); 135 } 136 137 } // namespace audio_proxy 138