Merge "Refactor media metrics based on changed MediaDrm statsd atom definition"
diff --git a/cmds/stagefright/Android.bp b/cmds/stagefright/Android.bp
index e1fe07e..445541e 100644
--- a/cmds/stagefright/Android.bp
+++ b/cmds/stagefright/Android.bp
@@ -211,46 +211,6 @@
}
cc_binary {
- name: "mediafilter",
-
- srcs: [
- "filters/argbtorgba.rscript",
- "filters/nightvision.rscript",
- "filters/saturation.rscript",
- "mediafilter.cpp",
- ],
-
- header_libs: [
- "libmediadrm_headers",
- "libmediametrics_headers",
- "libstagefright_headers",
- "rs-headers",
- ],
-
- shared_libs: [
- "libstagefright",
- "liblog",
- "libutils",
- "libbinder",
- "libstagefright_foundation",
- "libmedia_omx",
- "libui",
- "libgui",
- "libRScpp",
- ],
-
- static_libs: ["libstagefright_mediafilter"],
-
- cflags: [
- "-Wno-multichar",
- ],
-
- sanitize: {
- cfi: true,
- },
-}
-
-cc_binary {
name: "muxer",
srcs: ["muxer.cpp"],
diff --git a/cmds/stagefright/filters/argbtorgba.rscript b/cmds/stagefright/filters/argbtorgba.rscript
deleted file mode 100644
index 229ff8c..0000000
--- a/cmds/stagefright/filters/argbtorgba.rscript
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.rs.cppbasic)
-#pragma rs_fp_relaxed
-
-void root(const uchar4 *v_in, uchar4 *v_out) {
- v_out->x = v_in->y;
- v_out->y = v_in->z;
- v_out->z = v_in->w;
- v_out->w = v_in->x;
-}
\ No newline at end of file
diff --git a/cmds/stagefright/filters/nightvision.rscript b/cmds/stagefright/filters/nightvision.rscript
deleted file mode 100644
index f61413c..0000000
--- a/cmds/stagefright/filters/nightvision.rscript
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.rs.cppbasic)
-#pragma rs_fp_relaxed
-
-const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
-const static float3 gNightVisionMult = {0.5f, 1.f, 0.5f};
-
-// calculates luminance of pixel, then biases color balance toward green
-void root(const uchar4 *v_in, uchar4 *v_out) {
- v_out->x = v_in->x; // don't modify A
-
- // get RGB, scale 0-255 uchar to 0-1.0 float
- float3 rgb = {v_in->y * 0.003921569f, v_in->z * 0.003921569f,
- v_in->w * 0.003921569f};
-
- // apply filter
- float3 result = dot(rgb, gMonoMult) * gNightVisionMult;
-
- v_out->y = (uchar)clamp((result.r * 255.f + 0.5f), 0.f, 255.f);
- v_out->z = (uchar)clamp((result.g * 255.f + 0.5f), 0.f, 255.f);
- v_out->w = (uchar)clamp((result.b * 255.f + 0.5f), 0.f, 255.f);
-}
diff --git a/cmds/stagefright/filters/saturation.rscript b/cmds/stagefright/filters/saturation.rscript
deleted file mode 100644
index 1de9dd8..0000000
--- a/cmds/stagefright/filters/saturation.rscript
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.rs.cppbasic)
-#pragma rs_fp_relaxed
-
-const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
-
-// global variables (parameters accessible to application code)
-float gSaturation = 1.0f;
-
-void root(const uchar4 *v_in, uchar4 *v_out) {
- v_out->x = v_in->x; // don't modify A
-
- // get RGB, scale 0-255 uchar to 0-1.0 float
- float3 rgb = {v_in->y * 0.003921569f, v_in->z * 0.003921569f,
- v_in->w * 0.003921569f};
-
- // apply saturation filter
- float3 result = dot(rgb, gMonoMult);
- result = mix(result, rgb, gSaturation);
-
- v_out->y = (uchar)clamp((result.r * 255.f + 0.5f), 0.f, 255.f);
- v_out->z = (uchar)clamp((result.g * 255.f + 0.5f), 0.f, 255.f);
- v_out->w = (uchar)clamp((result.b * 255.f + 0.5f), 0.f, 255.f);
-}
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
deleted file mode 100644
index f042d5e..0000000
--- a/cmds/stagefright/mediafilter.cpp
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Copyright (C) 2014 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_NDEBUG 0
-#define LOG_TAG "mediafilterTest"
-
-#include <inttypes.h>
-
-#include <binder/ProcessState.h>
-#include <filters/ColorConvert.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/Surface.h>
-#include <media/IMediaHTTPService.h>
-#include <media/MediaCodecBuffer.h>
-#include <mediadrm/ICrypto.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/NuMediaExtractor.h>
-#include <media/stagefright/RenderScriptWrapper.h>
-#include <OMX_IVCommon.h>
-#include <ui/DisplayMode.h>
-
-#include "RenderScript.h"
-#include "ScriptC_argbtorgba.h"
-#include "ScriptC_nightvision.h"
-#include "ScriptC_saturation.h"
-
-// test parameters
-static const bool kTestFlush = true; // Note: true will drop 1 out of
-static const int kFlushAfterFrames = 25; // kFlushAfterFrames output frames
-static const int64_t kTimeout = 500ll;
-
-// built-in filter parameters
-static const int32_t kInvert = false; // ZeroFilter param
-static const float kBlurRadius = 15.0f; // IntrinsicBlurFilter param
-static const float kSaturation = 0.0f; // SaturationFilter param
-
-static void usage(const char *me) {
- fprintf(stderr, "usage: [flags] %s\n"
- "\t[-b] use IntrinsicBlurFilter\n"
- "\t[-c] use argb to rgba conversion RSFilter\n"
- "\t[-n] use night vision RSFilter\n"
- "\t[-r] use saturation RSFilter\n"
- "\t[-s] use SaturationFilter\n"
- "\t[-z] use ZeroFilter (copy filter)\n"
- "\t[-R] render output to surface (enables -S)\n"
- "\t[-S] allocate buffers from a surface\n"
- "\t[-T] use render timestamps (enables -R)\n",
- me);
- exit(1);
-}
-
-namespace android {
-
-struct SaturationRSFilter : RenderScriptWrapper::RSFilterCallback {
- void init(const RSC::sp<RSC::RS> &context) {
- mScript = new ScriptC_saturation(context);
- mScript->set_gSaturation(3.f);
- }
-
- virtual status_t processBuffers(
- RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
- mScript->forEach_root(inBuffer, outBuffer);
-
- return OK;
- }
-
- status_t handleSetParameters(const sp<AMessage> &msg __unused) {
- return OK;
- }
-
-private:
- RSC::sp<ScriptC_saturation> mScript;
-};
-
-struct NightVisionRSFilter : RenderScriptWrapper::RSFilterCallback {
- void init(const RSC::sp<RSC::RS> &context) {
- mScript = new ScriptC_nightvision(context);
- }
-
- virtual status_t processBuffers(
- RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
- mScript->forEach_root(inBuffer, outBuffer);
-
- return OK;
- }
-
- status_t handleSetParameters(const sp<AMessage> &msg __unused) {
- return OK;
- }
-
-private:
- RSC::sp<ScriptC_nightvision> mScript;
-};
-
-struct ARGBToRGBARSFilter : RenderScriptWrapper::RSFilterCallback {
- void init(const RSC::sp<RSC::RS> &context) {
- mScript = new ScriptC_argbtorgba(context);
- }
-
- virtual status_t processBuffers(
- RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
- mScript->forEach_root(inBuffer, outBuffer);
-
- return OK;
- }
-
- status_t handleSetParameters(const sp<AMessage> &msg __unused) {
- return OK;
- }
-
-private:
- RSC::sp<ScriptC_argbtorgba> mScript;
-};
-
-struct CodecState {
- sp<MediaCodec> mCodec;
- Vector<sp<MediaCodecBuffer> > mInBuffers;
- Vector<sp<MediaCodecBuffer> > mOutBuffers;
- bool mSignalledInputEOS;
- bool mSawOutputEOS;
- int64_t mNumBuffersDecoded;
-};
-
-struct DecodedFrame {
- size_t index;
- size_t offset;
- size_t size;
- int64_t presentationTimeUs;
- uint32_t flags;
-};
-
-enum FilterType {
- FILTERTYPE_ZERO,
- FILTERTYPE_INTRINSIC_BLUR,
- FILTERTYPE_SATURATION,
- FILTERTYPE_RS_SATURATION,
- FILTERTYPE_RS_NIGHT_VISION,
- FILTERTYPE_RS_ARGB_TO_RGBA,
-};
-
-size_t inputFramesSinceFlush = 0;
-void tryCopyDecodedBuffer(
- List<DecodedFrame> *decodedFrameIndices,
- CodecState *filterState,
- CodecState *vidState) {
- if (decodedFrameIndices->empty()) {
- return;
- }
-
- size_t filterIndex;
- status_t err = filterState->mCodec->dequeueInputBuffer(
- &filterIndex, kTimeout);
- if (err != OK) {
- return;
- }
-
- ++inputFramesSinceFlush;
-
- DecodedFrame frame = *decodedFrameIndices->begin();
-
- // only consume a buffer if we are not going to flush, since we expect
- // the dequeue -> flush -> queue operation to cause an error and
- // not produce an output frame
- if (!kTestFlush || inputFramesSinceFlush < kFlushAfterFrames) {
- decodedFrameIndices->erase(decodedFrameIndices->begin());
- }
- size_t outIndex = frame.index;
-
- const sp<MediaCodecBuffer> &srcBuffer =
- vidState->mOutBuffers.itemAt(outIndex);
- const sp<MediaCodecBuffer> &destBuffer =
- filterState->mInBuffers.itemAt(filterIndex);
-
- sp<AMessage> srcFormat, destFormat;
- vidState->mCodec->getOutputFormat(&srcFormat);
- filterState->mCodec->getInputFormat(&destFormat);
-
- int32_t srcWidth, srcHeight, srcStride, srcSliceHeight;
- int32_t srcColorFormat, destColorFormat;
- int32_t destWidth, destHeight, destStride, destSliceHeight;
- CHECK(srcFormat->findInt32("stride", &srcStride)
- && srcFormat->findInt32("slice-height", &srcSliceHeight)
- && srcFormat->findInt32("width", &srcWidth)
- && srcFormat->findInt32("height", & srcHeight)
- && srcFormat->findInt32("color-format", &srcColorFormat));
- CHECK(destFormat->findInt32("stride", &destStride)
- && destFormat->findInt32("slice-height", &destSliceHeight)
- && destFormat->findInt32("width", &destWidth)
- && destFormat->findInt32("height", & destHeight)
- && destFormat->findInt32("color-format", &destColorFormat));
-
- CHECK(srcWidth <= destStride && srcHeight <= destSliceHeight);
-
- convertYUV420spToARGB(
- srcBuffer->data(),
- srcBuffer->data() + srcStride * srcSliceHeight,
- srcWidth,
- srcHeight,
- destBuffer->data());
-
- // copy timestamp
- int64_t timeUs;
- CHECK(srcBuffer->meta()->findInt64("timeUs", &timeUs));
- destBuffer->meta()->setInt64("timeUs", timeUs);
-
- if (kTestFlush && inputFramesSinceFlush >= kFlushAfterFrames) {
- inputFramesSinceFlush = 0;
-
- // check that queueing a buffer that was dequeued before flush
- // fails with expected error EACCES
- filterState->mCodec->flush();
-
- err = filterState->mCodec->queueInputBuffer(
- filterIndex, 0 /* offset */, destBuffer->size(),
- timeUs, frame.flags);
-
- if (err == OK) {
- ALOGE("FAIL: queue after flush returned OK");
- } else if (err != -EACCES) {
- ALOGE("queueInputBuffer after flush returned %d, "
- "expected -EACCES (-13)", err);
- }
- } else {
- err = filterState->mCodec->queueInputBuffer(
- filterIndex, 0 /* offset */, destBuffer->size(),
- timeUs, frame.flags);
- CHECK(err == OK);
-
- err = vidState->mCodec->releaseOutputBuffer(outIndex);
- CHECK(err == OK);
- }
-}
-
-size_t outputFramesSinceFlush = 0;
-void tryDrainOutputBuffer(
- CodecState *filterState,
- const sp<Surface> &surface, bool renderSurface,
- bool useTimestamp, int64_t *startTimeRender) {
- size_t index;
- size_t offset;
- size_t size;
- int64_t presentationTimeUs;
- uint32_t flags;
- status_t err = filterState->mCodec->dequeueOutputBuffer(
- &index, &offset, &size, &presentationTimeUs, &flags,
- kTimeout);
-
- if (err != OK) {
- return;
- }
-
- ++outputFramesSinceFlush;
-
- if (kTestFlush && outputFramesSinceFlush >= kFlushAfterFrames) {
- filterState->mCodec->flush();
- }
-
- if (surface == NULL || !renderSurface) {
- err = filterState->mCodec->releaseOutputBuffer(index);
- } else if (useTimestamp) {
- if (*startTimeRender == -1) {
- // begin rendering 2 vsyncs after first decode
- *startTimeRender = systemTime(SYSTEM_TIME_MONOTONIC)
- + 33000000 - (presentationTimeUs * 1000);
- }
- presentationTimeUs =
- (presentationTimeUs * 1000) + *startTimeRender;
- err = filterState->mCodec->renderOutputBufferAndRelease(
- index, presentationTimeUs);
- } else {
- err = filterState->mCodec->renderOutputBufferAndRelease(index);
- }
-
- if (kTestFlush && outputFramesSinceFlush >= kFlushAfterFrames) {
- outputFramesSinceFlush = 0;
-
- // releasing the buffer dequeued before flush should cause an error
- // if so, the frame will also be skipped in output stream
- if (err == OK) {
- ALOGE("FAIL: release after flush returned OK");
- } else if (err != -EACCES) {
- ALOGE("releaseOutputBuffer after flush returned %d, "
- "expected -EACCES (-13)", err);
- }
- } else {
- CHECK(err == OK);
- }
-
- if (flags & MediaCodec::BUFFER_FLAG_EOS) {
- ALOGV("reached EOS on output.");
- filterState->mSawOutputEOS = true;
- }
-}
-
-static int decode(
- const sp<android::ALooper> &looper,
- const char *path,
- const sp<Surface> &surface,
- bool renderSurface,
- bool useTimestamp,
- FilterType filterType) {
-
- static int64_t kTimeout = 500ll;
-
- sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
-
- if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
- fprintf(stderr, "unable to instantiate extractor.\n");
- return 1;
- }
-
- KeyedVector<size_t, CodecState> stateByTrack;
-
- CodecState *vidState = NULL;
- for (size_t i = 0; i < extractor->countTracks(); ++i) {
- sp<AMessage> format;
- status_t err = extractor->getTrackFormat(i, &format);
- CHECK(err == OK);
-
- AString mime;
- CHECK(format->findString("mime", &mime));
- bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
- if (!isVideo) {
- continue;
- }
-
- ALOGV("selecting track %zu", i);
-
- err = extractor->selectTrack(i);
- CHECK(err == OK);
-
- CodecState *state =
- &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
-
- vidState = state;
-
- state->mNumBuffersDecoded = 0;
-
- state->mCodec = MediaCodec::CreateByType(
- looper, mime.c_str(), false /* encoder */);
-
- CHECK(state->mCodec != NULL);
-
- err = state->mCodec->configure(
- format, NULL /* surface */, NULL /* crypto */, 0 /* flags */);
-
- CHECK(err == OK);
-
- state->mSignalledInputEOS = false;
- state->mSawOutputEOS = false;
-
- break;
- }
- CHECK(!stateByTrack.isEmpty());
- CHECK(vidState != NULL);
- sp<AMessage> vidFormat;
- vidState->mCodec->getOutputFormat(&vidFormat);
-
- // set filter to use ARGB8888
- vidFormat->setInt32("color-format", OMX_COLOR_Format32bitARGB8888);
- // set app cache directory path
- vidFormat->setString("cacheDir", "/system/bin");
-
- // create RenderScript context for RSFilters
- RSC::sp<RSC::RS> context = new RSC::RS();
- context->init("/system/bin");
-
- sp<RenderScriptWrapper::RSFilterCallback> rsFilter;
-
- // create renderscript wrapper for RSFilters
- sp<RenderScriptWrapper> rsWrapper = new RenderScriptWrapper;
- rsWrapper->mContext = context.get();
-
- CodecState *filterState = new CodecState();
- filterState->mNumBuffersDecoded = 0;
-
- sp<AMessage> params = new AMessage();
-
- switch (filterType) {
- case FILTERTYPE_ZERO:
- {
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.zerofilter");
- params->setInt32("invert", kInvert);
- break;
- }
- case FILTERTYPE_INTRINSIC_BLUR:
- {
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.intrinsicblur");
- params->setFloat("blur-radius", kBlurRadius);
- break;
- }
- case FILTERTYPE_SATURATION:
- {
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.saturation");
- params->setFloat("saturation", kSaturation);
- break;
- }
- case FILTERTYPE_RS_SATURATION:
- {
- SaturationRSFilter *satFilter = new SaturationRSFilter;
- satFilter->init(context);
- rsFilter = satFilter;
- rsWrapper->mCallback = rsFilter;
- vidFormat->setObject("rs-wrapper", rsWrapper);
-
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.RenderScript");
- break;
- }
- case FILTERTYPE_RS_NIGHT_VISION:
- {
- NightVisionRSFilter *nightVisionFilter = new NightVisionRSFilter;
- nightVisionFilter->init(context);
- rsFilter = nightVisionFilter;
- rsWrapper->mCallback = rsFilter;
- vidFormat->setObject("rs-wrapper", rsWrapper);
-
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.RenderScript");
- break;
- }
- case FILTERTYPE_RS_ARGB_TO_RGBA:
- {
- ARGBToRGBARSFilter *argbToRgbaFilter = new ARGBToRGBARSFilter;
- argbToRgbaFilter->init(context);
- rsFilter = argbToRgbaFilter;
- rsWrapper->mCallback = rsFilter;
- vidFormat->setObject("rs-wrapper", rsWrapper);
-
- filterState->mCodec = MediaCodec::CreateByComponentName(
- looper, "android.filter.RenderScript");
- break;
- }
- default:
- {
- LOG_ALWAYS_FATAL("mediacodec.cpp error: unrecognized FilterType");
- break;
- }
- }
- CHECK(filterState->mCodec != NULL);
-
- status_t err = filterState->mCodec->configure(
- vidFormat /* format */, surface, NULL /* crypto */, 0 /* flags */);
- CHECK(err == OK);
-
- filterState->mSignalledInputEOS = false;
- filterState->mSawOutputEOS = false;
-
- int64_t startTimeUs = android::ALooper::GetNowUs();
- int64_t startTimeRender = -1;
-
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- sp<MediaCodec> codec = state->mCodec;
-
- CHECK_EQ((status_t)OK, codec->start());
-
- CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
- CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
-
- ALOGV("got %zu input and %zu output buffers",
- state->mInBuffers.size(), state->mOutBuffers.size());
- }
-
- CHECK_EQ((status_t)OK, filterState->mCodec->setParameters(params));
-
- if (kTestFlush) {
- status_t flushErr = filterState->mCodec->flush();
- if (flushErr == OK) {
- ALOGE("FAIL: Flush before start returned OK");
- } else {
- ALOGV("Flush before start returned status %d, usually ENOSYS (-38)",
- flushErr);
- }
- }
-
- CHECK_EQ((status_t)OK, filterState->mCodec->start());
- CHECK_EQ((status_t)OK, filterState->mCodec->getInputBuffers(
- &filterState->mInBuffers));
- CHECK_EQ((status_t)OK, filterState->mCodec->getOutputBuffers(
- &filterState->mOutBuffers));
-
- if (kTestFlush) {
- status_t flushErr = filterState->mCodec->flush();
- if (flushErr != OK) {
- ALOGE("FAIL: Flush after start returned %d, expect OK (0)",
- flushErr);
- } else {
- ALOGV("Flush immediately after start OK");
- }
- }
-
- List<DecodedFrame> decodedFrameIndices;
-
- // loop until decoder reaches EOS
- bool sawInputEOS = false;
- bool sawOutputEOSOnAllTracks = false;
- while (!sawOutputEOSOnAllTracks) {
- if (!sawInputEOS) {
- size_t trackIndex;
- status_t err = extractor->getSampleTrackIndex(&trackIndex);
-
- if (err != OK) {
- ALOGV("saw input eos");
- sawInputEOS = true;
- } else {
- CodecState *state = &stateByTrack.editValueFor(trackIndex);
-
- size_t index;
- err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
-
- if (err == OK) {
- ALOGV("filling input buffer %zu", index);
-
- const sp<MediaCodecBuffer> &buffer = state->mInBuffers.itemAt(index);
- sp<ABuffer> abuffer = new ABuffer(buffer->base(), buffer->capacity());
-
- err = extractor->readSampleData(abuffer);
- CHECK(err == OK);
- buffer->setRange(abuffer->offset(), abuffer->size());
-
- int64_t timeUs;
- err = extractor->getSampleTime(&timeUs);
- CHECK(err == OK);
-
- uint32_t bufferFlags = 0;
-
- err = state->mCodec->queueInputBuffer(
- index, 0 /* offset */, buffer->size(),
- timeUs, bufferFlags);
-
- CHECK(err == OK);
-
- extractor->advance();
- } else {
- CHECK_EQ(err, -EAGAIN);
- }
- }
- } else {
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- if (!state->mSignalledInputEOS) {
- size_t index;
- status_t err =
- state->mCodec->dequeueInputBuffer(&index, kTimeout);
-
- if (err == OK) {
- ALOGV("signalling input EOS on track %zu", i);
-
- err = state->mCodec->queueInputBuffer(
- index, 0 /* offset */, 0 /* size */,
- 0ll /* timeUs */, MediaCodec::BUFFER_FLAG_EOS);
-
- CHECK(err == OK);
-
- state->mSignalledInputEOS = true;
- } else {
- CHECK_EQ(err, -EAGAIN);
- }
- }
- }
- }
-
- sawOutputEOSOnAllTracks = true;
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- if (state->mSawOutputEOS) {
- continue;
- } else {
- sawOutputEOSOnAllTracks = false;
- }
-
- DecodedFrame frame;
- status_t err = state->mCodec->dequeueOutputBuffer(
- &frame.index, &frame.offset, &frame.size,
- &frame.presentationTimeUs, &frame.flags, kTimeout);
-
- if (err == OK) {
- ALOGV("draining decoded buffer %zu, time = %lld us",
- frame.index, (long long)frame.presentationTimeUs);
-
- ++(state->mNumBuffersDecoded);
-
- decodedFrameIndices.push_back(frame);
-
- if (frame.flags & MediaCodec::BUFFER_FLAG_EOS) {
- ALOGV("reached EOS on decoder output.");
- state->mSawOutputEOS = true;
- }
-
- } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
- ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
- CHECK_EQ((status_t)OK, state->mCodec->getOutputBuffers(
- &state->mOutBuffers));
-
- ALOGV("got %zu output buffers", state->mOutBuffers.size());
- } else if (err == INFO_FORMAT_CHANGED) {
- sp<AMessage> format;
- CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
-
- ALOGV("INFO_FORMAT_CHANGED: %s",
- format->debugString().c_str());
- } else {
- CHECK_EQ(err, -EAGAIN);
- }
-
- tryCopyDecodedBuffer(&decodedFrameIndices, filterState, vidState);
-
- tryDrainOutputBuffer(
- filterState, surface, renderSurface,
- useTimestamp, &startTimeRender);
- }
- }
-
- // after EOS on decoder, let filter reach EOS
- while (!filterState->mSawOutputEOS) {
- tryCopyDecodedBuffer(&decodedFrameIndices, filterState, vidState);
-
- tryDrainOutputBuffer(
- filterState, surface, renderSurface,
- useTimestamp, &startTimeRender);
- }
-
- int64_t elapsedTimeUs = android::ALooper::GetNowUs() - startTimeUs;
-
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- CHECK_EQ((status_t)OK, state->mCodec->release());
-
- printf("track %zu: %" PRId64 " frames decoded and filtered, "
- "%.2f fps.\n", i, state->mNumBuffersDecoded,
- state->mNumBuffersDecoded * 1E6 / elapsedTimeUs);
- }
-
- return 0;
-}
-
-} // namespace android
-
-int main(int argc, char **argv) {
- using namespace android;
-
- const char *me = argv[0];
-
- bool useSurface = false;
- bool renderSurface = false;
- bool useTimestamp = false;
- FilterType filterType = FILTERTYPE_ZERO;
-
- int res;
- while ((res = getopt(argc, argv, "bcnrszTRSh")) >= 0) {
- switch (res) {
- case 'b':
- {
- filterType = FILTERTYPE_INTRINSIC_BLUR;
- break;
- }
- case 'c':
- {
- filterType = FILTERTYPE_RS_ARGB_TO_RGBA;
- break;
- }
- case 'n':
- {
- filterType = FILTERTYPE_RS_NIGHT_VISION;
- break;
- }
- case 'r':
- {
- filterType = FILTERTYPE_RS_SATURATION;
- break;
- }
- case 's':
- {
- filterType = FILTERTYPE_SATURATION;
- break;
- }
- case 'z':
- {
- filterType = FILTERTYPE_ZERO;
- break;
- }
- case 'T':
- {
- useTimestamp = true;
- FALLTHROUGH_INTENDED;
- }
- case 'R':
- {
- renderSurface = true;
- FALLTHROUGH_INTENDED;
- }
- case 'S':
- {
- useSurface = true;
- break;
- }
- case '?':
- case 'h':
- default:
- {
- usage(me);
- break;
- }
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- usage(me);
- }
-
- ProcessState::self()->startThreadPool();
-
- android::sp<android::ALooper> looper = new android::ALooper;
- looper->start();
-
- android::sp<SurfaceComposerClient> composerClient;
- android::sp<SurfaceControl> control;
- android::sp<Surface> surface;
-
- if (useSurface) {
- composerClient = new SurfaceComposerClient;
- CHECK_EQ((status_t)OK, composerClient->initCheck());
-
- const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
- CHECK(!ids.empty());
-
- const android::sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
- CHECK(display != nullptr);
-
- ui::DisplayMode mode;
- CHECK_EQ(SurfaceComposerClient::getActiveDisplayMode(display, &mode), NO_ERROR);
-
- const ui::Size& resolution = mode.resolution;
- const ssize_t displayWidth = resolution.getWidth();
- const ssize_t displayHeight = resolution.getHeight();
-
- ALOGV("display is %zd x %zd", displayWidth, displayHeight);
-
- control = composerClient->createSurface(
- String8("A Surface"), displayWidth, displayHeight,
- PIXEL_FORMAT_RGBA_8888, 0);
-
- CHECK(control != NULL);
- CHECK(control->isValid());
-
- SurfaceComposerClient::Transaction{}
- .setLayer(control, INT_MAX)
- .show(control)
- .apply();
-
- surface = control->getSurface();
- CHECK(surface != NULL);
- }
-
- decode(looper, argv[0], surface, renderSurface, useTimestamp, filterType);
-
- if (useSurface) {
- composerClient->dispose();
- }
-
- looper->stop();
-
- return 0;
-}
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
index bcdfadf..9c737a0 100644
--- a/drm/libmediadrm/DrmMetricsLogger.cpp
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -458,7 +458,7 @@
mediametrics_delete(handle);
}
-void DrmMetricsLogger::reportMediaDrmSessionOpened(std::vector<uint8_t> sessionId) const {
+void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
@@ -475,8 +475,8 @@
mediametrics_delete(handle);
}
-void DrmMetricsLogger::reportMediaDrmErrored(DrmStatus error_code, const char* api,
- std::vector<uint8_t> sessionId) const {
+void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
+ const std::vector<uint8_t>& sessionId) const {
mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
@@ -491,6 +491,9 @@
mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
mediametrics_setInt32(handle, "error_code", error_code);
+ mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
+ mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
+ mediametrics_setInt32(handle, "error_context", error_code.getContext());
mediametrics_setCString(handle, "api", api);
mediametrics_setInt32(handle, "frontend", mFrontend);
mediametrics_selfRecord(handle);
diff --git a/drm/libmediadrm/DrmStatus.cpp b/drm/libmediadrm/DrmStatus.cpp
index 0258801..f622160 100644
--- a/drm/libmediadrm/DrmStatus.cpp
+++ b/drm/libmediadrm/DrmStatus.cpp
@@ -27,21 +27,20 @@
return;
}
- std::string errMsg;
auto val = errorDetails["cdmError"];
- if (!val.isNull()) {
+ if (val.isInt()) {
mCdmErr = val.asInt();
}
val = errorDetails["oemError"];
- if (!val.isNull()) {
+ if (val.isInt()) {
mOemErr = val.asInt();
}
val = errorDetails["context"];
- if (!val.isNull()) {
+ if (val.isInt()) {
mCtx = val.asInt();
}
val = errorDetails["errorMessage"];
- if (!val.isNull()) {
+ if (val.isString()) {
mErrMsg = val.asString();
} else {
mErrMsg = msg;
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
index 638fb35..b618314 100644
--- a/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
@@ -144,10 +144,11 @@
void reportMediaDrmCreated() const;
- void reportMediaDrmSessionOpened(std::vector<uint8_t> sessionId) const;
+ void reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const;
- void reportMediaDrmErrored(DrmStatus error_code, const char* api,
- std::vector<uint8_t> sessionId = std::vector<uint8_t>()) const;
+ void reportMediaDrmErrored(
+ const DrmStatus& error_code, const char* api,
+ const std::vector<uint8_t>& sessionId = std::vector<uint8_t>()) const;
DrmStatus checkGetRandom(int64_t* nonce, const char* api);
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 6dfcc6b..cb25ddd 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -477,6 +477,15 @@
{
AUDIO_DEVICE_IN_ECHO_REFERENCE, make_AudioDeviceDescription(
AudioDeviceType::IN_ECHO_REFERENCE)
+ },
+ {
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, make_AudioDeviceDescription(
+ AudioDeviceType::IN_SUBMIX)
+ },
+ {
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SUBMIX,
+ GET_DEVICE_DESC_CONNECTION(VIRTUAL))
}
}};
append_AudioDeviceDescription(pairs,
@@ -495,9 +504,6 @@
AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
GET_DEVICE_DESC_CONNECTION(HDMI));
append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AudioDeviceType::IN_SUBMIX, AudioDeviceType::OUT_SUBMIX);
- append_AudioDeviceDescription(pairs,
AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,
AudioDeviceType::IN_DOCK, AudioDeviceType::OUT_DOCK,
GET_DEVICE_DESC_CONNECTION(ANALOG));
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
index a3e39c7..8fec660 100644
--- a/media/audioaidlconversion/AidlConversionNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -29,8 +29,14 @@
namespace aidl {
namespace android {
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::Flags;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::android::BAD_VALUE;
using ::android::base::unexpected;
@@ -54,6 +60,22 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_TYPE_MASK) {
+ case EFFECT_FLAG_TYPE_INSERT:
+ return Flags::Type::INSERT;
+ case EFFECT_FLAG_TYPE_AUXILIARY:
+ return Flags::Type::AUXILIARY;
+ case EFFECT_FLAG_TYPE_REPLACE:
+ return Flags::Type::REPLACE;
+ case EFFECT_FLAG_TYPE_PRE_PROC:
+ return Flags::Type::PRE_PROC;
+ case EFFECT_FLAG_TYPE_POST_PROC:
+ return Flags::Type::POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
switch (insert) {
case Flags::Insert::ANY:
@@ -68,6 +90,20 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_INSERT_MASK) {
+ case EFFECT_FLAG_INSERT_ANY:
+ return Flags::Insert::ANY;
+ case EFFECT_FLAG_INSERT_FIRST:
+ return Flags::Insert::FIRST;
+ case EFFECT_FLAG_INSERT_LAST:
+ return Flags::Insert::LAST;
+ case EFFECT_FLAG_INSERT_EXCLUSIVE:
+ return Flags::Insert::EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
switch (volume) {
case Flags::Volume::NONE:
@@ -81,15 +117,17 @@
}
return unexpected(BAD_VALUE);
}
-ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
- Flags::HardwareAccelerator hwAcceleratorMode) {
- switch (hwAcceleratorMode) {
- case Flags::HardwareAccelerator::NONE:
- return 0;
- case Flags::HardwareAccelerator::SIMPLE:
- return EFFECT_FLAG_HW_ACC_SIMPLE;
- case Flags::HardwareAccelerator::TUNNEL:
- return EFFECT_FLAG_HW_ACC_TUNNEL;
+
+ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
+ case EFFECT_FLAG_VOLUME_CTRL:
+ return Flags::Volume::CTRL;
+ case EFFECT_FLAG_VOLUME_IND:
+ return Flags::Volume::IND;
+ case EFFECT_FLAG_VOLUME_MONITOR:
+ return Flags::Volume::MONITOR;
+ case EFFECT_FLAG_VOLUME_NONE:
+ return Flags::Volume::NONE;
}
return unexpected(BAD_VALUE);
}
@@ -119,59 +157,6 @@
return legacy;
}
-ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_TYPE_MASK) {
- case EFFECT_FLAG_TYPE_INSERT:
- return Flags::Type::INSERT;
- case EFFECT_FLAG_TYPE_AUXILIARY:
- return Flags::Type::AUXILIARY;
- case EFFECT_FLAG_TYPE_REPLACE:
- return Flags::Type::REPLACE;
- case EFFECT_FLAG_TYPE_PRE_PROC:
- return Flags::Type::PRE_PROC;
- case EFFECT_FLAG_TYPE_POST_PROC:
- return Flags::Type::POST_PROC;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_INSERT_MASK) {
- case EFFECT_FLAG_INSERT_ANY:
- return Flags::Insert::ANY;
- case EFFECT_FLAG_INSERT_FIRST:
- return Flags::Insert::FIRST;
- case EFFECT_FLAG_INSERT_LAST:
- return Flags::Insert::LAST;
- case EFFECT_FLAG_INSERT_EXCLUSIVE:
- return Flags::Insert::EXCLUSIVE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
- case EFFECT_FLAG_VOLUME_IND:
- return Flags::Volume::IND;
- case EFFECT_FLAG_VOLUME_MONITOR:
- return Flags::Volume::MONITOR;
- case EFFECT_FLAG_VOLUME_NONE:
- return Flags::Volume::NONE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
- uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
- case EFFECT_FLAG_HW_ACC_SIMPLE:
- return Flags::HardwareAccelerator::SIMPLE;
- case EFFECT_FLAG_HW_ACC_TUNNEL:
- return Flags::HardwareAccelerator::TUNNEL;
- }
- return unexpected(BAD_VALUE);
-}
-
ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
Flags aidl;
@@ -187,6 +172,32 @@
return aidl;
}
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ Flags::HardwareAccelerator hwAcceleratorMode) {
+ switch (hwAcceleratorMode) {
+ case Flags::HardwareAccelerator::NONE:
+ return 0;
+ case Flags::HardwareAccelerator::SIMPLE:
+ return EFFECT_FLAG_HW_ACC_SIMPLE;
+ case Flags::HardwareAccelerator::TUNNEL:
+ return EFFECT_FLAG_HW_ACC_TUNNEL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
+ uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
+ case EFFECT_FLAG_HW_ACC_SIMPLE:
+ return Flags::HardwareAccelerator::SIMPLE;
+ case EFFECT_FLAG_HW_ACC_TUNNEL:
+ return Flags::HardwareAccelerator::TUNNEL;
+ case 0:
+ return Flags::HardwareAccelerator::NONE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<effect_descriptor_t>
aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
effect_descriptor_t legacy;
@@ -220,6 +231,7 @@
return aidl;
}
+// buffer_provider_t is not supported thus skipped
ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
const media::audio::common::AudioConfigBase& aidl, bool isInput) {
buffer_config_t legacy;
@@ -234,11 +246,12 @@
legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
legacy.mask |= EFFECT_CONFIG_FORMAT;
+ // TODO: add accessMode and mask
return legacy;
}
ConversionResult<media::audio::common::AudioConfigBase>
-legacy2aidl_AudioConfigBase_buffer_config_t(const buffer_config_t& legacy, bool isInput) {
+legacy2aidl_buffer_config_t_AudioConfigBase(const buffer_config_t& legacy, bool isInput) {
media::audio::common::AudioConfigBase aidl;
if (legacy.mask & EFFECT_CONFIG_SMP_RATE) {
@@ -252,8 +265,101 @@
aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(
static_cast<audio_format_t>(legacy.format)));
}
+
+ // TODO: add accessMode and mask
return aidl;
}
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(const Parameter& aidl) {
+ int echoDelay = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, int));
+ return VALUE_OR_RETURN(convertReinterpret<uint32_t>(echoDelay));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy) {
+ int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, delay);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(const Parameter& aidl) {
+ bool mobileMode = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AcousticEchoCanceler, acousticEchoCanceler, mobileMode, bool));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy) {
+ bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, mobileMode, mode);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
+ const Parameter& aidl) {
+ int gain = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AutomaticGainControl, automaticGainControl, fixedDigitalGainMb, int));
+ return VALUE_OR_RETURN(convertReinterpret<uint32_t>(gain));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy) {
+ int gain = VALUE_OR_RETURN(convertReinterpret<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, fixedDigitalGainMb,
+ gain);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
+ const Parameter& aidl) {
+ const auto& le = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControl, automaticGainControl,
+ levelEstimator, AutomaticGainControl::LevelEstimator));
+ return static_cast<uint32_t>(le);
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy) {
+ if (legacy > (uint32_t) AutomaticGainControl::LevelEstimator::PEAK) {
+ return unexpected(BAD_VALUE);
+ }
+ AutomaticGainControl::LevelEstimator le =
+ static_cast<AutomaticGainControl::LevelEstimator>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, levelEstimator, le);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
+ const Parameter& aidl) {
+ int saturationMargin = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AutomaticGainControl, automaticGainControl, saturationMarginMb, int));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(saturationMargin));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy) {
+ int saturationMargin = VALUE_OR_RETURN(convertIntegral<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, saturationMarginMb,
+ saturationMargin);
+}
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const Parameter& aidl) {
+ int strength = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, BassBoost, bassBoost, strengthPm, int));
+ return VALUE_OR_RETURN(convertIntegral<uint16_t>(strength));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy) {
+ int strength = VALUE_OR_RETURN(convertIntegral<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, strengthPm, strength);
+}
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(const Parameter& aidl) {
+ Downmix::Type aidlType = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, Downmix, downmix, type, Downmix::Type));
+ return VALUE_OR_RETURN(convertIntegral<int16_t>(static_cast<uint32_t>(aidlType)));
+}
+
+ConversionResult<Parameter> legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy) {
+ if (legacy > (uint32_t) Downmix::Type::FOLD) {
+ return unexpected(BAD_VALUE);
+ }
+ Downmix::Type aidlType = static_cast<Downmix::Type>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(Downmix, downmix, type, aidlType);
+}
+
} // namespace android
} // aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
index a3176f6..d094dff 100644
--- a/media/audioaidlconversion/include/media/AidlConversionNdk.h
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -32,6 +32,33 @@
namespace aidl {
namespace android {
+template <typename P, typename T, typename P::Specific::Tag tag>
+ConversionResult<T> getParameterSpecific(const P& u) {
+ const auto& spec = VALUE_OR_RETURN(UNION_GET(u, specific));
+ return unionGetField<typename P::Specific, tag>(spec);
+}
+
+template <typename P, typename T, typename P::Specific::Tag tag, typename T::Tag field, typename F>
+ConversionResult<F> getParameterSpecificField(const P& u) {
+ const auto& spec =
+ VALUE_OR_RETURN((getParameterSpecific<std::decay_t<decltype(u)>, T, tag>(u)));
+ return VALUE_OR_RETURN((unionGetField<T, field>(spec)));
+}
+
+#define GET_PARAMETER_SPECIFIC_FIELD(u, specific, tag, field, fieldType) \
+ getParameterSpecificField<std::decay_t<decltype(u)>, specific, \
+ aidl::android::hardware::audio::effect::Parameter::Specific::tag, \
+ specific::field, fieldType>(u)
+
+#define MAKE_SPECIFIC_PARAMETER(spec, tag, field, value) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter, specific, \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Specific, tag, \
+ UNION_MAKE(spec, field, value)))
+
+#define MAKE_SPECIFIC_PARAMETER_ID(spec, tag, field) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Id, tag, \
+ UNION_MAKE(spec::Id, commonTag, spec::field))
+
ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
::aidl::android::hardware::audio::effect::Flags::Type type);
ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
@@ -61,8 +88,43 @@
ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
const media::audio::common::AudioConfigBase& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_AudioConfigBase_buffer_config_t(
+ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_buffer_config_t_AudioConfigBase(
const buffer_config_t& legacy, bool isInput);
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy);
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy);
+
} // namespace android
} // namespace aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil.h b/media/audioaidlconversion/include/media/AidlConversionUtil.h
index a7a96b8..8b2e0de 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil.h
@@ -278,6 +278,8 @@
#define UNION_SET(u, field, value) \
(u).set<std::decay_t<decltype(u)>::Tag::field>(value)
+#define UNION_MAKE(u, field, value) u::make<u::Tag::field>(value)
+
namespace aidl_utils {
/**
@@ -411,7 +413,6 @@
return Status::fromServiceSpecificError(status, emptyIfNull);
}
-
} // namespace aidl_utils
} // namespace android
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index b9270de..8bd633f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -1137,6 +1137,11 @@
err = C2_CORRUPTED;
}
}
+
+ if (err != C2_OK) {
+ staticInfo->reset();
+ }
+
if (dynamicInfo) {
ALOGV("Grabbing dynamic HDR info from gralloc4 metadata");
dynamicInfo->reset();
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index 68a8590..f65ff18 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -416,7 +416,7 @@
LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
}
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
const media::AudioPortConfigFw& aidl) {
audio_port_config legacy{};
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
@@ -457,7 +457,7 @@
return legacy;
}
-ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
const audio_port_config& legacy) {
media::AudioPortConfigFw aidl;
aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
@@ -491,7 +491,7 @@
return aidl;
}
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
const media::AudioPatchFw& aidl) {
struct audio_patch legacy;
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_patch_handle_t(aidl.id));
@@ -501,7 +501,7 @@
}
for (size_t i = 0; i < legacy.num_sinks; ++i) {
legacy.sinks[i] =
- VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sinks[i]));
+ VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sinks[i]));
}
legacy.num_sources = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.sources.size()));
if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
@@ -509,12 +509,12 @@
}
for (size_t i = 0; i < legacy.num_sources; ++i) {
legacy.sources[i] =
- VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sources[i]));
+ VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sources[i]));
}
return legacy;
}
-ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
const struct audio_patch& legacy) {
media::AudioPatchFw aidl;
aidl.id = VALUE_OR_RETURN(legacy2aidl_audio_patch_handle_t_int32_t(legacy.id));
@@ -524,14 +524,14 @@
}
for (unsigned int i = 0; i < legacy.num_sinks; ++i) {
aidl.sinks.push_back(
- VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sinks[i])));
+ VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sinks[i])));
}
if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
return unexpected(BAD_VALUE);
}
for (unsigned int i = 0; i < legacy.num_sources; ++i) {
aidl.sources.push_back(
- VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sources[i])));
+ VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sources[i])));
}
return aidl;
}
@@ -541,7 +541,7 @@
const audio_io_handle_t io_handle = VALUE_OR_RETURN(
aidl2legacy_int32_t_audio_io_handle_t(aidl.ioHandle));
const struct audio_patch patch = VALUE_OR_RETURN(
- aidl2legacy_AudioPatch_audio_patch(aidl.patch));
+ aidl2legacy_AudioPatchFw_audio_patch(aidl.patch));
const bool isInput = aidl.isInput;
const uint32_t sampling_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.samplingRate));
const audio_format_t format = VALUE_OR_RETURN(
@@ -561,7 +561,7 @@
const sp<AudioIoDescriptor>& legacy) {
media::AudioIoDescriptor aidl;
aidl.ioHandle = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(legacy->getIoHandle()));
- aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatch(legacy->getPatch()));
+ aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatchFw(legacy->getPatch()));
aidl.isInput = legacy->getIsInput();
aidl.samplingRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy->getSamplingRate()));
aidl.format = VALUE_OR_RETURN(
@@ -930,7 +930,7 @@
}
ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPortFw& aidl) {
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl) {
audio_port_v7 legacy;
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.sys.role));
@@ -969,14 +969,14 @@
legacy.num_gains = aidl.hal.gains.size();
legacy.active_config = VALUE_OR_RETURN(
- aidl2legacy_AudioPortConfig_audio_port_config(aidl.sys.activeConfig));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sys.activeConfig));
legacy.ext = VALUE_OR_RETURN(
aidl2legacy_AudioPortExt_audio_port_v7_ext(aidl.hal.ext, aidl.sys.type, aidl.sys.ext));
return legacy;
}
ConversionResult<media::AudioPortFw>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy) {
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy) {
media::AudioPortFw aidl;
aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
aidl.sys.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
@@ -1016,7 +1016,7 @@
aidl.sys.gains.resize(legacy.num_gains);
aidl.sys.activeConfig = VALUE_OR_RETURN(
- legacy2aidl_audio_port_config_AudioPortConfig(legacy.active_config));
+ legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.active_config));
aidl.sys.activeConfig.hal.portId = aidl.hal.id;
RETURN_IF_ERROR(
legacy2aidl_AudioPortExt(legacy.ext, legacy.type, &aidl.hal.ext, &aidl.sys.ext));
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 8b7a63a..59016ad 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1572,7 +1572,7 @@
*num_ports = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPortsAidl.value));
*generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
RETURN_STATUS_IF_ERROR(convertRange(portsAidl.begin(), portsAidl.end(), ports,
- aidl2legacy_AudioPort_audio_port_v7));
+ aidl2legacy_AudioPortFw_audio_port_v7));
return OK;
}
@@ -1586,7 +1586,7 @@
media::AudioPortFw portAidl;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(aps->getAudioPort(port->id, &portAidl)));
- *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(portAidl));
+ *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(portAidl));
return OK;
}
@@ -1600,7 +1600,7 @@
if (aps == 0) return PERMISSION_DENIED;
media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_patch_AudioPatch(*patch));
+ legacy2aidl_audio_patch_AudioPatchFw(*patch));
int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(*handle));
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(aps->createAudioPatch(patchAidl, handleAidl, &handleAidl)));
@@ -1638,7 +1638,7 @@
*num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPatchesAidl.value));
*generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
RETURN_STATUS_IF_ERROR(convertRange(patchesAidl.begin(), patchesAidl.end(), patches,
- aidl2legacy_AudioPatch_audio_patch));
+ aidl2legacy_AudioPatchFw_audio_patch));
return OK;
}
@@ -1651,7 +1651,7 @@
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*config));
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
return statusTFromBinderStatus(aps->setAudioPortConfig(configAidl));
}
@@ -1872,7 +1872,7 @@
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*source));
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*source));
media::AudioAttributesInternal attributesAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attributes));
int32_t portIdAidl;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 30ccefe..1c634e7 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -674,18 +674,18 @@
status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
media::AudioPortFw portAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_v7_AudioPort(*port));
+ legacy2aidl_audio_port_v7_AudioPortFw(*port));
media::AudioPortFw aidlRet;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mDelegate->getAudioPort(portAidl, &aidlRet)));
- *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(aidlRet));
+ *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(aidlRet));
return OK;
}
status_t AudioFlingerClientAdapter::createAudioPatch(const struct audio_patch* patch,
audio_patch_handle_t* handle) {
media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_patch_AudioPatch(*patch));
+ legacy2aidl_audio_patch_AudioPatchFw(*patch));
int32_t aidlRet = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(
AUDIO_PATCH_HANDLE_NONE));
if (handle != nullptr) {
@@ -712,12 +712,12 @@
mDelegate->listAudioPatches(maxPatches, &aidlRet)));
*num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(aidlRet.size()));
return convertRange(aidlRet.begin(), aidlRet.end(), patches,
- aidl2legacy_AudioPatch_audio_patch);
+ aidl2legacy_AudioPatchFw_audio_patch);
}
status_t AudioFlingerClientAdapter::setAudioPortConfig(const struct audio_port_config* config) {
media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*config));
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
return statusTFromBinderStatus(mDelegate->setAudioPortConfig(configAidl));
}
@@ -815,7 +815,7 @@
status_t AudioFlingerClientAdapter::setDeviceConnectedState(
const struct audio_port_v7 *port, bool connected) {
media::AudioPortFw aidlPort = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_v7_AudioPort(*port));
+ legacy2aidl_audio_port_v7_AudioPortFw(*port));
return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
}
@@ -1256,15 +1256,15 @@
Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPortFw& port,
media::AudioPortFw* _aidl_return) {
- audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
RETURN_BINDER_IF_ERROR(mDelegate->getAudioPort(&portLegacy));
- *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPort(portLegacy));
+ *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPortFw(portLegacy));
return Status::ok();
}
Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatchFw& patch,
int32_t* _aidl_return) {
- audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatch_audio_patch(patch));
+ audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatchFw_audio_patch(patch));
audio_patch_handle_t handleLegacy = VALUE_OR_RETURN_BINDER(
aidl2legacy_int32_t_audio_patch_handle_t(*_aidl_return));
RETURN_BINDER_IF_ERROR(mDelegate->createAudioPatch(&patchLegacy, &handleLegacy));
@@ -1287,13 +1287,13 @@
RETURN_BINDER_IF_ERROR(convertRange(&patchesLegacy[0],
&patchesLegacy[count],
std::back_inserter(*_aidl_return),
- legacy2aidl_audio_patch_AudioPatch));
+ legacy2aidl_audio_patch_AudioPatchFw));
return Status::ok();
}
Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfigFw& config) {
audio_port_config configLegacy = VALUE_OR_RETURN_BINDER(
- aidl2legacy_AudioPortConfig_audio_port_config(config));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(config));
return Status::fromStatusT(mDelegate->setAudioPortConfig(&configLegacy));
}
@@ -1372,7 +1372,7 @@
Status AudioFlingerServerAdapter::setDeviceConnectedState(
const media::AudioPortFw& port, bool connected) {
- audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
}
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index a1012a1..9a88f76 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -88,14 +88,14 @@
ConversionResult<int32_t> legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
const audio_port_config_session_ext& legacy);
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
const media::AudioPortConfigFw& aidl);
-ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
const audio_port_config& legacy);
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
const media::AudioPatchFw& aidl);
-ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
const struct audio_patch& legacy);
ConversionResult<sp<AudioIoDescriptor>> aidl2legacy_AudioIoDescriptor_AudioIoDescriptor(
@@ -167,9 +167,9 @@
legacy2aidl_audio_port_session_ext_int32_t(const audio_port_session_ext& legacy);
ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPortFw& aidl);
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl);
ConversionResult<media::AudioPortFw>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy);
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy);
ConversionResult<audio_unique_id_use_t>
aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl);
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 8cbe3ea..b6602ec 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -207,6 +207,8 @@
cc_library_shared {
name: "libaudiohal@7.1",
defaults: [
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
+ "latest_android_hardware_audio_sounddose_ndk_shared",
"libaudiohal_default",
"libaudiohal_hidl_default"
],
@@ -226,6 +228,9 @@
"android.hardware.audio@7.1-util",
"libaudiohal.effect@7.0",
],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
cflags: [
"-DMAJOR_VERSION=7",
"-DMINOR_VERSION=1",
@@ -241,6 +246,7 @@
"libaudiohal_default",
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_audio_core_ndk_shared",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_hardware_audio_effect_ndk_static",
"latest_android_media_audio_common_types_ndk_shared",
],
@@ -248,6 +254,7 @@
"DeviceHalAidl.cpp",
"DevicesFactoryHalEntry.cpp",
"DevicesFactoryHalAidl.cpp",
+ "EffectConversionHelperAidl.cpp",
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
"EffectsFactoryHalAidl.cpp",
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
index 097ccfd..db6b6cf 100644
--- a/media/libaudiohal/impl/ConversionHelperAidl.h
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -18,9 +18,28 @@
#include <string>
#include <string_view>
+#include <vector>
+
+#include <utils/String16.h>
+#include <utils/Vector.h>
namespace android {
+class Args {
+ public:
+ explicit Args(const Vector<String16>& args)
+ : mValues(args.size()), mPtrs(args.size()) {
+ for (size_t i = 0; i < args.size(); ++i) {
+ mValues[i] = std::string(String8(args[i]));
+ mPtrs[i] = mValues[i].c_str();
+ }
+ }
+ const char** args() { return mPtrs.data(); }
+ private:
+ std::vector<std::string> mValues;
+ std::vector<const char*> mPtrs;
+};
+
class ConversionHelperAidl {
protected:
ConversionHelperAidl(std::string_view className) : mClassName(className) {}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 02e8fa7..280306d 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -15,16 +15,25 @@
*/
#define LOG_TAG "DeviceHalAidl"
-
-#include <mediautils/TimeCheck.h>
-#include <utils/Log.h>
+// #define LOG_NDEBUG 0
#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionUtil.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
#include "DeviceHalAidl.h"
#include "StreamHalAidl.h"
-using ::aidl::android::hardware::audio::core::StreamDescriptor;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::Float;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::ITelephony;
+using aidl::android::hardware::audio::core::StreamDescriptor;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
namespace android {
@@ -41,58 +50,66 @@
status_t DeviceHalAidl::setVoiceVolume(float volume) {
TIME_CHECK();
- mVoiceVolume = volume;
- ALOGE("%s not implemented yet %f", __func__, volume);
- return OK;
+ if (!mModule) return NO_INIT;
+ std::shared_ptr<ITelephony> telephony;
+ if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+ status.isOk() && telephony != nullptr) {
+ ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(telephony->setTelecomConfig(inConfig, &outConfig)));
+ ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
+ "%s: the resulting voice volume %f is not the same as requested %f",
+ __func__, outConfig.voiceVolume.value().value, volume);
+ }
+ return INVALID_OPERATION;
}
status_t DeviceHalAidl::setMasterVolume(float volume) {
TIME_CHECK();
- mMasterVolume = volume;
- ALOGE("%s not implemented yet %f", __func__, volume);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMasterVolume(volume));
}
status_t DeviceHalAidl::getMasterVolume(float *volume) {
TIME_CHECK();
- *volume = mMasterVolume;
- ALOGE("%s not implemented yet %f", __func__, *volume);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMasterVolume(volume));
}
-status_t DeviceHalAidl::setMode(audio_mode_t mode __unused) {
+status_t DeviceHalAidl::setMode(audio_mode_t mode) {
TIME_CHECK();
if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
+ std::shared_ptr<ITelephony> telephony;
+ if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+ status.isOk() && telephony != nullptr) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(telephony->switchAudioMode(audioMode)));
+ }
+ return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
}
status_t DeviceHalAidl::setMicMute(bool state) {
TIME_CHECK();
- mMicMute = state;
- ALOGE("%s not implemented yet %d", __func__, state);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMicMute(state));
}
status_t DeviceHalAidl::getMicMute(bool *state) {
TIME_CHECK();
- *state = mMicMute;
- ALOGE("%s not implemented yet %d", __func__, *state);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMicMute(state));
}
status_t DeviceHalAidl::setMasterMute(bool state) {
TIME_CHECK();
- mMasterMute = state;
- ALOGE("%s not implemented yet %d", __func__, state);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMasterMute(state));
}
status_t DeviceHalAidl::getMasterMute(bool *state) {
TIME_CHECK();
- *state = mMasterMute;
- ALOGE("%s not implemented yet %d", __func__, *state);
- return OK;
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMasterMute(state));
}
status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
@@ -259,9 +276,10 @@
return base::unexpected(INVALID_OPERATION);
}
-status_t DeviceHalAidl::dump(int __unused, const Vector<String16>& __unused) {
- ALOGE("%s not implemented yet", __func__);
- return OK;
+status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return mModule->dump(fd, Args(args).args(), args.size());
};
int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
@@ -270,4 +288,24 @@
return INVALID_OPERATION;
}
+status_t DeviceHalAidl::getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ if (mSoundDose == nullptr) {
+ ndk::ScopedAStatus status = mModule->getSoundDose(&mSoundDose);
+ if (!status.isOk()) {
+ ALOGE("%s failed to return the sound dose interface for module %s: %s",
+ __func__,
+ module.c_str(),
+ status.getDescription().c_str());
+ return BAD_VALUE;
+ }
+ }
+ *soundDoseBinder = mSoundDose->asBinder();
+ ALOGI("%s using audio AIDL HAL sound dose interface", __func__);
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 91d48cc..b1aa351 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -16,6 +16,7 @@
#pragma once
+#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
#include <aidl/android/hardware/audio/core/BpModule.h>
#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/EffectHalInterface.h>
@@ -117,15 +118,15 @@
int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
+ status_t getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) override;
+
private:
friend class sp<DeviceHalAidl>;
const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
- // FIXME: Remove these after implementing calls into the HAL.
- float mMasterVolume = 0.0f;
- float mVoiceVolume = 0.0f;
- bool mMasterMute = false;
- bool mMicMute = false;
+ std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>
+ mSoundDose = nullptr;
// Can not be constructed directly by clients.
explicit DeviceHalAidl(
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 12acebd..e0b1afb 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -17,7 +17,7 @@
#include <stdio.h>
#define LOG_TAG "DeviceHalHidl"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <cutils/native_handle.h>
#include <cutils/properties.h>
@@ -35,6 +35,17 @@
#include "ParameterUtils.h"
#include "StreamHalHidl.h"
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
+#include <aidl/android/hardware/audio/sounddose/BpSoundDoseFactory.h>
+#include <android/binder_manager.h>
+
+constexpr std::string_view kSoundDoseInterfaceModule = "/default";
+
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
+using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
+#endif
+
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
@@ -46,8 +57,21 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+class DeviceHalHidl::SoundDoseWrapper {
+public:
+ SoundDoseWrapper() = default;
+ ~SoundDoseWrapper() = default;
+
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ std::shared_ptr<ISoundDoseFactory> mSoundDoseFactory;
+ std::shared_ptr<ISoundDose> mSoundDose;
+#endif
+};
+
DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
- : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
+ : CoreConversionHelperHidl("DeviceHalHidl"),
+ mDevice(device),
+ mSoundDoseWrapper(std::make_unique<DeviceHalHidl::SoundDoseWrapper>()) {
}
DeviceHalHidl::DeviceHalHidl(
@@ -56,7 +80,8 @@
#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
mDevice(device),
#endif
- mPrimaryDevice(device) {
+ mPrimaryDevice(device),
+ mSoundDoseWrapper(std::make_unique<DeviceHalHidl::SoundDoseWrapper>()) {
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
auto getDeviceRet = mPrimaryDevice->getDevice();
if (getDeviceRet.isOk()) {
@@ -574,4 +599,50 @@
return processReturn("dump", ret);
}
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) {
+ if (mSoundDoseWrapper->mSoundDose != nullptr) {
+ *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
+ return OK;
+ }
+
+ if (mSoundDoseWrapper->mSoundDoseFactory == nullptr) {
+ std::string interface =
+ std::string(ISoundDoseFactory::descriptor) + kSoundDoseInterfaceModule.data();
+ AIBinder* binder = AServiceManager_checkService(interface.c_str());
+ if (binder == nullptr) {
+ ALOGW("%s service %s doesn't exist", __func__, interface.c_str());
+ return NO_INIT;
+ }
+ mSoundDoseWrapper->mSoundDoseFactory =
+ ISoundDoseFactory::fromBinder(ndk::SpAIBinder(binder));
+ }
+
+ auto result = mSoundDoseWrapper->mSoundDoseFactory->getSoundDose(
+ module, &mSoundDoseWrapper->mSoundDose);
+ if (!result.isOk()) {
+ ALOGW("%s could not get sound dose interface: %s", __func__, result.getMessage());
+ return BAD_VALUE;
+ }
+
+ if (mSoundDoseWrapper->mSoundDose == nullptr) {
+ ALOGW("%s standalone sound dose interface is not implemented", __func__);
+ *soundDoseBinder = nullptr;
+ return OK;
+ }
+
+ *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
+ ALOGI("%s using standalone sound dose interface", __func__);
+ return OK;
+}
+#else
+status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) {
+ (void)module; // avoid unused param
+ (void)soundDoseBinder; // avoid unused param
+ return INVALID_OPERATION;
+}
+#endif
+
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 052eb65..30fbd6d 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -130,12 +130,17 @@
status_t dump(int fd, const Vector<String16>& args) override;
+ status_t getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) override;
+
private:
friend class DevicesFactoryHalHidl;
sp<::android::hardware::audio::CPP_VERSION::IDevice> mDevice;
// Null if it's not a primary device.
sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice> mPrimaryDevice;
bool supportsSetConnectedState7_1 = true;
+ class SoundDoseWrapper;
+ const std::unique_ptr<SoundDoseWrapper> mSoundDoseWrapper;
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device);
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index ee29f09..78d03e7 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -19,6 +19,7 @@
#include <aidl/android/hardware/audio/core/IModule.h>
#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
#include <memory>
#include <utils/Log.h>
@@ -64,8 +65,23 @@
if (pids == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+ // The functionality for retrieving debug infos of services is not exposed via the NDK.
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == nullptr) {
+ return NO_INIT;
+ }
+ std::set<pid_t> pidsSet;
+ const auto moduleServiceName = std::string(IModule::descriptor) + "/";
+ auto debugInfos = sm->getServiceDebugInfo();
+ for (const auto& info : debugInfos) {
+ if (info.pid > 0 &&
+ info.name.size() > moduleServiceName.size() && // '>' as there must be instance name
+ info.name.substr(0, moduleServiceName.size()) == moduleServiceName) {
+ pidsSet.insert(info.pid);
+ }
+ }
+ *pids = {pidsSet.begin(), pidsSet.end()};
+ return NO_ERROR;
}
status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
new file mode 100644
index 0000000..ec8abd7
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#include <cstdint>
+#include <cstring>
+#include <optional>
+#define LOG_TAG "EffectConversionHelperAidl"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_agc2.h>
+#include <system/audio_effects/effect_bassboost.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_environmentalreverb.h>
+#include <system/audio_effects/effect_equalizer.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_loudnessenhancer.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_presetreverb.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_virtualizer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
+#include <utils/Log.h>
+
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Downmix;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioUuid;
+using android::effect::utils::EffectParamReader;
+using android::effect::utils::EffectParamWriter;
+
+using ::android::status_t;
+
+const std::map<uint32_t /* effect_command_e */, EffectConversionHelperAidl::CommandHandler>
+ EffectConversionHelperAidl::mCommandHandlerMap = {
+ {EFFECT_CMD_INIT, &EffectConversionHelperAidl::handleInit},
+ {EFFECT_CMD_SET_PARAM, &EffectConversionHelperAidl::handleSetParameter},
+ {EFFECT_CMD_GET_PARAM, &EffectConversionHelperAidl::handleGetParameter},
+ {EFFECT_CMD_SET_CONFIG, &EffectConversionHelperAidl::handleSetConfig},
+ {EFFECT_CMD_GET_CONFIG, &EffectConversionHelperAidl::handleGetConfig},
+ {EFFECT_CMD_RESET, &EffectConversionHelperAidl::handleReset},
+ {EFFECT_CMD_ENABLE, &EffectConversionHelperAidl::handleEnable},
+ {EFFECT_CMD_DISABLE, &EffectConversionHelperAidl::handleDisable},
+ {EFFECT_CMD_SET_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+ {EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+ {EFFECT_CMD_SET_VOLUME, &EffectConversionHelperAidl::handleSetVolume},
+ {EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
+ {EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
+
+const std::map<AudioUuid /* TypeUUID */, std::pair<EffectConversionHelperAidl::SetParameter,
+ EffectConversionHelperAidl::GetParameter>>
+ EffectConversionHelperAidl::mParameterHandlerMap = {
+ {kAcousticEchoCancelerTypeUUID,
+ {&EffectConversionHelperAidl::setAecParameter,
+ &EffectConversionHelperAidl::getAecParameter}},
+ {kAutomaticGainControlTypeUUID,
+ {&EffectConversionHelperAidl::setAgcParameter,
+ &EffectConversionHelperAidl::getAgcParameter}},
+ {kBassBoostTypeUUID,
+ {&EffectConversionHelperAidl::setBassBoostParameter,
+ &EffectConversionHelperAidl::getBassBoostParameter}},
+ {kDownmixTypeUUID,
+ {&EffectConversionHelperAidl::setDownmixParameter,
+ &EffectConversionHelperAidl::getDownmixParameter}}};
+
+EffectConversionHelperAidl::EffectConversionHelperAidl(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
+ mCommon.session = sessionId;
+ mCommon.ioHandle = ioId;
+ mCommon.input = mCommon.output = kDefaultAudioConfig;
+}
+
+status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
+ void* pCmdData, uint32_t* replySize,
+ void* pReplyData) {
+ const auto& handler = mCommandHandlerMap.find(cmdCode);
+ if (handler == mCommandHandlerMap.end() || !handler->second) {
+ ALOGE("%s handler for command %u doesn't exist", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+ return (this->*handler->second)(cmdSize, pCmdData, replySize, pReplyData);
+}
+
+status_t EffectConversionHelperAidl::handleInit(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize < sizeof(int) || !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ return *(status_t*)pReplyData =
+ statusTFromBinderStatus(mEffect->open(mCommon, std::nullopt, &mOpenReturn));
+}
+
+status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize ||
+ *replySize < sizeof(int) || !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+ if (!reader.validateCmdSize(cmdSize)) {
+ ALOGE("%s illegal param %s size %u", __func__, reader.toString().c_str(), cmdSize);
+ return BAD_VALUE;
+ }
+
+ const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
+ if (handler == mParameterHandlerMap.end() || !handler->second.first) {
+ ALOGE("%s handler for uuid %s not found", __func__,
+ mDesc.common.id.type.toString().c_str());
+ return BAD_VALUE;
+ }
+ const SetParameter& functor = handler->second.first;
+ return *(status_t*)pReplyData = (this->*functor)(reader);
+}
+
+status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize || !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ const auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+ if (!reader.validateCmdSize(cmdSize)) {
+ ALOGE("%s illegal param %s, replysize %u", __func__, reader.toString().c_str(),
+ *replySize);
+ return BAD_VALUE;
+ }
+
+ const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
+ if (handler == mParameterHandlerMap.end() || !handler->second.second) {
+ ALOGE("%s handler for uuid %s not found", __func__,
+ mDesc.common.id.type.toString().c_str());
+ return BAD_VALUE;
+ }
+ const GetParameter& functor = handler->second.second;
+ memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + reader.getParameterSize());
+ auto writer = EffectParamWriter(*(effect_param_t *)pReplyData);
+ (this->*functor)(writer);
+ *replySize = writer.getTotalSize();
+ return writer.getStatus();
+}
+
+status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != sizeof(int) || !pReplyData ||
+ cmdSize != sizeof(effect_config_t)) {
+ return BAD_VALUE;
+ }
+
+ const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
+ // already open, apply latest settings
+ mCommon.input.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ legacyConfig->inputCfg, true /* isInput */));
+ mCommon.output.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ legacyConfig->outputCfg, false /* isInput */));
+ mCommon.session = mSessionId;
+ mCommon.ioHandle = mIoId;
+ // TODO: add access mode support
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::common>(mCommon))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ Parameter param;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(
+ Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common), ¶m)));
+
+ const auto& common = param.get<Parameter::common>();
+ effect_config_t* pConfig = (effect_config_t*)pReplyData;
+ pConfig->inputCfg = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(common.input.base, true));
+ pConfig->outputCfg =
+ VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
+ common.output.base, false));
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ return statusTFromBinderStatus(mEffect->command(CommandId::RESET));
+}
+
+status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ return statusTFromBinderStatus(mEffect->command(CommandId::START));
+}
+
+status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ return statusTFromBinderStatus(mEffect->command(CommandId::STOP));
+}
+
+status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize ||
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
+ // const auto& legacyDevice = *(uint32_t*)(pCmdData);
+ std::vector<AudioDeviceDescription> aidlDevices;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize ||
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
+ .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize ||
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ // TODO: handle this after effectproxy implemented in libaudiohal
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ // TODO to be implemented
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setAecParameter(EffectParamReader& param) {
+ uint32_t type, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) ||
+ OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ Parameter aidlParam;
+ switch (type) {
+ case AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_echoDelay_Parameter_aec(value));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_mobileMode_Parameter_aec(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getAecParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ param.setStatus(BAD_VALUE);
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+ acousticEchoCancelerTag, echoDelayUs);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+ acousticEchoCancelerTag, mobileMode);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
+ break;
+ }
+ default:
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setAgcParameter(EffectParamReader& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(value));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_levelEstimator_Parameter_agc(value));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_saturationMargin_Parameter_agc(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getAgcParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+ AutomaticGainControl, automaticGainControlTag, fixedDigitalGainMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl,
+ automaticGainControlTag, levelEstimator);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+ AutomaticGainControl, automaticGainControlTag, saturationMarginMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_saturationMargin(aidlParam));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setBassBoostParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ uint16_t value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint16_strengthPm_Parameter_BassBoost(value));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ ALOGW("%s set BASSBOOST_PARAM_STRENGTH_SUPPORTED not supported", __func__);
+ return BAD_VALUE;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getBassBoostParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ param.setStatus(BAD_VALUE);
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, strengthPm);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_BassBoost_uint16_strengthPm(aidlParam));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ const auto& cap =
+ VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::convertIntegral<uint32_t>(cap.strengthSupported));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setDownmixParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ int16_t value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_int16_type_Parameter_Downmix(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getDownmixParameter(EffectParamWriter& param) {
+ int16_t value = 0;
+ uint32_t type = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ param.setStatus(BAD_VALUE);
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Downmix, downmixTag, type);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_Downmix_int16_type(aidlParam));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
new file mode 100644
index 0000000..35249f5
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <cstddef>
+#include <map>
+#include <memory>
+#include <utils/Errors.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+#include <media/AidlConversionNdk.h>
+#include <system/audio_effect.h>
+#include <system/audio_effects/audio_effects_utils.h>
+
+namespace android {
+namespace effect {
+
+class EffectConversionHelperAidl {
+ protected:
+ EffectConversionHelperAidl(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+
+ status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+
+ private:
+ const int32_t mSessionId;
+ const int32_t mIoId;
+ const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
+ ::aidl::android::media::audio::common::AudioUuid mTypeUuid;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+ ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
+ ::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
+
+ const aidl::android::media::audio::common::AudioFormatDescription kDefaultFormatDescription = {
+ .type = aidl::android::media::audio::common::AudioFormatType::PCM,
+ .pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT};
+
+ static constexpr int kDefaultframeCount = 0x100;
+
+ using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout;
+ const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = {
+ .base = {.sampleRate = 44100,
+ .channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO),
+ .format = kDefaultFormatDescription},
+ .frameCount = kDefaultframeCount};
+ // command handler map
+ typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */,
+ const void* /* pCmdData */,
+ uint32_t* /* replySize */,
+ void* /* pReplyData */);
+ static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
+
+ // parameter set/get handler map
+ typedef status_t (EffectConversionHelperAidl::*SetParameter)(
+ android::effect::utils::EffectParamReader& param);
+ typedef status_t (EffectConversionHelperAidl::*GetParameter)(
+ android::effect::utils::EffectParamWriter& param);
+ static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
+ std::pair<SetParameter, GetParameter>>
+ mParameterHandlerMap;
+
+ status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleEnable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleDisable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleReset(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetDevice(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetVolume(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetOffload(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+
+ // set/get parameter handler
+ status_t setAecParameter(android::effect::utils::EffectParamReader& param);
+ status_t getAecParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setAgcParameter(android::effect::utils::EffectParamReader& param);
+ status_t getAgcParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setBassBoostParameter(android::effect::utils::EffectParamReader& param);
+ status_t getBassBoostParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setDownmixParameter(android::effect::utils::EffectParamReader& param);
+ status_t getDownmixParameter(android::effect::utils::EffectParamWriter& param);
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index daa68a1..0c37552 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -25,27 +25,47 @@
#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
#include "EffectHalAidl.h"
#include <system/audio.h>
-
#include <aidl/android/hardware/audio/effect/IEffect.h>
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IEffect;
-using ::aidl::android::hardware::audio::effect::State;
+using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Parameter;
namespace android {
namespace effect {
-EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
- int32_t sessionId, int32_t ioId)
- : mEffectId(effectId), mSessionId(sessionId), mIoId(ioId), mEffect(effect) {}
+EffectHalAidl::EffectHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc),
+ mFactory(factory),
+ mEffect(effect),
+ mEffectId(effectId),
+ mSessionId(sessionId),
+ mIoId(ioId),
+ mDesc(desc) {}
-EffectHalAidl::~EffectHalAidl() {}
+EffectHalAidl::~EffectHalAidl() {
+ if (mFactory) {
+ mFactory->destroyEffect(mEffect);
+ }
+}
status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
if (buffer == nullptr) {
@@ -65,7 +85,7 @@
status_t EffectHalAidl::process() {
ALOGW("%s not implemented yet", __func__);
- // write to input FMQ here?
+ // write to input FMQ here, and wait for statusMQ STATUS_OK
return OK;
}
@@ -75,138 +95,9 @@
return OK;
}
-status_t EffectHalAidl::handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData) {
- if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || replySize == NULL ||
- *replySize != sizeof(int32_t) || pReplyData == NULL) {
- ALOGE("%s parameter error code %u", __func__, cmdCode);
- return BAD_VALUE;
- }
-
- *static_cast<int32_t*>(pReplyData) = FAILED_TRANSACTION;
- memcpy(&mConfig, pCmdData, cmdSize);
-
- State state;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getState(&state)));
- // effect not open yet, save settings locally
- if (state != State::INIT) {
- effect_config_t* legacyConfig = static_cast<effect_config_t*>(pCmdData);
- // already open, apply latest settings
- Parameter aidlParam;
- Parameter::Common aidlCommon;
- aidlCommon.input.base =
- VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
- legacyConfig->inputCfg, true /* isInput */));
- aidlCommon.output.base =
- VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
- legacyConfig->outputCfg, false /* isInput */));
- aidlCommon.session = mSessionId;
- aidlCommon.ioHandle = mIoId;
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- aidlParam.set<Parameter::common>(aidlCommon);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
- }
- *(int*)pReplyData = 0;
- *static_cast<int32_t*>(pReplyData) = OK;
- return OK;
-}
-
-status_t EffectHalAidl::handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData) {
- if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
- *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
- ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
- return BAD_VALUE;
- }
-
- *(effect_config_t*)pReplyData = mConfig;
- return OK;
-}
-
-status_t EffectHalAidl::handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData) {
- ALOGW("%s not implemented yet", __func__);
- if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
- *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
- ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
- return BAD_VALUE;
- }
- return OK;
-}
-
-status_t EffectHalAidl::handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData) {
- ALOGW("%s not implemented yet", __func__);
- if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
- *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
- ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
- return BAD_VALUE;
- }
- return OK;
-}
-
status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- ALOGW("%s code %d not implemented yet", __func__, cmdCode);
- ::ndk::ScopedAStatus status;
- switch (cmdCode) {
- case EFFECT_CMD_INIT: {
- // open with default effect_config_t (convert to Parameter.Common)
- IEffect::OpenEffectReturn ret;
- Parameter::Common common;
- RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(mEffect->open(common, std::nullopt, &ret)));
- return OK;
- }
- case EFFECT_CMD_SET_CONFIG:
- return handleSetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
- case EFFECT_CMD_GET_CONFIG:
- return handleGetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
- case EFFECT_CMD_RESET:
- return mEffect->command(CommandId::RESET).getStatus();
- case EFFECT_CMD_ENABLE:
- return mEffect->command(CommandId::START).getStatus();
- case EFFECT_CMD_DISABLE:
- return mEffect->command(CommandId::STOP).getStatus();
- case EFFECT_CMD_SET_PARAM:
- return handleSetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
- case EFFECT_CMD_SET_PARAM_DEFERRED:
- case EFFECT_CMD_SET_PARAM_COMMIT:
- // TODO
- return OK;
- case EFFECT_CMD_GET_PARAM:
- return handleGetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
- case EFFECT_CMD_SET_DEVICE:
- return OK;
- case EFFECT_CMD_SET_VOLUME:
- return OK;
- case EFFECT_CMD_SET_AUDIO_MODE:
- return OK;
- case EFFECT_CMD_SET_CONFIG_REVERSE:
- return OK;
- case EFFECT_CMD_SET_INPUT_DEVICE:
- return OK;
- case EFFECT_CMD_GET_CONFIG_REVERSE:
- return OK;
- case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS:
- return OK;
- case EFFECT_CMD_GET_FEATURE_CONFIG:
- return OK;
- case EFFECT_CMD_SET_FEATURE_CONFIG:
- return OK;
- case EFFECT_CMD_SET_AUDIO_SOURCE:
- return OK;
- case EFFECT_CMD_OFFLOAD:
- return OK;
- case EFFECT_CMD_DUMP:
- return OK;
- case EFFECT_CMD_FIRST_PROPRIETARY:
- return OK;
- default:
- return INVALID_OPERATION;
- }
- return INVALID_OPERATION;
+ return handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
}
status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
@@ -223,9 +114,7 @@
}
status_t EffectHalAidl::close() {
- auto ret = mEffect->close();
- ALOGI("%s %s", __func__, ret.getMessage());
- return ret.getStatus();
+ return statusTFromBinderStatus(mEffect->close());
}
status_t EffectHalAidl::dump(int fd) {
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 76bb240..6a1ec1c 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -17,13 +17,16 @@
#pragma once
#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio_effect.h>
+#include "EffectConversionHelperAidl.h"
+
namespace android {
namespace effect {
-class EffectHalAidl : public EffectHalInterface {
+class EffectHalAidl : public EffectHalInterface, public EffectConversionHelperAidl {
public:
// Set the input buffer.
status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
@@ -55,28 +58,30 @@
uint64_t effectId() const override { return mEffectId; }
- private:
- friend class EffectsFactoryHalAidl;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> getIEffect() const {
+ return mEffect;
+ }
+ private:
+ friend class sp<EffectHalAidl>;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
const uint64_t mEffectId;
const int32_t mSessionId;
const int32_t mIoId;
+ const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
+
sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
effect_config_t mConfig;
- std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
// Can not be constructed directly by clients.
- EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
- uint64_t effectId, int32_t sessionId, int32_t ioId);
-
- status_t handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData);
- status_t handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData);
- status_t handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData);
- status_t handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
- uint32_t* replySize, void* pReplyData);
+ EffectHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+ bool setEffectReverse(bool reverse);
// The destructor automatically releases the effect.
virtual ~EffectHalAidl();
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index c6234e4..878c19e 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -21,15 +21,19 @@
//#define LOG_NDEBUG 0
#include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <error/expected_utils.h>
#include <android/binder_manager.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionNdk.h>
+#include <system/audio.h>
#include <utils/Log.h>
#include "EffectBufferHalAidl.h"
#include "EffectHalAidl.h"
#include "EffectsFactoryHalAidl.h"
+using ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::media::audio::common::AudioUuid;
using android::detail::AudioHalVersionInfo;
@@ -86,8 +90,7 @@
return BAD_VALUE;
}
- AudioUuid uuid =
- VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
+ AudioUuid uuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
std::lock_guard lg(mLock);
return getHalDescriptorWithImplUuid_l(uuid, pDescriptor);
}
@@ -98,8 +101,7 @@
return BAD_VALUE;
}
- AudioUuid type =
- VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halType));
+ AudioUuid type = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halType));
std::lock_guard lg(mLock);
return getHalDescriptorWithTypeUuid_l(type, descriptors);
}
@@ -110,24 +112,29 @@
if (uuid == nullptr || effect == nullptr) {
return BAD_VALUE;
}
- ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
-
- AudioUuid aidlUuid =
- VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
- std::shared_ptr<IEffect> aidlEffect;
- ndk::ScopedAStatus status = mFactory->createEffect(aidlUuid, &aidlEffect);
- if (!status.isOk() || aidlEffect == nullptr) {
- ALOGE("%s IFactory::createFactory failed %s UUID %s", __func__,
- status.getDescription().c_str(), aidlUuid.toString().c_str());
+ if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
return INVALID_OPERATION;
}
+
+ ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
+
+ AudioUuid aidlUuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+ std::shared_ptr<IEffect> aidlEffect;
+ Descriptor desc;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
+ if (aidlEffect == nullptr) {
+ ALOGE("%s IFactory::createFactory failed UUID %s", __func__, aidlUuid.toString().c_str());
+ return NAME_NOT_FOUND;
+ }
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aidlEffect->getDescriptor(&desc)));
+
uint64_t effectId;
{
std::lock_guard lg(mLock);
effectId = ++mEffectIdCounter;
}
- *effect = new EffectHalAidl(aidlEffect, effectId, sessionId, ioId);
+ *effect = sp<EffectHalAidl>::make(mFactory, aidlEffect, effectId, sessionId, ioId, desc);
return OK;
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 7338952..1c6a014 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -31,6 +31,20 @@
namespace android {
+// static
+template<class T>
+std::shared_ptr<IStreamCommon> StreamHalAidl::getStreamCommon(const std::shared_ptr<T>& stream) {
+ std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> streamCommon;
+ if (stream != nullptr) {
+ if (ndk::ScopedAStatus status = stream->getStreamCommon(&streamCommon);
+ !status.isOk()) {
+ ALOGE("%s: failed to retrieve IStreamCommon instance: %s", __func__,
+ status.getDescription().c_str());
+ }
+ }
+ return streamCommon;
+}
+
StreamHalAidl::StreamHalAidl(
std::string_view className, bool isInput, const StreamDescriptor& descriptor,
const std::shared_ptr<IStreamCommon>& stream)
@@ -130,11 +144,10 @@
return OK;
}
-status_t StreamHalAidl::dump(int fd __unused, const Vector<String16>& args __unused) {
+status_t StreamHalAidl::dump(int fd, const Vector<String16>& args) {
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ return mStream->dump(fd, Args(args).args(), args.size());
}
status_t StreamHalAidl::start() {
@@ -190,18 +203,13 @@
status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
std::optional<audio_source_t> source __unused,
audio_devices_t type __unused) {
- TIME_CHECK();
- LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
- if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+ return INVALID_OPERATION;
}
status_t StreamHalAidl::legacyReleaseAudioPatch() {
- TIME_CHECK();
- if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+ return INVALID_OPERATION;
}
namespace {
@@ -237,8 +245,7 @@
StreamOutHalAidl::StreamOutHalAidl(
const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
- : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor,
- nullptr /* FIXME: Retrieve IStreamCommon */),
+ : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor, getStreamCommon(stream)),
mStream(stream) {}
status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
@@ -452,8 +459,7 @@
StreamInHalAidl::StreamInHalAidl(
const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
- : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor,
- nullptr /* FIXME: Retrieve IStreamCommon */),
+ : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor, getStreamCommon(stream)),
mStream(stream) {}
status_t StreamInHalAidl::setGain(float gain __unused) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 86f48f3..c56d5e3 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -94,6 +94,10 @@
typedef AidlMessageQueue<int8_t,
::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
+ template<class T>
+ static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
+ const std::shared_ptr<T>& stream);
+
// Subclasses can not be constructed directly by clients.
StreamHalAidl(std::string_view className,
bool isInput,
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
new file mode 100644
index 0000000..20a10f6
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <aidl/android/media/audio/common/AudioUuid.h>
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::media::audio::common::AudioUuid;
+
+// 7b491460-8d4d-11e0-bd61-0002a5d5c51b.
+static const AudioUuid kAcousticEchoCancelerTypeUUID = {static_cast<int32_t>(0x7b491460),
+ 0x8d4d,
+ 0x11e0,
+ 0xbd61,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
+ 0xbe18,
+ 0x4ab8,
+ 0x8938,
+ {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
+// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
+static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
+ 0xddd4,
+ 0x11db,
+ 0xa0fc,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa81862a-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
+static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
+ 0xddd6,
+ 0x11db,
+ 0x8f34,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 7261676f-6d75-7369-6364-28e2fd3ac39e
+static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
+ 0x6d75,
+ 0x7369,
+ 0x6364,
+ {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
+// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
+static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
+ 0xaecd,
+ 0x4021,
+ 0xa1cf,
+ {0xa6, 0xac, 0xeb, 0x0d, 0x71, 0xe5}};
+// fe3199be-aed0-413f-87bb-11260eb63cf1
+static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
+ 0xaed0,
+ 0x413f,
+ 0x87bb,
+ {0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}};
+// c2e5d5f0-94bd-4763-9cac-4e234d06839e
+static const AudioUuid kEnvReverbTypeUUID = {static_cast<int32_t>(0xc2e5d5f0),
+ 0x94bd,
+ 0x4763,
+ 0x9cac,
+ {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}};
+// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
+static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
+ 0x8e06,
+ 0x11e0,
+ 0xaa8e,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
+static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
+ 0xddd8,
+ 0x11db,
+ 0xbf3a,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 37cc2c00-dddd-11db-8577-0002a5d5c51b
+static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
+ 0xdddd,
+ 0x11db,
+ 0x8577,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa819f3e-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a2b8-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 094b415..d5a1a60 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -26,6 +26,10 @@
#include <utils/RefBase.h>
#include <utils/String8.h>
+namespace ndk {
+class SpAIBinder;
+}
+
namespace android {
class StreamInHalInterface;
@@ -140,6 +144,10 @@
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+ // Returns the sound dose binder interface if it is supported by the HAL, nullptr otherwise
+ virtual status_t getSoundDoseInterface(const std::string& module,
+ ::ndk::SpAIBinder* soundDoseBinder) = 0;
+
protected:
// Subclasses can not be constructed directly by clients.
DeviceHalInterface() {}
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index 83c7809..c2e2ba7 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -20,11 +20,17 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/audio_effects/audio_effects_utils.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effect.h>
+
#include <gtest/gtest.h>
#include <utils/RefBase.h>
namespace android {
+using effect::utils::EffectParamWriter;
+
// EffectsFactoryHalInterface
TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
ASSERT_NE(nullptr, EffectsFactoryHalInterface::create());
@@ -78,6 +84,81 @@
EXPECT_NE(0, version.getMajorVersion());
}
+static char testDataBuffer[sizeof(effect_param_t) + 0xff] = {};
+static char testResponseBuffer[sizeof(effect_param_t) + 0xff] = {};
+TEST(libAudioHalTest, agcNotInit) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ std::vector<effect_descriptor_t> descs;
+ EXPECT_EQ(OK, factory->getDescriptors(&FX_IID_AEC_, &descs));
+ for (const auto& desc : descs) {
+ ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(FX_IID_AEC_)));
+ sp<EffectHalInterface> interface;
+ EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+ 1 /* deviceId */, &interface));
+ EXPECT_NE(nullptr, interface);
+ effect_param_t* param = (effect_param_t*)testDataBuffer;
+ uint32_t type = AEC_PARAM_ECHO_DELAY, value = 0xbead;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ //EXPECT_EQ(1, 0) << param->psize << " " << param->vsize;
+ EffectParamWriter writer(*param);
+ EXPECT_EQ(OK, writer.writeToParameter(&type)) << writer.toString();
+ EXPECT_EQ(OK, writer.writeToValue(&value)) << writer.toString();
+ status_t reply = 0;
+ uint32_t replySize = sizeof(reply);
+ EXPECT_NE(OK, interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, &reply));
+ EXPECT_EQ(replySize, sizeof(reply));
+ EXPECT_NE(OK, reply);
+ }
+}
+
+// TODO: rethink about this test case to make it general for all types of effects
+TEST(libAudioHalTest, aecInitSetAndGet) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ std::vector<effect_descriptor_t> descs;
+ EXPECT_EQ(OK, factory->getDescriptors(&FX_IID_AEC_, &descs));
+ static constexpr uint32_t delayValue = 0x20;
+ for (const auto& desc : descs) {
+ ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(FX_IID_AEC_)));
+ sp<EffectHalInterface> interface;
+ EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+ 1 /* deviceId */, &interface));
+ EXPECT_NE(nullptr, interface);
+ effect_param_t* param = (effect_param_t*)testDataBuffer;
+ uint32_t type = AEC_PARAM_ECHO_DELAY, value = delayValue;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ //EXPECT_EQ(1, 0) << param->psize << " " << param->vsize;
+ EffectParamWriter writer(*param);
+ EXPECT_EQ(OK, writer.writeToParameter(&type)) << writer.toString();
+ EXPECT_EQ(OK, writer.writeToValue(&value)) << writer.toString();
+ status_t reply = 0;
+ uint32_t replySize = sizeof(reply);
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &replySize, &reply));
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, &reply));
+ EXPECT_EQ(replySize, sizeof(reply));
+ EXPECT_EQ(OK, reply);
+
+ effect_param_t* responseParam = (effect_param_t*)testResponseBuffer;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ EffectParamWriter response(*param);
+ EXPECT_EQ(OK, response.writeToParameter(&type)) << response.toString();
+ replySize = response.getTotalSize();
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_GET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, responseParam));
+ EXPECT_EQ(replySize, response.getTotalSize());
+ EXPECT_EQ(OK, response.readFromValue(&value));
+ EXPECT_EQ(delayValue, value);
+ }
+}
+
// TODO: b/263986405 Add multi-thread testing
} // namespace android
diff --git a/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
index ef9c4f8..fdd327f 100644
--- a/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
+++ b/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
@@ -337,6 +337,8 @@
// Should have created new transcoder.
EXPECT_EQ(mTranscoder->getGeneration(), generation);
EXPECT_EQ(mTranscoder.use_count(), 2);
+ // b/240537336: Allow extra time to finish onError call
+ sleep(1);
}
void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess) {
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index bac4b22..2b5bacf 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -183,11 +183,11 @@
AMediaCodecCryptoInfo_setPattern; # introduced=24
AMediaCodec_configure;
AMediaCodec_createCodecByName;
- AMediaCodec_createCodecByNameForClient; # apex # introduced=31
+ AMediaCodec_createCodecByNameForClient; # systemapi # introduced=31
AMediaCodec_createDecoderByType;
- AMediaCodec_createDecoderByTypeForClient; # apex # introduced=31
+ AMediaCodec_createDecoderByTypeForClient; # systemapi # introduced=31
AMediaCodec_createEncoderByType;
- AMediaCodec_createEncoderByTypeForClient; # apex # introduced=31
+ AMediaCodec_createEncoderByTypeForClient; # systemapi # introduced=31
AMediaCodec_delete;
AMediaCodec_dequeueInputBuffer;
AMediaCodec_dequeueOutputBuffer;
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 4b6d5f2..43ef311 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -24,7 +24,7 @@
defaults: [
"latest_android_media_audio_common_types_cpp_shared",
- "latest_android_hardware_audio_sounddose_ndk_shared",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
],
srcs: [
@@ -111,7 +111,7 @@
export_shared_lib_headers: [
"libpermission",
- "android.hardware.audio.sounddose-V1-ndk",
+ "android.hardware.audio.core.sounddose-V1-ndk",
],
cflags: [
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f8d7c70..7bb0fd3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2573,7 +2573,7 @@
ALOGE("loadHwModule() error %d loading module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
- if (!mMelReporter->activateHalSoundDoseComputation(name)) {
+ if (!mMelReporter->activateHalSoundDoseComputation(name, dev)) {
ALOGW("loadHwModule() sound dose reporting is not available");
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 100d8c7..e8133d9 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -33,7 +33,6 @@
#include <sys/types.h>
#include <limits.h>
-#include <aidl/android/hardware/audio/sounddose/ISoundDoseFactory.h>
#include <android/media/BnAudioTrack.h>
#include <android/media/IAudioFlingerClient.h>
#include <android/media/IAudioTrackCallback.h>
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 5ac7cde..bc5b5db 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -22,38 +22,37 @@
#include <android/media/ISoundDoseCallback.h>
#include <audio_utils/power.h>
-#include <android/binder_manager.h>
#include <utils/Log.h>
using aidl::android::hardware::audio::core::sounddose::ISoundDose;
-using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
namespace android {
-constexpr std::string_view kSoundDoseInterfaceModule = "/default";
-
-bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::string& module) {
+bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::string& module,
+ const sp<DeviceHalInterface>& device) {
if (mSoundDoseManager->forceUseFrameworkMel()) {
ALOGD("%s: Forcing use of internal MEL computation.", __func__);
activateInternalSoundDoseComputation();
return false;
}
- if (mSoundDoseFactory == nullptr) {
- ALOGW("%s: sound dose HAL reporting not available", __func__);
- activateInternalSoundDoseComputation();
- return false;
- }
-
- std::shared_ptr<ISoundDose> soundDoseInterface;
- auto result = mSoundDoseFactory->getSoundDose(module, &soundDoseInterface);
- if (!result.isOk()) {
- ALOGW("%s: HAL cannot provide sound dose interface for module %s",
+ ndk::SpAIBinder soundDoseBinder;
+ if (device->getSoundDoseInterface(module, &soundDoseBinder) != OK) {
+ ALOGW("%s: HAL cannot provide sound dose interface for module %s, use internal MEL",
__func__, module.c_str());
activateInternalSoundDoseComputation();
return false;
}
+ if (soundDoseBinder == nullptr) {
+ ALOGW("%s: HAL doesn't implement a sound dose interface for module %s, use internal MEL",
+ __func__, module.c_str());
+ activateInternalSoundDoseComputation();
+ return false;
+ }
+
+ std::shared_ptr<ISoundDose> soundDoseInterface = ISoundDose::fromBinder(soundDoseBinder);
+
if (!mSoundDoseManager->setHalSoundDoseInterface(soundDoseInterface)) {
ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str());
activateInternalSoundDoseComputation();
@@ -79,16 +78,6 @@
void AudioFlinger::MelReporter::onFirstRef() {
mAudioFlinger.mPatchCommandThread->addListener(this);
-
- std::string interface =
- std::string(ISoundDoseFactory::descriptor) + kSoundDoseInterfaceModule.data();
- AIBinder* binder = AServiceManager_checkService(interface.c_str());
- if (binder == nullptr) {
- ALOGW("%s service %s doesn't exist", __func__, interface.c_str());
- return;
- }
-
- mSoundDoseFactory = ISoundDoseFactory::fromBinder(ndk::SpAIBinder(binder));
}
bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index acbc8ed..5e7f0cc 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -45,13 +45,16 @@
* does not support the sound dose interface for this module, the internal MEL
* calculation will be use.
*
- * For now support internal MelReporting only if the sound dose standalone HAL
- * is not implemented
+ * <p>If the device is using the audio AIDL HAL then this method will try to get the sound
+ * dose interface from IModule#getSoundDose(). Otherwise, if the legacy audio HIDL HAL is used
+ * this method will be looking for the standalone sound dose implementation. It falls back to
+ * the internal MEL computation if no valid sound dose interface can be retrieved.
*
- * @return true if the MEL reporting will be done from the sound dose HAL
- * interface
+ * @return true if the MEL reporting will be done from any sound dose HAL interface
+ * implementation, false otherwise.
*/
- bool activateHalSoundDoseComputation(const std::string& module);
+ bool activateHalSoundDoseComputation(const std::string& module,
+ const sp<DeviceHalInterface>& device);
/**
* Activates the MEL reporting from internal framework values. These are used
@@ -78,8 +81,6 @@
audio_port_handle_t deviceId);
AudioFlinger& mAudioFlinger; // does not own the object
- std::shared_ptr<::aidl::android::hardware::audio::sounddose::ISoundDoseFactory>
- mSoundDoseFactory;
sp<SoundDoseManager> mSoundDoseManager;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f850ede..d274e41 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3644,9 +3644,9 @@
if (result != OK) return result;
#ifdef FLOAT_EFFECT_CHAIN
- buffer = halInBuffer->audioBuffer()->f32;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
#else
- buffer = halInBuffer->audioBuffer()->s16;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
#endif
ALOGV("addEffectChain_l() creating new input buffer %p session %d",
buffer, session);
@@ -3675,7 +3675,8 @@
halOutBuffer = halInBuffer;
ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
if (!audio_is_global_session(session)) {
- buffer = reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData());
+ buffer = halInBuffer ? reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData())
+ : buffer;
// Only one effect chain can be present in direct output thread and it uses
// the sink buffer as input
if (mType != DIRECT) {
@@ -3687,9 +3688,9 @@
&halInBuffer);
if (result != OK) return result;
#ifdef FLOAT_EFFECT_CHAIN
- buffer = halInBuffer->audioBuffer()->f32;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
#else
- buffer = halInBuffer->audioBuffer()->s16;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
#endif
ALOGV("addEffectChain_l() creating new input buffer %p session %d",
buffer, session);
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index df6eb5b..ad65612 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -116,23 +116,26 @@
ALOGV("%s", __func__);
std::lock_guard _l(mLock);
- mRs2Value = rs2Value;
if (mHalSoundDose != nullptr) {
// using the HAL sound dose interface
- if (!mHalSoundDose->setOutputRs2(mRs2Value).isOk()) {
- ALOGE("%s: Cannot set RS2 value for momentary exposure %f", __func__, mRs2Value);
+ if (!mHalSoundDose->setOutputRs2(rs2Value).isOk()) {
+ ALOGE("%s: Cannot set RS2 value for momentary exposure %f", __func__, rs2Value);
+ return;
}
+ mRs2Value = rs2Value;
return;
}
for (auto& streamProcessor : mActiveProcessors) {
sp<audio_utils::MelProcessor> processor = streamProcessor.second.promote();
if (processor != nullptr) {
- status_t result = processor->setOutputRs2(mRs2Value);
+ status_t result = processor->setOutputRs2(rs2Value);
if (result != NO_ERROR) {
- ALOGW("%s: could not set RS2 value %f for stream %d", __func__, mRs2Value,
+ ALOGW("%s: could not set RS2 value %f for stream %d", __func__, rs2Value,
streamProcessor.first);
+ return;
}
+ mRs2Value = rs2Value;
}
}
}
diff --git a/services/audiopolicy/engine/common/include/VolumeGroup.h b/services/audiopolicy/engine/common/include/VolumeGroup.h
index 5378f64..f40ab1c 100644
--- a/services/audiopolicy/engine/common/include/VolumeGroup.h
+++ b/services/audiopolicy/engine/common/include/VolumeGroup.h
@@ -39,7 +39,7 @@
VolumeCurves *getVolumeCurves() { return &mGroupVolumeCurves; }
void addSupportedAttributes(const audio_attributes_t &attr);
- AttributesVector getSupportedAttributes() const { return mGroupVolumeCurves.getAttributes(); }
+ AttributesVector getSupportedAttributes() const;
void addSupportedStream(audio_stream_type_t stream);
StreamTypeVector getStreamTypes() const { return mGroupVolumeCurves.getStreamTypes(); }
diff --git a/services/audiopolicy/engine/common/src/VolumeGroup.cpp b/services/audiopolicy/engine/common/src/VolumeGroup.cpp
index e189807..f5ffbba 100644
--- a/services/audiopolicy/engine/common/src/VolumeGroup.cpp
+++ b/services/audiopolicy/engine/common/src/VolumeGroup.cpp
@@ -37,6 +37,17 @@
{
}
+// Used for introspection, e.g. JAVA
+AttributesVector VolumeGroup::getSupportedAttributes() const
+{
+ AttributesVector supportedAttributes = {};
+ for (auto &aa : mGroupVolumeCurves.getAttributes()) {
+ aa.source = AUDIO_SOURCE_INVALID;
+ supportedAttributes.push_back(aa);
+ }
+ return supportedAttributes;
+}
+
void VolumeGroup::dump(String8 *dst, int spaces) const
{
dst->appendFormat("\n%*s-%s (id: %d)\n", spaces, "", mName.c_str(), mId);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 1774600..35411f9 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1534,7 +1534,7 @@
numPortsReq = std::min(numPortsReq, num_ports);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl),
- legacy2aidl_audio_port_v7_AudioPort)));
+ legacy2aidl_audio_port_v7_AudioPortFw)));
count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_ports));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
return Status::ok();
@@ -1549,7 +1549,7 @@
}
AutoCallerClear acc;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
- *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPort(port));
+ *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port));
return Status::ok();
}
@@ -1557,7 +1557,7 @@
int32_t handleAidl,
int32_t* _aidl_return) {
audio_patch patch = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPatch_audio_patch(patchAidl));
+ aidl2legacy_AudioPatchFw_audio_patch(patchAidl));
audio_patch_handle_t handle = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_port_handle_t(handleAidl));
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(AudioValidator::validateAudioPatch(patch)));
@@ -1616,7 +1616,7 @@
numPatchesReq = std::min(numPatchesReq, num_patches);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(patches.get(), patches.get() + numPatchesReq,
- std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatch)));
+ std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw)));
count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_patches));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
return Status::ok();
@@ -1625,7 +1625,7 @@
Status AudioPolicyService::setAudioPortConfig(const media::AudioPortConfigFw& configAidl)
{
audio_port_config config = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPortConfig_audio_port_config(configAidl));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(configAidl));
RETURN_IF_BINDER_ERROR(
binderStatusFromStatusT(AudioValidator::validateAudioPortConfig(config)));
@@ -1799,7 +1799,7 @@
const media::AudioAttributesInternal& attributesAidl,
int32_t* _aidl_return) {
audio_port_config source = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPortConfig_audio_port_config(sourceAidl));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(sourceAidl));
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioAttributesInternal_audio_attributes_t(attributesAidl));
audio_port_handle_t portId;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 8b8dbe8..e652546 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -1615,7 +1615,7 @@
return OK;
}
-void HeicCompositeStream::initCopyRowFunction(int32_t width)
+void HeicCompositeStream::initCopyRowFunction([[maybe_unused]] int32_t width)
{
using namespace libyuv;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 4555838..f06ed1c 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -359,6 +359,29 @@
}
template <typename TClientBase>
+void Camera2ClientBase<TClientBase>::notifyPhysicalCameraChange(const std::string &physicalId) {
+ // We're only interested in this notification if overrideToPortrait is turned on.
+ if (!TClientBase::mOverrideToPortrait) {
+ return;
+ }
+
+ String8 physicalId8(physicalId.c_str());
+ auto physicalCameraMetadata = mDevice->infoPhysical(physicalId8);
+ auto orientationEntry = physicalCameraMetadata.find(ANDROID_SENSOR_ORIENTATION);
+
+ if (orientationEntry.count == 1) {
+ int orientation = orientationEntry.data.i32[0];
+ int rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_NONE;
+
+ if (orientation == 0 || orientation == 180) {
+ rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_90;
+ }
+
+ static_cast<TClientBase *>(this)->setRotateAndCropOverride(rotateAndCropMode);
+ }
+}
+
+template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::notifyActive(float maxPreviewFps) {
if (!mDeviceActive) {
status_t res = TClientBase::startCameraStreamingOps();
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 89347eb..5cf3033 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -77,6 +77,7 @@
virtual void notifyError(int32_t errorCode,
const CaptureResultExtras& resultExtras);
+ virtual void notifyPhysicalCameraChange(const std::string &physicalId) override;
// Returns errors on app ops permission failures
virtual status_t notifyActive(float maxPreviewFps);
virtual void notifyIdle(int64_t /*requestCount*/, int64_t /*resultErrorCount*/,
diff --git a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
index f39b92a..63abcf0 100644
--- a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
+++ b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
@@ -40,6 +40,10 @@
// Required for API 1 and 2
virtual void notifyError(int32_t errorCode,
const CaptureResultExtras &resultExtras) = 0;
+
+ // Optional for API 1 and 2
+ virtual void notifyPhysicalCameraChange(const std::string &/*physicalId*/) {}
+
// May return an error since it checks appops
virtual status_t notifyActive(float maxPreviewFps) = 0;
virtual void notifyIdle(int64_t requestCount, int64_t resultError, bool deviceError,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 26c9794..4047c13 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -96,7 +96,8 @@
mLastTemplateId(-1),
mNeedFixupMonochromeTags(false),
mOverrideForPerfClass(overrideForPerfClass),
- mOverrideToPortrait(overrideToPortrait)
+ mOverrideToPortrait(overrideToPortrait),
+ mActivePhysicalId("")
{
ATRACE_CALL();
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 8752312..21cf6fc 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1413,6 +1413,9 @@
// app compatibility reasons.
bool mOverrideToPortrait;
+ // Current active physical id of the logical multi-camera, if any
+ std::string mActivePhysicalId;
+
// The current minimum expected frame duration based on AE_TARGET_FPS_RANGE
nsecs_t mMinExpectedDuration = 0;
// Whether the camera device runs at fixed frame rate based on AE_MODE and
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index a441638..738c314 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -623,27 +623,35 @@
if (result->partial_result != 0)
request.resultExtras.partialResultCount = result->partial_result;
- if ((result->result != nullptr) && !states.legacyClient && !states.overrideToPortrait) {
+ if (result->result != nullptr) {
camera_metadata_ro_entry entry;
auto ret = find_camera_metadata_ro_entry(result->result,
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID, &entry);
if ((ret == OK) && (entry.count > 0)) {
std::string physicalId(reinterpret_cast<const char *>(entry.data.u8));
- auto deviceInfo = states.physicalDeviceInfoMap.find(physicalId);
- if (deviceInfo != states.physicalDeviceInfoMap.end()) {
- auto orientation = deviceInfo->second.find(ANDROID_SENSOR_ORIENTATION);
- if (orientation.count > 0) {
- ret = CameraUtils::getRotationTransform(deviceInfo->second,
- OutputConfiguration::MIRROR_MODE_AUTO, &request.transform);
- if (ret != OK) {
- ALOGE("%s: Failed to calculate current stream transformation: %s (%d)",
- __FUNCTION__, strerror(-ret), ret);
+ if (!states.activePhysicalId.empty() && physicalId != states.activePhysicalId) {
+ states.listener->notifyPhysicalCameraChange(physicalId);
+ }
+ states.activePhysicalId = physicalId;
+
+ if (!states.legacyClient && !states.overrideToPortrait) {
+ auto deviceInfo = states.physicalDeviceInfoMap.find(physicalId);
+ if (deviceInfo != states.physicalDeviceInfoMap.end()) {
+ auto orientation = deviceInfo->second.find(ANDROID_SENSOR_ORIENTATION);
+ if (orientation.count > 0) {
+ ret = CameraUtils::getRotationTransform(deviceInfo->second,
+ OutputConfiguration::MIRROR_MODE_AUTO, &request.transform);
+ if (ret != OK) {
+ ALOGE("%s: Failed to calculate current stream transformation: %s "
+ "(%d)", __FUNCTION__, strerror(-ret), ret);
+ }
+ } else {
+ ALOGE("%s: Physical device orientation absent!", __FUNCTION__);
}
} else {
- ALOGE("%s: Physical device orientation absent!", __FUNCTION__);
+ ALOGE("%s: Physical device not found in device info map found!",
+ __FUNCTION__);
}
- } else {
- ALOGE("%s: Physical device not found in device info map found!", __FUNCTION__);
}
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index 019c8a8..d5328c5 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -108,6 +108,7 @@
nsecs_t& minFrameDuration;
bool& isFixedFps;
bool overrideToPortrait;
+ std::string &activePhysicalId;
};
void processCaptureResult(CaptureOutputStates& states, const camera_capture_result *result);
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index 7eba57f..30f6d18 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -379,7 +379,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
*this, *(mInterface), mLegacyClient, mMinExpectedDuration, mIsFixedFps,
- mOverrideToPortrait}, mResultMetadataQueue
+ mOverrideToPortrait, mActivePhysicalId}, mResultMetadataQueue
};
for (const auto& result : results) {
@@ -421,7 +421,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
*this, *(mInterface), mLegacyClient, mMinExpectedDuration, mIsFixedFps,
- mOverrideToPortrait}, mResultMetadataQueue
+ mOverrideToPortrait, mActivePhysicalId}, mResultMetadataQueue
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
index 9ce0622..4b1fb1d 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
@@ -111,6 +111,7 @@
listener = mListener.promote();
}
+ std::string activePhysicalId(""); // Unused
AidlCaptureOutputStates states {
{mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
@@ -125,7 +126,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
*this, mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
- /*overrideToPortrait*/false}, mResultMetadataQueue
+ /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
};
std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -157,6 +158,7 @@
listener = mListener.promote();
}
+ std::string activePhysicalId(""); // Unused
AidlCaptureOutputStates states {
{mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
@@ -171,7 +173,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
*this, mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
- /*overrideToPortrait*/false}, mResultMetadataQueue
+ /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 44c60cf..382b287 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -365,8 +365,8 @@
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
- *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait},
- mResultMetadataQueue
+ *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait,
+ mActivePhysicalId}, mResultMetadataQueue
};
//HidlCaptureOutputStates hidlStates {
@@ -428,8 +428,8 @@
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
- *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait},
- mResultMetadataQueue
+ *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait,
+ mActivePhysicalId}, mResultMetadataQueue
};
for (const auto& result : results) {
@@ -476,8 +476,8 @@
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
- *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait},
- mResultMetadataQueue
+ *mInterface, mLegacyClient, mMinExpectedDuration, mIsFixedFps, mOverrideToPortrait,
+ mActivePhysicalId}, mResultMetadataQueue
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
index c7f8fa1..0a6a6f7 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
@@ -92,6 +92,7 @@
listener = mListener.promote();
}
+ std::string activePhysicalId("");
HidlCaptureOutputStates states {
{mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
@@ -106,7 +107,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
- /*overrideToPortrait*/false}, mResultMetadataQueue
+ /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
};
std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -133,6 +134,7 @@
hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
+ std::string activePhysicalId("");
HidlCaptureOutputStates states {
{mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
@@ -147,7 +149,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
- /*overrideToPortrait*/false}, mResultMetadataQueue
+ /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
};
std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -169,6 +171,7 @@
listener = mListener.promote();
}
+ std::string activePhysicalId("");
HidlCaptureOutputStates states {
{mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
@@ -183,7 +186,7 @@
mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
- /*overrideToPortrait*/false}, mResultMetadataQueue
+ /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index 3222950..a2f17c2 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -147,6 +147,9 @@
arm64: {
src: "seccomp_policy/mediacodec-arm64.policy",
},
+ riscv64: {
+ enabled: false,
+ },
x86: {
src: "seccomp_policy/mediacodec-x86.policy",
},
diff --git a/services/tuner/TunerHelper.cpp b/services/tuner/TunerHelper.cpp
index dc67110..a03386f 100644
--- a/services/tuner/TunerHelper.cpp
+++ b/services/tuner/TunerHelper.cpp
@@ -83,6 +83,22 @@
tunerRM->setFrontendInfoList(feInfos);
tunerRM->setLnbInfoList(lnbHandles);
}
+void TunerHelper::updateTunerResources(const vector<TunerFrontendInfo>& feInfos,
+ const vector<TunerDemuxInfo>& demuxInfos,
+ const vector<int32_t>& lnbHandles) {
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService("tv_tuner_resource_mgr"));
+ shared_ptr<ITunerResourceManager> tunerRM = ITunerResourceManager::fromBinder(binder);
+ if (tunerRM == nullptr) {
+ return;
+ }
+
+ updateTunerResources(feInfos, lnbHandles);
+
+ // for Tuner 2.0 and below, Demux resource is not really managed under TRM
+ if (demuxInfos.size() > 0) {
+ tunerRM->setDemuxInfoList(demuxInfos);
+ }
+}
// TODO: create a map between resource id and handles.
int TunerHelper::getResourceIdFromHandle(int resourceHandle, int /*type*/) {
diff --git a/services/tuner/TunerHelper.h b/services/tuner/TunerHelper.h
index 755df57..65a9b0b 100644
--- a/services/tuner/TunerHelper.h
+++ b/services/tuner/TunerHelper.h
@@ -17,9 +17,11 @@
#ifndef ANDROID_MEDIA_TUNERDVRHELPER_H
#define ANDROID_MEDIA_TUNERDVRHELPER_H
+#include <aidl/android/media/tv/tunerresourcemanager/TunerDemuxInfo.h>
#include <aidl/android/media/tv/tunerresourcemanager/TunerFrontendInfo.h>
#include <utils/String16.h>
+using ::aidl::android::media::tv::tunerresourcemanager::TunerDemuxInfo;
using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
using ::android::String16;
@@ -55,6 +57,10 @@
// TODO: update Demux, Descrambler.
static void updateTunerResources(const vector<TunerFrontendInfo>& feInfos,
const vector<int32_t>& lnbHandles);
+
+ static void updateTunerResources(const vector<TunerFrontendInfo>& feInfos,
+ const vector<TunerDemuxInfo>& demuxInfos,
+ const vector<int32_t>& lnbHandles);
// TODO: create a map between resource id and handles.
static int getResourceIdFromHandle(int resourceHandle, int type);
static int getResourceHandleFromId(int id, int resourceType);
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index d59d95f..e5bcf1f 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -82,18 +82,75 @@
return AServiceManager_addService(tunerService->asBinder().get(), getServiceName());
}
-::ndk::ScopedAStatus TunerService::openDemux(int32_t /* in_demuxHandle */,
+::ndk::ScopedAStatus TunerService::openDemux(int32_t in_demuxHandle,
shared_ptr<ITunerDemux>* _aidl_return) {
ALOGV("openDemux");
- vector<int32_t> id;
shared_ptr<IDemux> demux;
- auto status = mTuner->openDemux(&id, &demux);
- if (status.isOk()) {
- *_aidl_return =
- ::ndk::SharedRefBase::make<TunerDemux>(demux, id[0], this->ref<TunerService>());
+ bool fallBackToOpenDemux = false;
+ vector<int32_t> ids;
+
+ if (mTunerVersion <= TUNER_HAL_VERSION_2_0) {
+ fallBackToOpenDemux = true;
+ } else {
+ mTuner->getDemuxIds(&ids);
+ if (ids.size() == 0) {
+ fallBackToOpenDemux = true;
+ }
}
- return status;
+ if (fallBackToOpenDemux) {
+ auto status = mTuner->openDemux(&ids, &demux);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ } else {
+ int id = TunerHelper::getResourceIdFromHandle(in_demuxHandle, DEMUX);
+ auto status = mTuner->openDemuxById(id, &demux);
+ if (status.isOk()) {
+ *_aidl_return =
+ ::ndk::SharedRefBase::make<TunerDemux>(demux, id, this->ref<TunerService>());
+ }
+ return status;
+ }
+}
+
+::ndk::ScopedAStatus TunerService::getDemuxInfo(int32_t in_demuxHandle, DemuxInfo* _aidl_return) {
+ if (mTunerVersion <= TUNER_HAL_VERSION_2_0) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+ int id = TunerHelper::getResourceIdFromHandle(in_demuxHandle, DEMUX);
+ return mTuner->getDemuxInfo(id, _aidl_return);
+}
+
+::ndk::ScopedAStatus TunerService::getDemuxInfoList(vector<DemuxInfo>* _aidl_return) {
+ if (mTunerVersion <= TUNER_HAL_VERSION_2_0) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+ vector<DemuxInfo> demuxInfoList;
+ vector<int32_t> ids;
+ auto status = mTuner->getDemuxIds(&ids);
+ if (!status.isOk()) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ for (int i = 0; i < ids.size(); i++) {
+ DemuxInfo demuxInfo;
+ auto res = mTuner->getDemuxInfo(ids[i], &demuxInfo);
+ if (!res.isOk()) {
+ continue;
+ }
+ demuxInfoList.push_back(demuxInfo);
+ }
+
+ if (demuxInfoList.size() > 0) {
+ *_aidl_return = demuxInfoList;
+ return ::ndk::ScopedAStatus::ok();
+ } else {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
}
::ndk::ScopedAStatus TunerService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
@@ -230,7 +287,9 @@
}
void TunerService::updateTunerResources() {
- TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
+ TunerHelper::updateTunerResources(getTRMFrontendInfos(),
+ getTRMDemuxInfos(),
+ getTRMLnbHandles());
}
vector<TunerFrontendInfo> TunerService::getTRMFrontendInfos() {
@@ -258,6 +317,32 @@
return infos;
}
+vector<TunerDemuxInfo> TunerService::getTRMDemuxInfos() {
+ vector<TunerDemuxInfo> infos;
+ vector<int32_t> ids;
+
+ if (mTunerVersion <= TUNER_HAL_VERSION_2_0) {
+ return infos;
+ }
+
+ auto status = mTuner->getDemuxIds(&ids);
+ if (!status.isOk()) {
+ return infos;
+ }
+
+ for (int i = 0; i < ids.size(); i++) {
+ DemuxInfo demuxInfo;
+ mTuner->getDemuxInfo(ids[i], &demuxInfo);
+ TunerDemuxInfo tunerDemuxInfo{
+ .handle = TunerHelper::getResourceHandleFromId((int)ids[i], DEMUX),
+ .filterTypes = static_cast<int>(demuxInfo.filterTypes)
+ };
+ infos.push_back(tunerDemuxInfo);
+ }
+
+ return infos;
+}
+
vector<int32_t> TunerService::getTRMLnbHandles() {
vector<int32_t> lnbHandles;
if (mTuner != nullptr) {
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 517df4a..190ccd4 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -32,6 +32,7 @@
using ::aidl::android::hardware::tv::tuner::DemuxCapabilities;
using ::aidl::android::hardware::tv::tuner::DemuxFilterEvent;
using ::aidl::android::hardware::tv::tuner::DemuxFilterStatus;
+using ::aidl::android::hardware::tv::tuner::DemuxInfo;
using ::aidl::android::hardware::tv::tuner::FrontendInfo;
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::ITuner;
@@ -71,6 +72,8 @@
::ndk::ScopedAStatus openDemux(int32_t in_demuxHandle,
shared_ptr<ITunerDemux>* _aidl_return) override;
::ndk::ScopedAStatus getDemuxCaps(DemuxCapabilities* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxInfo(int32_t in_demuxHandle, DemuxInfo* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxInfoList(vector<DemuxInfo>* _aidl_return) override;
::ndk::ScopedAStatus openDescrambler(int32_t in_descramblerHandle,
shared_ptr<ITunerDescrambler>* _aidl_return) override;
::ndk::ScopedAStatus getTunerHalVersion(int32_t* _aidl_return) override;
@@ -90,6 +93,7 @@
private:
void updateTunerResources();
vector<TunerFrontendInfo> getTRMFrontendInfos();
+ vector<TunerDemuxInfo> getTRMDemuxInfos();
vector<int32_t> getTRMLnbHandles();
shared_ptr<ITuner> mTuner;
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index 8d285e3..932133e 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -17,6 +17,7 @@
package android.media.tv.tuner;
import android.hardware.tv.tuner.DemuxCapabilities;
+import android.hardware.tv.tuner.DemuxInfo;
import android.hardware.tv.tuner.FrontendInfo;
import android.hardware.tv.tuner.FrontendType;
import android.media.tv.tuner.ITunerDemux;
@@ -77,6 +78,21 @@
ITunerDemux openDemux(in int demuxHandle);
/**
+ * Retrieve the supported filter main types
+ *
+ * @param demuxHandle the handle of the demux to query demux info for
+ * @return the demux info
+ */
+ DemuxInfo getDemuxInfo(in int demuxHandle);
+
+ /**
+ * Retrieve the list of demux info for all the demuxes on the system
+ *
+ * @return the list of DemuxInfo
+ */
+ DemuxInfo[] getDemuxInfoList();
+
+ /**
* Retrieve the Tuner Demux capabilities.
*
* @return the demux’s capabilities.
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index 52005c2..6bc36be 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -123,6 +123,20 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
+::ndk::ScopedAStatus TunerHidlService::getDemuxInfo(int32_t /* in_demuxHandle */,
+ DemuxInfo* /* _aidl_return */) {
+ ALOGE("getDemuxInfo is not supported");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(HidlResult::UNAVAILABLE));
+}
+
+::ndk::ScopedAStatus TunerHidlService::getDemuxInfoList(
+ vector<DemuxInfo>* /* _aidle_return */) {
+ ALOGE("getDemuxInfoList is not supported");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(HidlResult::UNAVAILABLE));
+}
+
::ndk::ScopedAStatus TunerHidlService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
ALOGV("getDemuxCaps");
HidlResult res;
diff --git a/services/tuner/hidl/TunerHidlService.h b/services/tuner/hidl/TunerHidlService.h
index 872aefc..526c5e6 100644
--- a/services/tuner/hidl/TunerHidlService.h
+++ b/services/tuner/hidl/TunerHidlService.h
@@ -33,6 +33,7 @@
using ::aidl::android::hardware::tv::tuner::DemuxCapabilities;
using ::aidl::android::hardware::tv::tuner::DemuxFilterEvent;
using ::aidl::android::hardware::tv::tuner::DemuxFilterStatus;
+using ::aidl::android::hardware::tv::tuner::DemuxInfo;
using ::aidl::android::hardware::tv::tuner::FrontendInfo;
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::media::tv::tuner::ITunerDemux;
@@ -83,6 +84,8 @@
::ndk::ScopedAStatus openDemux(int32_t in_demuxHandle,
shared_ptr<ITunerDemux>* _aidl_return) override;
::ndk::ScopedAStatus getDemuxCaps(DemuxCapabilities* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxInfo(int32_t in_demuxHandle, DemuxInfo* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxInfoList(vector<DemuxInfo>* _aidl_return) override;
::ndk::ScopedAStatus openDescrambler(int32_t in_descramblerHandle,
shared_ptr<ITunerDescrambler>* _aidl_return) override;
::ndk::ScopedAStatus getTunerHalVersion(int32_t* _aidl_return) override;