1f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov/* 2f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Copyright (C) 2016 The Android Open Source Project 3f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * 4f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License"); 5f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * you may not use this file except in compliance with the License. 6f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * You may obtain a copy of the License at 7f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * 8f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * http://www.apache.org/licenses/LICENSE-2.0 9f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * 10f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Unless required by applicable law or agreed to in writing, software 11f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS, 12f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * See the License for the specific language governing permissions and 14f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * limitations under the License. 15f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov */ 16f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 17f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#define LOG_TAG "EffectHalHidl" 18f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov//#define LOG_NDEBUG 0 19f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 2023feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov#include <hwbinder/IPCThreadState.h> 21f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <media/EffectsFactoryApi.h> 22f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <utils/Log.h> 23f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 249f57e3c9da8923649adff62e63c644537f565e90Mikhail Naganov#include "ConversionHelperHidl.h" 25022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include "EffectBufferHalHidl.h" 26f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "EffectHalHidl.h" 27f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "HidlUtils.h" 28f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 29022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::AudioBuffer; 30f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::EffectBufferAccess; 31f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::EffectConfigParameters; 32022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::MessageQueueFlagBits; 33f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::Result; 34f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioChannelMask; 35f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioFormat; 36f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::hidl_vec; 37022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::MQDescriptorSync; 38f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::Return; 39f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 40f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovnamespace android { 41f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 42f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovEffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId) 43022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov : mEffect(effect), mEffectId(effectId), mBuffersChanged(true) { 44f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 45f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 46f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovEffectHalHidl::~EffectHalHidl() { 4723feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov if (mEffect != 0) { 4823feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov close(); 4923feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov mEffect.clear(); 5023feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov hardware::IPCThreadState::self()->flushCommands(); 5123feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov } 52f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 53f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 54f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov// static 55f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovvoid EffectHalHidl::effectDescriptorToHal( 56f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) { 57f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type); 58f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid); 59f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->flags = static_cast<uint32_t>(descriptor.flags); 60f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->cpuLoad = descriptor.cpuLoad; 61f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->memoryUsage = descriptor.memoryUsage; 62f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size()); 63f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(halDescriptor->implementor, 64f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov descriptor.implementor.data(), descriptor.implementor.size()); 65f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 66f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 67f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov// TODO(mnaganov): These buffer conversion functions should be shared with Effect wrapper 68f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov// via HidlUtils. Move them there when hardware/interfaces will get un-frozen again. 69f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 70f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov// static 71f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovvoid EffectHalHidl::effectBufferConfigFromHal( 72f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov const buffer_config_t& halConfig, EffectBufferConfig* config) { 73f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov config->samplingRateHz = halConfig.samplingRate; 74f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov config->channels = AudioChannelMask(halConfig.channels); 75f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov config->format = AudioFormat(halConfig.format); 76f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov config->accessMode = EffectBufferAccess(halConfig.accessMode); 77f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov config->mask = EffectConfigParameters(halConfig.mask); 78f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov} 79f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 80f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov// static 81ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganovvoid EffectHalHidl::effectBufferConfigToHal( 82ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov const EffectBufferConfig& config, buffer_config_t* halConfig) { 83ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->buffer.frameCount = 0; 84ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->buffer.raw = NULL; 85ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->samplingRate = config.samplingRateHz; 86ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->channels = static_cast<uint32_t>(config.channels); 87ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->bufferProvider.cookie = NULL; 88ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->bufferProvider.getBuffer = NULL; 89ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->bufferProvider.releaseBuffer = NULL; 90ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->format = static_cast<uint8_t>(config.format); 91ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->accessMode = static_cast<uint8_t>(config.accessMode); 92ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov halConfig->mask = static_cast<uint8_t>(config.mask); 93ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov} 94ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov 95ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov// static 96f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovvoid EffectHalHidl::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) { 97f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg); 98f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg); 99f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov} 100f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 101f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov// static 102ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganovvoid EffectHalHidl::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) { 103ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg); 104ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg); 105ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov} 106ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov 107ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov// static 108f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::analyzeResult(const Result& result) { 109f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov switch (result) { 110f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::OK: return OK; 111f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::INVALID_ARGUMENTS: return BAD_VALUE; 112f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::INVALID_STATE: return NOT_ENOUGH_DATA; 113f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::NOT_INITIALIZED: return NO_INIT; 114f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::NOT_SUPPORTED: return INVALID_OPERATION; 115f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::RESULT_TOO_BIG: return NO_MEMORY; 116f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov default: return NO_INIT; 117f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 118f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 119f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 120022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) { 121022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mInBuffer == 0 || buffer->audioBuffer() != mInBuffer->audioBuffer()) { 122022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = true; 123022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 124022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mInBuffer = buffer; 125f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov return OK; 126f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 127f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 128022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) { 129022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mOutBuffer == 0 || buffer->audioBuffer() != mOutBuffer->audioBuffer()) { 130022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = true; 131022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 132022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mOutBuffer = buffer; 133f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov return OK; 134f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 135f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 136022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::process() { 137022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS)); 138022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 139022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 140022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::processReverse() { 141022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE)); 142022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 143022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 144022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::prepareForProcessing() { 145022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::unique_ptr<StatusMQ> tempStatusMQ; 146022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Result retval; 147022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<void> ret = mEffect->prepareForProcessing( 148022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov [&](Result r, const MQDescriptorSync<Result>& statusMQ) { 149022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov retval = r; 150022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (retval == Result::OK) { 151022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov tempStatusMQ.reset(new StatusMQ(statusMQ)); 152022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (tempStatusMQ->isValid() && tempStatusMQ->getEventFlagWord()) { 153022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup); 154022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 155022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 156022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov }); 15767d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen if (!ret.isOk() || retval != Result::OK) { 15867d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION; 159022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 160022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (!tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) { 161022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for effects"); 162022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(), 163022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov "Status message queue for effects is invalid"); 164022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(!mEfGroup, "Event flag creation for effects failed"); 165022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return NO_INIT; 166022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 167022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mStatusMQ = std::move(tempStatusMQ); 168022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return OK; 169022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 170022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 17140be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganovbool EffectHalHidl::needToResetBuffers() { 17240be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov if (mBuffersChanged) return true; 17340be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov bool inBufferFrameCountUpdated = mInBuffer->checkFrameCountChange(); 17440be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov bool outBufferFrameCountUpdated = mOutBuffer->checkFrameCountChange(); 17540be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov return inBufferFrameCountUpdated || outBufferFrameCountUpdated; 17640be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov} 17740be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov 178022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::processImpl(uint32_t mqFlag) { 179022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT; 180022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t status; 181022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (!mStatusMQ && (status = prepareForProcessing()) != OK) { 182022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return status; 183022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 18440be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov if (needToResetBuffers() && (status = setProcessBuffers()) != OK) { 185022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return status; 186022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 187022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov // The data is already in the buffers, just need to flush it and wake up the server side. 188022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::atomic_thread_fence(std::memory_order_release); 189022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEfGroup->wake(mqFlag); 190022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov uint32_t efState = 0; 191022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovretry: 192022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t ret = mEfGroup->wait( 193b4e779137c1849b7b3b09ee782e8bc14de9e2655Mikhail Naganov static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState); 194022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) { 195022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Result retval = Result::NOT_INITIALIZED; 196022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mStatusMQ->read(&retval); 197022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (retval == Result::OK || retval == Result::INVALID_STATE) { 198022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov // Sync back the changed contents of the buffer. 199022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::atomic_thread_fence(std::memory_order_acquire); 200022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 201022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return analyzeResult(retval); 202022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 203d2ae9cd57cfbb6f2f4dd0a91dbc7ea2e9e5fc447Mikhail Naganov if (ret == -EAGAIN || ret == -EINTR) { 204d2ae9cd57cfbb6f2f4dd0a91dbc7ea2e9e5fc447Mikhail Naganov // Spurious wakeup. This normally retries no more than once. 205022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov goto retry; 206022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 207022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return ret; 208022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 209022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 210022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setProcessBuffers() { 211022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<Result> ret = mEffect->setProcessBuffers( 2126b111f32247800dccd34dd396e731b9e7888b185Mikhail Naganov static_cast<EffectBufferHalHidl*>(mInBuffer.get())->hidlBuffer(), 2136b111f32247800dccd34dd396e731b9e7888b185Mikhail Naganov static_cast<EffectBufferHalHidl*>(mOutBuffer.get())->hidlBuffer()); 21467d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen if (ret.isOk() && ret == Result::OK) { 215022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = false; 216022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return OK; 217022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 218d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION; 219022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 220022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 221f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, 222f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov uint32_t *replySize, void *pReplyData) { 223f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (mEffect == 0) return NO_INIT; 224f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 225f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov // Special cases. 226f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov if (cmdCode == EFFECT_CMD_SET_CONFIG || cmdCode == EFFECT_CMD_SET_CONFIG_REVERSE) { 227f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov return setConfigImpl(cmdCode, cmdSize, pCmdData, replySize, pReplyData); 228ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } else if (cmdCode == EFFECT_CMD_GET_CONFIG || cmdCode == EFFECT_CMD_GET_CONFIG_REVERSE) { 229ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov return getConfigImpl(cmdCode, replySize, pReplyData); 230f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov } 231f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 232f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov // Common case. 233f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov hidl_vec<uint8_t> hidlData; 2349dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov if (pCmdData != nullptr && cmdSize > 0) { 2359dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov hidlData.setToExternal(reinterpret_cast<uint8_t*>(pCmdData), cmdSize); 2369dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov } 237f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov status_t status; 238bcd0a04befb085da19fec70a681096dad99afc30Mikhail Naganov uint32_t replySizeStub = 0; 2390688880d2862e6cddfea1fceca24e8a081a6be60Mikhail Naganov if (replySize == nullptr || pReplyData == nullptr) replySize = &replySizeStub; 240f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Return<void> ret = mEffect->command(cmdCode, hidlData, *replySize, 241f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov [&](int32_t s, const hidl_vec<uint8_t>& result) { 242f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov status = s; 243f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (status == 0) { 244f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (*replySize > result.size()) *replySize = result.size(); 2459dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov if (pReplyData != nullptr && *replySize > 0) { 246f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(pReplyData, &result[0], *replySize); 247f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 248f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 249f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov }); 250d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov return ret.isOk() ? status : FAILED_TRANSACTION; 251f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 252f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 253f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::getDescriptor(effect_descriptor_t *pDescriptor) { 254f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (mEffect == 0) return NO_INIT; 255f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Result retval = Result::NOT_INITIALIZED; 256f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Return<void> ret = mEffect->getDescriptor( 257f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov [&](Result r, const EffectDescriptor& result) { 258f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov retval = r; 259f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (retval == Result::OK) { 260f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov effectDescriptorToHal(result, pDescriptor); 261f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 262f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov }); 263d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION; 264f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 265f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 266022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::close() { 267022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mEffect == 0) return NO_INIT; 268022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<Result> ret = mEffect->close(); 269d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION; 270022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 271022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 272ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganovstatus_t EffectHalHidl::getConfigImpl( 273ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov uint32_t cmdCode, uint32_t *replySize, void *pReplyData) { 274ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov if (replySize == NULL || *replySize != sizeof(effect_config_t) || pReplyData == NULL) { 275ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov return BAD_VALUE; 276ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } 277ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov status_t result = FAILED_TRANSACTION; 278ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov Return<void> ret; 279ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov if (cmdCode == EFFECT_CMD_GET_CONFIG) { 280ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov ret = mEffect->getConfig([&] (Result r, const EffectConfig &hidlConfig) { 281ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov result = analyzeResult(r); 282ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov if (r == Result::OK) { 283ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData)); 284ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } 285ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov }); 286ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } else { 287ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov ret = mEffect->getConfigReverse([&] (Result r, const EffectConfig &hidlConfig) { 288ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov result = analyzeResult(r); 289ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov if (r == Result::OK) { 290ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData)); 291ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } 292ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov }); 293ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } 294ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov if (!ret.isOk()) { 295ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov result = FAILED_TRANSACTION; 296ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov } 297ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov return result; 298ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov} 299ed01be521e6e265dd8a27e43b581d13342e2528bMikhail Naganov 300f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganovstatus_t EffectHalHidl::setConfigImpl( 301f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { 302f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || 303f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov replySize == NULL || *replySize != sizeof(int32_t) || pReplyData == NULL) { 304f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov return BAD_VALUE; 305f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov } 306f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov const effect_config_t *halConfig = static_cast<effect_config_t*>(pCmdData); 307f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov if (halConfig->inputCfg.bufferProvider.getBuffer != NULL || 308f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov halConfig->inputCfg.bufferProvider.releaseBuffer != NULL || 309f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov halConfig->outputCfg.bufferProvider.getBuffer != NULL || 310f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov halConfig->outputCfg.bufferProvider.releaseBuffer != NULL) { 311f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov ALOGE("Buffer provider callbacks are not supported"); 312f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov } 313f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov EffectConfig hidlConfig; 314f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov effectConfigFromHal(*halConfig, &hidlConfig); 315f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov Return<Result> ret = cmdCode == EFFECT_CMD_SET_CONFIG ? 316f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov mEffect->setConfig(hidlConfig, nullptr, nullptr) : 317f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov mEffect->setConfigReverse(hidlConfig, nullptr, nullptr); 318f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov status_t result = FAILED_TRANSACTION; 319f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov if (ret.isOk()) { 320f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov result = analyzeResult(ret); 321f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov *static_cast<int32_t*>(pReplyData) = result; 322f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov } 323f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov return result; 324f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov} 325f508bd4692736e1455553099f3276f43f4229e27Mikhail Naganov 326f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} // namespace android 327