EffectHalHidl.cpp revision bcd0a04befb085da19fec70a681096dad99afc30
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 20f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <media/EffectsFactoryApi.h> 21f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <utils/Log.h> 22f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 239f57e3c9da8923649adff62e63c644537f565e90Mikhail Naganov#include "ConversionHelperHidl.h" 24022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include "EffectBufferHalHidl.h" 25f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "EffectHalHidl.h" 26f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "HidlUtils.h" 27f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 28022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::AudioBuffer; 29022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::MessageQueueFlagBits; 30f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::effect::V2_0::Result; 31f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::hidl_vec; 32022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::MQDescriptorSync; 33f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::Return; 34f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::Status; 35f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 36f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovnamespace android { 37f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 38f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovEffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId) 39022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov : mEffect(effect), mEffectId(effectId), mBuffersChanged(true) { 40f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 41f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 42f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovEffectHalHidl::~EffectHalHidl() { 43022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov close(); 44f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 45f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 46f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov// static 47f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovvoid EffectHalHidl::effectDescriptorToHal( 48f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) { 49f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type); 50f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid); 51f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->flags = static_cast<uint32_t>(descriptor.flags); 52f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->cpuLoad = descriptor.cpuLoad; 53f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov halDescriptor->memoryUsage = descriptor.memoryUsage; 54f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size()); 55f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(halDescriptor->implementor, 56f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov descriptor.implementor.data(), descriptor.implementor.size()); 57f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 58f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 59f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov// static 60f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::analyzeResult(const Result& result) { 61f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov switch (result) { 62f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::OK: return OK; 63f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::INVALID_ARGUMENTS: return BAD_VALUE; 64f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::INVALID_STATE: return NOT_ENOUGH_DATA; 65f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::NOT_INITIALIZED: return NO_INIT; 66f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::NOT_SUPPORTED: return INVALID_OPERATION; 67f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov case Result::RESULT_TOO_BIG: return NO_MEMORY; 68f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov default: return NO_INIT; 69f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 70f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 71f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 72022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) { 73022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mInBuffer == 0 || buffer->audioBuffer() != mInBuffer->audioBuffer()) { 74022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = true; 75022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 76022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mInBuffer = buffer; 77f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov return OK; 78f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 79f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 80022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) { 81022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mOutBuffer == 0 || buffer->audioBuffer() != mOutBuffer->audioBuffer()) { 82022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = true; 83022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 84022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mOutBuffer = buffer; 85f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov return OK; 86f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 87f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 88022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::process() { 89022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS)); 90022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 91022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 92022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::processReverse() { 93022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE)); 94022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 95022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 96022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::prepareForProcessing() { 97022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::unique_ptr<StatusMQ> tempStatusMQ; 98022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Result retval; 99022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<void> ret = mEffect->prepareForProcessing( 100022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov [&](Result r, const MQDescriptorSync<Result>& statusMQ) { 101022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov retval = r; 102022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (retval == Result::OK) { 103022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov tempStatusMQ.reset(new StatusMQ(statusMQ)); 104022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (tempStatusMQ->isValid() && tempStatusMQ->getEventFlagWord()) { 105022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup); 106022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 107022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 108022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov }); 10967d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen if (!ret.isOk() || retval != Result::OK) { 11067d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION; 111022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 112022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (!tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) { 113022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for effects"); 114022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(), 115022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov "Status message queue for effects is invalid"); 116022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE_IF(!mEfGroup, "Event flag creation for effects failed"); 117022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return NO_INIT; 118022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 119022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mStatusMQ = std::move(tempStatusMQ); 120022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return OK; 121022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 122022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 123022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::processImpl(uint32_t mqFlag) { 124022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT; 125022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t status; 126022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (!mStatusMQ && (status = prepareForProcessing()) != OK) { 127022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return status; 128022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 129022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mBuffersChanged && (status = setProcessBuffers()) != OK) { 130022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return status; 131022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 132022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov // The data is already in the buffers, just need to flush it and wake up the server side. 133022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::atomic_thread_fence(std::memory_order_release); 134022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEfGroup->wake(mqFlag); 135022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov uint32_t efState = 0; 136022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovretry: 137022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t ret = mEfGroup->wait( 138022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState, NS_PER_SEC); 139022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) { 140022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Result retval = Result::NOT_INITIALIZED; 141022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mStatusMQ->read(&retval); 142022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (retval == Result::OK || retval == Result::INVALID_STATE) { 143022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov // Sync back the changed contents of the buffer. 144022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov std::atomic_thread_fence(std::memory_order_acquire); 145022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 146022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return analyzeResult(retval); 147022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 148022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (ret == -EAGAIN) { 149022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov // This normally retries no more than once. 150022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov goto retry; 151022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 152022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return ret; 153022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 154022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 155022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::setProcessBuffers() { 156022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<Result> ret = mEffect->setProcessBuffers( 157022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov reinterpret_cast<EffectBufferHalHidl*>(mInBuffer.get())->hidlBuffer(), 158022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov reinterpret_cast<EffectBufferHalHidl*>(mOutBuffer.get())->hidlBuffer()); 15967d0d7eb36e7c36d0a9dec9264c0cab832196d57Martijn Coenen if (ret.isOk() && ret == Result::OK) { 160022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBuffersChanged = false; 161022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return OK; 162022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 163022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return ret.isOk() ? analyzeResult(ret) : UNKNOWN_ERROR; 164022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 165022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 166f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, 167f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov uint32_t *replySize, void *pReplyData) { 168f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (mEffect == 0) return NO_INIT; 169f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov hidl_vec<uint8_t> hidlData; 1709dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov if (pCmdData != nullptr && cmdSize > 0) { 1719dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov hidlData.setToExternal(reinterpret_cast<uint8_t*>(pCmdData), cmdSize); 1729dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov } 173f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov status_t status; 174bcd0a04befb085da19fec70a681096dad99afc30Mikhail Naganov uint32_t replySizeStub = 0; 175bcd0a04befb085da19fec70a681096dad99afc30Mikhail Naganov if (replySize == nullptr) replySize = &replySizeStub; 176f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Return<void> ret = mEffect->command(cmdCode, hidlData, *replySize, 177f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov [&](int32_t s, const hidl_vec<uint8_t>& result) { 178f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov status = s; 179f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (status == 0) { 180f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (*replySize > result.size()) *replySize = result.size(); 1819dc1747e214a3d4b3c08e8c1f3d7982ef5108162Mikhail Naganov if (pReplyData != nullptr && *replySize > 0) { 182f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov memcpy(pReplyData, &result[0], *replySize); 183f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 184f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 185f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov }); 186f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov return status; 187f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 188f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 189f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t EffectHalHidl::getDescriptor(effect_descriptor_t *pDescriptor) { 190f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (mEffect == 0) return NO_INIT; 191f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Result retval = Result::NOT_INITIALIZED; 192f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov Return<void> ret = mEffect->getDescriptor( 193f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov [&](Result r, const EffectDescriptor& result) { 194f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov retval = r; 195f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov if (retval == Result::OK) { 196f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov effectDescriptorToHal(result, pDescriptor); 197f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov } 198f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov }); 199e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland return ret.isOk() ? analyzeResult(retval) : UNKNOWN_ERROR; 200f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} 201f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov 202022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectHalHidl::close() { 203022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mEffect == 0) return NO_INIT; 204022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<Result> ret = mEffect->close(); 205022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return ret.isOk() ? analyzeResult(ret) : UNKNOWN_ERROR; 206022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 207022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 208f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} // namespace android 209