Merge "WriterTest: remove output file after test completes"
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
index 8476f82..8493e30 100644
--- a/media/libeffects/config/Android.bp
+++ b/media/libeffects/config/Android.bp
@@ -15,6 +15,7 @@
"libtinyxml2",
"libutils",
"libmedia_helper",
+ "libcutils",
],
header_libs: ["libaudio_system_headers"],
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index ef10e0d..57d4dd7 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -35,11 +35,6 @@
/** Default path of effect configuration file. Relative to DEFAULT_LOCATIONS. */
constexpr const char* DEFAULT_NAME = "audio_effects.xml";
-/** Default path of effect configuration file.
- * The /vendor partition is the recommended one, the others are deprecated.
- */
-constexpr const char* DEFAULT_LOCATIONS[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-
/** Directories where the effect libraries will be search for. */
constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
#ifdef __LP64__
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 85fbf11..26eaaf8 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -27,6 +27,7 @@
#include <media/EffectsConfig.h>
#include <media/TypeConverter.h>
+#include <system/audio_config.h>
using namespace tinyxml2;
@@ -338,7 +339,7 @@
return parseWithPath(path);
}
- for (const std::string& location : DEFAULT_LOCATIONS) {
+ for (const std::string& location : audio_get_configuration_paths()) {
std::string defaultPath = location + '/' + DEFAULT_NAME;
if (access(defaultPath.c_str(), R_OK) != 0) {
continue;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 778ee44..b56ea56 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -282,11 +282,13 @@
"bionic_libc_platform_headers",
"libstagefright_headers",
"media_ndk_headers",
+ "jni_headers",
],
export_header_lib_headers: [
"libstagefright_headers",
"media_ndk_headers",
+ "jni_headers",
],
shared_libs: [
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
new file mode 100644
index 0000000..b28a7bc
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __AVC_UTILS_TEST_ENVIRONMENT_H__
+#define __AVC_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class AVCUtilsTestEnvironment : public::testing::Environment {
+ public:
+ AVCUtilsTestEnvironment() : res("/data/local/tmp/") {}
+
+ // Parses the command line arguments
+ int initFromOptions(int argc, char **argv);
+
+ void setRes(const char *_res) { res = _res; }
+
+ const string getRes() const { return res; }
+
+ private:
+ string res;
+};
+
+int AVCUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
+ static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "P:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'P': {
+ setRes(optarg);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-P, --path: Resource files directory location\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+}
+
+#endif // __AVC_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
new file mode 100644
index 0000000..77a8599
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AVCUtilsUnitTest"
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include "media/stagefright/foundation/ABitReader.h"
+#include "media/stagefright/foundation/avc_utils.h"
+
+#include "AVCUtilsTestEnvironment.h"
+
+constexpr size_t kSmallBufferSize = 2;
+constexpr uint8_t kSPSmask = 0x1f;
+constexpr uint8_t kSPSStartCode = 0x07;
+constexpr uint8_t kConfigVersion = 0x01;
+
+using namespace android;
+
+static AVCUtilsTestEnvironment *gEnv = nullptr;
+
+class MpegAudioUnitTest
+ : public ::testing::TestWithParam<
+ tuple</*audioHeader*/ uint32_t, /*frameSize*/ int32_t, /*sampleRate*/ int32_t,
+ /*numChannels*/ int32_t, /*bitRate*/ int32_t, /*numSamples*/ int32_t>> {};
+
+class VOLDimensionTest
+ : public ::testing::TestWithParam<
+ tuple</*fileName*/ string, /*volWidth*/ int32_t, /*volHeight*/ int32_t>> {};
+
+class AVCUtils {
+ public:
+ bool SetUpAVCUtils(string fileName, string infoFileName) {
+ mInputFile = gEnv->getRes() + fileName;
+ mInputFileStream.open(mInputFile, ifstream::in);
+ if (!mInputFileStream.is_open()) return false;
+
+ mInfoFile = gEnv->getRes() + infoFileName;
+ mInfoFileStream.open(mInfoFile, ifstream::in);
+ if (!mInputFileStream.is_open()) return false;
+ return true;
+ }
+
+ ~AVCUtils() {
+ if (mInputFileStream.is_open()) mInputFileStream.close();
+ if (mInfoFileStream.is_open()) mInfoFileStream.close();
+ }
+
+ string mInputFile;
+ string mInfoFile;
+
+ ifstream mInputFileStream;
+ ifstream mInfoFileStream;
+};
+
+class AVCDimensionTest
+ : public AVCUtils,
+ public ::testing::TestWithParam<
+ tuple</*fileName*/ string, /*infoFileName*/ string,
+ /*avcWidth*/ size_t, /*avcHeight*/ size_t, /*numberOfNALUnits*/ int32_t>> {
+ public:
+ virtual void SetUp() override {
+ tuple<string, string, size_t, size_t, size_t> params = GetParam();
+ string fileName = get<0>(params);
+ string infoFileName = get<1>(params);
+ AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+
+ mFrameWidth = get<2>(params);
+ mFrameHeight = get<3>(params);
+ mNalUnitsExpected = get<4>(params);
+ }
+
+ size_t mFrameWidth;
+ size_t mFrameHeight;
+ int32_t mNalUnitsExpected;
+};
+
+class AvccBoxTest : public AVCDimensionTest {
+ public:
+ virtual void SetUp() override { AVCDimensionTest::SetUp(); }
+};
+
+class AVCFrameTest
+ : public AVCUtils,
+ public ::testing::TestWithParam<pair</*fileName*/ string, /*infoFileName*/ string>> {
+ public:
+ virtual void SetUp() override {
+ string fileName = GetParam().first;
+ string infoFileName = GetParam().second;
+ AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+ }
+};
+
+TEST_P(MpegAudioUnitTest, AudioProfileTest) {
+ tuple<uint32_t, size_t, int, int, int, int> params = GetParam();
+ uint32_t header = get<0>(params);
+
+ size_t audioFrameSize = get<1>(params);
+ int audioSampleRate = get<2>(params);
+ int audioNumChannels = get<3>(params);
+ int audioBitRate = get<4>(params);
+ int audioNumSamples = get<5>(params);
+
+ size_t frameSize = 0;
+ int sampleRate = 0;
+ int numChannels = 0;
+ int bitRate = 0;
+ int numSamples = 0;
+
+ bool status = GetMPEGAudioFrameSize(header, &frameSize, &sampleRate, &numChannels, &bitRate,
+ &numSamples);
+ ASSERT_TRUE(status) << "Failed to get Audio properties";
+
+ ASSERT_EQ(frameSize, audioFrameSize) << "Wrong frame size found";
+
+ ASSERT_EQ(sampleRate, audioSampleRate) << "Wrong sample rate found";
+
+ ASSERT_EQ(numChannels, audioNumChannels) << "Wrong number of channels found";
+
+ ASSERT_EQ(bitRate, audioBitRate) << "Wrong bit rate found";
+
+ ASSERT_EQ(numSamples, audioNumSamples) << "Wrong number of samples found";
+}
+
+TEST_P(VOLDimensionTest, DimensionTest) {
+ tuple<string, int32_t, int32_t> params = GetParam();
+ string inputFile = gEnv->getRes() + get<0>(params);
+ ifstream inputFileStream;
+ inputFileStream.open(inputFile, ifstream::in);
+ ASSERT_TRUE(inputFileStream.is_open()) << "Failed to open: " << inputFile;
+
+ struct stat buf;
+ int8_t err = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+ size_t fileSize = buf.st_size;
+ ASSERT_NE(fileSize, 0) << "Invalid file size found";
+
+ const uint8_t *volBuffer = new uint8_t[fileSize];
+ ASSERT_NE(volBuffer, nullptr) << "Failed to allocate VOL buffer of size: " << fileSize;
+
+ inputFileStream.read((char *)(volBuffer), fileSize);
+ ASSERT_EQ(inputFileStream.gcount(), fileSize)
+ << "Failed to read complete file, bytes read: " << inputFileStream.gcount();
+
+ int32_t width = get<1>(params);
+ int32_t height = get<2>(params);
+ int32_t volWidth = -1;
+ int32_t volHeight = -1;
+
+ bool status = ExtractDimensionsFromVOLHeader(volBuffer, fileSize, &volWidth, &volHeight);
+ ASSERT_TRUE(status)
+ << "Failed to get VOL dimensions from function: ExtractDimensionsFromVOLHeader()";
+
+ ASSERT_EQ(volWidth, width) << "Expected width: " << width << "Found: " << volWidth;
+
+ ASSERT_EQ(volHeight, height) << "Expected height: " << height << "Found: " << volHeight;
+
+ delete[] volBuffer;
+}
+
+TEST_P(AVCDimensionTest, DimensionTest) {
+ int32_t numNalUnits = 0;
+ int32_t avcWidth = -1;
+ int32_t avcHeight = -1;
+ string line;
+ string type;
+ size_t chunkLength;
+ while (getline(mInfoFileStream, line)) {
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ const uint8_t *data = new uint8_t[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+ const uint8_t *nalStart;
+ size_t nalSize;
+
+ mInputFileStream.read((char *)data, chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ size_t smallBufferSize = kSmallBufferSize;
+ const uint8_t *sanityData = new uint8_t[smallBufferSize];
+ memcpy((void *)sanityData, (void *)data, smallBufferSize);
+
+ status_t result = getNextNALUnit(&sanityData, &smallBufferSize, &nalStart, &nalSize, true);
+ ASSERT_EQ(result, -EAGAIN) << "Invalid result found when wrong NAL unit passed";
+
+ while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+ numNalUnits++;
+ // Check if it's an SPS
+ if ((nalStart[0] & kSPSmask) != kSPSStartCode) continue;
+ ASSERT_TRUE(nalSize > 0) << "NAL unit size must be greater than 0";
+
+ sp<ABuffer> spsBuffer = new ABuffer(nalSize);
+ ASSERT_NE(spsBuffer, nullptr) << "ABuffer returned null for size: " << nalSize;
+
+ memcpy(spsBuffer->data(), nalStart, nalSize);
+ FindAVCDimensions(spsBuffer, &avcWidth, &avcHeight);
+ spsBuffer.clear();
+ ASSERT_EQ(avcWidth, mFrameWidth)
+ << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+ ASSERT_EQ(avcHeight, mFrameHeight)
+ << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+ }
+ delete[] data;
+ }
+ if (mNalUnitsExpected < 0) {
+ ASSERT_GT(numNalUnits, 0) << "Failed to find an NAL Unit";
+ } else {
+ ASSERT_EQ(numNalUnits, mNalUnitsExpected)
+ << "Expected number of NAL units: " << mNalUnitsExpected
+ << " found: " << numNalUnits;
+ }
+}
+
+TEST_P(AvccBoxTest, AvccBoxValidationTest) {
+ int32_t avcWidth = -1;
+ int32_t avcHeight = -1;
+ int32_t accessUnitLength = 0;
+ int32_t profile = -1;
+ int32_t level = -1;
+ string line;
+ string type;
+ size_t chunkLength;
+ while (getline(mInfoFileStream, line)) {
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength;
+
+ if (type.compare("SPS") && type.compare("PPS")) continue;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ accessUnitLength += chunkLength;
+
+ if (!type.compare("SPS")) {
+ const uint8_t *data = new uint8_t[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+ const uint8_t *nalStart;
+ size_t nalSize;
+
+ mInputFileStream.read((char *)data, (uint32_t)chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+ // Check if it's an SPS
+ ASSERT_TRUE(nalSize > 0 && (nalStart[0] & kSPSmask) == kSPSStartCode)
+ << "Failed to get SPS";
+
+ ASSERT_GE(nalSize, 4) << "SPS size must be greater than or equal to 4";
+
+ profile = nalStart[1];
+ level = nalStart[3];
+ }
+ delete[] data;
+ }
+ }
+ const uint8_t *accessUnitData = new uint8_t[accessUnitLength];
+ ASSERT_NE(accessUnitData, nullptr) << "Failed to create a buffer of size: " << accessUnitLength;
+
+ mInputFileStream.seekg(0, ios::beg);
+ mInputFileStream.read((char *)accessUnitData, accessUnitLength);
+ ASSERT_EQ(mInputFileStream.gcount(), accessUnitLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ sp<ABuffer> accessUnit = new ABuffer(accessUnitLength);
+ ASSERT_NE(accessUnit, nullptr)
+ << "Failed to create an android data buffer of size: " << accessUnitLength;
+
+ memcpy(accessUnit->data(), accessUnitData, accessUnitLength);
+ sp<ABuffer> csdDataBuffer = MakeAVCCodecSpecificData(accessUnit, &avcWidth, &avcHeight);
+ ASSERT_NE(csdDataBuffer, nullptr) << "No data returned from MakeAVCCodecSpecificData()";
+
+ ASSERT_EQ(avcWidth, mFrameWidth) << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+ ASSERT_EQ(avcHeight, mFrameHeight)
+ << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+
+ uint8_t *csdData = csdDataBuffer->data();
+ ASSERT_EQ(*csdData, kConfigVersion) << "Invalid configuration version";
+
+ ASSERT_GE(csdDataBuffer->size(), 4) << "CSD data size must be greater than or equal to 4";
+
+ ASSERT_EQ(*(csdData + 1), profile)
+ << "Expected AVC profile: " << profile << " found: " << *(csdData + 1);
+
+ ASSERT_EQ(*(csdData + 3), level)
+ << "Expected AVC level: " << level << " found: " << *(csdData + 3);
+ csdDataBuffer.clear();
+ delete[] accessUnitData;
+ accessUnit.clear();
+}
+
+TEST_P(AVCFrameTest, FrameTest) {
+ string line;
+ string type;
+ size_t chunkLength;
+ int32_t frameLayerID;
+ while (getline(mInfoFileStream, line)) {
+ uint32_t layerID = 0;
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength >> frameLayerID;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ char *data = new char[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to allocation data buffer of size: " << chunkLength;
+
+ mInputFileStream.read(data, chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ if (!type.compare("IDR")) {
+ bool isIDR = IsIDR((uint8_t *)data, chunkLength);
+ ASSERT_TRUE(isIDR);
+
+ layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+ } else if (!type.compare("P") || !type.compare("B")) {
+ sp<ABuffer> accessUnit = new ABuffer(chunkLength);
+ ASSERT_NE(accessUnit, nullptr) << "Unable to create access Unit";
+
+ memcpy(accessUnit->data(), data, chunkLength);
+ bool isReferenceFrame = IsAVCReferenceFrame(accessUnit);
+ ASSERT_TRUE(isReferenceFrame);
+
+ accessUnit.clear();
+ layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+ }
+ delete[] data;
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, MpegAudioUnitTest,
+ ::testing::Values(make_tuple(0xFFFB9204, 418, 44100, 2, 128, 1152),
+ make_tuple(0xFFFB7604, 289, 48000, 2, 96, 1152),
+ make_tuple(0xFFFE5604, 164, 48000, 2, 160, 384)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+ AVCUtilsTestAll, AVCDimensionTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+ make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+ "crowd_640x360p24f300_1000kbps_bp.info", 640, 360, 11),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14),
+ make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+ "crowd_3840x2160p60f300_68000kbps_bp.info", 3840, 2160, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+ AVCUtilsTestAll, AvccBoxTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, VOLDimensionTest,
+ ::testing::Values(make_tuple("volData_720_480", 720, 480),
+ make_tuple("volData_1280_720", 1280, 720),
+ make_tuple("volData_1920_1080", 1920, 1080)));
+
+// Info File contains the type, length and layer ID for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, AVCFrameTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info"),
+ make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+ "crowd_640x360p24f300_1000kbps_bp.info"),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info"),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info"),
+ make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+ "crowd_3840x2160p60f300_68000kbps_bp.info")));
+
+int main(int argc, char **argv) {
+ gEnv = new AVCUtilsTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ }
+ return status;
+}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/Android.bp b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
new file mode 100644
index 0000000..5d0e481
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "AVCUtilsUnitTest",
+ gtest: true,
+
+ srcs: [
+ "AVCUtilsUnitTest.cpp",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ ],
+
+ static_libs: [
+ "libstagefright",
+ "libstagefright_foundation",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright/foundation",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
new file mode 100644
index 0000000..6a088a8
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Test module config for AVC Utils unit tests">
+ <option name="test-suite-tag" value="AVCUtilsUnitTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="false" />
+ <option name="push" value="AVCUtilsUnitTest->/data/local/tmp/AVCUtilsUnitTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip?unzip=true"
+ value="/data/local/tmp/AVCUtilsUnitTest/" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="AVCUtilsUnitTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/AVCUtilsUnitTest/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/foundation/tests/AVCUtils/README.md b/media/libstagefright/foundation/tests/AVCUtils/README.md
new file mode 100644
index 0000000..609d72e
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### AVCUtils Test
+The AVC Utility Unit Test Suite validates the avc_utils librariy available in libstagefright/foundation.
+
+Run the following steps to build the test suite:
+```
+m AVCUtilsUnitTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push AVCUtilsUnitTest /data/local/tmp/
+```
+
+usage: AVCUtilsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/AVCUtilsUnitTest -P /data/local/tmp/AVCUtilsUnitTest/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest AVCUtilsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 24cad4d..ce91249 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -70,6 +70,7 @@
],
header_libs: [
+ "jni_headers",
"libmediadrm_headers",
],
@@ -97,6 +98,8 @@
"libmediandk_utils",
],
+ export_header_lib_headers: ["jni_headers"],
+
export_include_dirs: ["include"],
export_shared_lib_headers: [
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 7f5ed5e..5d22c24 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -31,9 +31,6 @@
/** Default path of audio policy usages configuration file. */
constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
using AttributesVector = std::vector<audio_attributes_t>;
using StreamVector = std::vector<audio_stream_type_t>;
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 7f8cdd9..4842cb2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -21,6 +21,7 @@
#include <cutils/properties.h>
#include <media/TypeConverter.h>
#include <media/convert.h>
+#include <system/audio_config.h>
#include <utils/Log.h>
#include <libxml/parser.h>
#include <libxml/xinclude.h>
@@ -693,9 +694,6 @@
return deserializeLegacyVolumeCollection(doc, cur, volumeGroups, nbSkippedElements);
}
-static const char *kConfigLocationList[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
- (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
static const int gApmXmlConfigFilePathMaxLength = 128;
static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
@@ -715,9 +713,9 @@
fileNames.push_back(apmXmlConfigFileName);
for (const char* fileName : fileNames) {
- for (int i = 0; i < kConfigLocationListSize; i++) {
+ for (const auto& path : audio_get_configuration_paths()) {
snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
- "%s/%s", kConfigLocationList[i], fileName);
+ "%s/%s", path.c_str(), fileName);
ret = parseLegacyVolumeFile(audioPolicyXmlConfigFile, volumeGroups);
if (ret == NO_ERROR) {
return ret;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index f30b6f1..2a2e449 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -48,6 +48,7 @@
#include <private/android_filesystem_config.h>
#include <soundtrigger/SoundTrigger.h>
#include <system/audio.h>
+#include <system/audio_config.h>
#include "AudioPolicyManager.h"
#include <Serializer.h>
#include "TypeConverter.h"
@@ -4312,12 +4313,6 @@
return mAudioPortGeneration++;
}
-// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
-static const char *kConfigLocationList[] =
- {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
- (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
-
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
std::vector<const char*> fileNames;
@@ -4339,9 +4334,9 @@
fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
for (const char* fileName : fileNames) {
- for (int i = 0; i < kConfigLocationListSize; i++) {
+ for (const auto& path : audio_get_configuration_paths()) {
snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
- "%s/%s", kConfigLocationList[i], fileName);
+ "%s/%s", path.c_str(), fileName);
ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile, &config);
if (ret == NO_ERROR) {
config.setSource(audioPolicyXmlConfigFile);