/* * Copyright 2018 Fuzhou Rockchip Electronics Co. LTD * * 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 "RKATVAudioPolicyManager" //#define LOG_NDEBUG 0 #include #include #include #include #include #include #include #include #include #include "ATVAudioPolicyManager.h" #include namespace android { using media::audio::common::AudioPortExt; // --- class factory extern "C" AudioPolicyInterface* createAudioPolicyManager( AudioPolicyClientInterface *clientInterface) { ATVAudioPolicyManager *apm = nullptr; media::AudioPolicyConfig apmConfig; if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) { auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig); LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() != AudioPolicyConfig::kDefaultEngineLibraryNameSuffix, "Only default engine is currently supported with the AIDL HAL"); apm = new ATVAudioPolicyManager(config, loadApmEngineLibraryAndCreateEngine( config->getEngineLibraryNameSuffix(), apmConfig.engineConfig), clientInterface); } else { auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail. apm = new ATVAudioPolicyManager(config, loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()), clientInterface); } status_t status = apm->initialize(); if (status != NO_ERROR) { delete apm; apm = nullptr; } return apm; } extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface) { delete interface; } ATVAudioPolicyManager::ATVAudioPolicyManager(const sp& config, EngineInstance&& engine, AudioPolicyClientInterface *clientInterface) :AudioPolicyManager(config, std::move(engine), clientInterface) { ALOGD("%s",__FUNCTION__); mBitstreamDevice = AUDIO_DEVICE_NONE; } status_t ATVAudioPolicyManager::initialize() { return AudioPolicyManager::initialize(); } status_t ATVAudioPolicyManager::setDeviceConnectionState(audio_policy_dev_state_t state, const android::media::audio::common::AudioPort& port, audio_format_t encodedFormat) { status_t status; audio_devices_t device_type; std::string address; const char* setBitstreamDevice = "RK_BITSTREAM_DEVICE_NAME"; if (status = aidl2legacy_AudioDevice_audio_device( port.ext.get().device, &device_type, &address); status != OK) { return status; }; const char* device_name = port.name.c_str(); // const char* device_address = address.c_str(); // connect/disconnect only 1 device at a time if (!audio_is_output_device(device_type) && !audio_is_input_device(device_type)) return BAD_VALUE; // update bistream device if new device is selected. if ((device_name != NULL) && (strcmp(device_name, setBitstreamDevice) == 0)) { if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { mBitstreamDevice = device_type; } else if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) { if (mBitstreamDevice == device_type) mBitstreamDevice = AUDIO_DEVICE_NONE; } } /* * ignore the spdif/hdmi unavailable msg which is not setted by setting, * for avoid spdif/hdmi is using for bistream */ if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) { if (mBitstreamDevice == device_type && strcmp(device_name, setBitstreamDevice) != 0) { return INVALID_OPERATION; } } status = AudioPolicyManager::setDeviceConnectionState(state, port, encodedFormat); return status; } /* String deviceAddress = "RK_BITSTREAM_DEVICE_ADDRESS"; String deviceName = "RK_BITSTREAM_DEVICE_NAME"; */ status_t ATVAudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, audio_io_handle_t *output, audio_session_t session, audio_stream_type_t *stream, const AttributionSourceState& attributionSource, audio_config_t *config, audio_output_flags_t *flags, audio_port_handle_t *selectedDeviceId, audio_port_handle_t *portId, std::vector *secondaryOutputs, output_type_t *outputType, bool *isSpatialized, bool *isBitPerfect) { /* * see flags which set in AudioTrack.cpp * if (format == AUDIO_FORMAT_IEC61937) { * flags = static_cast(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO); */ if ((config->format == AUDIO_FORMAT_IEC61937) && (*flags & AUDIO_OUTPUT_FLAG_DIRECT)) { String8 address("RK_BITSTREAM_DEVICE_ADDRESS"); ALOGD("%s : getDevice for mBitstreamDevice = 0x%x", __FUNCTION__, mBitstreamDevice); sp device = mAvailableOutputDevices.getDevice(mBitstreamDevice, address, AUDIO_FORMAT_IEC61937); if (device != nullptr) { *selectedDeviceId = device->getId(); } else{ ALOGD("%s,%d, connot get selectedDeviceId",__FUNCTION__,__LINE__); } } return AudioPolicyManager::getOutputForAttr(attr, output, session, stream, attributionSource, config, flags, selectedDeviceId, portId, secondaryOutputs, outputType, isSpatialized, isBitPerfect); } } // namespace android