blob: ac48462288b7c2d0bfd2dc83812edc47a2f826ef [file] [log] [blame]
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define LOG_TAG "audio_proxy_client"
#include "AudioProxyManager.h"
#include <mutex>
// clang-format off
#include PATH(device/google/atv/audio_proxy/AUDIO_PROXY_FILE_VERSION/IAudioProxyDevicesManager.h)
// clang-format on
#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
#include "AudioProxyDevice.h"
#include "BusDeviceImpl.h"
#define QUOTE(s) #s
#define TO_STR(s) QUOTE(s)
using ::android::sp;
using ::android::status_t;
using ::android::hardware::hidl_death_recipient;
using ::android::hardware::Return;
using ::device::google::atv::audio_proxy::AUDIO_PROXY_CPP_VERSION::
IAudioProxyDevicesManager;
namespace audio_proxy {
namespace AUDIO_PROXY_CPP_VERSION {
namespace {
bool checkDevice(audio_proxy_device_t* device) {
return device && device->get_address && device->open_output_stream &&
device->close_output_stream;
}
class DeathRecipient;
class AudioProxyManagerImpl : public AudioProxyManager {
public:
explicit AudioProxyManagerImpl(const sp<IAudioProxyDevicesManager>& manager);
~AudioProxyManagerImpl() override = default;
bool registerDevice(audio_proxy_device_t* device) override;
void reconnectService();
private:
std::mutex mLock;
sp<IAudioProxyDevicesManager> mService;
std::unique_ptr<AudioProxyDevice> mDevice;
sp<DeathRecipient> mDeathRecipient;
};
class DeathRecipient : public hidl_death_recipient {
public:
explicit DeathRecipient(AudioProxyManagerImpl& manager) : mManager(manager) {}
~DeathRecipient() override = default;
void serviceDied(
uint64_t cookie,
const android::wp<::android::hidl::base::V1_0::IBase>& who) override {
mManager.reconnectService();
}
private:
AudioProxyManagerImpl& mManager;
};
AudioProxyManagerImpl::AudioProxyManagerImpl(
const sp<IAudioProxyDevicesManager>& manager)
: mService(manager), mDeathRecipient(new DeathRecipient(*this)) {
mService->linkToDeath(mDeathRecipient, 1234);
}
bool AudioProxyManagerImpl::registerDevice(audio_proxy_device_t* device) {
if (!checkDevice(device)) {
ALOGE("Invalid device.");
return false;
}
std::lock_guard<std::mutex> guard(mLock);
if (mDevice) {
ALOGE("Device already registered!");
return false;
}
mDevice = std::make_unique<AudioProxyDevice>(device);
const char* address = mDevice->getAddress();
return mService->registerDevice(address, new BusDeviceImpl(mDevice.get()));
}
void AudioProxyManagerImpl::reconnectService() {
std::lock_guard<std::mutex> guard(mLock);
mService = IAudioProxyDevicesManager::getService();
if (!mService) {
ALOGE("Failed to reconnect service");
return;
}
if (mDevice) {
bool success = mService->registerDevice(mDevice->getAddress(),
new BusDeviceImpl(mDevice.get()));
ALOGE_IF(!success, "fail to register device after reconnect.");
}
}
} // namespace
std::unique_ptr<AudioProxyManager> createAudioProxyManager() {
auto service = IAudioProxyDevicesManager::getService();
if (!service) {
return nullptr;
}
ALOGI("Connect to audio proxy service %s", TO_STR(AUDIO_PROXY_FILE_VERSION));
return std::make_unique<AudioProxyManagerImpl>(service);
}
} // namespace AUDIO_PROXY_CPP_VERSION
} // namespace audio_proxy