Merge "libcamera_client: Updated Android.bp"
diff --git a/Android.bp b/Android.bp
index ee609e1..0e0ea1f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
@@ -86,7 +86,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/OWNERS b/OWNERS
index 40c65e7..87bc809 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,7 +1,12 @@
-# Bug component: 1344
+## Media team top-level OWNERS, bug component: 1344
+## Only contact for camera changes as a fallback
elaurent@google.com
-etalvala@google.com
lajos@google.com
# go/android-fwk-media-solutions for info on areas of ownership.
include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
+
+## Camera team top-level OWNERS, bug component: 41727
+## Only contact for media changes as a fallback
+etalvala@google.com
+shuzhenwang@google.com
diff --git a/camera/OWNERS b/camera/OWNERS
index 385c163..b705548 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,7 +1,11 @@
# Bug component: 41727
etalvala@google.com
arakesh@google.com
+borgera@google.com
+bkukreja@google.com
epeev@google.com
jchowdhary@google.com
-shuzhenwang@google.com
+rdhanjal@google.com
ruchamk@google.com
+shuzhenwang@google.com
+
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 88783fb..fefea13 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -48,5 +48,5 @@
/**
* Checks if the camera has been disabled via device policy.
*/
- boolean isCameraDisabled();
+ boolean isCameraDisabled(int userId);
}
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index b6f8552..0d156a5 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -2198,6 +2198,10 @@
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#turnOnTorchWithStrengthLevel">CameraManager#turnOnTorchWithStrengthLevel</a>.
* If this value is equal to 1, flashlight brightness control is not supported.
* The value for this key will be null for devices with no flash unit.</p>
+ * <p>The maximum value is guaranteed to be safe to use for an indefinite duration in
+ * terms of device flashlight lifespan, but may be too bright for comfort for many
+ * use cases. Use the default torch brightness value to avoid problems with an
+ * over-bright flashlight.</p>
*/
ACAMERA_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL = // int32
ACAMERA_FLASH_INFO_START + 2,
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index b277bed..79b1263 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <algorithm>
+#include <string_view>
+#include <type_traits>
#include <assert.h>
#include <ctype.h>
@@ -85,6 +88,7 @@
using android::Vector;
using android::sp;
using android::status_t;
+using android::SurfaceControl;
using android::INVALID_OPERATION;
using android::NAME_NOT_FOUND;
@@ -100,7 +104,6 @@
static const uint32_t kFallbackHeight = 720;
static const char* kMimeTypeAvc = "video/avc";
static const char* kMimeTypeApplicationOctetstream = "application/octet-stream";
-static const char* kWinscopeMagicString = "#VV1NSC0PET1ME!#";
// Command-line parameters.
static bool gVerbose = false; // chatty on stdout
@@ -339,13 +342,20 @@
static status_t prepareVirtualDisplay(
const ui::DisplayState& displayState,
const sp<IGraphicBufferProducer>& bufferProducer,
- sp<IBinder>* pDisplayHandle) {
+ sp<IBinder>* pDisplayHandle, sp<SurfaceControl>* mirrorRoot) {
sp<IBinder> dpy = SurfaceComposerClient::createDisplay(
String8("ScreenRecorder"), false /*secure*/);
SurfaceComposerClient::Transaction t;
t.setDisplaySurface(dpy, bufferProducer);
setDisplayProjection(t, dpy, displayState);
- t.setDisplayLayerStack(dpy, displayState.layerStack);
+ ui::LayerStack layerStack = ui::LayerStack::fromValue(std::rand());
+ t.setDisplayLayerStack(dpy, layerStack);
+ *mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(gPhysicalDisplayId);
+ if (*mirrorRoot == nullptr) {
+ ALOGE("Failed to create a mirror for screenrecord");
+ return UNKNOWN_ERROR;
+ }
+ t.setLayerStack(*mirrorRoot, layerStack);
t.apply();
*pDisplayHandle = dpy;
@@ -354,14 +364,15 @@
}
/*
- * Writes an unsigned integer byte-by-byte in little endian order regardless
+ * Writes an unsigned/signed integer byte-by-byte in little endian order regardless
* of the platform endianness.
*/
-template <typename UINT>
-static void writeValueLE(UINT value, uint8_t* buffer) {
- for (int i = 0; i < sizeof(UINT); ++i) {
- buffer[i] = static_cast<uint8_t>(value);
- value >>= 8;
+template <typename T>
+static void writeValueLE(T value, uint8_t* buffer) {
+ std::remove_const_t<T> temp = value;
+ for (int i = 0; i < sizeof(T); ++i) {
+ buffer[i] = static_cast<std::uint8_t>(temp & 0xff);
+ temp >>= 8;
}
}
@@ -377,16 +388,18 @@
* - for every frame its presentation time relative to the elapsed realtime clock in microseconds
* (as little endian uint64).
*/
-static status_t writeWinscopeMetadata(const Vector<int64_t>& timestamps,
+static status_t writeWinscopeMetadataLegacy(const Vector<int64_t>& timestamps,
const ssize_t metaTrackIdx, AMediaMuxer *muxer) {
- ALOGV("Writing metadata");
+ static constexpr auto kWinscopeMagicStringLegacy = "#VV1NSC0PET1ME!#";
+
+ ALOGV("Writing winscope metadata legacy");
int64_t systemTimeToElapsedTimeOffsetMicros = (android::elapsedRealtimeNano()
- systemTime(SYSTEM_TIME_MONOTONIC)) / 1000;
sp<ABuffer> buffer = new ABuffer(timestamps.size() * sizeof(int64_t)
- + sizeof(uint32_t) + strlen(kWinscopeMagicString));
+ + sizeof(uint32_t) + strlen(kWinscopeMagicStringLegacy));
uint8_t* pos = buffer->data();
- strcpy(reinterpret_cast<char*>(pos), kWinscopeMagicString);
- pos += strlen(kWinscopeMagicString);
+ strcpy(reinterpret_cast<char*>(pos), kWinscopeMagicStringLegacy);
+ pos += strlen(kWinscopeMagicStringLegacy);
writeValueLE<uint32_t>(timestamps.size(), pos);
pos += sizeof(uint32_t);
for (size_t idx = 0; idx < timestamps.size(); ++idx) {
@@ -395,10 +408,68 @@
pos += sizeof(uint64_t);
}
AMediaCodecBufferInfo bufferInfo = {
- 0,
+ 0 /* offset */,
static_cast<int32_t>(buffer->size()),
- timestamps[0],
- 0
+ timestamps[0] /* presentationTimeUs */,
+ 0 /* flags */
+ };
+ return AMediaMuxer_writeSampleData(muxer, metaTrackIdx, buffer->data(), &bufferInfo);
+}
+
+/*
+ * Saves metadata needed by Winscope to synchronize the screen recording playback with other traces.
+ *
+ * The metadata (version 1) is written as a binary array with the following format:
+ * - winscope magic string (#VV1NSC0PET1ME2#, 16B).
+ * - the metadata version number (4B).
+ * - Realtime-to-monotonic time offset in nanoseconds (8B).
+ * - the recorded frames count (8B)
+ * - for each recorded frame:
+ * - System time in monotonic clock timebase in nanoseconds (8B).
+ *
+ * All numbers are Little Endian encoded.
+ */
+static status_t writeWinscopeMetadata(const Vector<std::int64_t>& timestampsMonotonicUs,
+ const ssize_t metaTrackIdx, AMediaMuxer *muxer) {
+ ALOGV("Writing winscope metadata");
+
+ static constexpr auto kWinscopeMagicString = std::string_view {"#VV1NSC0PET1ME2#"};
+ static constexpr std::uint32_t metadataVersion = 1;
+ const std::int64_t realToMonotonicTimeOffsetNs =
+ systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC);
+ const std::uint32_t framesCount = static_cast<std::uint32_t>(timestampsMonotonicUs.size());
+
+ sp<ABuffer> buffer = new ABuffer(
+ kWinscopeMagicString.size() +
+ sizeof(decltype(metadataVersion)) +
+ sizeof(decltype(realToMonotonicTimeOffsetNs)) +
+ sizeof(decltype(framesCount)) +
+ framesCount * sizeof(std::uint64_t)
+ );
+ std::uint8_t* pos = buffer->data();
+
+ std::copy(kWinscopeMagicString.cbegin(), kWinscopeMagicString.cend(), pos);
+ pos += kWinscopeMagicString.size();
+
+ writeValueLE(metadataVersion, pos);
+ pos += sizeof(decltype(metadataVersion));
+
+ writeValueLE(realToMonotonicTimeOffsetNs, pos);
+ pos += sizeof(decltype(realToMonotonicTimeOffsetNs));
+
+ writeValueLE(framesCount, pos);
+ pos += sizeof(decltype(framesCount));
+
+ for (const auto timestampMonotonicUs : timestampsMonotonicUs) {
+ writeValueLE<std::uint64_t>(timestampMonotonicUs * 1000, pos);
+ pos += sizeof(std::uint64_t);
+ }
+
+ AMediaCodecBufferInfo bufferInfo = {
+ 0 /* offset */,
+ static_cast<std::int32_t>(buffer->size()),
+ timestampsMonotonicUs[0] /* presentationTimeUs */,
+ 0 /* flags */
};
return AMediaMuxer_writeSampleData(muxer, metaTrackIdx, buffer->data(), &bufferInfo);
}
@@ -418,11 +489,12 @@
static int kTimeout = 250000; // be responsive on signal
status_t err;
ssize_t trackIdx = -1;
+ ssize_t metaLegacyTrackIdx = -1;
ssize_t metaTrackIdx = -1;
uint32_t debugNumFrames = 0;
int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
- Vector<int64_t> timestamps;
+ Vector<int64_t> timestampsMonotonicUs;
bool firstFrame = true;
assert((rawFp == NULL && muxer != NULL) || (rawFp != NULL && muxer == NULL));
@@ -520,9 +592,9 @@
sp<ABuffer> buffer = new ABuffer(
buffers[bufIndex]->data(), buffers[bufIndex]->size());
AMediaCodecBufferInfo bufferInfo = {
- 0,
+ 0 /* offset */,
static_cast<int32_t>(buffer->size()),
- ptsUsec,
+ ptsUsec /* presentationTimeUs */,
flags
};
err = AMediaMuxer_writeSampleData(muxer, trackIdx, buffer->data(), &bufferInfo);
@@ -532,7 +604,7 @@
return err;
}
if (gOutputFormat == FORMAT_MP4) {
- timestamps.add(ptsUsec);
+ timestampsMonotonicUs.add(ptsUsec);
}
}
debugNumFrames++;
@@ -565,6 +637,7 @@
if (gOutputFormat == FORMAT_MP4) {
AMediaFormat *metaFormat = AMediaFormat_new();
AMediaFormat_setString(metaFormat, AMEDIAFORMAT_KEY_MIME, kMimeTypeApplicationOctetstream);
+ metaLegacyTrackIdx = AMediaMuxer_addTrack(muxer, metaFormat);
metaTrackIdx = AMediaMuxer_addTrack(muxer, metaFormat);
AMediaFormat_delete(metaFormat);
}
@@ -604,10 +677,16 @@
systemTime(CLOCK_MONOTONIC) - startWhenNsec));
fflush(stdout);
}
- if (metaTrackIdx >= 0 && !timestamps.isEmpty()) {
- err = writeWinscopeMetadata(timestamps, metaTrackIdx, muxer);
+ if (metaLegacyTrackIdx >= 0 && metaTrackIdx >= 0 && !timestampsMonotonicUs.isEmpty()) {
+ err = writeWinscopeMetadataLegacy(timestampsMonotonicUs, metaLegacyTrackIdx, muxer);
if (err != NO_ERROR) {
- fprintf(stderr, "Failed writing metadata to muxer (err=%d)\n", err);
+ fprintf(stderr, "Failed writing legacy winscope metadata to muxer (err=%d)\n", err);
+ return err;
+ }
+
+ err = writeWinscopeMetadata(timestampsMonotonicUs, metaTrackIdx, muxer);
+ if (err != NO_ERROR) {
+ fprintf(stderr, "Failed writing winscope metadata to muxer (err=%d)\n", err);
return err;
}
}
@@ -656,6 +735,23 @@
return num & ~1;
}
+struct RecordingData {
+ sp<MediaCodec> encoder;
+ // Configure virtual display.
+ sp<IBinder> dpy;
+
+ sp<Overlay> overlay;
+
+ ~RecordingData() {
+ if (dpy != nullptr) SurfaceComposerClient::destroyDisplay(dpy);
+ if (overlay != nullptr) overlay->stop();
+ if (encoder != nullptr) {
+ encoder->stop();
+ encoder->release();
+ }
+ }
+};
+
/*
* Main "do work" start point.
*
@@ -713,12 +809,12 @@
gVideoHeight = floorToEven(layerStackSpaceRect.getHeight());
}
+ RecordingData recordingData = RecordingData();
// Configure and start the encoder.
- sp<MediaCodec> encoder;
sp<FrameOutput> frameOutput;
sp<IGraphicBufferProducer> encoderInputSurface;
if (gOutputFormat != FORMAT_FRAMES && gOutputFormat != FORMAT_RAW_FRAMES) {
- err = prepareEncoder(displayMode.refreshRate, &encoder, &encoderInputSurface);
+ err = prepareEncoder(displayMode.refreshRate, &recordingData.encoder, &encoderInputSurface);
if (err != NO_ERROR && !gSizeSpecified) {
// fallback is defined for landscape; swap if we're in portrait
@@ -731,7 +827,8 @@
gVideoWidth, gVideoHeight, newWidth, newHeight);
gVideoWidth = newWidth;
gVideoHeight = newHeight;
- err = prepareEncoder(displayMode.refreshRate, &encoder, &encoderInputSurface);
+ err = prepareEncoder(displayMode.refreshRate, &recordingData.encoder,
+ &encoderInputSurface);
}
}
if (err != NO_ERROR) return err;
@@ -758,13 +855,11 @@
// Configure optional overlay.
sp<IGraphicBufferProducer> bufferProducer;
- sp<Overlay> overlay;
if (gWantFrameTime) {
// Send virtual display frames to an external texture.
- overlay = new Overlay(gMonotonicTime);
- err = overlay->start(encoderInputSurface, &bufferProducer);
+ recordingData.overlay = new Overlay(gMonotonicTime);
+ err = recordingData.overlay->start(encoderInputSurface, &bufferProducer);
if (err != NO_ERROR) {
- if (encoder != NULL) encoder->release();
return err;
}
if (gVerbose) {
@@ -776,11 +871,13 @@
bufferProducer = encoderInputSurface;
}
+ // We need to hold a reference to mirrorRoot during the entire recording to ensure it's not
+ // cleaned up by SurfaceFlinger. When the reference is dropped, SurfaceFlinger will delete
+ // the resource.
+ sp<SurfaceControl> mirrorRoot;
// Configure virtual display.
- sp<IBinder> dpy;
- err = prepareVirtualDisplay(displayState, bufferProducer, &dpy);
+ err = prepareVirtualDisplay(displayState, bufferProducer, &recordingData.dpy, &mirrorRoot);
if (err != NO_ERROR) {
- if (encoder != NULL) encoder->release();
return err;
}
@@ -820,7 +917,6 @@
case FORMAT_RAW_FRAMES: {
rawFp = prepareRawOutput(fileName);
if (rawFp == NULL) {
- if (encoder != NULL) encoder->release();
return -1;
}
break;
@@ -861,7 +957,8 @@
}
} else {
// Main encoder loop.
- err = runEncoder(encoder, muxer, rawFp, display, dpy, displayState.orientation);
+ err = runEncoder(recordingData.encoder, muxer, rawFp, display, recordingData.dpy,
+ displayState.orientation);
if (err != NO_ERROR) {
fprintf(stderr, "Encoder failed (err=%d)\n", err);
// fall through to cleanup
@@ -875,9 +972,6 @@
// Shut everything down, starting with the producer side.
encoderInputSurface = NULL;
- SurfaceComposerClient::destroyDisplay(dpy);
- if (overlay != NULL) overlay->stop();
- if (encoder != NULL) encoder->stop();
if (muxer != NULL) {
// If we don't stop muxer explicitly, i.e. let the destructor run,
// it may hang (b/11050628).
@@ -885,7 +979,6 @@
} else if (rawFp != stdout) {
fclose(rawFp);
}
- if (encoder != NULL) encoder->release();
return err;
}
diff --git a/drm/mediadrm/plugins/clearkey/aidl/Android.bp b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
index 397e4c6..2732aa7 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
@@ -112,31 +112,11 @@
name: "android.hardware.drm-service.clearkey.aidl_fuzzer",
defaults: [
"fuzz_aidl_clearkey_service_defaults",
+ "service_fuzzer_defaults",
],
static_libs: [
- "libbase",
- "libbinder_random_parcel",
- "libcutils",
"liblog",
- "libutils",
],
- target: {
- android: {
- shared_libs: [
- "libbinder_ndk",
- "libbinder",
- ],
- },
- host: {
- static_libs: [
- "libbinder_ndk",
- "libbinder",
- ],
- },
- darwin: {
- enabled: false,
- },
- },
srcs: ["fuzzer.cpp"],
fuzz_config: {
cc: [
diff --git a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
index ea51e9d..12aa4ea 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
@@ -474,6 +474,7 @@
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
}
+ Mutex::Autolock lock(mSecurityLevelLock);
std::map<std::vector<uint8_t>, ::aidl::android::hardware::drm::SecurityLevel>::iterator itr =
mSecurityLevel.find(sid);
if (itr == mSecurityLevel.end()) {
@@ -1009,6 +1010,7 @@
return Status::ERROR_DRM_SESSION_NOT_OPENED;
}
+ Mutex::Autolock lock(mSecurityLevelLock);
std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr = mSecurityLevel.find(sid);
if (itr != mSecurityLevel.end()) {
mSecurityLevel[sid] = level;
diff --git a/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
index 25c05f0..7acc1b6 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
@@ -182,7 +182,8 @@
std::map<std::string, std::vector<uint8_t>> mByteArrayProperties;
std::map<std::string, std::vector<uint8_t>> mReleaseKeysMap;
std::map<std::vector<uint8_t>, std::string> mPlaybackId;
- std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
+ std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel
+ GUARDED_BY(mSecurityLevelLock);
::std::shared_ptr<IDrmPluginListener> mListener;
SessionLibrary* mSessionLibrary;
int64_t mOpenSessionOkCount;
@@ -201,6 +202,7 @@
DeviceFiles mFileHandle;
::android::Mutex mSecureStopLock;
+ ::android::Mutex mSecurityLevelLock;
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
};
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 4e82f57..e04dd7e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -619,7 +619,6 @@
return Void();
}
- android_errorWriteLog(0x534e4554, "235601882");
Mutex::Autolock lock(mSecurityLevelLock);
std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
mSecurityLevel.find(sid);
@@ -693,7 +692,6 @@
return Status::ERROR_DRM_SESSION_NOT_OPENED;
}
- android_errorWriteLog(0x534e4554, "235601882");
Mutex::Autolock lock(mSecurityLevelLock);
std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
mSecurityLevel.find(sid);
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 3f7cb3c..48a060b 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -1,7 +1,24 @@
// for frameworks/av/media
{
- // TODO (b/229286407) Add EncodeDecodeTest and DecodeEditEncodeTest to
- // presubmit-large once issues in cuttlefish are fixed
+ "presubmit-large": [
+ // runs whenever we change something in this tree
+ {
+ "name": "CtsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.EncodeDecodeTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
+ }
+ ]
+ }
+ ],
"presubmit": [
{
"name": "GtsMediaTestCases",
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 0bd0d88..d62dd91 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -8,6 +8,7 @@
task_profiles ProcessCapacityHigh HighPerformance
onrestart restart vendor.audio-hal
onrestart restart vendor.audio-hal-aidl
+ onrestart restart vendor.audio-effect-hal-aidl
onrestart restart vendor.audio-hal-4-0-msd
onrestart restart audio_proxy_service
@@ -19,6 +20,7 @@
on property:init.svc.audioserver=stopped
stop vendor.audio-hal
stop vendor.audio-hal-aidl
+ stop vendor.audio-effect-hal-aidl
stop vendor.audio-hal-4-0-msd
stop audio_proxy_service
# See b/155364397. Need to have HAL service running for VTS.
@@ -26,12 +28,14 @@
# audioserver bringing it back into running state.
start vendor.audio-hal
start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
on property:init.svc.audioserver=running
start vendor.audio-hal
start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
@@ -40,10 +44,12 @@
# Keep the original service names for backward compatibility
stop vendor.audio-hal
stop vendor.audio-hal-aidl
+ stop vendor.audio-effect-hal-aidl
stop vendor.audio-hal-4-0-msd
stop audio_proxy_service
start vendor.audio-hal
start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
# reset the property
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 4e4a9a1..d1b08bd 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -275,7 +275,8 @@
mStreamInfo(nullptr),
mSignalledError(false),
mOutputPortDelay(kDefaultOutputPortDelay),
- mOutputDelayRingBuffer(nullptr) {
+ mOutputDelayRingBuffer(nullptr),
+ mDeviceApiLevel(android_get_device_api_level()) {
}
C2SoftAacDec::~C2SoftAacDec() {
@@ -891,7 +892,7 @@
work->worklets.front()->output.configUpdate.push_back(
C2Param::Copy(currentBoostFactor));
- if (android_get_device_api_level() < __ANDROID_API_S__) {
+ if (mDeviceApiLevel < __ANDROID_API_S__) {
// We used to report DRC compression mode in the output format
// in Q and R, but stopped doing that in S
C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
diff --git a/media/codec2/components/aac/C2SoftAacDec.h b/media/codec2/components/aac/C2SoftAacDec.h
index b45f148..f85d45f 100644
--- a/media/codec2/components/aac/C2SoftAacDec.h
+++ b/media/codec2/components/aac/C2SoftAacDec.h
@@ -97,6 +97,7 @@
int32_t mOutputDelayRingBufferWritePos;
int32_t mOutputDelayRingBufferReadPos;
int32_t mOutputDelayRingBufferFilled;
+ int mDeviceApiLevel;
bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferSamplesAvailable();
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index 8b46d3f..5d2856a 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -392,9 +392,9 @@
static C2R PictureQuantizationSetter(bool mayBlock,
C2P<C2StreamPictureQuantizationTuning::output> &me) {
(void)mayBlock;
- (void)me;
- // TODO: refactor with same algorithm in the SetQp()
+ // these are the ones we're going to set, so want them to default
+ // to the DEFAULT values for the codec
int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
@@ -419,13 +419,14 @@
ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d b %d-%d",
iMin, iMax, pMin, pMax, bMin, bMax);
- // ensure we have legal values
- iMax = std::clamp(iMax, CODEC_QP_MIN, CODEC_QP_MAX);
- iMin = std::clamp(iMin, CODEC_QP_MIN, CODEC_QP_MAX);
- pMax = std::clamp(pMax, CODEC_QP_MIN, CODEC_QP_MAX);
- pMin = std::clamp(pMin, CODEC_QP_MIN, CODEC_QP_MAX);
- bMax = std::clamp(bMax, CODEC_QP_MIN, CODEC_QP_MAX);
- bMin = std::clamp(bMin, CODEC_QP_MIN, CODEC_QP_MAX);
+ // min is clamped to [AVC_QP_MIN, max] to avoid error
+ // cases where layer.min > layer.max
+ iMax = std::clamp(iMax, AVC_QP_MIN, AVC_QP_MAX);
+ iMin = std::clamp(iMin, AVC_QP_MIN, iMax);
+ pMax = std::clamp(pMax, AVC_QP_MIN, AVC_QP_MAX);
+ pMin = std::clamp(pMin, AVC_QP_MIN, pMax);
+ bMax = std::clamp(bMax, AVC_QP_MIN, AVC_QP_MAX);
+ bMin = std::clamp(bMin, AVC_QP_MIN, bMax);
// put them back into the structure
for (size_t i = 0; i < me.v.flexCount(); ++i) {
@@ -819,7 +820,8 @@
s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
- // TODO: refactor with same algorithm in the PictureQuantizationSetter()
+ // we resolved out-of-bound and unspecified values in PictureQuantizationSetter()
+ // so we can start with defaults that are overridden as needed.
int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
@@ -1766,17 +1768,20 @@
// }
// }
// }
- std::shared_ptr<const C2GraphicView> view;
+ std::shared_ptr<C2GraphicView> view;
std::shared_ptr<C2Buffer> inputBuffer;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- view = std::make_shared<const C2GraphicView>(
+ view = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (view->error() != C2_OK) {
ALOGE("graphic view map err = %d", view->error());
work->workletsProcessed = 1u;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ view->setCrop_be(C2Rect(mSize->width, mSize->height));
}
do {
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index 293867d..cde6604 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -103,8 +103,8 @@
/** limits as specified by h264
* (QP_MIN==4 is actually a limitation of this SW codec, not the H.264 standard)
**/
-#define CODEC_QP_MIN 4
-#define CODEC_QP_MAX 51
+#define AVC_QP_MIN 4
+#define AVC_QP_MAX 51
#define MIN(a, b) ((a) < (b))? (a) : (b)
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 4dec57f..d234f21 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -102,6 +102,29 @@
.withSetter(Hdr10PlusInfoOutputSetter)
.build());
+ // default static info
+ C2HdrStaticMetadataStruct defaultStaticInfo{};
+ helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
+ addParameter(
+ DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
+ .withDefault(new C2StreamHdrStaticInfo::output(0u, defaultStaticInfo))
+ .withFields({
+ C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.red.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.maxLuminance).inRange(0, 65535),
+ C2F(mHdrStaticInfo, mastering.minLuminance).inRange(0, 6.5535),
+ C2F(mHdrStaticInfo, maxCll).inRange(0, 0XFFFF),
+ C2F(mHdrStaticInfo, maxFall).inRange(0, 0XFFFF)
+ })
+ .withSetter(HdrStaticInfoSetter)
+ .build());
+
addParameter(
DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
.withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
@@ -331,6 +354,47 @@
// unsafe getters
std::shared_ptr<C2StreamPixelFormatInfo::output> getPixelFormat_l() const { return mPixelFormat; }
+ static C2R HdrStaticInfoSetter(bool mayBlock, C2P<C2StreamHdrStaticInfo::output> &me) {
+ (void)mayBlock;
+ if (me.v.mastering.red.x > 1) {
+ me.set().mastering.red.x = 1;
+ }
+ if (me.v.mastering.red.y > 1) {
+ me.set().mastering.red.y = 1;
+ }
+ if (me.v.mastering.green.x > 1) {
+ me.set().mastering.green.x = 1;
+ }
+ if (me.v.mastering.green.y > 1) {
+ me.set().mastering.green.y = 1;
+ }
+ if (me.v.mastering.blue.x > 1) {
+ me.set().mastering.blue.x = 1;
+ }
+ if (me.v.mastering.blue.y > 1) {
+ me.set().mastering.blue.y = 1;
+ }
+ if (me.v.mastering.white.x > 1) {
+ me.set().mastering.white.x = 1;
+ }
+ if (me.v.mastering.white.y > 1) {
+ me.set().mastering.white.y = 1;
+ }
+ if (me.v.mastering.maxLuminance > 65535.0) {
+ me.set().mastering.maxLuminance = 65535.0;
+ }
+ if (me.v.mastering.minLuminance > 6.5535) {
+ me.set().mastering.minLuminance = 6.5535;
+ }
+ if (me.v.maxCll > 65535.0) {
+ me.set().maxCll = 65535.0;
+ }
+ if (me.v.maxFall > 65535.0) {
+ me.set().maxFall = 65535.0;
+ }
+ return C2R::Ok();
+ }
+
private:
std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
@@ -343,6 +407,7 @@
std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+ std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
};
C2SoftGav1Dec::C2SoftGav1Dec(const char *name, c2_node_id_t id,
@@ -558,6 +623,76 @@
}
}
+void C2SoftGav1Dec::getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work) {
+ C2StreamHdrStaticMetadataInfo::output hdrStaticMetadataInfo{};
+ bool infoPresent = false;
+ if (buffer->has_hdr_mdcv) {
+ // hdr_mdcv.primary_chromaticity_* values are in 0.16 fixed-point format.
+ hdrStaticMetadataInfo.mastering.red.x = buffer->hdr_mdcv.primary_chromaticity_x[0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.red.y = buffer->hdr_mdcv.primary_chromaticity_y[0] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.green.x = buffer->hdr_mdcv.primary_chromaticity_x[1] / 65536.0;
+ hdrStaticMetadataInfo.mastering.green.y = buffer->hdr_mdcv.primary_chromaticity_y[1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.blue.x = buffer->hdr_mdcv.primary_chromaticity_x[2] / 65536.0;
+ hdrStaticMetadataInfo.mastering.blue.y = buffer->hdr_mdcv.primary_chromaticity_y[2] / 65536.0;
+
+ // hdr_mdcv.white_point_chromaticity_* values are in 0.16 fixed-point format.
+ hdrStaticMetadataInfo.mastering.white.x = buffer->hdr_mdcv.white_point_chromaticity_x / 65536.0;
+ hdrStaticMetadataInfo.mastering.white.y = buffer->hdr_mdcv.white_point_chromaticity_y / 65536.0;
+
+ // hdr_mdcv.luminance_max is in 24.8 fixed-point format.
+ hdrStaticMetadataInfo.mastering.maxLuminance = buffer->hdr_mdcv.luminance_max / 256.0;
+ // hdr_mdcv.luminance_min is in 18.14 format.
+ hdrStaticMetadataInfo.mastering.minLuminance = buffer->hdr_mdcv.luminance_min / 16384.0;
+ infoPresent = true;
+ }
+
+ if (buffer->has_hdr_cll) {
+ hdrStaticMetadataInfo.maxCll = buffer->hdr_cll.max_cll;
+ hdrStaticMetadataInfo.maxFall = buffer->hdr_cll.max_fall;
+ infoPresent = true;
+ }
+ // config if static info has changed
+ if (infoPresent && !(hdrStaticMetadataInfo == mHdrStaticMetadataInfo)) {
+ mHdrStaticMetadataInfo = hdrStaticMetadataInfo;
+ work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(mHdrStaticMetadataInfo));
+ }
+}
+
+void C2SoftGav1Dec::getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work) {
+ if (buffer->has_itut_t35) {
+ std::vector<uint8_t> payload;
+ size_t payloadSize = buffer->itut_t35.payload_size;
+ if (payloadSize > 0) {
+ payload.push_back(buffer->itut_t35.country_code);
+ if (buffer->itut_t35.country_code == 0xFF) {
+ payload.push_back(buffer->itut_t35.country_code_extension_byte);
+ }
+ payload.insert(payload.end(), buffer->itut_t35.payload_bytes,
+ buffer->itut_t35.payload_bytes + buffer->itut_t35.payload_size);
+ }
+
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
+ C2StreamHdr10PlusInfo::output::AllocUnique(payload.size());
+ if (!hdr10PlusInfo) {
+ ALOGE("Hdr10PlusInfo allocation failed");
+ mSignalledError = true;
+ work->result = C2_NO_MEMORY;
+ return;
+ }
+ memcpy(hdr10PlusInfo->m.value, payload.data(), payload.size());
+
+ // config if hdr10Plus info has changed
+ if (nullptr == mHdr10PlusInfo || !(*hdr10PlusInfo == *mHdr10PlusInfo)) {
+ mHdr10PlusInfo = std::move(hdr10PlusInfo);
+ work->worklets.front()->output.configUpdate.push_back(std::move(mHdr10PlusInfo));
+ }
+ }
+}
+
void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
VuiColorAspects vuiColorAspects;
vuiColorAspects.primaries = buffer->color_primary;
@@ -633,6 +768,9 @@
}
getVuiParams(buffer);
+ getHDRStaticParams(buffer, work);
+ getHDR10PlusInfoData(buffer, work);
+
if (!(buffer->image_format == libgav1::kImageFormatYuv420 ||
buffer->image_format == libgav1::kImageFormatMonochrome400)) {
ALOGE("image_format %d not supported", buffer->image_format);
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index 3d4db55..e51c511 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -61,6 +61,9 @@
bool mSignalledOutputEos;
bool mSignalledError;
+ C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
+
// Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
// converting them to C2 values for each frame
struct VuiColorAspects {
@@ -86,6 +89,10 @@
nsecs_t mTimeEnd = 0; // Time at the end of decode()
bool initDecoder();
+ void getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work);
+ void getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work);
void getVuiParams(const libgav1::DecoderBuffer *buffer);
void destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 5a660c5..a27c218 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -917,7 +917,8 @@
if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN128(ps_decode_op->u4_pic_wd), IVD_DECODE_FRAME);
+ mStride = ALIGN128(ps_decode_op->u4_pic_wd);
+ setParams(mStride, IVD_DECODE_FRAME);
}
if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
mWidth = ps_decode_op->u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 60d5875..9c26c02 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -1109,14 +1109,14 @@
}
}
- std::shared_ptr<const C2GraphicView> view;
+ std::shared_ptr<C2GraphicView> view;
std::shared_ptr<C2Buffer> inputBuffer = nullptr;
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
if (eos) mSignalledEos = true;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- view = std::make_shared<const C2GraphicView>(
+ view = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (view->error() != C2_OK) {
ALOGE("graphic view map err = %d", view->error());
@@ -1125,6 +1125,9 @@
work->workletsProcessed = 1u;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ view->setCrop_be(C2Rect(mSize->width, mSize->height));
}
IHEVCE_PLUGIN_STATUS_T err = IHEVCE_EOK;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 3bfec66..d5e8c56 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -464,18 +464,21 @@
}
}
- std::shared_ptr<const C2GraphicView> rView;
+ std::shared_ptr<C2GraphicView> rView;
std::shared_ptr<C2Buffer> inputBuffer;
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
+ rView = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (rView->error() != C2_OK) {
ALOGE("graphic view map err = %d", rView->error());
work->result = rView->error();
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ rView->setCrop_be(C2Rect(mSize->width, mSize->height));
} else {
fillEmptyWork(work);
if (eos) {
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index f99ee24..2efc00f 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -683,17 +683,20 @@
return;
}
- std::shared_ptr<const C2GraphicView> rView;
+ std::shared_ptr<C2GraphicView> rView;
std::shared_ptr<C2Buffer> inputBuffer;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
+ rView = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (rView->error() != C2_OK) {
ALOGE("graphic view map err = %d", rView->error());
work->result = C2_CORRUPTED;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ rView->setCrop_be(C2Rect(mSize->width, mSize->height));
} else {
ALOGV("Empty input Buffer");
uint32_t flags = 0;
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
index e469d8b..d6793e0 100644
--- a/media/codec2/fuzzer/C2Fuzzer.cpp
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -246,7 +246,8 @@
bufferSource->parse();
c2_status_t status = C2_OK;
size_t numFrames = 0;
- while (!bufferSource->isEos()) {
+ int32_t iterationCount = 0;
+ while (!bufferSource->isEos() && ++iterationCount <= kMaxIterations) {
uint8_t* frame = nullptr;
size_t frameSize = 0;
FrameData frameData = bufferSource->getFrame();
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
index da76885..4e3e3ea 100644
--- a/media/codec2/fuzzer/C2Fuzzer.h
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -37,6 +37,7 @@
#define C2FUZZER_ALIGN(_sz, _align) (((_sz) + ((_align)-1)) & ~((_align)-1))
constexpr std::chrono::milliseconds kC2FuzzerTimeOut = 5000ms;
+constexpr int32_t kMaxIterations = 100;
constexpr int32_t kNumberOfC2WorkItems = 8;
constexpr uint32_t kWidthOfVideo = 3840;
constexpr uint32_t kHeightOfVideo = 2160;
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 5c24bd7..319ba62 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -1447,6 +1447,10 @@
bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
switch (s.getDiscriminator()) {
case BaseBlock::hidl_discriminator::nativeBlock: {
+ if (s.nativeBlock() == nullptr) {
+ LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
+ return false;
+ }
native_handle_t* sHandle =
native_handle_clone(s.nativeBlock());
if (sHandle == nullptr) {
@@ -1609,6 +1613,7 @@
// assuming blob is const here
size_t size = blob.size();
size_t ix = 0;
+ size_t old_ix = 0;
const uint8_t *data = blob.data();
C2Param *p = nullptr;
@@ -1616,8 +1621,13 @@
p = C2ParamUtils::ParseFirst(data + ix, size - ix);
if (p) {
params->emplace_back(p);
+ old_ix = ix;
ix += p->size();
ix = align(ix, PARAMS_ALIGNMENT);
+ if (ix <= old_ix || ix > size) {
+ android_errorWriteLog(0x534e4554, "238083570");
+ break;
+ }
}
} while (p);
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
index bd7ec0d..327717b 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
@@ -372,9 +372,8 @@
ULock l(queueLock);
flushedIndices.emplace_back(frameID);
}
- char* data = (char*)malloc(bytesCount);
- ASSERT_NE(data, nullptr);
- eleStream.read(data, bytesCount);
+ std::vector<char> eleData(bytesCount);
+ eleStream.read(eleData.data(), bytesCount);
// if we have reached at the end of input stream, signal eos
if (eleStream.gcount() < bytesCount) {
bytesCount = eleStream.gcount();
@@ -396,12 +395,11 @@
ASSERT_EQ(0u, view.offset());
ASSERT_EQ((size_t)bytesCount, view.size());
- memcpy(view.base(), data, bytesCount);
+ memcpy(view.base(), eleData.data(), bytesCount);
work->input.buffers.clear();
work->input.buffers.emplace_back(new LinearBuffer(block));
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 67873fa..117d9ca 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -214,10 +214,8 @@
calc_md5_cksum(uPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_u_chksum);
calc_md5_cksum(vPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_v_chksum);
} else if (bitDepth == 8 && layoutType == C2PlanarLayout::TYPE_YUV && colInc == 2) {
- uint8_t* cbPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
- uint8_t* crPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
- ASSERT_NE(cbPlane, nullptr);
- ASSERT_NE(crPlane, nullptr);
+ std::vector<uint8_t> cbPlane(cropWidth * cropHeight / 4);
+ std::vector<uint8_t> crPlane(cropWidth * cropHeight / 4);
size_t count = 0;
for (size_t k = 0; k < (cropHeight / 2); k++) {
for (size_t l = 0; l < (cropWidth); l = l + 2) {
@@ -227,10 +225,10 @@
}
}
calc_md5_cksum(yPlane, yStride, cropWidth, cropHeight, au1_y_chksum);
- calc_md5_cksum(cbPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_u_chksum);
- calc_md5_cksum(crPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_v_chksum);
- free(cbPlane);
- free(crPlane);
+ calc_md5_cksum(cbPlane.data(), cropWidth / 2, cropWidth / 2, cropHeight / 2,
+ au1_u_chksum);
+ calc_md5_cksum(crPlane.data(), cropWidth / 2, cropWidth / 2, cropHeight / 2,
+ au1_v_chksum);
} else {
mMd5Enable = false;
ALOGV("Disabling MD5 chksm flag");
diff --git a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
index 6c8ce3c..c77eb22 100644
--- a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
+++ b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
@@ -666,6 +666,7 @@
grallocHandle, GraphicBuffer::CLONE_HANDLE,
width, height, format, 1, usage, stride);
+ native_handle_delete(grallocHandle);
std::shared_ptr<C2GraphicBlock> dstBlock;
C2BlockPool::local_id_t poolId = mIntf->getPoolId();
std::shared_ptr<C2BlockPool> pool;
@@ -684,6 +685,7 @@
grallocHandle, GraphicBuffer::CLONE_HANDLE,
width, height, format, 1, usage, stride);
+ native_handle_delete(grallocHandle);
Rect sourceCrop(0, 0, width, height);
renderengine::DisplaySettings clientCompositionDisplay;
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 5a652a3..ecd5463 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -44,7 +44,7 @@
],
static_libs: [
- "SurfaceFlingerProperties",
+ "libSurfaceFlingerProperties",
],
shared_libs: [
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 296d7ed..72301db 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1899,6 +1899,7 @@
comp = state->comp;
}
status_t err = comp->stop();
+ mChannel->stopUseOutputSurface();
if (err != C2_OK) {
// TODO: convert err into status_t
mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
@@ -1992,6 +1993,7 @@
comp = state->comp;
}
comp->release();
+ mChannel->stopUseOutputSurface();
{
Mutexed<State>::Locked state(mState);
@@ -2139,7 +2141,8 @@
std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers;
status_t err = mChannel->prepareInitialInputBuffers(&clientInputBuffers);
- if (err != OK) {
+ // FIXME(b/237656746)
+ if (err != OK && err != NO_MEMORY) {
ALOGE("Resume request for Input Buffers failed");
mCallback->onError(err, ACTION_CODE_FATAL);
return;
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 5ecb130..4bf8dce 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -960,9 +960,9 @@
hdrDynamicInfo->m.data + hdrDynamicInfo->flexCount());
}
qbi.setHdrMetadata(hdr);
-
- SetHdrMetadataToGralloc4Handle(hdrStaticInfo, hdrDynamicInfo, block.handle());
}
+ SetMetadataToGralloc4Handle(dataSpace, hdrStaticInfo, hdrDynamicInfo, block.handle());
+
// we don't have dirty regions
qbi.setSurfaceDamage(Region::INVALID_REGION);
android::IGraphicBufferProducer::QueueBufferOutput qbo;
@@ -1578,6 +1578,17 @@
mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
}
+void CCodecBufferChannel::stopUseOutputSurface() {
+ if (mOutputSurface.lock()->surface) {
+ C2BlockPool::local_id_t outputPoolId;
+ {
+ Mutexed<BlockPools>::Locked pools(mBlockPools);
+ outputPoolId = pools->outputPoolId;
+ }
+ if (mComponent) mComponent->stopUsingOutputSurface(outputPoolId);
+ }
+}
+
void CCodecBufferChannel::reset() {
stop();
if (mInputSurface != nullptr) {
@@ -1593,14 +1604,6 @@
Mutexed<Output>::Locked output(mOutput);
output->buffers.reset();
}
- if (mOutputSurface.lock()->surface) {
- C2BlockPool::local_id_t outputPoolId;
- {
- Mutexed<BlockPools>::Locked pools(mBlockPools);
- outputPoolId = pools->outputPoolId;
- }
- mComponent->stopUsingOutputSurface(outputPoolId);
- }
}
void CCodecBufferChannel::release() {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index f29a225..61fb06f 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -149,6 +149,12 @@
std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers);
/**
+ * Stop using buffers of the current output surface for other Codec
+ * instances to use the surface safely.
+ */
+ void stopUseOutputSurface();
+
+ /**
* Stop queueing buffers to the component. This object should never queue
* buffers after this call, until start() is called.
*/
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index cde4c72..876c96d 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -843,6 +843,10 @@
}
}
sp<ABuffer> aBuffer(alloc(align(width, 16) * align(height, 16) * bpp / 8));
+ if (aBuffer == nullptr) {
+ ALOGD("%s: failed to allocate buffer", __func__);
+ return nullptr;
+ }
return new ConstGraphicBlockBuffer(
format,
aBuffer,
@@ -998,9 +1002,11 @@
}
using ::aidl::android::hardware::graphics::common::Cta861_3;
+using ::aidl::android::hardware::graphics::common::Dataspace;
using ::aidl::android::hardware::graphics::common::Smpte2086;
using ::android::gralloc4::MetadataType_Cta861_3;
+using ::android::gralloc4::MetadataType_Dataspace;
using ::android::gralloc4::MetadataType_Smpte2086;
using ::android::gralloc4::MetadataType_Smpte2094_40;
@@ -1156,7 +1162,8 @@
return err;
}
-c2_status_t SetHdrMetadataToGralloc4Handle(
+c2_status_t SetMetadataToGralloc4Handle(
+ android_dataspace_t dataSpace,
const std::shared_ptr<const C2StreamHdrStaticMetadataInfo::output> &staticInfo,
const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
const C2Handle *const handle) {
@@ -1167,6 +1174,17 @@
// Gralloc4 not supported; nothing to do
return err;
}
+ {
+ hidl_vec<uint8_t> metadata;
+ if (gralloc4::encodeDataspace(static_cast<Dataspace>(dataSpace), &metadata) == OK) {
+ Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Dataspace, metadata);
+ if (!ret.isOk()) {
+ err = C2_REFUSED;
+ } else if (ret != Error4::NONE) {
+ err = C2_CORRUPTED;
+ }
+ }
+ }
if (staticInfo && *staticInfo) {
ALOGV("Setting static HDR info as gralloc4 metadata");
std::optional<Smpte2086> smpte2086 = Smpte2086{
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
index b02b042..b73acab 100644
--- a/media/codec2/sfplugin/Codec2Buffer.h
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -410,14 +410,16 @@
std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> *dynamicInfo);
/**
- * Set HDR metadata to Gralloc4 handle.
+ * Set metadata to Gralloc4 handle.
*
+ * \param[in] dataSpace Dataspace to set.
* \param[in] staticInfo HDR static info to set. Ignored if null or invalid.
* \param[in] dynamicInfo HDR dynamic info to set. Ignored if null or invalid.
* \param[out] handle handle of the allocation.
* \return C2_OK if successful
*/
-c2_status_t SetHdrMetadataToGralloc4Handle(
+c2_status_t SetMetadataToGralloc4Handle(
+ const android_dataspace_t dataSpace,
const std::shared_ptr<const C2StreamHdrStaticMetadataInfo::output> &staticInfo,
const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
const C2Handle *const handle);
diff --git a/media/janitors/avic_OWNERS b/media/janitors/avic_OWNERS
new file mode 100644
index 0000000..eca9978
--- /dev/null
+++ b/media/janitors/avic_OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1344
+# gerrit owner/approvers in the AVIC team
+arifdikici@google.com
+dichenzhang@google.com
+kyslov@google.com
+richardxie@google.com
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
index 8dc1c7b..69e3a5e 100644
--- a/media/janitors/media_solutions_OWNERS
+++ b/media/janitors/media_solutions_OWNERS
@@ -2,9 +2,9 @@
# go/android-fwk-media-solutions for info on areas of ownership.
# Main owners:
+adadukin@google.com
aquilescanta@google.com
-krocard@google.com
+ivanbuper@google.com
# In case of emergency:
andrewlewis@google.com #{LAST_RESORT_SUGGESTION}
-olly@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/media/libaaudio/TEST_MAPPING b/media/libaaudio/TEST_MAPPING
index 3de5a9f..9aff137 100644
--- a/media/libaaudio/TEST_MAPPING
+++ b/media/libaaudio/TEST_MAPPING
@@ -1,10 +1,19 @@
{
- "presubmit": [
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index 2a12191..f5d2939 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -25,6 +25,9 @@
cc_fuzz {
name: "libaaudio_fuzzer",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
srcs: [
"libaaudio_fuzzer.cpp",
],
@@ -39,7 +42,6 @@
"libutils",
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"liblog",
"libcutils",
"libaaudio",
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 400a81b..a727db2 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -277,6 +277,7 @@
AAUDIO_STREAM_STATE_CLOSED,
/**
* The stream is disconnected from audio device.
+ * @deprecated
*/
AAUDIO_STREAM_STATE_DISCONNECTED
};
@@ -1173,7 +1174,10 @@
* in the streams current data format to the audioData buffer.
*
* For an input stream, this function should read and process numFrames of data
- * from the audioData buffer.
+ * from the audioData buffer. The data in the audioData buffer must not be modified
+ * directly. Instead, it should be copied to another buffer before doing any modification.
+ * In many cases, writing to the audioData buffer of an input stream will result in a
+ * native exception.
*
* The audio data is passed through the buffer. So do NOT call AAudioStream_read() or
* AAudioStream_write() on the stream that is making the callback.
diff --git a/media/libaaudio/include/aaudio/AAudioTesting.h b/media/libaaudio/include/aaudio/AAudioTesting.h
index 0f2d7a2..01d97b6 100644
--- a/media/libaaudio/include/aaudio/AAudioTesting.h
+++ b/media/libaaudio/include/aaudio/AAudioTesting.h
@@ -87,7 +87,7 @@
* @note This is only for testing. Do not use this in an application.
* It may change or be removed at any time.
*
- * @return true if the stream uses ther MMAP data path
+ * @return true if the stream uses the MMAP data path
*/
AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream);
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 363d219..30f451a 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -134,6 +134,10 @@
cc_library {
name: "libaaudio_internal",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
local_include_dirs: [
"binding",
"client",
@@ -167,7 +171,6 @@
"libbinder",
"framework-permission-aidl-cpp",
"aaudio-aidl-cpp",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
],
@@ -209,6 +212,7 @@
"flowgraph/ChannelCountConverter.cpp",
"flowgraph/ClipToRange.cpp",
"flowgraph/FlowGraphNode.cpp",
+ "flowgraph/Limiter.cpp",
"flowgraph/ManyToMultiConverter.cpp",
"flowgraph/MonoBlend.cpp",
"flowgraph/MonoToMultiConverter.cpp",
@@ -260,7 +264,7 @@
"binding/aidl/aaudio/IAAudioService.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"shared-file-region-aidl",
"framework-permission-aidl",
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
index 2ed3e3c..5444565 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.cpp
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -20,7 +20,7 @@
#include "AAudioFlowGraph.h"
-#include <flowgraph/ClipToRange.h>
+#include <flowgraph/Limiter.h>
#include <flowgraph/ManyToMultiConverter.h>
#include <flowgraph/MonoBlend.h>
#include <flowgraph/MonoToMultiConverter.h>
@@ -78,11 +78,11 @@
}
// For a pure float graph, there is chance that the data range may be very large.
- // So we should clip to a reasonable value that allows a little headroom.
+ // So we should limit to a reasonable value that allows a little headroom.
if (sourceFormat == AUDIO_FORMAT_PCM_FLOAT && sinkFormat == AUDIO_FORMAT_PCM_FLOAT) {
- mClipper = std::make_unique<ClipToRange>(sourceChannelCount);
- lastOutput->connect(&mClipper->input);
- lastOutput = &mClipper->output;
+ mLimiter = std::make_unique<Limiter>(sourceChannelCount);
+ lastOutput->connect(&mLimiter->input);
+ lastOutput = &mLimiter->output;
}
// Expand the number of channels if required.
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.h b/media/libaaudio/src/client/AAudioFlowGraph.h
index 602c17f..35fef37 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.h
+++ b/media/libaaudio/src/client/AAudioFlowGraph.h
@@ -24,7 +24,7 @@
#include <aaudio/AAudio.h>
#include <audio_utils/Balance.h>
-#include <flowgraph/ClipToRange.h>
+#include <flowgraph/Limiter.h>
#include <flowgraph/ManyToMultiConverter.h>
#include <flowgraph/MonoBlend.h>
#include <flowgraph/MonoToMultiConverter.h>
@@ -74,7 +74,7 @@
private:
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSourceBuffered> mSource;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoBlend> mMonoBlend;
- std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::ClipToRange> mClipper;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::Limiter> mLimiter;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoToMultiConverter> mChannelConverter;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::ManyToMultiConverter>
mManyToMultiConverter;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 34ecd25..27f519b 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -315,11 +315,10 @@
aaudio_result_t result = AAUDIO_OK;
ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) {
- aaudio_stream_state_t currentState = getState();
// Don't release a stream while it is running. Stop it first.
// If DISCONNECTED then we should still try to stop in case the
// error callback is still running.
- if (isActive() || currentState == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isActive() || isDisconnected()) {
requestStop_l();
}
@@ -432,11 +431,11 @@
return AAUDIO_ERROR_INVALID_STATE;
}
- aaudio_stream_state_t originalState = getState();
- if (originalState == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isDisconnected()) {
ALOGD("requestStart() but DISCONNECTED");
return AAUDIO_ERROR_DISCONNECTED;
}
+ aaudio_stream_state_t originalState = getState();
setState(AAUDIO_STREAM_STATE_STARTING);
// Clear any stale timestamps from the previous run.
@@ -456,7 +455,7 @@
ALOGD("%s() error = %d, stream was probably stolen", __func__, result);
// Stealing was added in R. Coerce result to improve backward compatibility.
result = AAUDIO_ERROR_DISCONNECTED;
- setState(AAUDIO_STREAM_STATE_DISCONNECTED);
+ setDisconnected();
}
startTime = AudioClock::getNanoseconds();
@@ -473,7 +472,6 @@
result = createThread_l(periodNanos, aaudio_callback_thread_proc, this);
}
if (result != AAUDIO_OK) {
- // TODO(b/214607638): Do we want to roll back to original state or keep as disconnected?
setState(originalState);
}
return result;
@@ -499,8 +497,7 @@
// This must be called under mStreamLock.
aaudio_result_t AudioStreamInternal::stopCallback_l()
{
- if (isDataCallbackSet()
- && (isActive() || getState() == AAUDIO_STREAM_STATE_DISCONNECTED)) {
+ if (isDataCallbackSet() && (isActive() || isDisconnected())) {
mCallbackEnabled.store(false);
aaudio_result_t result = joinThread_l(nullptr); // may temporarily unlock mStreamLock
if (result == AAUDIO_ERROR_INVALID_HANDLE) {
@@ -525,7 +522,7 @@
// and the callback may have stopped the stream.
// Check to make sure the stream still needs to be stopped.
// See also AudioStream::safeStop_l().
- if (!(isActive() || getState() == AAUDIO_STREAM_STATE_DISCONNECTED)) {
+ if (!(isActive() || isDisconnected())) {
ALOGD("%s() returning early, not active or disconnected", __func__);
return AAUDIO_OK;
}
@@ -647,6 +644,8 @@
if (getState() == AAUDIO_STREAM_STATE_STARTING) {
setState(AAUDIO_STREAM_STATE_STARTED);
}
+ mPlayerBase->triggerPortIdUpdate(static_cast<audio_port_handle_t>(
+ message->event.dataLong));
break;
case AAUDIO_SERVICE_EVENT_PAUSED:
ALOGD("%s - got AAUDIO_SERVICE_EVENT_PAUSED", __func__);
@@ -673,7 +672,7 @@
mAudioEndpoint->eraseDataMemory();
}
result = AAUDIO_ERROR_DISCONNECTED;
- setState(AAUDIO_STREAM_STATE_DISCONNECTED);
+ setDisconnected();
ALOGW("%s - AAUDIO_SERVICE_EVENT_DISCONNECTED - FIFO cleared", __func__);
break;
case AAUDIO_SERVICE_EVENT_VOLUME:
@@ -807,7 +806,6 @@
if (wakeTimeNanos > deadlineNanos) {
// If we time out, just return the framesWritten so far.
- // TODO remove after we fix the deadline bug
ALOGW("processData(): entered at %lld nanos, currently %lld",
(long long) entryTimeNanos, (long long) currentTimeNanos);
ALOGW("processData(): TIMEOUT after %lld nanos",
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 1efccb1..f5cc2be 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -25,6 +25,7 @@
#include "client/AudioStreamInternalCapture.h"
#include "utility/AudioClock.h"
+#undef ATRACE_TAG
#define ATRACE_TAG ATRACE_TAG_AUDIO
#include <utils/Trace.h>
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 8a5186a..c9351e0 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -61,10 +61,9 @@
// If the stream is deleted when OPEN or in use then audio resources will leak.
// This would indicate an internal error. So we want to find this ASAP.
LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
- || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
- || getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
- "~AudioStream() - still in use, state = %s",
- AudioGlobal_convertStreamStateToText(getState()));
+ || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED),
+ "~AudioStream() - still in use, state = %s disconnected = %d",
+ AudioGlobal_convertStreamStateToText(getState()), isDisconnected());
}
aaudio_result_t AudioStream::open(const AudioStreamBuilder& builder)
@@ -158,6 +157,11 @@
std::lock_guard<std::mutex> lock(mStreamLock);
+ if (isDisconnected()) {
+ ALOGW("%s() stream is disconnected", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
switch (getState()) {
// Is this a good time to start?
case AAUDIO_STREAM_STATE_OPEN:
@@ -176,8 +180,13 @@
AudioGlobal_convertStreamStateToText(getState()));
return AAUDIO_ERROR_INVALID_STATE;
- // Don't start when the stream is dead!
case AAUDIO_STREAM_STATE_DISCONNECTED:
+ // This must not happen after deprecating AAUDIO_STREAM_STATE_DISCONNECTED, trying to
+ // start will finally return ERROR_DISCONNECTED.
+ ALOGE("%s, unexpected state = AAUDIO_STREAM_STATE_DISCONNECTED", __func__);
+ return AAUDIO_ERROR_INTERNAL;
+
+ // Don't start when the stream is dead!
case AAUDIO_STREAM_STATE_CLOSING:
case AAUDIO_STREAM_STATE_CLOSED:
default:
@@ -210,7 +219,11 @@
// Proceed with pausing.
case AAUDIO_STREAM_STATE_STARTING:
case AAUDIO_STREAM_STATE_STARTED:
+ break;
+
case AAUDIO_STREAM_STATE_DISCONNECTED:
+ // This must not happen after deprecating AAUDIO_STREAM_STATE_DISCONNECTED
+ ALOGE("%s, unexpected state = AAUDIO_STREAM_STATE_DISCONNECTED", __func__);
break;
// Transition from one inactive state to another.
@@ -289,7 +302,10 @@
// Proceed with stopping.
case AAUDIO_STREAM_STATE_STARTING:
case AAUDIO_STREAM_STATE_STARTED:
+ break;
case AAUDIO_STREAM_STATE_DISCONNECTED:
+ // This must not happen after deprecating AAUDIO_STREAM_STATE_DISCONNECTED
+ ALOGE("%s, unexpected state = AAUDIO_STREAM_STATE_DISCONNECTED", __func__);
break;
// Transition from one inactive state to another.
@@ -369,13 +385,8 @@
if (state == oldState) {
return; // no change
}
- // Track transition to DISCONNECTED state.
- if (state == AAUDIO_STREAM_STATE_DISCONNECTED) {
- android::mediametrics::LogItem(mMetricsId)
- .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT)
- .set(AMEDIAMETRICS_PROP_STATE, AudioGlobal_convertStreamStateToText(oldState))
- .record();
- }
+ LOG_ALWAYS_FATAL_IF(state == AAUDIO_STREAM_STATE_DISCONNECTED,
+ "Disconnected state must be separated from mState");
// CLOSED is a final state
if (oldState == AAUDIO_STREAM_STATE_CLOSED) {
ALOGW("%s(%d) tried to set to %d but already CLOSED", __func__, getId(), state);
@@ -385,12 +396,6 @@
&& state != AAUDIO_STREAM_STATE_CLOSED) {
ALOGW("%s(%d) tried to set to %d but already CLOSING", __func__, getId(), state);
- // Once DISCONNECTED, we can only move to CLOSING or CLOSED state.
- } else if (oldState == AAUDIO_STREAM_STATE_DISCONNECTED
- && !(state == AAUDIO_STREAM_STATE_CLOSING
- || state == AAUDIO_STREAM_STATE_CLOSED)) {
- ALOGW("%s(%d) tried to set to %d but already DISCONNECTED", __func__, getId(), state);
-
} else {
mState.store(state);
// Wake up a wakeForStateChange thread if it exists.
@@ -398,6 +403,21 @@
}
}
+void AudioStream::setDisconnected() {
+ const bool old = isDisconnected();
+ ALOGD("%s setting disconnected, current disconnected: %d, current state: %d",
+ __func__, old, getState());
+ if (old) {
+ return; // no change, the stream is already disconnected
+ }
+ mDisconnected.store(true);
+ // Track transition to DISCONNECTED state.
+ android::mediametrics::LogItem(mMetricsId)
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT)
+ .set(AMEDIAMETRICS_PROP_STATE, AudioGlobal_convertStreamStateToText(getState()))
+ .record();
+}
+
aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
aaudio_stream_state_t *nextState,
int64_t timeoutNanoseconds)
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 8dd5538..50f6aa0 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -410,7 +410,7 @@
* This should only be called for client streams and not for streams
* that run in the service.
*/
- void registerPlayerBase() {
+ virtual void registerPlayerBase() {
if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
mPlayerBase->registerWithAudioManager(this);
}
@@ -558,6 +558,11 @@
void setState(aaudio_stream_state_t state);
+ bool isDisconnected() const {
+ return mDisconnected.load();
+ }
+ void setDisconnected();
+
void setDeviceId(int32_t deviceId) {
mDeviceId = deviceId;
}
@@ -664,6 +669,8 @@
std::mutex mStreamLock;
+ const android::sp<MyPlayerBase> mPlayerBase;
+
private:
aaudio_result_t safeStop_l() REQUIRES(mStreamLock);
@@ -679,10 +686,10 @@
close_l();
}
- const android::sp<MyPlayerBase> mPlayerBase;
-
std::atomic<aaudio_stream_state_t> mState{AAUDIO_STREAM_STATE_UNINITIALIZED};
+ std::atomic_bool mDisconnected{false};
+
// These do not change after open().
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
aaudio_channel_mask_t mChannelMask = AAUDIO_UNSPECIFIED;
diff --git a/media/libaaudio/src/flowgraph/Limiter.cpp b/media/libaaudio/src/flowgraph/Limiter.cpp
new file mode 100644
index 0000000..def905a
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/Limiter.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 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 <algorithm>
+#include <math.h>
+#include <unistd.h>
+#include "FlowGraphNode.h"
+#include "Limiter.h"
+
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
+
+Limiter::Limiter(int32_t channelCount)
+ : FlowGraphFilter(channelCount) {
+}
+
+int32_t Limiter::onProcess(int32_t numFrames) {
+ const float *inputBuffer = input.getBuffer();
+ float *outputBuffer = output.getBuffer();
+
+ int32_t numSamples = numFrames * output.getSamplesPerFrame();
+
+ // Cache the last valid output to reduce memory read/write
+ float lastValidOutput = mLastValidOutput;
+
+ for (int32_t i = 0; i < numSamples; i++) {
+ // Use the previous output if the input is NaN
+ if (!isnan(*inputBuffer)) {
+ lastValidOutput = processFloat(*inputBuffer);
+ }
+ inputBuffer++;
+ *outputBuffer++ = lastValidOutput;
+ }
+ mLastValidOutput = lastValidOutput;
+
+ return numFrames;
+}
+
+float Limiter::processFloat(float in)
+{
+ float in_abs = fabsf(in);
+ if (in_abs <= 1) {
+ return in;
+ }
+ float out;
+ if (in_abs < kXWhenYis3Decibels) {
+ out = (kPolynomialSplineA * in_abs + kPolynomialSplineB) * in_abs + kPolynomialSplineC;
+ } else {
+ out = M_SQRT2;
+ }
+ if (in < 0) {
+ out = -out;
+ }
+ return out;
+}
diff --git a/media/libaaudio/src/flowgraph/Limiter.h b/media/libaaudio/src/flowgraph/Limiter.h
new file mode 100644
index 0000000..393a7bf
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/Limiter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2022 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 FLOWGRAPH_LIMITER_H
+#define FLOWGRAPH_LIMITER_H
+
+#include <atomic>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "FlowGraphNode.h"
+
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
+
+class Limiter : public FlowGraphFilter {
+public:
+ explicit Limiter(int32_t channelCount);
+
+ int32_t onProcess(int32_t numFrames) override;
+
+ const char *getName() override {
+ return "Limiter";
+ }
+
+private:
+ // These numbers are based on a polynomial spline for a quadratic solution Ax^2 + Bx + C
+ // The range is up to 3 dB, (10^(3/20)), to match AudioTrack for float data.
+ static constexpr float kPolynomialSplineA = -0.6035533905; // -(1+sqrt(2))/4
+ static constexpr float kPolynomialSplineB = 2.2071067811; // (3+sqrt(2))/2
+ static constexpr float kPolynomialSplineC = -0.6035533905; // -(1+sqrt(2))/4
+ static constexpr float kXWhenYis3Decibels = 1.8284271247; // -1+2sqrt(2)
+
+ /**
+ * Process an input based on the following:
+ * If between -1 and 1, return the input value.
+ * If above kXWhenYis3Decibels, return sqrt(2).
+ * If below -kXWhenYis3Decibels, return -sqrt(2).
+ * If between 1 and kXWhenYis3Decibels, use a quadratic spline (Ax^2 + Bx + C).
+ * If between -kXWhenYis3Decibels and -1, use the absolute value for the spline and flip it.
+ * The derivative of the spline is 1 at 1 and 0 at kXWhenYis3Decibels.
+ * This way, the graph is both continuous and differentiable.
+ */
+ float processFloat(float in);
+
+ // Use the previous valid output for NaN inputs
+ float mLastValidOutput = 0.0f;
+};
+
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
+
+#endif //FLOWGRAPH_LIMITER_H
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index f32ef65..8595308 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -85,7 +85,7 @@
// AudioRecord::Buffer
// TODO define our own AudioBuffer and pass it from the subclasses.
size_t written = buffer.size();
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isDisconnected()) {
ALOGW("%s() data, stream disconnected", __func__);
// This will kill the stream and prevent it from being restarted.
// That is OK because the stream is disconnected.
@@ -150,7 +150,7 @@
// AudioRecord::Buffer
// TODO define our own AudioBuffer and pass it from the subclasses.
size_t written = buffer.size();
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isDisconnected()) {
ALOGW("%s() data, stream disconnected", __func__);
// This will kill the stream and prevent it from being restarted.
// That is OK because the stream is disconnected.
@@ -214,11 +214,11 @@
void AudioStreamLegacy::forceDisconnect(bool errorCallbackEnabled) {
// There is no need to disconnect if already in these states.
- if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED
+ if (!isDisconnected()
&& getState() != AAUDIO_STREAM_STATE_CLOSING
&& getState() != AAUDIO_STREAM_STATE_CLOSED
) {
- setState(AAUDIO_STREAM_STATE_DISCONNECTED);
+ setDisconnected();
if (errorCallbackEnabled) {
maybeCallErrorCallback(AAUDIO_ERROR_DISCONNECTED);
}
@@ -268,7 +268,7 @@
ALOGD("%s(deviceId = %d)", __func__, (int)deviceId);
if (getDeviceId() != AAUDIO_UNSPECIFIED
&& getDeviceId() != deviceId
- && getState() != AAUDIO_STREAM_STATE_DISCONNECTED
+ && !isDisconnected()
) {
// Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING.
// If we have a data callback and the stream is active, then ask the data callback
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 9a136a7..da152b0 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -403,7 +403,7 @@
return result;
}
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isDisconnected()) {
return AAUDIO_ERROR_DISCONNECTED;
}
@@ -446,7 +446,7 @@
// In this context, a DEAD_OBJECT is more likely to be a disconnect notification due to
// AudioRecord invalidation.
if (bytesActuallyRead == DEAD_OBJECT) {
- setState(AAUDIO_STREAM_STATE_DISCONNECTED);
+ setDisconnected();
return AAUDIO_ERROR_DISCONNECTED;
}
return AAudioConvert_androidToAAudioResult(bytesActuallyRead);
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 09caa5c..10bd5f7 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -248,7 +248,7 @@
if (getState() != AAUDIO_STREAM_STATE_UNINITIALIZED) {
ALOGE("%s - Open canceled since state = %d", __func__, getState());
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED)
+ if (isDisconnected())
{
ALOGE("%s - Opening while state is disconnected", __func__);
safeReleaseClose();
@@ -406,7 +406,6 @@
if (err != OK) {
return AAudioConvert_androidToAAudioResult(err);
} else if (position == 0) {
- // TODO Advance frames read to match written.
setState(AAUDIO_STREAM_STATE_FLUSHED);
}
}
@@ -433,7 +432,7 @@
return result;
}
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ if (isDisconnected()) {
return AAUDIO_ERROR_DISCONNECTED;
}
@@ -447,7 +446,7 @@
// in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to
// AudioTrack invalidation
if (bytesWritten == DEAD_OBJECT) {
- setState(AAUDIO_STREAM_STATE_DISCONNECTED);
+ setDisconnected();
return AAUDIO_ERROR_DISCONNECTED;
}
return AAudioConvert_androidToAAudioResult(bytesWritten);
@@ -552,6 +551,16 @@
return status;
}
+void AudioStreamTrack::registerPlayerBase() {
+ AudioStream::registerPlayerBase();
+
+ if (mAudioTrack == nullptr) {
+ ALOGW("%s: cannot set piid, AudioTrack is null", __func__);
+ return;
+ }
+ mAudioTrack->setPlayerIId(mPlayerBase->getPlayerIId());
+}
+
#if AAUDIO_USE_VOLUME_SHAPER
using namespace android::media::VolumeShaper;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index 1f877b5..05609c4 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -87,6 +87,8 @@
android::status_t doSetVolume() override;
+ void registerPlayerBase() override;
+
#if AAUDIO_USE_VOLUME_SHAPER
virtual android::binder::Status applyVolumeShaper(
const android::media::VolumeShaper::Configuration& configuration,
diff --git a/media/libaaudio/tests/test_flowgraph.cpp b/media/libaaudio/tests/test_flowgraph.cpp
index 66b77eb..6f75f5a 100644
--- a/media/libaaudio/tests/test_flowgraph.cpp
+++ b/media/libaaudio/tests/test_flowgraph.cpp
@@ -26,6 +26,7 @@
#include <gtest/gtest.h>
#include "flowgraph/ClipToRange.h"
+#include "flowgraph/Limiter.h"
#include "flowgraph/MonoBlend.h"
#include "flowgraph/MonoToMultiConverter.h"
#include "flowgraph/SourceFloat.h"
@@ -319,3 +320,77 @@
}
}
+TEST(test_flowgraph, module_limiter) {
+ constexpr int kNumSamples = 101;
+ constexpr float kLastSample = 3.0f;
+ constexpr float kFirstSample = -kLastSample;
+ constexpr float kDeltaBetweenSamples = (kLastSample - kFirstSample) / (kNumSamples - 1);
+ constexpr float kTolerance = 0.00001f;
+
+ float input[kNumSamples];
+ float output[kNumSamples];
+ SourceFloat sourceFloat{1};
+ Limiter limiter{1};
+ SinkFloat sinkFloat{1};
+
+ for (int i = 0; i < kNumSamples; i++) {
+ input[i] = kFirstSample + i * kDeltaBetweenSamples;
+ }
+
+ const int numInputFrames = std::size(input);
+ sourceFloat.setData(input, numInputFrames);
+
+ sourceFloat.output.connect(&limiter.input);
+ limiter.output.connect(&sinkFloat.input);
+
+ const int numOutputFrames = std::size(output);
+ int32_t numRead = sinkFloat.read(output, numOutputFrames);
+ ASSERT_EQ(numInputFrames, numRead);
+
+ for (int i = 0; i < numRead; i++) {
+ // limiter must be symmetric wrt 0.
+ EXPECT_NEAR(output[i], -output[kNumSamples - i - 1], kTolerance);
+ if (i > 0) {
+ EXPECT_GE(output[i], output[i - 1]); // limiter must be monotonic
+ }
+ if (input[i] == 0.f) {
+ EXPECT_EQ(0.f, output[i]);
+ } else if (input[i] > 0.0f) {
+ EXPECT_GE(output[i], 0.0f);
+ EXPECT_LE(output[i], M_SQRT2); // limiter actually limits
+ EXPECT_LE(output[i], input[i]); // a limiter, gain <= 1
+ } else {
+ EXPECT_LE(output[i], 0.0f);
+ EXPECT_GE(output[i], -M_SQRT2); // limiter actually limits
+ EXPECT_GE(output[i], input[i]); // a limiter, gain <= 1
+ }
+ if (-1.f <= input[i] && input[i] <= 1.f) {
+ EXPECT_EQ(input[i], output[i]);
+ }
+ }
+}
+
+TEST(test_flowgraph, module_limiter_nan) {
+ constexpr int kArbitraryOutputSize = 100;
+ static const float input[] = {NAN, 0.5f, NAN, NAN, -10.0f, NAN};
+ static const float expected[] = {0.0f, 0.5f, 0.5f, 0.5f, -M_SQRT2, -M_SQRT2};
+ constexpr float tolerance = 0.00001f;
+ float output[kArbitraryOutputSize];
+ SourceFloat sourceFloat{1};
+ Limiter limiter{1};
+ SinkFloat sinkFloat{1};
+
+ const int numInputFrames = std::size(input);
+ sourceFloat.setData(input, numInputFrames);
+
+ sourceFloat.output.connect(&limiter.input);
+ limiter.output.connect(&sinkFloat.input);
+
+ const int numOutputFrames = std::size(output);
+ int32_t numRead = sinkFloat.read(output, numOutputFrames);
+ ASSERT_EQ(numInputFrames, numRead);
+
+ for (int i = 0; i < numRead; i++) {
+ EXPECT_NEAR(expected[i], output[i], tolerance);
+ }
+}
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 79dae27..b6ddf56 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -54,8 +54,10 @@
"AudioVolumeGroup.cpp",
"PolicyAidlConversion.cpp"
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -76,7 +78,6 @@
include_dirs: ["system/media/audio_utils/include"],
export_include_dirs: ["include"],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -116,8 +117,10 @@
"RecordingActivityTracker.cpp",
"TrackPlayerBase.cpp",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -211,7 +214,7 @@
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
@@ -237,8 +240,10 @@
export_header_lib_headers: [
"libaudioclient_aidl_conversion_util",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libbase",
"libbinder",
@@ -250,7 +255,6 @@
"framework-permission-aidl-cpp",
],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libbase",
"shared-file-region-aidl-cpp",
@@ -307,7 +311,7 @@
"aidl/android/media/IEffectClient.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"shared-file-region-aidl",
],
backend: {
@@ -360,7 +364,7 @@
"aidl/android/media/TrackSecondaryOutputInfo.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"framework-permission-aidl",
],
backend: {
@@ -404,7 +408,7 @@
"aidl/android/media/SpatializerHeadTrackingMode.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
],
backend: {
@@ -447,7 +451,7 @@
"aidl/android/media/IAudioTrackCallback.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"av-types-aidl",
"effect-aidl",
@@ -484,7 +488,7 @@
"aidl/android/media/IAudioPolicyServiceClient.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"audiopolicy-types-aidl",
"capture_state_listener-aidl",
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index c2f7229..4d2b6b1 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -71,6 +71,10 @@
return NO_ERROR;
}
+bool AudioMixMatchCriterion::isExcludeCriterion() const {
+ return mRule & RULE_EXCLUSION_MASK;
+}
+
//
// AudioMix implementation
//
@@ -91,10 +95,11 @@
if (size > MAX_CRITERIA_PER_MIX) {
size = MAX_CRITERIA_PER_MIX;
}
+ mCriteria.reserve(size);
for (size_t i = 0; i < size; i++) {
AudioMixMatchCriterion criterion;
if (criterion.readFromParcel(parcel) == NO_ERROR) {
- mCriteria.add(criterion);
+ mCriteria.push_back(criterion);
}
}
return NO_ERROR;
@@ -135,18 +140,18 @@
return NO_ERROR;
}
-void AudioMix::setExcludeUid(uid_t uid) const {
+void AudioMix::setExcludeUid(uid_t uid) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_UID;
crit.mValue.mUid = uid;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
-void AudioMix::setMatchUid(uid_t uid) const {
+void AudioMix::setMatchUid(uid_t uid) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_MATCH_UID;
crit.mValue.mUid = uid;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
bool AudioMix::hasUidRule(bool match, uid_t uid) const {
@@ -169,18 +174,18 @@
return false;
}
-void AudioMix::setExcludeUserId(int userId) const {
+void AudioMix::setExcludeUserId(int userId) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_USERID;
crit.mValue.mUserId = userId;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
-void AudioMix::setMatchUserId(int userId) const {
+void AudioMix::setMatchUserId(int userId) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_MATCH_USERID;
crit.mValue.mUserId = userId;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
bool AudioMix::hasUserIdRule(bool match, int userId) const {
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 965c40f..05f27b0 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1015,7 +1015,7 @@
audio_session_t session,
audio_stream_type_t* stream,
const AttributionSourceState& attributionSource,
- const audio_config_t* config,
+ audio_config_t* config,
audio_output_flags_t flags,
audio_port_handle_t* selectedDeviceId,
audio_port_handle_t* portId,
@@ -1057,9 +1057,18 @@
media::GetOutputForAttrResponse responseAidl;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ status_t status = statusTFromBinderStatus(
aps->getOutputForAttr(attrAidl, sessionAidl, attributionSource, configAidl, flagsAidl,
- selectedDeviceIdAidl, &responseAidl)));
+ selectedDeviceIdAidl, &responseAidl));
+ if (status != NO_ERROR) {
+ config->format = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioFormatDescription_audio_format_t(responseAidl.configBase.format));
+ config->channel_mask = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ responseAidl.configBase.channelMask, false /*isInput*/));
+ config->sample_rate = responseAidl.configBase.sampleRate;
+ return status;
+ }
*output = VALUE_OR_RETURN_STATUS(
aidl2legacy_int32_t_audio_io_handle_t(responseAidl.output));
@@ -1114,7 +1123,7 @@
audio_unique_id_t riid,
audio_session_t session,
const AttributionSourceState &attributionSource,
- const audio_config_base_t* config,
+ audio_config_base_t* config,
audio_input_flags_t flags,
audio_port_handle_t* selectedDeviceId,
audio_port_handle_t* portId) {
@@ -1151,9 +1160,14 @@
media::GetInputForAttrResponse response;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ status_t status = statusTFromBinderStatus(
aps->getInputForAttr(attrAidl, inputAidl, riidAidl, sessionAidl, attributionSource,
- configAidl, flagsAidl, selectedDeviceIdAidl, &response)));
+ configAidl, flagsAidl, selectedDeviceIdAidl, &response));
+ if (status != NO_ERROR) {
+ *config = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioConfigBase_audio_config_base_t(response.config, true /*isInput*/));
+ return status;
+ }
*input = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_io_handle_t(response.input));
*selectedDeviceId = VALUE_OR_RETURN_STATUS(
@@ -2339,6 +2353,9 @@
const AudioDeviceTypeAddrVector &devices,
bool *canBeSpatialized) {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (canBeSpatialized == nullptr) {
+ return BAD_VALUE;
+ }
if (aps == 0) {
return PERMISSION_DENIED;
}
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index ffbb32f..b18a569 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -29,6 +29,7 @@
#include <audio_utils/clock.h>
#include <audio_utils/primitives.h>
#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
#include <media/AudioTrack.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
@@ -42,7 +43,9 @@
#define WAIT_PERIOD_MS 10
#define WAIT_STREAM_END_TIMEOUT_SEC 120
+
static const int kMaxLoopCountNotifications = 32;
+static constexpr char kAudioServiceName[] = "audio";
using ::android::aidl_utils::statusTFromBinderStatus;
using ::android::base::StringPrintf;
@@ -450,7 +453,7 @@
std::string errorMessage;
// Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
- "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
+ "flags %#x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
__func__,
streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
sessionId, transferType, attributionSource.uid, attributionSource.pid);
@@ -1289,6 +1292,10 @@
legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(playbackRate))));
if (status == NO_ERROR) {
mPlaybackRate = playbackRate;
+ } else if (status == INVALID_OPERATION
+ && playbackRate.mSpeed == 1.0f && mPlaybackRate.mPitch == 1.0f) {
+ mPlaybackRate = playbackRate;
+ return NO_ERROR;
}
return status;
}
@@ -1945,6 +1952,9 @@
}
mPortId = output.portId;
+ // notify the upper layers about the new portId
+ triggerPortIdUpdate_l();
+
// We retain a copy of the I/O handle, but don't own the reference
mOutput = output.outputId;
mRefreshRemaining = true;
@@ -3507,12 +3517,34 @@
if (mPlayerIId == playerIId) return;
mPlayerIId = playerIId;
+ triggerPortIdUpdate_l();
mediametrics::LogItem(mMetricsId)
.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETPLAYERIID)
.set(AMEDIAMETRICS_PROP_PLAYERIID, playerIId)
.record();
}
+void AudioTrack::triggerPortIdUpdate_l() {
+ if (mAudioManager == nullptr) {
+ // use checkService() to avoid blocking if audio service is not up yet
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16(kAudioServiceName));
+ if (binder == nullptr) {
+ ALOGE("%s(%d): binding to audio service failed.",
+ __func__,
+ mPlayerIId);
+ return;
+ }
+
+ mAudioManager = interface_cast<IAudioManager>(binder);
+ }
+
+ // first time when the track is created we do not have a valid piid
+ if (mPlayerIId != PLAYER_PIID_INVALID) {
+ mAudioManager->playerEvent(mPlayerIId, PLAYER_UPDATE_PORT_ID, mPortId);
+ }
+}
+
status_t AudioTrack::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
{
diff --git a/media/libaudioclient/PlayerBase.cpp b/media/libaudioclient/PlayerBase.cpp
index 446a58c..651255a 100644
--- a/media/libaudioclient/PlayerBase.cpp
+++ b/media/libaudioclient/PlayerBase.cpp
@@ -58,6 +58,20 @@
}
}
+void PlayerBase::triggerPortIdUpdate(audio_port_handle_t portId) const {
+ if (mAudioManager == nullptr) {
+ ALOGE("%s: no audio service, player %d will not update portId %d",
+ __func__,
+ mPIId,
+ portId);
+ return;
+ }
+
+ if (mPIId != PLAYER_PIID_INVALID && portId != AUDIO_PORT_HANDLE_NONE) {
+ mAudioManager->playerEvent(mPIId, android::PLAYER_UPDATE_PORT_ID, portId);
+ }
+}
+
void PlayerBase::baseDestroy() {
serviceReleasePlayer();
if (mAudioManager != 0) {
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index 51080ef..1aecfc6 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -7,14 +7,6 @@
"name": "audio_aidl_status_tests"
},
{
- "name": "CtsNativeMediaAAudioTestCases",
- "options" : [
- {
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
- }
- ]
- },
- {
"name": "audiorecord_tests"
},
{
@@ -32,5 +24,24 @@
{
"name": "audiosystem_tests"
}
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
+ }
+ ]
+ }
]
}
diff --git a/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
index 9696124..347bf79 100644
--- a/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
@@ -16,6 +16,8 @@
package android.media;
+import android.media.audio.common.AudioConfigBase;
+
/**
* {@hide}
*/
@@ -26,4 +28,6 @@
int selectedDeviceId;
/** Interpreted as audio_port_handle_t. */
int portId;
+ /** The suggested config if fails to get an input. **/
+ AudioConfigBase config;
}
diff --git a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
index f1848b6..5b25d79 100644
--- a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
@@ -16,6 +16,7 @@
package android.media;
+import android.media.audio.common.AudioConfigBase;
import android.media.audio.common.AudioStreamType;
/**
@@ -33,4 +34,6 @@
int[] secondaryOutputs;
/** True if the track is connected to a spatializer mixer and actually spatialized */
boolean isSpatialized;
+ /** The suggested audio config if fails to get an output. **/
+ AudioConfigBase configBase;
}
diff --git a/media/libaudioclient/fuzzer/Android.bp b/media/libaudioclient/fuzzer/Android.bp
index 969e3e6..dd3e3ba 100644
--- a/media/libaudioclient/fuzzer/Android.bp
+++ b/media/libaudioclient/fuzzer/Android.bp
@@ -25,6 +25,9 @@
cc_fuzz {
name: "audioflinger_fuzzer",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
srcs: [
"audioflinger_fuzzer.cpp",
],
@@ -46,7 +49,6 @@
],
shared_libs: [
"android.hardware.audio.common-util",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index 72c050b..291312e 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -648,7 +648,7 @@
{
public:
- EffectClient(AudioEffect *effect) : mEffect(effect){}
+ explicit EffectClient(const sp<AudioEffect>& effect) : mEffect(effect){}
// IEffectClient
binder::Status controlStatusChanged(bool controlGranted) override {
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 08b3da1..cab476e 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -72,6 +72,7 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
+ bool isExcludeCriterion() const;
union {
audio_usage_t mUsage;
audio_source_t mSource;
@@ -88,23 +89,24 @@
static const uint32_t kCbFlagNotifyActivity = 0x1;
AudioMix() {}
- AudioMix(Vector<AudioMixMatchCriterion> criteria, uint32_t mixType, audio_config_t format,
- uint32_t routeFlags, String8 registrationId, uint32_t flags) :
+ AudioMix(const std::vector<AudioMixMatchCriterion> &criteria, uint32_t mixType,
+ audio_config_t format, uint32_t routeFlags,const String8 ®istrationId,
+ uint32_t flags) :
mCriteria(criteria), mMixType(mixType), mFormat(format),
mRouteFlags(routeFlags), mDeviceAddress(registrationId), mCbFlags(flags){}
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
- void setExcludeUid(uid_t uid) const;
- void setMatchUid(uid_t uid) const;
+ void setExcludeUid(uid_t uid);
+ void setMatchUid(uid_t uid);
/** returns true if this mix has a rule to match or exclude the given uid */
bool hasUidRule(bool match, uid_t uid) const;
/** returns true if this mix has a rule for uid match (any uid) */
bool hasMatchUidRule() const;
- void setExcludeUserId(int userId) const;
- void setMatchUserId(int userId) const;
+ void setExcludeUserId(int userId);
+ void setMatchUserId(int userId);
/** returns true if this mix has a rule to match or exclude the given userId */
bool hasUserIdRule(bool match, int userId) const;
/** returns true if this mix has a rule for userId match (any userId) */
@@ -112,7 +114,7 @@
/** returns true if this mix can be used for uid-device affinity routing */
bool isDeviceAffinityCompatible() const;
- mutable Vector<AudioMixMatchCriterion> mCriteria;
+ std::vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
audio_config_t mFormat;
uint32_t mRouteFlags;
@@ -137,6 +139,11 @@
== MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER;
}
+static inline bool is_mix_loopback(uint32_t routeFlags) {
+ return (routeFlags & MIX_ROUTE_FLAG_LOOP_BACK)
+ == MIX_ROUTE_FLAG_LOOP_BACK;
+}
+
}; // namespace android
#endif // ANDROID_AUDIO_POLICY_H
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 9411f46..1c414ec 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -26,8 +26,11 @@
#include <android/media/AudioVibratorInfo.h>
#include <android/media/BnAudioFlingerClient.h>
#include <android/media/BnAudioPolicyServiceClient.h>
+#include <android/media/EffectDescriptor.h>
#include <android/media/INativeSpatializerCallback.h>
#include <android/media/ISpatializer.h>
+#include <android/media/RecordClientInfo.h>
+#include <android/media/audio/common/AudioConfigBase.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <android/media/audio/common/AudioPort.h>
@@ -279,12 +282,31 @@
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
+ /**
+ * Get output stream for given parameters.
+ *
+ * @param[in] attr the requested audio attributes
+ * @param[in|out] output the io handle of the output for the playback. It is specified when
+ * starting mmap thread.
+ * @param[in] session the session id for the client
+ * @param[in|out] stream the stream type used for the playback
+ * @param[in] attributionSource a source to which access to permission protected data
+ * @param[in|out] config the requested configuration client, the suggested configuration will
+ * be returned if no proper output is found for requested configuration
+ * @param[in] flags the requested output flag from client
+ * @param[in|out] selectedDeviceId the requested device id for playback, the actual device id
+ * for playback will be returned
+ * @param[out] portId the generated port id to identify the client
+ * @param[out] secondaryOutputs collection of io handle for secondary outputs
+ * @param[out] isSpatialized true if the playback will be spatialized
+ * @return if the call is successful or not
+ */
static status_t getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
const AttributionSourceState& attributionSource,
- const audio_config_t *config,
+ audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
@@ -294,14 +316,31 @@
static status_t stopOutput(audio_port_handle_t portId);
static void releaseOutput(audio_port_handle_t portId);
- // Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
- // or release it with releaseInput().
+ /**
+ * Get input stream for given parameters.
+ * Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
+ * or release it with releaseInput().
+ *
+ * @param[in] attr the requested audio attributes
+ * @param[in|out] input the io handle of the input for the capture. It is specified when
+ * starting mmap thread.
+ * @param[in] riid an unique id to identify the record client
+ * @param[in] session the session id for the client
+ * @param[in] attributionSource a source to which access to permission protected data
+ * @param[in|out] config the requested configuration client, the suggested configuration will
+ * be returned if no proper input is found for requested configuration
+ * @param[in] flags the requested input flag from client
+ * @param[in|out] selectedDeviceId the requested device id for playback, the actual device id
+ * for playback will be returned
+ * @param[out] portId the generated port id to identify the client
+ * @return if the call is successful or not
+ */
static status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
- const AttributionSourceState& attributionSource,
- const audio_config_base_t *config,
+ const AttributionSourceState& attributionSource,
+ audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId);
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 32576c2..e873607 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIOTRACK_H
#define ANDROID_AUDIOTRACK_H
+#include <audiomanager/IAudioManager.h>
#include <binder/IMemory.h>
#include <cutils/sched_policy.h>
#include <media/AudioSystem.h>
@@ -1145,6 +1146,8 @@
void setAudioTrackCallback(const sp<media::IAudioTrackCallback>& callback) {
mAudioTrackCallback->setAudioTrackCallback(callback);
}
+ private:
+ void triggerPortIdUpdate_l();
protected:
/* copying audio tracks is not allowed */
@@ -1419,6 +1422,9 @@
*/
int mPlayerIId = -1; // AudioManager.h PLAYER_PIID_INVALID
+ /** Interface for interacting with the AudioService. */
+ sp<IAudioManager> mAudioManager;
+
/**
* mLogSessionId is a string identifying this AudioTrack for the metrics service.
* It may be unique or shared with other objects. An empty string means the
diff --git a/media/libaudioclient/include/media/PlayerBase.h b/media/libaudioclient/include/media/PlayerBase.h
index 23b6bfd..5475f76 100644
--- a/media/libaudioclient/include/media/PlayerBase.h
+++ b/media/libaudioclient/include/media/PlayerBase.h
@@ -53,6 +53,10 @@
void baseUpdateDeviceId(audio_port_handle_t deviceId);
+ /**
+ * Updates the mapping in the AudioService between portId and piid
+ */
+ void triggerPortIdUpdate(audio_port_handle_t portId) const;
protected:
void init(player_type_t playerType, audio_usage_t usage, audio_session_t sessionId);
@@ -74,7 +78,6 @@
// player interface ID, uniquely identifies the player in the system
// effectively const after PlayerBase::init().
audio_unique_id_t mPIId;
-
private:
// report events to AudioService
void servicePlayerEvent(player_state_t event, audio_port_handle_t deviceId);
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index e861932..1b09173 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -24,7 +24,10 @@
cc_test {
name: "audio_aidl_conversion_tests",
- defaults: ["libaudioclient_tests_defaults"],
+ defaults: [
+ "libaudioclient_tests_defaults",
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
srcs: ["audio_aidl_legacy_conversion_tests.cpp"],
shared_libs: [
"libbinder",
@@ -33,7 +36,6 @@
"libutils",
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
"libstagefright_foundation",
@@ -100,6 +102,9 @@
"-Wall",
"-Werror",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
shared_libs: [
"capture_state_listener-aidl-cpp",
"framework-permission-aidl-cpp",
@@ -125,7 +130,6 @@
],
static_libs: [
"android.hardware.audio.common@7.0-enums",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/media/libaudioclient/tests/audioclient_serialization_tests.cpp b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
index 93baefd6..ef8500b 100644
--- a/media/libaudioclient/tests/audioclient_serialization_tests.cpp
+++ b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
@@ -189,12 +189,13 @@
TEST_F(SerializationTest, AudioMixBinderization) {
for (int j = 0; j < 512; j++) {
const std::string msg{"Test AMBinderization for seed::" + std::to_string(mSeed)};
- Vector<AudioMixMatchCriterion> criteria;
+ std::vector<AudioMixMatchCriterion> criteria;
+ criteria.reserve(16);
for (int i = 0; i < 16; i++) {
AudioMixMatchCriterion ammc{kUsages[rand() % kUsages.size()],
kInputSources[rand() % kInputSources.size()],
kMixMatchRules[rand() % kMixMatchRules.size()]};
- criteria.add(ammc);
+ criteria.push_back(ammc);
}
audio_config_t config{};
config.sample_rate = 48000;
diff --git a/media/libaudioclient/tests/audioeffect_tests.cpp b/media/libaudioclient/tests/audioeffect_tests.cpp
index 93fe306..e6149e4 100644
--- a/media/libaudioclient/tests/audioeffect_tests.cpp
+++ b/media/libaudioclient/tests/audioeffect_tests.cpp
@@ -19,19 +19,43 @@
#include <gtest/gtest.h>
#include <media/AudioEffect.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_spatializer.h>
#include <system/audio_effects/effect_visualizer.h>
#include "audio_test_utils.h"
using namespace android;
+class AudioEffectCallback : public AudioEffect::IAudioEffectCallback {
+ public:
+ bool receivedFramesProcessed = false;
+
+ void onFramesProcessed(int32_t framesProcessed) override {
+ ALOGE("number of frames processed %d", framesProcessed);
+ receivedFramesProcessed = true;
+ }
+};
+
static constexpr int kDefaultInputEffectPriority = -1;
static constexpr int kDefaultOutputEffectPriority = 0;
static const char* gPackageName = "AudioEffectTest";
-bool isEffectExistsOnAudioSession(const effect_uuid_t* type, int priority,
- audio_session_t sessionId) {
+bool doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7>& ports) {
+ for (const auto& port : ports) {
+ if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_MIX) {
+ if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_FAST) != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+sp<AudioEffect> createEffect(const effect_uuid_t* type, const effect_uuid_t* uuid = nullptr,
+ int priority = 0, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ const wp<AudioEffectCallback>& callback = nullptr) {
std::string packageName{gPackageName};
AttributionSourceState attributionSource;
attributionSource.packageName = packageName;
@@ -39,11 +63,19 @@
attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
attributionSource.token = sp<BBinder>::make();
sp<AudioEffect> effect = new AudioEffect(attributionSource);
- effect->set(type, nullptr /* uid */, priority, nullptr /* callback */, sessionId);
- return effect->initCheck() == ALREADY_EXISTS;
+ effect->set(type, uuid, priority, callback, sessionId, AUDIO_IO_HANDLE_NONE, {}, false,
+ (callback != nullptr));
+ return effect;
}
-bool isEffectDefaultOnRecord(const effect_uuid_t* type, const sp<AudioRecord>& audioRecord) {
+status_t isEffectExistsOnAudioSession(const effect_uuid_t* type, const effect_uuid_t* uuid,
+ int priority, audio_session_t sessionId) {
+ sp<AudioEffect> effect = createEffect(type, uuid, priority, sessionId);
+ return effect->initCheck();
+}
+
+bool isEffectDefaultOnRecord(const effect_uuid_t* type, const effect_uuid_t* uuid,
+ const sp<AudioRecord>& audioRecord) {
effect_descriptor_t descriptors[AudioEffect::kMaxPreProcessing];
uint32_t numEffects = AudioEffect::kMaxPreProcessing;
status_t ret = AudioEffect::queryDefaultPreProcessing(audioRecord->getSessionId(), descriptors,
@@ -52,7 +84,8 @@
return false;
}
for (int i = 0; i < numEffects; i++) {
- if (memcmp(&descriptors[i].type, type, sizeof(effect_uuid_t)) == 0) {
+ if ((memcmp(&descriptors[i].type, type, sizeof(effect_uuid_t)) == 0) &&
+ (memcmp(&descriptors[i].uuid, uuid, sizeof(effect_uuid_t)) == 0)) {
return true;
}
}
@@ -61,11 +94,11 @@
void listEffectsAvailable(std::vector<effect_descriptor_t>& descriptors) {
uint32_t numEffects = 0;
- if (NO_ERROR == AudioEffect::queryNumberEffects(&numEffects)) {
- for (auto i = 0; i < numEffects; i++) {
- effect_descriptor_t des;
- if (NO_ERROR == AudioEffect::queryEffect(i, &des)) descriptors.push_back(des);
- }
+ ASSERT_EQ(NO_ERROR, AudioEffect::queryNumberEffects(&numEffects));
+ for (auto i = 0; i < numEffects; i++) {
+ effect_descriptor_t des;
+ ASSERT_EQ(NO_ERROR, AudioEffect::queryEffect(i, &des));
+ descriptors.push_back(des);
}
}
@@ -81,11 +114,31 @@
return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY);
}
+bool isPostproc(effect_descriptor_t& descriptor) {
+ return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC);
+}
+
bool isFastCompatible(effect_descriptor_t& descriptor) {
return !(((descriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0) &&
((descriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0));
}
+bool isSpatializer(effect_descriptor_t& descriptor) {
+ return (memcmp(&descriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0);
+}
+
+bool isHapticGenerator(effect_descriptor_t& descriptor) {
+ return (memcmp(&descriptor.type, FX_IID_HAPTICGENERATOR, sizeof(effect_uuid_t)) == 0);
+}
+
+std::tuple<std::string, std::string> typeAndUuidToString(const effect_descriptor_t& desc) {
+ char type[512];
+ AudioEffect::guidToString(&desc.type, type, sizeof(type));
+ char uuid[512];
+ AudioEffect::guidToString(&desc.uuid, uuid, sizeof(uuid));
+ return std::make_tuple(type, uuid);
+}
+
// UNIT TESTS
TEST(AudioEffectTest, getEffectDescriptor) {
effect_uuid_t randomType = {
@@ -99,7 +152,7 @@
EFFECT_FLAG_TYPE_MASK, &descriptor));
std::vector<effect_descriptor_t> descriptors;
- listEffectsAvailable(descriptors);
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
for (auto i = 0; i < descriptors.size(); i++) {
EXPECT_EQ(NO_ERROR,
@@ -124,15 +177,7 @@
}
TEST(AudioEffectTest, DISABLED_GetSetParameterForEffect) {
- std::string packageName{gPackageName};
- AttributionSourceState attributionSource;
- attributionSource.packageName = packageName;
- attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
- attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
- attributionSource.token = sp<BBinder>::make();
- sp<AudioEffect> visualizer = new AudioEffect(attributionSource);
- ASSERT_NE(visualizer, nullptr) << "effect not created";
- visualizer->set(SL_IID_VISUALIZATION);
+ sp<AudioEffect> visualizer = createEffect(SL_IID_VISUALIZATION);
status_t status = visualizer->initCheck();
ASSERT_TRUE(status == NO_ERROR || status == ALREADY_EXISTS) << "Init check error";
ASSERT_EQ(NO_ERROR, visualizer->setEnabled(true)) << "visualizer not enabled";
@@ -195,51 +240,58 @@
sp<AudioCapture> capture = nullptr;
std::vector<effect_descriptor_t> descriptors;
- listEffectsAvailable(descriptors);
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
for (auto i = 0; i < descriptors.size(); i++) {
if (isPreprocessing(descriptors[i])) {
capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
EXPECT_EQ(NO_ERROR, capture->create());
EXPECT_EQ(NO_ERROR, capture->start());
- if (!isEffectDefaultOnRecord(&descriptors[i].type, capture->getAudioRecordHandle())) {
+ if (!isEffectDefaultOnRecord(&descriptors[i].type, &descriptors[i].uuid,
+ capture->getAudioRecordHandle())) {
selectedEffect = i;
break;
}
}
}
if (selectedEffect == -1) GTEST_SKIP() << " expected at least one preprocessing effect";
- effect_uuid_t selectedEffectType = descriptors[selectedEffect].type;
- char type[512];
- AudioEffect::guidToString(&selectedEffectType, type, sizeof(type));
-
+ effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
EXPECT_EQ(NO_ERROR, capture->create());
EXPECT_EQ(NO_ERROR, capture->start());
- EXPECT_FALSE(isEffectDefaultOnRecord(&selectedEffectType, capture->getAudioRecordHandle()))
+ EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
<< "Effect should not have been default on record. " << type;
- EXPECT_FALSE(isEffectExistsOnAudioSession(&selectedEffectType, kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ EXPECT_EQ(NO_ERROR,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should not have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
String16 name{gPackageName};
audio_unique_id_t effectId;
- status_t status = AudioEffect::addSourceDefaultEffect(
- type, name, nullptr, kDefaultInputEffectPriority, AUDIO_SOURCE_MIC, &effectId);
+ status_t status = AudioEffect::addSourceDefaultEffect(type.c_str(), name, uuid.c_str(),
+ kDefaultInputEffectPriority,
+ AUDIO_SOURCE_MIC, &effectId);
EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
EXPECT_EQ(NO_ERROR, capture->create());
EXPECT_EQ(NO_ERROR, capture->start());
- EXPECT_TRUE(isEffectDefaultOnRecord(&selectedEffectType, capture->getAudioRecordHandle()))
+ EXPECT_TRUE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
<< "Effect should have been default on record. " << type;
- EXPECT_TRUE(isEffectExistsOnAudioSession(&selectedEffectType, kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ EXPECT_EQ(ALREADY_EXISTS,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
@@ -250,86 +302,258 @@
ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
EXPECT_EQ(NO_ERROR, capture->create());
EXPECT_EQ(NO_ERROR, capture->start());
- EXPECT_FALSE(isEffectDefaultOnRecord(&selectedEffectType, capture->getAudioRecordHandle()))
+ EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
<< "Effect should not have been default on record. " << type;
- EXPECT_FALSE(isEffectExistsOnAudioSession(&selectedEffectType, kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ EXPECT_EQ(NO_ERROR,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should not have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
}
-TEST(AudioEffectTest, ManageStreamDefaultEffects) {
+TEST(AudioEffectTest, AuxEffectSanityTest) {
int32_t selectedEffect = -1;
-
std::vector<effect_descriptor_t> descriptors;
- listEffectsAvailable(descriptors);
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
for (auto i = 0; i < descriptors.size(); i++) {
if (isAux(descriptors[i])) {
selectedEffect = i;
break;
}
}
- if (selectedEffect == -1) GTEST_SKIP() << " expected at least one Aux effect";
+ if (selectedEffect == -1) GTEST_SKIP() << "expected at least one aux effect";
effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
+ String16 name{gPackageName};
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority, sessionId);
+ EXPECT_EQ(NO_INIT, audioEffect->initCheck())
+ << "error, creating auxiliary effect (" << type << ") on session id " << (int)sessionId
+ << " successful ";
+ audio_unique_id_t id;
+ status_t status = AudioEffect::addStreamDefaultEffect(
+ type.c_str(), name, uuid.c_str(), kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
+ if (status == NO_ERROR) {
+ EXPECT_EQ(NO_ERROR, AudioEffect::removeStreamDefaultEffect(id));
+ EXPECT_NE(NO_ERROR, status) << "error, adding auxiliary effect (" << type
+ << ") as stream default effect is successful";
+ }
+}
- char type[512];
- AudioEffect::guidToString(selectedEffectType, type, sizeof(type));
+class AudioPlaybackEffectTest : public ::testing::TestWithParam<bool> {
+ public:
+ AudioPlaybackEffectTest() : mSelectFastMode(GetParam()){};
+
+ const bool mSelectFastMode;
+
+ bool mIsFastCompatibleEffect;
+ effect_uuid_t mType;
+ effect_uuid_t mUuid;
+ std::string mTypeStr;
+ std::string mUuidStr;
+
+ void SetUp() override {
+ if (mSelectFastMode) {
+ std::vector<struct audio_port_v7> ports;
+ ASSERT_EQ(OK, listAudioPorts(ports));
+ if (!doesDeviceSupportLowLatencyMode(ports)) {
+ GTEST_SKIP() << "device does not support low latency mode";
+ }
+ }
+
+ int32_t selectedEffect = -1;
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (isSpatializer(descriptors[i])) continue;
+ if (isHapticGenerator(descriptors[i]) && !AudioSystem::isHapticPlaybackSupported())
+ continue;
+ if (!isInsert(descriptors[i])) continue;
+ selectedEffect = i;
+ mIsFastCompatibleEffect = isFastCompatible(descriptors[i]);
+ // in fast mode, pick fast compatible effect if available
+ if (mSelectFastMode == mIsFastCompatibleEffect) break;
+ }
+ if (selectedEffect == -1) {
+ GTEST_SKIP() << "expected at least one valid effect";
+ }
+
+ mType = descriptors[selectedEffect].type;
+ mUuid = descriptors[selectedEffect].uuid;
+ std::tie(mTypeStr, mUuidStr) = typeAndUuidToString(descriptors[selectedEffect]);
+ }
+};
+
+TEST_P(AudioPlaybackEffectTest, StreamDefaultEffectTest) {
+ SCOPED_TRACE(testing::Message()
+ << "\n selected effect type is :: " << mTypeStr
+ << "\n selected effect uuid is :: " << mUuidStr
+ << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
+ << "\n audio effect is fast compatible : "
+ << (mIsFastCompatibleEffect ? "yes" : "no"));
+
+ bool compatCheck = !mSelectFastMode || (mSelectFastMode && mIsFastCompatibleEffect);
+
// create track
audio_attributes_t attributes;
attributes.usage = AUDIO_USAGE_MEDIA;
attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
auto playback = sp<AudioPlayback>::make(
- 44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
- AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE, AudioTrack::TRANSFER_SHARED, &attributes);
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
ASSERT_NE(nullptr, playback);
ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
- EXPECT_FALSE(isEffectExistsOnAudioSession(selectedEffectType, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
- << "Effect should not have been added. " << type;
+ EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should not have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
playback->stop();
playback.clear();
String16 name{gPackageName};
audio_unique_id_t id;
- status_t status = AudioEffect::addStreamDefaultEffect(
- type, name, nullptr, kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
- EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
+ status_t status = AudioEffect::addStreamDefaultEffect(mTypeStr.c_str(), name, mUuidStr.c_str(),
+ kDefaultOutputEffectPriority,
+ AUDIO_USAGE_MEDIA, &id);
+ EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << mTypeStr;
playback = sp<AudioPlayback>::make(
- 44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
- AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE, AudioTrack::TRANSFER_SHARED, &attributes);
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
ASSERT_NE(nullptr, playback);
ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
EXPECT_EQ(NO_ERROR, playback->create());
- float level = 0.2f, levelGot;
- playback->getAudioTrackHandle()->setAuxEffectSendLevel(level);
EXPECT_EQ(NO_ERROR, playback->start());
- EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
- << "Effect should have been added. " << type;
+ // If effect chosen is not compatible with the session, then effect won't be applied
+ EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
- playback->getAudioTrackHandle()->getAuxEffectSendLevel(&levelGot);
- EXPECT_EQ(level, levelGot);
+ if (mSelectFastMode) {
+ EXPECT_EQ(AUDIO_OUTPUT_FLAG_FAST,
+ playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
+ }
playback->stop();
playback.clear();
status = AudioEffect::removeStreamDefaultEffect(id);
EXPECT_EQ(NO_ERROR, status);
playback = sp<AudioPlayback>::make(
- 44100 /*sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
- AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE, AudioTrack::TRANSFER_SHARED, &attributes);
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
ASSERT_NE(nullptr, playback);
ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
- EXPECT_FALSE(isEffectExistsOnAudioSession(selectedEffectType, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
- << "Effect should not have been added. " << type;
+ EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should not have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
playback->stop();
playback.clear();
}
+
+TEST_P(AudioPlaybackEffectTest, CheckOutputFlagCompatibility) {
+ SCOPED_TRACE(testing::Message()
+ << "\n selected effect type is :: " << mTypeStr
+ << "\n selected effect uuid is :: " << mUuidStr
+ << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
+ << "\n audio effect is fast compatible : "
+ << (mIsFastCompatibleEffect ? "yes" : "no"));
+
+ audio_attributes_t attributes;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
+ sp<AudioEffect> audioEffect =
+ createEffect(&mType, &mUuid, kDefaultOutputEffectPriority, sessionId, cb);
+ ASSERT_EQ(OK, audioEffect->initCheck());
+ ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
+ auto playback = sp<AudioPlayback>::make(
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, sessionId,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+
+ EXPECT_EQ(ALREADY_EXISTS, isEffectExistsOnAudioSession(
+ &mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
+ << "Effect should have been added. " << mTypeStr;
+ if (mSelectFastMode) {
+ EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
+ playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
+ }
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ EXPECT_EQ(NO_ERROR, playback->getAudioTrackHandle()->attachAuxEffect(0));
+ playback->stop();
+ playback.clear();
+ EXPECT_TRUE(cb->receivedFramesProcessed)
+ << "AudioEffect frames processed callback not received";
+}
+
+INSTANTIATE_TEST_SUITE_P(EffectParameterizedTests, AudioPlaybackEffectTest, ::testing::Bool());
+
+TEST(AudioEffectTest, TestHapticEffect) {
+ if (!AudioSystem::isHapticPlaybackSupported())
+ GTEST_SKIP() << "Haptic playback is not supported";
+ int32_t selectedEffect = -1;
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (!isHapticGenerator(descriptors[i])) continue;
+ selectedEffect = i;
+ break;
+ }
+ if (selectedEffect == -1) GTEST_SKIP() << "expected at least one valid effect";
+
+ effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
+
+ SCOPED_TRACE(testing::Message() << "\n selected effect type is :: " << type
+ << "\n selected effect uuid is :: " << uuid);
+
+ audio_attributes_t attributes;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
+ sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultOutputEffectPriority, sessionId, cb);
+ ASSERT_EQ(OK, audioEffect->initCheck());
+ ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
+ auto playback = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
+ sessionId, AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+ EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultOutputEffectPriority - 1, sessionId))
+ << "Effect should have been added. " << type;
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ playback->stop();
+ playback.clear();
+ EXPECT_TRUE(cb->receivedFramesProcessed)
+ << "AudioEffect frames processed callback not received";
+}
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index 159f898..a456a2a 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -27,12 +27,13 @@
"libaudio_system_headers",
"libmedia_helper_headers",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_static",
+ ],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
export_static_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
host_supported: true,
@@ -57,8 +58,11 @@
"DeviceDescriptorBase.cpp",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
+
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
"libaudioutils",
@@ -70,7 +74,6 @@
],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
],
diff --git a/media/libaudiofoundation/TEST_MAPPING b/media/libaudiofoundation/TEST_MAPPING
index efe8437..dbae9a0 100644
--- a/media/libaudiofoundation/TEST_MAPPING
+++ b/media/libaudiofoundation/TEST_MAPPING
@@ -2,12 +2,23 @@
"presubmit": [
{
"name": "audiofoundation_parcelable_test"
- },
+ }
+ ],
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 1f0c768..dc2899a 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -53,7 +53,7 @@
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const {
- return static_cast<AudioPort*>(const_cast<DeviceDescriptorBase*>(this));
+ return sp<AudioPort>::fromExisting(const_cast<DeviceDescriptorBase*>(this));
}
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
diff --git a/media/libaudiofoundation/tests/Android.bp b/media/libaudiofoundation/tests/Android.bp
index 3f1fbea..0e733d3 100644
--- a/media/libaudiofoundation/tests/Android.bp
+++ b/media/libaudiofoundation/tests/Android.bp
@@ -10,6 +10,9 @@
cc_test {
name: "audiofoundation_parcelable_test",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
shared_libs: [
"libbase",
"libbinder",
@@ -18,7 +21,6 @@
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
"libaudiofoundation",
diff --git a/media/libaudiohal/TEST_MAPPING b/media/libaudiohal/TEST_MAPPING
index 3de5a9f..9aff137 100644
--- a/media/libaudiohal/TEST_MAPPING
+++ b/media/libaudiohal/TEST_MAPPING
@@ -1,10 +1,19 @@
{
- "presubmit": [
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index d7217fc..3470380 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -17,6 +17,9 @@
#define LOG_TAG "EffectsFactoryHalHidl"
//#define LOG_NDEBUG 0
+#include <optional>
+#include <tuple>
+
#include <cutils/native_handle.h>
#include <UuidUtils.h>
@@ -38,51 +41,71 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
+class EffectDescriptorCache {
+ public:
+ using QueryResult = std::tuple<Return<void>, Result, hidl_vec<EffectDescriptor>>;
+ QueryResult queryAllDescriptors(IEffectsFactory* effectsFactory);
+ private:
+ std::mutex mLock;
+ std::optional<hidl_vec<EffectDescriptor>> mLastDescriptors; // GUARDED_BY(mLock)
+};
+
+EffectDescriptorCache::QueryResult EffectDescriptorCache::queryAllDescriptors(
+ IEffectsFactory* effectsFactory) {
+ {
+ std::lock_guard l(mLock);
+ if (mLastDescriptors.has_value()) {
+ return {::android::hardware::Void(), Result::OK, mLastDescriptors.value()};
+ }
+ }
+ Result retval = Result::NOT_INITIALIZED;
+ hidl_vec<EffectDescriptor> descriptors;
+ Return<void> ret = effectsFactory->getAllDescriptors(
+ [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+ retval = r;
+ if (retval == Result::OK) {
+ descriptors = result;
+ }
+ });
+ if (ret.isOk() && retval == Result::OK) {
+ std::lock_guard l(mLock);
+ mLastDescriptors = descriptors;
+ }
+ return {std::move(ret), retval, std::move(descriptors)};
+}
+
EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
- : EffectConversionHelperHidl("EffectsFactory") {
+ : EffectConversionHelperHidl("EffectsFactory"), mCache(new EffectDescriptorCache) {
ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
mEffectsFactory = effectsFactory;
}
-status_t EffectsFactoryHalHidl::queryAllDescriptors() {
- if (mEffectsFactory == 0) return NO_INIT;
- Result retval = Result::NOT_INITIALIZED;
- Return<void> ret = mEffectsFactory->getAllDescriptors(
- [&](Result r, const hidl_vec<EffectDescriptor>& result) {
- retval = r;
- if (retval == Result::OK) {
- mLastDescriptors = result;
- }
- });
- if (ret.isOk()) {
- return retval == Result::OK ? OK : NO_INIT;
- }
- mLastDescriptors.resize(0);
- return processReturn(__FUNCTION__, ret);
-}
-
status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
- status_t queryResult = queryAllDescriptors();
- if (queryResult == OK) {
- *pNumEffects = mLastDescriptors.size();
+ if (mEffectsFactory == 0) return NO_INIT;
+ auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
+ if (ret.isOk() && retval == Result::OK) {
+ *pNumEffects = descriptors.size();
+ return OK;
+ } else if (ret.isOk()) {
+ return NO_INIT;
}
- return queryResult;
+ return processReturn(__FUNCTION__, ret);
}
status_t EffectsFactoryHalHidl::getDescriptor(
uint32_t index, effect_descriptor_t *pDescriptor) {
- // TODO: We need somehow to track the changes on the server side
- // or figure out how to convert everybody to query all the descriptors at once.
if (pDescriptor == nullptr) {
return BAD_VALUE;
}
- if (mLastDescriptors.size() == 0) {
- status_t queryResult = queryAllDescriptors();
- if (queryResult != OK) return queryResult;
+ if (mEffectsFactory == 0) return NO_INIT;
+ auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
+ if (ret.isOk() && retval == Result::OK) {
+ if (index >= descriptors.size()) return NAME_NOT_FOUND;
+ EffectUtils::effectDescriptorToHal(descriptors[index], pDescriptor);
+ } else if (ret.isOk()) {
+ return NO_INIT;
}
- if (index >= mLastDescriptors.size()) return NAME_NOT_FOUND;
- EffectUtils::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
- return OK;
+ return processReturn(__FUNCTION__, ret);
}
status_t EffectsFactoryHalHidl::getDescriptor(
@@ -114,21 +137,15 @@
if (pEffectType == nullptr || descriptors == nullptr) {
return BAD_VALUE;
}
+ if (mEffectsFactory == 0) return NO_INIT;
- uint32_t numEffects = 0;
- status_t status = queryNumberEffects(&numEffects);
- if (status != NO_ERROR) {
- ALOGW("%s error %d from FactoryHal queryNumberEffects", __func__, status);
- return status;
+ auto [ret, retval, hidlDescs] = mCache->queryAllDescriptors(mEffectsFactory.get());
+ if (!ret.isOk() || retval != Result::OK) {
+ return processReturn(__FUNCTION__, ret, retval);
}
-
- for (uint32_t i = 0; i < numEffects; i++) {
+ for (const auto& hidlDesc : hidlDescs) {
effect_descriptor_t descriptor;
- status = getDescriptor(i, &descriptor);
- if (status != NO_ERROR) {
- ALOGW("%s error %d from FactoryHal getDescriptor", __func__, status);
- continue;
- }
+ EffectUtils::effectDescriptorToHal(hidlDesc, &descriptor);
if (memcmp(&descriptor.type, pEffectType, sizeof(effect_uuid_t)) == 0) {
descriptors->push_back(descriptor);
}
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index e1882e1..7ccddc6 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
+#include <memory>
+
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
#include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -28,6 +30,8 @@
using ::android::hardware::hidl_vec;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
+class EffectDescriptorCache;
+
class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public EffectConversionHelperHidl
{
public:
@@ -63,9 +67,7 @@
private:
sp<IEffectsFactory> mEffectsFactory;
- hidl_vec<EffectDescriptor> mLastDescriptors;
-
- status_t queryAllDescriptors();
+ std::unique_ptr<EffectDescriptorCache> mCache;
};
} // namespace effect
diff --git a/media/libaudioprocessing/TEST_MAPPING b/media/libaudioprocessing/TEST_MAPPING
index 3de5a9f..9aff137 100644
--- a/media/libaudioprocessing/TEST_MAPPING
+++ b/media/libaudioprocessing/TEST_MAPPING
@@ -1,10 +1,19 @@
{
- "presubmit": [
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/media/liberror/Android.bp b/media/liberror/Android.bp
index f54d354..5e94b0a 100644
--- a/media/liberror/Android.bp
+++ b/media/liberror/Android.bp
@@ -25,7 +25,7 @@
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
@@ -51,7 +51,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libheadtracking/Android.bp b/media/libheadtracking/Android.bp
index 9d63f9b..f64aedf 100644
--- a/media/libheadtracking/Android.bp
+++ b/media/libheadtracking/Android.bp
@@ -22,6 +22,10 @@
"StillnessDetector.cpp",
"Twist.cpp",
],
+ shared_libs: [
+ "libaudioutils",
+ "libbase",
+ ],
export_include_dirs: [
"include",
],
@@ -39,6 +43,7 @@
"SensorPoseProvider.cpp",
],
shared_libs: [
+ "libbase",
"libheadtracking",
"liblog",
"libsensor",
@@ -78,6 +83,7 @@
"Twist-test.cpp",
],
shared_libs: [
+ "libaudioutils",
"libheadtracking",
],
}
diff --git a/media/libheadtracking/HeadTrackingProcessor.cpp b/media/libheadtracking/HeadTrackingProcessor.cpp
index 71fae8a..101b825 100644
--- a/media/libheadtracking/HeadTrackingProcessor.cpp
+++ b/media/libheadtracking/HeadTrackingProcessor.cpp
@@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <inttypes.h>
+#include <android-base/stringprintf.h>
+#include <audio_utils/SimpleLog.h>
#include "media/HeadTrackingProcessor.h"
#include "ModeSelector.h"
@@ -26,6 +29,7 @@
namespace media {
namespace {
+using android::base::StringAppendF;
using Eigen::Quaternionf;
using Eigen::Vector3f;
@@ -84,10 +88,12 @@
}
void calculate(int64_t timestamp) override {
- // Handle the screen first, since it might trigger a recentering of the head.
+ bool screenStable = true;
+
+ // Handle the screen first, since it might: trigger a recentering of the head.
if (mWorldToScreenTimestamp.has_value()) {
const Pose3f worldToLogicalScreen = mScreenPoseBias.getOutput();
- bool screenStable = mScreenStillnessDetector.calculate(timestamp);
+ screenStable = mScreenStillnessDetector.calculate(timestamp);
mModeSelector.setScreenStable(mWorldToScreenTimestamp.value(), screenStable);
// Whenever the screen is unstable, recenter the head pose.
if (!screenStable) {
@@ -101,7 +107,8 @@
if (mWorldToHeadTimestamp.has_value()) {
Pose3f worldToHead = mHeadPoseBias.getOutput();
// Auto-recenter.
- if (mHeadStillnessDetector.calculate(timestamp)) {
+ bool headStable = mHeadStillnessDetector.calculate(timestamp);
+ if (headStable || !screenStable) {
recenter(true, false);
worldToHead = mHeadPoseBias.getOutput();
}
@@ -136,10 +143,12 @@
if (recenterHead) {
mHeadPoseBias.recenter();
mHeadStillnessDetector.reset();
+ mLocalLog.log("recenter Head");
}
if (recenterScreen) {
mScreenPoseBias.recenter();
mScreenStillnessDetector.reset();
+ mLocalLog.log("recenter Screen");
}
// If a sensor being recentered is included in the current mode, apply rate limiting to
@@ -152,6 +161,36 @@
}
}
+ std::string toString_l(unsigned level) const override {
+ std::string prefixSpace(level, ' ');
+ std::string ss = prefixSpace + "HeadTrackingProcessor:\n";
+ StringAppendF(&ss, "%s maxTranslationalVelocity: %f meter/second\n", prefixSpace.c_str(),
+ mOptions.maxTranslationalVelocity);
+ StringAppendF(&ss, "%s maxRotationalVelocity: %f rad/second\n", prefixSpace.c_str(),
+ mOptions.maxRotationalVelocity);
+ StringAppendF(&ss, "%s freshnessTimeout: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.freshnessTimeout));
+ StringAppendF(&ss, "%s predictionDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.predictionDuration));
+ StringAppendF(&ss, "%s autoRecenterWindowDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.autoRecenterWindowDuration));
+ StringAppendF(&ss, "%s autoRecenterTranslationalThreshold: %f meter\n", prefixSpace.c_str(),
+ mOptions.autoRecenterTranslationalThreshold);
+ StringAppendF(&ss, "%s autoRecenterRotationalThreshold: %f radians\n", prefixSpace.c_str(),
+ mOptions.autoRecenterRotationalThreshold);
+ StringAppendF(&ss, "%s screenStillnessWindowDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.screenStillnessWindowDuration));
+ StringAppendF(&ss, "%s screenStillnessTranslationalThreshold: %f meter\n",
+ prefixSpace.c_str(), mOptions.screenStillnessTranslationalThreshold);
+ StringAppendF(&ss, "%s screenStillnessRotationalThreshold: %f radians\n",
+ prefixSpace.c_str(), mOptions.screenStillnessRotationalThreshold);
+ ss += mModeSelector.toString(level + 1);
+ ss += mRateLimiter.toString(level + 1);
+ ss.append(prefixSpace + "ReCenterHistory:\n");
+ ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
+ return ss;
+ }
+
private:
const Options mOptions;
float mPhysicalToLogicalAngle = 0;
@@ -168,6 +207,8 @@
ScreenHeadFusion mScreenHeadFusion;
ModeSelector mModeSelector;
PoseRateLimiter mRateLimiter;
+ static constexpr std::size_t mMaxLocalLogLine = 10;
+ SimpleLog mLocalLog{mMaxLocalLogLine};
};
} // namespace
@@ -177,5 +218,17 @@
return std::make_unique<HeadTrackingProcessorImpl>(options, initialMode);
}
+std::string toString(HeadTrackingMode mode) {
+ switch (mode) {
+ case HeadTrackingMode::STATIC:
+ return "STATIC";
+ case HeadTrackingMode::WORLD_RELATIVE:
+ return "WORLD_RELATIVE";
+ case HeadTrackingMode::SCREEN_RELATIVE:
+ return "SCREEN_RELATIVE";
+ }
+ return "EnumNotImplemented";
+};
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/ModeSelector.cpp b/media/libheadtracking/ModeSelector.cpp
index cb3a27f..6277090 100644
--- a/media/libheadtracking/ModeSelector.cpp
+++ b/media/libheadtracking/ModeSelector.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "ModeSelector.h"
namespace android {
namespace media {
+using android::base::StringAppendF;
ModeSelector::ModeSelector(const Options& options, HeadTrackingMode initialMode)
: mOptions(options), mDesiredMode(initialMode), mActualMode(initialMode) {}
@@ -47,12 +49,15 @@
}
void ModeSelector::calculateActualMode(int64_t timestamp) {
- bool isValidScreenToHead = mScreenToHead.has_value() &&
- timestamp - mScreenToHeadTimestamp < mOptions.freshnessTimeout;
- bool isValidWorldToHead = mWorldToHead.has_value() &&
- timestamp - mWorldToHeadTimestamp < mOptions.freshnessTimeout;
- bool isValidScreenStable = mScreenStable.has_value() &&
- timestamp - mScreenStableTimestamp < mOptions.freshnessTimeout;
+ int64_t screenToHeadGap = timestamp - mScreenToHeadTimestamp;
+ int64_t worldToHeadGap = timestamp - mWorldToHeadTimestamp;
+ int64_t screenStableGap = timestamp - mScreenStableTimestamp;
+ bool isValidScreenToHead =
+ mScreenToHead.has_value() && screenToHeadGap < mOptions.freshnessTimeout;
+ bool isValidWorldToHead =
+ mWorldToHead.has_value() && worldToHeadGap < mOptions.freshnessTimeout;
+ bool isValidScreenStable =
+ mScreenStable.has_value() && screenStableGap < mOptions.freshnessTimeout;
HeadTrackingMode mode = mDesiredMode;
@@ -70,7 +75,17 @@
}
}
- mActualMode = mode;
+ if (mode != mActualMode) {
+ mLocalLog.log(
+ "HT mode change from %s to %s, this ts %0.4f ms, lastTs+gap [ScreenToHead %0.4f + "
+ "%0.4f, WorldToHead %0.4f + %0.4f, ScreenStable %0.4f + %0.4f] ms",
+ media::toString(mActualMode).c_str(), media::toString(mode).c_str(),
+ media::nsToFloatMs(timestamp), media::nsToFloatMs(mScreenToHeadTimestamp),
+ media::nsToFloatMs(screenToHeadGap), media::nsToFloatMs(mWorldToHeadTimestamp),
+ media::nsToFloatMs(worldToHeadGap), media::nsToFloatMs(mScreenStableTimestamp),
+ media::nsToFloatMs(screenStableGap));
+ mActualMode = mode;
+ }
}
void ModeSelector::calculate(int64_t timestamp) {
@@ -99,5 +114,15 @@
return mActualMode;
}
+std::string ModeSelector::toString(unsigned level) const {
+ std::string prefixSpace(level, ' ');
+ std::string ss(prefixSpace);
+ StringAppendF(&ss, "ModeSelector: ScreenToStage %s\n",
+ mScreenToStage.toString().c_str());
+ ss.append(prefixSpace + "Mode downgrade history:\n");
+ ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), sMaxLocalLogLine);
+ return ss;
+}
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/ModeSelector.h b/media/libheadtracking/ModeSelector.h
index e537040..2475a5b 100644
--- a/media/libheadtracking/ModeSelector.h
+++ b/media/libheadtracking/ModeSelector.h
@@ -16,6 +16,7 @@
#pragma once
#include <optional>
+#include <audio_utils/SimpleLog.h>
#include "media/HeadTrackingMode.h"
#include "media/Pose.h"
@@ -114,6 +115,8 @@
*/
HeadTrackingMode getActualMode() const;
+ std::string toString(unsigned level) const;
+
private:
const Options mOptions;
@@ -129,6 +132,9 @@
HeadTrackingMode mActualMode;
Pose3f mHeadToStage;
+ static constexpr std::size_t sMaxLocalLogLine = 10;
+ SimpleLog mLocalLog{sMaxLocalLogLine};
+
void calculateActualMode(int64_t timestamp);
};
diff --git a/media/libheadtracking/Pose.cpp b/media/libheadtracking/Pose.cpp
index ae39512..4a4b56a 100644
--- a/media/libheadtracking/Pose.cpp
+++ b/media/libheadtracking/Pose.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "media/Pose.h"
#include "media/Twist.h"
@@ -21,6 +22,7 @@
namespace android {
namespace media {
+using android::base::StringAppendF;
using Eigen::Vector3f;
std::optional<Pose3f> Pose3f::fromVector(const std::vector<float>& vec) {
@@ -35,6 +37,19 @@
return {mTranslation[0], mTranslation[1], mTranslation[2], rot[0], rot[1], rot[2]};
}
+std::string Pose3f::toString() const {
+ const auto& vec = this->toVector();
+ std::string ss = "[";
+ for (auto f = vec.begin(); f != vec.end(); ++f) {
+ if (f != vec.begin()) {
+ ss.append(", ");
+ }
+ StringAppendF(&ss, "%0.2f", *f);
+ }
+ ss.append("]");
+ return ss;
+}
+
std::tuple<Pose3f, bool> moveWithRateLimit(const Pose3f& from, const Pose3f& to, float t,
float maxTranslationalVelocity,
float maxRotationalVelocity) {
diff --git a/media/libheadtracking/PoseRateLimiter.cpp b/media/libheadtracking/PoseRateLimiter.cpp
index 380e22b..060bb4b 100644
--- a/media/libheadtracking/PoseRateLimiter.cpp
+++ b/media/libheadtracking/PoseRateLimiter.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "PoseRateLimiter.h"
namespace android {
namespace media {
+using android::base::StringAppendF;
PoseRateLimiter::PoseRateLimiter(const Options& options) : mOptions(options), mLimiting(false) {}
@@ -48,5 +50,15 @@
return pose;
}
+std::string PoseRateLimiter::toString(unsigned level) const {
+ std::string ss(level, ' ');
+ if (mLimiting) {
+ StringAppendF(&ss, "PoseRateLimiter: enabled with target: %s\n",
+ mTargetPose.has_value() ? mTargetPose.value().toString().c_str() : "NULL");
+ } else {
+ StringAppendF(&ss, "PoseRateLimiter: disabled\n");
+ }
+ return ss;
+}
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/PoseRateLimiter.h b/media/libheadtracking/PoseRateLimiter.h
index aa2fe80..c673a33 100644
--- a/media/libheadtracking/PoseRateLimiter.h
+++ b/media/libheadtracking/PoseRateLimiter.h
@@ -77,6 +77,8 @@
Pose3f calculatePose(int64_t timestamp);
+ std::string toString(unsigned level) const;
+
private:
struct Point {
Pose3f pose;
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index e5e1521..bd8af04 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -18,12 +18,14 @@
#define LOG_TAG "SensorPoseProvider"
-#include <inttypes.h>
-
+#include <algorithm>
#include <future>
+#include <inttypes.h>
+#include <limits>
#include <map>
#include <thread>
+#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
#include <log/log_main.h>
#include <sensor/SensorEventQueue.h>
@@ -36,6 +38,8 @@
namespace media {
namespace {
+using android::base::StringAppendF;
+
// Identifier to use for our event queue on the loop.
// The number 19 is arbitrary, only useful if using multiple objects on the same looper.
constexpr int kIdent = 19;
@@ -132,7 +136,10 @@
{
std::lock_guard lock(mMutex);
- mEnabledSensorsExtra.emplace(sensor, SensorExtra{ .format = format });
+ mEnabledSensorsExtra.emplace(
+ sensor,
+ SensorExtra{.format = format,
+ .samplingPeriod = static_cast<int32_t>(samplingPeriod.count())});
}
// Enable the sensor.
@@ -153,6 +160,41 @@
mEnabledSensorsExtra.erase(handle);
}
+ std::string toString(unsigned level) override {
+ std::string prefixSpace(level, ' ');
+ std::string ss = prefixSpace + "SensorPoseProvider:\n";
+ bool needUnlock = false;
+
+ prefixSpace += " ";
+ auto now = std::chrono::steady_clock::now();
+ if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
+ ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
+ } else {
+ needUnlock = true;
+ }
+
+ // Enabled sensor information
+ StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
+ mEnabledSensorsExtra.size());
+ for (auto sensor : mEnabledSensorsExtra) {
+ StringAppendF(&ss,
+ "%s[Handle: 0x%08x, Format %s Period (set %d max %0.4f min %0.4f) ms",
+ prefixSpace.c_str(), sensor.first, toString(sensor.second.format).c_str(),
+ sensor.second.samplingPeriod, media::nsToFloatMs(sensor.second.maxPeriod),
+ media::nsToFloatMs(sensor.second.minPeriod));
+ if (sensor.second.discontinuityCount.has_value()) {
+ StringAppendF(&ss, ", DiscontinuityCount: %d",
+ sensor.second.discontinuityCount.value());
+ }
+ ss += "]\n";
+ }
+
+ if (needUnlock) {
+ mMutex.unlock();
+ }
+ return ss;
+ }
+
private:
enum DataFormat {
kUnknown,
@@ -167,14 +209,18 @@
};
struct SensorExtra {
- DataFormat format;
+ DataFormat format = DataFormat::kUnknown;
+ int32_t samplingPeriod = 0;
+ int64_t latestTimestamp = 0;
+ int64_t maxPeriod = 0;
+ int64_t minPeriod = std::numeric_limits<int64_t>::max();
std::optional<int32_t> discontinuityCount;
};
sp<Looper> mLooper;
Listener* const mListener;
SensorManager* const mSensorManager;
- std::mutex mMutex;
+ std::timed_mutex mMutex;
std::map<int32_t, SensorEnableGuard> mEnabledSensors;
std::map<int32_t, SensorExtra> mEnabledSensorsExtra GUARDED_BY(mMutex);
sp<SensorEventQueue> mQueue;
@@ -193,7 +239,6 @@
mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))) {
mThread = std::thread([this] { threadFunc(); });
}
-
void initFinished(bool success) { mInitPromise.set_value(success); }
bool waitInitFinished() { return mInitPromise.get_future().get(); }
@@ -262,6 +307,7 @@
return;
}
value = parseEvent(event, iter->second.format, &iter->second.discontinuityCount);
+ updateEventTimestamp(event, iter->second);
}
mListener->onPose(event.timestamp, event.sensor, value.pose, value.twist,
value.isNewReference);
@@ -317,6 +363,15 @@
return std::nullopt;
}
+ void updateEventTimestamp(const ASensorEvent& event, SensorExtra& extra) {
+ if (extra.latestTimestamp != 0) {
+ int64_t gap = event.timestamp - extra.latestTimestamp;
+ extra.maxPeriod = std::max(gap, extra.maxPeriod);
+ extra.minPeriod = std::min(gap, extra.minPeriod);
+ }
+ extra.latestTimestamp = event.timestamp;
+ }
+
static PoseEvent parseEvent(const ASensorEvent& event, DataFormat format,
std::optional<int32_t>* discontinutyCount) {
switch (format) {
@@ -346,6 +401,19 @@
LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
}
}
+
+ const static std::string toString(DataFormat format) {
+ switch (format) {
+ case DataFormat::kUnknown:
+ return "kUnknown";
+ case DataFormat::kQuaternion:
+ return "kQuaternion";
+ case DataFormat::kRotationVectorsAndDiscontinuityCount:
+ return "kRotationVectorsAndDiscontinuityCount";
+ default:
+ return "NotImplemented";
+ }
+ }
};
} // namespace
diff --git a/media/libheadtracking/StillnessDetector.cpp b/media/libheadtracking/StillnessDetector.cpp
index be7c893..5232084 100644
--- a/media/libheadtracking/StillnessDetector.cpp
+++ b/media/libheadtracking/StillnessDetector.cpp
@@ -26,6 +26,9 @@
mFifo.clear();
mWindowFull = false;
mSuppressionDeadline.reset();
+ // A "true" state indicates stillness is detected (default = true)
+ mCurrentState = true;
+ mPreviousState = true;
}
void StillnessDetector::setInput(int64_t timestamp, const Pose3f& input) {
@@ -33,7 +36,15 @@
discardOld(timestamp);
}
+bool StillnessDetector::getPreviousState() const {
+ return mPreviousState;
+}
+
bool StillnessDetector::calculate(int64_t timestamp) {
+ // Move the current stillness state to the previous state.
+ // This allows us to detect transitions into and out of stillness.
+ mPreviousState = mCurrentState;
+
discardOld(timestamp);
// Check whether all the poses in the queue are in the proximity of the new one. We want to do
@@ -60,15 +71,17 @@
// If the window has not been full, return the default value.
if (!mWindowFull) {
- return mOptions.defaultValue;
+ mCurrentState = mOptions.defaultValue;
}
-
// Force "in motion" while the suppression deadline is active.
- if (mSuppressionDeadline.has_value()) {
- return false;
+ else if (mSuppressionDeadline.has_value()) {
+ mCurrentState = false;
+ }
+ else {
+ mCurrentState = !moved;
}
- return !moved;
+ return mCurrentState;
}
void StillnessDetector::discardOld(int64_t timestamp) {
diff --git a/media/libheadtracking/StillnessDetector.h b/media/libheadtracking/StillnessDetector.h
index ee4b2d8..abd7cc4 100644
--- a/media/libheadtracking/StillnessDetector.h
+++ b/media/libheadtracking/StillnessDetector.h
@@ -80,7 +80,8 @@
void setInput(int64_t timestamp, const Pose3f& input);
/** Calculate whether the stream is still at the given timestamp. */
bool calculate(int64_t timestamp);
-
+ /** Return the stillness state from the previous call to calculate() */
+ bool getPreviousState() const;
private:
struct TimestampedPose {
int64_t timestamp;
@@ -92,6 +93,8 @@
const float mCosHalfRotationalThreshold;
std::deque<TimestampedPose> mFifo;
bool mWindowFull = false;
+ bool mCurrentState = true;
+ bool mPreviousState = true;
// As soon as motion is detected, this will be set for the time of detection + window duration,
// and during this time we will always consider outselves in motion without checking. This is
// used for hyteresis purposes, since because of the approximate method we use for determining
diff --git a/media/libheadtracking/include/media/HeadTrackingMode.h b/media/libheadtracking/include/media/HeadTrackingMode.h
index 38496e8..92d1165 100644
--- a/media/libheadtracking/include/media/HeadTrackingMode.h
+++ b/media/libheadtracking/include/media/HeadTrackingMode.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#include <string>
+
namespace android {
namespace media {
@@ -30,5 +32,7 @@
SCREEN_RELATIVE,
};
+std::string toString(HeadTrackingMode mode);
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/include/media/HeadTrackingProcessor.h b/media/libheadtracking/include/media/HeadTrackingProcessor.h
index 1744be3..8ef8ab0 100644
--- a/media/libheadtracking/include/media/HeadTrackingProcessor.h
+++ b/media/libheadtracking/include/media/HeadTrackingProcessor.h
@@ -96,8 +96,12 @@
* This causes the current poses for both the head and/or screen to be considered "center".
*/
virtual void recenter(bool recenterHead = true, bool recenterScreen = true) = 0;
-};
+ /**
+ * Dump HeadTrackingProcessor parameters under caller lock.
+ */
+ virtual std::string toString_l(unsigned level) const = 0;
+};
/**
* Creates an instance featuring a default implementation of the HeadTrackingProcessor interface.
*/
diff --git a/media/libheadtracking/include/media/Pose.h b/media/libheadtracking/include/media/Pose.h
index e660bb9..50294ed 100644
--- a/media/libheadtracking/include/media/Pose.h
+++ b/media/libheadtracking/include/media/Pose.h
@@ -16,6 +16,7 @@
#pragma once
#include <optional>
+#include <string>
#include <vector>
#include <Eigen/Geometry>
@@ -63,6 +64,9 @@
*/
std::vector<float> toVector() const;
+ // Convert instance to a string representation.
+ std::string toString() const;
+
Pose3f& operator=(const Pose3f& other) {
mTranslation = other.mTranslation;
mRotation = other.mRotation;
@@ -128,5 +132,10 @@
float maxTranslationalVelocity,
float maxRotationalVelocity);
+template <typename T>
+static float nsToFloatMs(T ns) {
+ return ns * 1e-6f;
+}
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/include/media/SensorPoseProvider.h b/media/libheadtracking/include/media/SensorPoseProvider.h
index 0f42074..4609e0c 100644
--- a/media/libheadtracking/include/media/SensorPoseProvider.h
+++ b/media/libheadtracking/include/media/SensorPoseProvider.h
@@ -28,6 +28,9 @@
namespace android {
namespace media {
+// Timeout for Spatializer dumpsys trylock, don't block for more than 3 seconds.
+constexpr auto kSpatializerDumpSysTimeOutInSecond = std::chrono::seconds(3);
+
/**
* A utility providing streaming of pose data from motion sensors provided by the Sensor Framework.
*
@@ -100,6 +103,11 @@
* discover properties of the sensor.
*/
virtual std::optional<const Sensor> getSensorByHandle(int32_t handle) = 0;
+
+ /**
+ * Dump SensorPoseProvider parameters and history data.
+ */
+ virtual std::string toString(unsigned level) = 0;
};
} // namespace media
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 2dd5784..ab1cf69 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -304,6 +304,10 @@
cc_library {
name: "libmedia",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
":mediaextractorservice_aidl",
"IDataSource.cpp",
@@ -356,7 +360,6 @@
shared_libs: [
"android.hidl.token@1.0-utils",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
"liblog",
diff --git a/media/libmedia/include/media/mediaplayer.h b/media/libmedia/include/media/mediaplayer.h
index de4c7db..b45dae5 100644
--- a/media/libmedia/include/media/mediaplayer.h
+++ b/media/libmedia/include/media/mediaplayer.h
@@ -195,7 +195,8 @@
INVOKE_ID_SELECT_TRACK = 4,
INVOKE_ID_UNSELECT_TRACK = 5,
INVOKE_ID_SET_VIDEO_SCALING_MODE = 6,
- INVOKE_ID_GET_SELECTED_TRACK = 7
+ INVOKE_ID_GET_SELECTED_TRACK = 7,
+ INVOKE_ID_SET_PLAYER_IID = 8,
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/tests/codeclist/Android.bp b/media/libmedia/tests/codeclist/Android.bp
index 2ed3126..d4494f6 100644
--- a/media/libmedia/tests/codeclist/Android.bp
+++ b/media/libmedia/tests/codeclist/Android.bp
@@ -25,7 +25,7 @@
cc_test {
name: "CodecListTest",
- test_suites: ["device-tests", "mts"],
+ test_suites: ["device-tests", "mts-media"],
gtest: true,
// Support multilib variants (using different suffix per sub-architecture), which is needed on
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 165a8ad..c66861b 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -20,7 +20,7 @@
},
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index 1c30510..bebd382 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -57,6 +57,10 @@
// The Audio Spatializer key appends the spatializerId (currently 0)
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER AMEDIAMETRICS_KEY_PREFIX_AUDIO "spatializer."
+// The Audio Spatializer device key appends the device type.
+#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER_DEVICE \
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "device."
+
// The AudioStream key appends the "streamId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM AMEDIAMETRICS_KEY_PREFIX_AUDIO "stream."
@@ -107,6 +111,7 @@
// of suppressed in the Time Machine.
#define AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED '#'
+#define AMEDIAMETRICS_PROP_ADDRESS "address" // string, for example MAC address
#define AMEDIAMETRICS_PROP_ALLOWUID "_allowUid" // int32_t, allow client uid to post
#define AMEDIAMETRICS_PROP_AUDIOMODE "audioMode" // string (audio.flinger)
#define AMEDIAMETRICS_PROP_AUXEFFECTID "auxEffectId" // int32 (AudioTrack)
@@ -116,6 +121,8 @@
#define AMEDIAMETRICS_PROP_CALLERNAME "callerName" // string, eg. "aaudio"
#define AMEDIAMETRICS_PROP_CHANNELCOUNT "channelCount" // int32
#define AMEDIAMETRICS_PROP_CHANNELMASK "channelMask" // int32
+#define AMEDIAMETRICS_PROP_CHANNELMASKS "channelMasks" // string with channelMask values
+ // separated by |.
#define AMEDIAMETRICS_PROP_CONTENTTYPE "contentType" // string attributes (AudioTrack)
#define AMEDIAMETRICS_PROP_CUMULATIVETIMENS "cumulativeTimeNs" // int64_t playback/record time
// since start
@@ -132,6 +139,7 @@
#define AMEDIAMETRICS_PROP_DIRECTION "direction" // string AAudio input or output
#define AMEDIAMETRICS_PROP_DURATIONNS "durationNs" // int64 duration time span
+#define AMEDIAMETRICS_PROP_ENABLED "enabled" // string true/false.
#define AMEDIAMETRICS_PROP_ENCODING "encoding" // string value of format
#define AMEDIAMETRICS_PROP_EVENT "event#" // string value (often func name)
@@ -141,6 +149,8 @@
#define AMEDIAMETRICS_PROP_FLAGS "flags"
#define AMEDIAMETRICS_PROP_FRAMECOUNT "frameCount" // int32
+#define AMEDIAMETRICS_PROP_HASHEADTRACKER "hasHeadTracker" // string true/false
+#define AMEDIAMETRICS_PROP_HEADTRACKERENABLED "headTrackerEnabled" // string true/false
#define AMEDIAMETRICS_PROP_HEADTRACKINGMODES "headTrackingModes" // string |, like modes.
#define AMEDIAMETRICS_PROP_INPUTDEVICES "inputDevices" // string value
#define AMEDIAMETRICS_PROP_INTERNALTRACKID "internalTrackId" // int32
diff --git a/media/libmediametrics/libmediametrics.map.txt b/media/libmediametrics/libmediametrics.map.txt
index c46281a..f37af64 100644
--- a/media/libmediametrics/libmediametrics.map.txt
+++ b/media/libmediametrics/libmediametrics.map.txt
@@ -1,29 +1,29 @@
LIBMEDIAMETRICS_1 {
global:
- mediametrics_addDouble; # apex
- mediametrics_addInt32; # apex
- mediametrics_addInt64; # apex
- mediametrics_addRate; # apex
- mediametrics_count; # apex
- mediametrics_create; # apex
- mediametrics_delete; # apex
- mediametrics_freeCString; # apex
- mediametrics_getAttributes; # apex
- mediametrics_getCString; # apex
- mediametrics_getDouble; # apex
- mediametrics_getInt32; # apex
- mediametrics_getInt64; # apex
- mediametrics_getKey; # apex
- mediametrics_getRate; # apex
- mediametrics_isEnabled; # apex
- mediametrics_readable; # apex
- mediametrics_selfRecord; # apex
- mediametrics_setCString; # apex
- mediametrics_setDouble; # apex
- mediametrics_setInt32; # apex
- mediametrics_setInt64; # apex
- mediametrics_setRate; # apex
- mediametrics_setUid; # apex
+ mediametrics_addDouble; # systemapi
+ mediametrics_addInt32; # systemapi
+ mediametrics_addInt64; # systemapi
+ mediametrics_addRate; # systemapi
+ mediametrics_count; # systemapi
+ mediametrics_create; # systemapi
+ mediametrics_delete; # systemapi
+ mediametrics_freeCString; # systemapi
+ mediametrics_getAttributes; # systemapi
+ mediametrics_getCString; # systemapi
+ mediametrics_getDouble; # systemapi
+ mediametrics_getInt32; # systemapi
+ mediametrics_getInt64; # systemapi
+ mediametrics_getKey; # systemapi
+ mediametrics_getRate; # systemapi
+ mediametrics_isEnabled; # systemapi
+ mediametrics_readable; # systemapi
+ mediametrics_selfRecord; # systemapi
+ mediametrics_setCString; # systemapi
+ mediametrics_setDouble; # systemapi
+ mediametrics_setInt32; # systemapi
+ mediametrics_setInt64; # systemapi
+ mediametrics_setRate; # systemapi
+ mediametrics_setUid; # systemapi
local:
*;
};
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8e19d02..f3cbdb0 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1805,7 +1805,8 @@
MediaPlayerService::AudioOutput::AudioOutput(audio_session_t sessionId,
const AttributionSourceState& attributionSource, const audio_attributes_t* attr,
const sp<AudioSystem::AudioDeviceCallback>& deviceCallback)
- : mCallback(NULL),
+ : mCachedPlayerIId(PLAYER_PIID_INVALID),
+ mCallback(NULL),
mCallbackCookie(NULL),
mCallbackData(NULL),
mStreamType(AUDIO_STREAM_MUSIC),
@@ -2314,6 +2315,10 @@
return t->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
});
+ if (mCachedPlayerIId != PLAYER_PIID_INVALID) {
+ t->setPlayerIId(mCachedPlayerIId);
+ }
+
mSampleRateHz = sampleRate;
mFlags = flags;
mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
@@ -2366,6 +2371,17 @@
return NO_INIT;
}
+void MediaPlayerService::AudioOutput::setPlayerIId(int32_t playerIId)
+{
+ ALOGV("setPlayerIId(%d)", playerIId);
+ Mutex::Autolock lock(mLock);
+ mCachedPlayerIId = playerIId;
+
+ if (mTrack != nullptr) {
+ mTrack->setPlayerIId(mCachedPlayerIId);
+ }
+}
+
void MediaPlayerService::AudioOutput::setNextOutput(const sp<AudioOutput>& nextOutput) {
Mutex::Autolock lock(mLock);
mNextOutput = nextOutput;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 86be3fe..52c2f79 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -113,6 +113,8 @@
bool doNotReconnect = false,
uint32_t suggestedFrameCount = 0);
+ virtual void setPlayerIId(int32_t playerIId);
+
virtual status_t start();
virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
virtual void stop();
@@ -160,6 +162,7 @@
sp<AudioTrack> mTrack;
sp<AudioTrack> mRecycledTrack;
sp<AudioOutput> mNextOutput;
+ int mCachedPlayerIId;
AudioCallback mCallback;
void * mCallbackCookie;
sp<CallbackData> mCallbackData;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index ea1fdf4..a0bc8ca 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1966,6 +1966,10 @@
format->setString("mime", MEDIA_MIMETYPE_VIDEO_HEVC);
break;
+ case VIDEO_ENCODER_DOLBY_VISION:
+ format->setString("mime", MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
+ break;
+
default:
CHECK(!"Should not be here, unsupported video encoding.");
break;
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 1cbd8a0..fb20aab 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -123,6 +123,8 @@
bool doNotReconnect = false,
uint32_t suggestedFrameCount = 0) = 0;
+ virtual void setPlayerIId(int32_t playerIId) = 0;
+
virtual status_t start() = 0;
/* Input parameter |size| is in byte units stored in |buffer|.
diff --git a/media/libmediaplayerservice/nuplayer/Android.bp b/media/libmediaplayerservice/nuplayer/Android.bp
index 71a3168..911463b 100644
--- a/media/libmediaplayerservice/nuplayer/Android.bp
+++ b/media/libmediaplayerservice/nuplayer/Android.bp
@@ -17,6 +17,14 @@
],
}
+cc_library_headers {
+ name: "libstagefright_nuplayer_headers",
+
+ export_include_dirs: [
+ "include",
+ ],
+}
+
cc_library_static {
srcs: [
@@ -81,6 +89,7 @@
static_libs: [
"libplayerservice_datasource",
+ "libstagefright_esds",
"libstagefright_timedtext",
],
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 9b4fc8f..4851684 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -60,7 +60,7 @@
#include <gui/Surface.h>
-#include "ESDS.h"
+#include <media/esds/ESDS.h>
#include <media/stagefright/Utils.h>
namespace android {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 2a50fc2..ceea2f4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -26,6 +26,7 @@
#include "NuPlayer.h"
#include "NuPlayerSource.h"
+#include <audiomanager/AudioManager.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AUtils.h>
@@ -85,6 +86,7 @@
mMediaClock(new MediaClock),
mPlayer(new NuPlayer(pid, mMediaClock)),
mPlayerFlags(0),
+ mCachedPlayerIId(PLAYER_PIID_INVALID),
mMetricsItem(NULL),
mClientUid(-1),
mAtEOS(false),
@@ -804,6 +806,16 @@
return mPlayer->getSelectedTrack(type, reply);
}
+ case INVOKE_ID_SET_PLAYER_IID:
+ {
+ Mutex::Autolock autoLock(mAudioSinkLock);
+ mCachedPlayerIId = request.readInt32();
+ if (mAudioSink != nullptr) {
+ mAudioSink->setPlayerIId(mCachedPlayerIId);
+ }
+ return OK;
+ }
+
default:
{
return INVALID_OPERATION;
@@ -812,8 +824,12 @@
}
void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
+ Mutex::Autolock autoLock(mAudioSinkLock);
mPlayer->setAudioSink(audioSink);
mAudioSink = audioSink;
+ if (mCachedPlayerIId != PLAYER_PIID_INVALID) {
+ mAudioSink->setPlayerIId(mCachedPlayerIId);
+ }
}
status_t NuPlayerDriver::setParameter(
@@ -1027,6 +1043,7 @@
if (mState != STATE_RESET_IN_PROGRESS) {
if (mAutoLoop) {
audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
+ Mutex::Autolock autoLock(mAudioSinkLock);
if (mAudioSink != NULL) {
streamType = mAudioSink->getAudioStreamType();
}
@@ -1037,6 +1054,7 @@
}
if (mLooping || mAutoLoop) {
mPlayer->seekToAsync(0);
+ Mutex::Autolock autoLock(mAudioSinkLock);
if (mAudioSink != NULL) {
// The renderer has stopped the sink at the end in order to play out
// the last little bit of audio. If we're looping, we need to restart it.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 45fac76..0382df3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1947,22 +1947,12 @@
CHECK(format->findInt32("channel-count", &numChannels));
// channel mask info as read from the audio format
- int32_t channelMaskFromFormat;
+ int32_t mediaFormatChannelMask;
// channel mask to use for native playback
audio_channel_mask_t channelMask;
- if (format->findInt32("channel-mask", &channelMaskFromFormat)) {
+ if (format->findInt32("channel-mask", &mediaFormatChannelMask)) {
// KEY_CHANNEL_MASK follows the android.media.AudioFormat java mask
- // which is left-bitshifted by 2 relative to the native mask
- if ((channelMaskFromFormat & 0b11) != 0) {
- // received an unexpected mask (supposed to follow AudioFormat constants
- // for output masks with the 2 least-significant bits at 0), but
- // it may come from an extractor that uses native masks: keeping
- // the mask as given is ok as it contains at least mono or stereo
- // and potentially the haptic channels
- channelMask = static_cast<audio_channel_mask_t>(channelMaskFromFormat);
- } else {
- channelMask = static_cast<audio_channel_mask_t>(channelMaskFromFormat >> 2);
- }
+ channelMask = audio_channel_mask_from_media_format_mask(mediaFormatChannelMask);
} else {
// no mask found: the mask will be derived from the channel count
channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
diff --git a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerDriver.h
index 55a0fad..138cd6f 100644
--- a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerDriver.h
@@ -140,9 +140,12 @@
sp<ALooper> mLooper;
const sp<MediaClock> mMediaClock;
const sp<NuPlayer> mPlayer;
- sp<AudioSink> mAudioSink;
uint32_t mPlayerFlags;
+ mutable Mutex mAudioSinkLock;
+ sp<AudioSink> mAudioSink GUARDED_BY(mAudioSinkLock);
+ int32_t mCachedPlayerIId GUARDED_BY(mAudioSinkLock);
+
mediametrics::Item *mMetricsItem;
mutable Mutex mMetricsLock;
uid_t mClientUid;
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index 2beb47f..30f6a91 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -25,8 +25,8 @@
#include <aidl/android/media/BnResourceManagerService.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/ProcessInfoInterface.h>
#include <mediadrm/DrmSessionManager.h>
+#include <mediautils/ProcessInfoInterface.h>
#include <algorithm>
#include <iostream>
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 10baec4..e4ba0b8 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -33,75 +33,6 @@
},
}
-cc_library_static {
- name: "libstagefright_esds",
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- ],
- min_sdk_version: "29",
-
- srcs: ["ESDS.cpp"],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
- sanitize: {
- misc_undefined: [
- "signed-integer-overflow",
- ],
- cfi: true,
- },
- shared_libs: [
- "libstagefright_foundation",
- "libutils"
- ],
- host_supported: true,
- target: {
- darwin: {
- enabled: false,
- },
- },
-}
-
-cc_library_static {
- name: "libstagefright_metadatautils",
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- ],
- min_sdk_version: "29",
-
- srcs: ["MetaDataUtils.cpp"],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
- sanitize: {
- misc_undefined: [
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-
- header_libs: [
- "libaudioclient_headers",
- "libstagefright_foundation_headers",
- "media_ndk_headers",
- ],
-
- host_supported: true,
- target: {
- darwin: {
- enabled: false,
- },
- },
-
- export_include_dirs: ["include"],
-}
-
cc_library_shared {
name: "libstagefright_codecbase",
@@ -166,6 +97,10 @@
"liblog",
],
+ static_libs: [
+ "libstagefright_esds",
+ ],
+
export_include_dirs: [
"include",
],
diff --git a/media/libstagefright/DataConverter.cpp b/media/libstagefright/DataConverter.cpp
index 52be054..b53ac77 100644
--- a/media/libstagefright/DataConverter.cpp
+++ b/media/libstagefright/DataConverter.cpp
@@ -24,6 +24,10 @@
#include <media/MediaCodecBuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
+#include <system/audio.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/format.h>
+
namespace android {
@@ -81,12 +85,38 @@
return numSamples * mTargetSampleSize;
}
+static audio_format_t getAudioFormat(AudioEncoding e) {
+ audio_format_t format = AUDIO_FORMAT_INVALID;
+ switch (e) {
+ case kAudioEncodingPcm16bit:
+ format = AUDIO_FORMAT_PCM_16_BIT;
+ break;
+ case kAudioEncodingPcm8bit:
+ format = AUDIO_FORMAT_PCM_8_BIT;
+ break;
+ case kAudioEncodingPcmFloat:
+ format = AUDIO_FORMAT_PCM_FLOAT;
+ break;
+ case kAudioEncodingPcm24bitPacked:
+ format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ break;
+ case kAudioEncodingPcm32bit:
+ format = AUDIO_FORMAT_PCM_32_BIT;
+ break;
+ default:
+ ALOGE("Invalid AudioEncoding %d", e);
+ }
+ return format;
+}
static size_t getAudioSampleSize(AudioEncoding e) {
switch (e) {
- case kAudioEncodingPcm16bit: return 2;
- case kAudioEncodingPcm8bit: return 1;
- case kAudioEncodingPcmFloat: return 4;
+ case kAudioEncodingPcm16bit:
+ case kAudioEncodingPcm8bit:
+ case kAudioEncodingPcmFloat:
+ case kAudioEncodingPcm24bitPacked:
+ case kAudioEncodingPcm32bit:
+ return audio_bytes_per_sample(getAudioFormat(e));
default: return 0;
}
}
@@ -116,7 +146,15 @@
} else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) {
memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
} else {
- return INVALID_OPERATION;
+ audio_format_t srcFormat = getAudioFormat(mFrom);
+ audio_format_t dstFormat = getAudioFormat(mTo);
+
+ if ((srcFormat == AUDIO_FORMAT_INVALID) || (dstFormat == AUDIO_FORMAT_INVALID))
+ return INVALID_OPERATION;
+
+ size_t frames = src->size() / audio_bytes_per_sample(srcFormat);
+ memcpy_by_audio_format((void*)tgt->base(), dstFormat, (void*)src->data(),
+ srcFormat, frames);
}
return OK;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 34b840e..fbc684b 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -30,7 +30,7 @@
#include <media/stagefright/MetaData.h>
#include <arpa/inet.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
namespace android {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 9ff2177..a78fb30 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -51,7 +51,7 @@
#include <media/mediarecorder.h>
#include <cutils/properties.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include "include/HevcUtils.h"
#ifndef __predict_false
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 6893324..b4baf03 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -20,7 +20,7 @@
#include <media/stagefright/NuMediaExtractor.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include <datasource/DataSourceFactory.h>
#include <datasource/FileSource.h>
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 900ac32..fd30b35 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -24,7 +24,7 @@
#include <utility>
#include <vector>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include "include/HevcUtils.h"
#include <cutils/properties.h>
@@ -794,6 +794,8 @@
{ "thumbnail-height", kKeyThumbnailHeight },
{ "track-id", kKeyTrackID },
{ "valid-samples", kKeyValidSamples },
+ { "dvb-component-tag", kKeyDvbComponentTag},
+ { "dvb-audio-description", kKeyDvbAudioDescription},
}
};
@@ -1002,6 +1004,16 @@
msg->setInt32("is-sync-frame", 1);
}
+ int32_t dvbComponentTag = 0;
+ if (meta->findInt32(kKeyDvbComponentTag, &dvbComponentTag)) {
+ msg->setInt32("dvb-component-tag", dvbComponentTag);
+ }
+
+ int32_t dvbAudioDescription = 0;
+ if (meta->findInt32(kKeyDvbAudioDescription, &dvbAudioDescription)) {
+ msg->setInt32("dvb-audio-description", dvbAudioDescription);
+ }
+
const char *lang;
if (meta->findCString(kKeyMediaLanguage, &lang)) {
msg->setString("language", lang);
@@ -1788,6 +1800,16 @@
meta->setInt32(kKeyMaxBitRate, maxBitrate);
}
+ int32_t dvbComponentTag = 0;
+ if (msg->findInt32("dvb-component-tag", &dvbComponentTag) && dvbComponentTag > 0) {
+ meta->setInt32(kKeyDvbComponentTag, dvbComponentTag);
+ }
+
+ int32_t dvbAudioDescription = 0;
+ if (msg->findInt32("dvb-audio-description", &dvbAudioDescription)) {
+ meta->setInt32(kKeyDvbAudioDescription, dvbAudioDescription);
+ }
+
AString lang;
if (msg->findString("language", &lang)) {
meta->setCString(kKeyMediaLanguage, lang.c_str());
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index fb4f9a0..d667685 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -73,7 +73,7 @@
<MediaCodec name="c2.android.raw.decoder" type="audio/raw">
<Alias name="OMX.google.raw.decoder" />
<Limit name="channel-count" max="8" />
- <Limit name="sample-rate" ranges="8000-96000" />
+ <Limit name="sample-rate" ranges="8000-192000" />
<Limit name="bitrate" range="1-10000000" />
</MediaCodec>
<MediaCodec name="c2.android.flac.decoder" type="audio/flac">
diff --git a/media/libstagefright/exports.lds b/media/libstagefright/exports.lds
index f5ddf1e..7fe6d6c 100644
--- a/media/libstagefright/exports.lds
+++ b/media/libstagefright/exports.lds
@@ -8,19 +8,19 @@
_ZNK7android14ColorConverter*;
_ZN7android16SoftwareRenderer*;
ABGRToARGB;
- ABGRToI420;
+ ABGRToI420*;
ABGRToUVRow_Any_NEON*;
ABGRToUVRow_C;
ABGRToUVRow_NEON*;
ABGRToYRow_Any_NEON*;
ABGRToYRow_C;
ABGRToYRow_NEON*;
- Android420ToI420;
+ Android420ToI420*;
ARGB1555ToARGB;
ARGB1555ToARGBRow_Any_NEON*;
ARGB1555ToARGBRow_C;
ARGB1555ToARGBRow_NEON*;
- ARGB1555ToI420;
+ ARGB1555ToI420*;
ARGB1555ToUVRow_Any_NEON*;
ARGB1555ToUVRow_C;
ARGB1555ToUVRow_NEON*;
@@ -31,7 +31,7 @@
ARGB4444ToARGBRow_Any_NEON*;
ARGB4444ToARGBRow_C;
ARGB4444ToARGBRow_NEON*;
- ARGB4444ToI420;
+ ARGB4444ToI420*;
ARGB4444ToUVRow_Any_NEON*;
ARGB4444ToUVRow_C;
ARGB4444ToUVRow_NEON*;
@@ -115,7 +115,7 @@
ARGBToARGB4444Row_C;
ARGBToARGB4444Row_NEON*;
ARGBToBGRA;
- ARGBToI420;
+ ARGBToI420*;
ARGBToRAWRow_Any_NEON*;
ARGBToRAWRow_C;
ARGBToRAWRow_NEON*;
@@ -147,7 +147,7 @@
ARGBUnattenuateRow_C;
ArmCpuCaps*;
BGRAToARGB;
- BGRAToI420;
+ BGRAToI420*;
BGRAToUVRow_Any_NEON*;
BGRAToUVRow_C;
BGRAToUVRow_NEON*;
@@ -156,9 +156,9 @@
BGRAToYRow_NEON*;
BlendPlane;
BlendPlaneRow_C;
- CanonicalFourCC;
+ CanonicalFourCC*;
ComputeCumulativeSumRow_C;
- ConvertFromI420;
+ ConvertFromI420*;
CopyPlane;
CopyPlane_16;
CopyRow_16_C;
@@ -182,40 +182,40 @@
HalfFloatRow_Any_NEON*;
HalfFloatRow_C;
HalfFloatRow_NEON*;
- I400Copy;
+ I400Copy*;
I400Mirror;
I400ToARGB;
I400ToARGBRow_Any_NEON*;
I400ToARGBRow_C;
I400ToARGBRow_NEON*;
I400ToI400;
- I400ToI420;
+ I400ToI420*;
I420AlphaToABGR;
I420AlphaToARGB;
I420Blend;
- I420Copy;
+ I420Copy*;
I420Interpolate;
I420Mirror;
I420Rect;
- I420Scale;
- I420Scale_16;
+ I420Scale*;
+ I420Scale_16*;
I420ToABGR;
I420ToARGB;
I420ToARGB1555;
I420ToARGB4444;
I420ToBGRA;
I420ToI400;
- I420ToI422;
- I420ToI444;
- I420ToNV12;
- I420ToNV21;
+ I420ToI422*;
+ I420ToI444*;
+ I420ToNV12*;
+ I420ToNV21*;
I420ToRAW;
I420ToRGB24;
I420ToRGB565;
I420ToRGB565Dither;
I420ToRGBA;
- I420ToUYVY;
- I420ToYUY2;
+ I420ToUYVY*;
+ I420ToYUY2*;
I422AlphaToARGBRow_Any_NEON*;
I422AlphaToARGBRow_C;
I422AlphaToARGBRow_NEON*;
@@ -232,7 +232,7 @@
I422ToARGBRow_C;
I422ToARGBRow_NEON*;
I422ToBGRA;
- I422ToI420;
+ I422ToI420*;
I422ToRGB24Row_Any_NEON*;
I422ToRGB24Row_C;
I422ToRGB24Row_NEON*;
@@ -244,11 +244,11 @@
I422ToRGBARow_Any_NEON*;
I422ToRGBARow_C;
I422ToRGBARow_NEON*;
- I422ToUYVY;
+ I422ToUYVY*;
I422ToUYVYRow_Any_NEON*;
I422ToUYVYRow_C;
I422ToUYVYRow_NEON*;
- I422ToYUY2;
+ I422ToYUY2*;
I422ToYUY2Row_Any_NEON*;
I422ToYUY2Row_C;
I422ToYUY2Row_NEON*;
@@ -258,7 +258,7 @@
I444ToARGBRow_Any_NEON*;
I444ToARGBRow_C;
I444ToARGBRow_NEON*;
- I444ToI420;
+ I444ToI420*;
InitCpuFlags*;
InterpolatePlane;
InterpolateRow_16_C;
@@ -280,8 +280,8 @@
kYvuH709Constants;
kYvuI601Constants;
kYvuJPEGConstants;
- M420ToARGB;
- M420ToI420;
+ M420ToARGB*;
+ M420ToI420*;
MaskCpuFlags*;
MergeUVPlane;
MergeUVRow_Any_NEON*;
@@ -297,7 +297,7 @@
NV12ToARGBRow_Any_NEON*;
NV12ToARGBRow_C;
NV12ToARGBRow_NEON*;
- NV12ToI420;
+ NV12ToI420*;
NV12ToRGB565;
NV12ToRGB565Row_Any_NEON*;
NV12ToRGB565Row_C;
@@ -306,12 +306,12 @@
NV21ToARGBRow_Any_NEON*;
NV21ToARGBRow_C;
NV21ToARGBRow_NEON*;
- NV21ToI420;
+ NV21ToI420*;
RAWToARGB;
RAWToARGBRow_Any_NEON*;
RAWToARGBRow_C;
RAWToARGBRow_NEON*;
- RAWToI420;
+ RAWToI420*;
RAWToRGB24;
RAWToRGB24Row_Any_NEON*;
RAWToRGB24Row_C;
@@ -326,7 +326,7 @@
RGB24ToARGBRow_Any_NEON*;
RGB24ToARGBRow_C;
RGB24ToARGBRow_NEON*;
- RGB24ToI420;
+ RGB24ToI420*;
RGB24ToUVRow_Any_NEON*;
RGB24ToUVRow_C;
RGB24ToUVRow_NEON*;
@@ -337,7 +337,7 @@
RGB565ToARGBRow_Any_NEON*;
RGB565ToARGBRow_C;
RGB565ToARGBRow_NEON*;
- RGB565ToI420;
+ RGB565ToI420*;
RGB565ToUVRow_Any_NEON*;
RGB565ToUVRow_C;
RGB565ToUVRow_NEON*;
@@ -345,7 +345,7 @@
RGB565ToYRow_C;
RGB565ToYRow_NEON*;
RGBAToARGB;
- RGBAToI420;
+ RGBAToI420*;
RGBAToUVRow_Any_NEON*;
RGBAToUVRow_C;
RGBAToUVRow_NEON*;
@@ -355,7 +355,7 @@
RGBColorMatrix;
RGBColorTable;
RGBColorTableRow_C;
- Scale;
+ Scale*;
ScaleAddRow_16_C;
ScaleAddRow_C;
ScaleAddRows_NEON*;
@@ -395,12 +395,12 @@
ScaleFilterCols_NEON*;
ScaleFilterReduce;
ScaleFilterRows_NEON*;
- ScalePlane;
- ScalePlane_16;
- ScalePlaneBilinearDown;
- ScalePlaneBilinearDown_16;
- ScalePlaneBilinearUp;
- ScalePlaneBilinearUp_16;
+ ScalePlane*;
+ ScalePlane_16*;
+ ScalePlaneBilinearDown*;
+ ScalePlaneBilinearDown_16*;
+ ScalePlaneBilinearUp*;
+ ScalePlaneBilinearUp_16*;
ScalePlaneVertical;
ScalePlaneVertical_16;
ScaleRowDown2_16_C;
@@ -475,7 +475,7 @@
UYVYToARGBRow_Any_NEON*;
UYVYToARGBRow_C;
UYVYToARGBRow_NEON*;
- UYVYToI420;
+ UYVYToI420*;
UYVYToI422;
UYVYToNV12;
UYVYToUV422Row_Any_NEON*;
@@ -491,7 +491,7 @@
YUY2ToARGBRow_Any_NEON*;
YUY2ToARGBRow_C;
YUY2ToARGBRow_NEON*;
- YUY2ToI420;
+ YUY2ToI420*;
YUY2ToI422;
YUY2ToNV12;
YUY2ToUV422Row_Any_NEON*;
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 88c1f3f..cdf8d35 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -277,6 +277,12 @@
kKeyLastSampleIndexInChunk = 'lsic', //int64_t, index of last sample in a chunk.
kKeySampleTimeBeforeAppend = 'lsba', // int64_t, timestamp of last sample of a track.
+ // DVB component tag
+ kKeyDvbComponentTag = 'copt', // int32_t, component tag for DVB video/audio/subtitle
+
+ // DVB audio description
+ kKeyDvbAudioDescription = 'addt', // bool (int32_t), DVB audio description only defined for
+ // audio component
};
enum {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index bebd516..c82a303 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -316,7 +316,7 @@
// that a new message is available on the queue. Otherwise, the message stays on the queue, but
// the listener is not notified of it. It will process this message when a subsequent message
// is posted with |realTime| set to true.
- void post(const omx_message &msg, bool realTime = true);
+ void post(const omx_message &msg, bool realTime);
bool loop();
@@ -325,18 +325,15 @@
private:
enum {
- // This is used for frame_rendered message batching, which will eventually end up in a
- // single AMessage in MediaCodec when it is signaled to the app. AMessage can contain
- // up-to 64 key-value pairs, and each frame_rendered message uses 2 keys, so the max
- // value for this would be 32. Nonetheless, limit this to 12 to which gives at least 10
- // mseconds of batching at 120Hz.
- kMaxQueueSize = 12,
+ // Don't delay non-realtime messages longer than 200ms
+ kMaxBatchedDelayNs = 200 * 1000 * 1000,
};
Mutex mLock;
sp<OMXNodeInstance> const mOwner;
bool mDone;
+ bool mHasBatchedMessages;
Condition mQueueChanged;
std::list<omx_message> mQueue;
@@ -350,7 +347,8 @@
OMXNodeInstance::CallbackDispatcher::CallbackDispatcher(const sp<OMXNodeInstance> &owner)
: mOwner(owner),
- mDone(false) {
+ mDone(false),
+ mHasBatchedMessages(false) {
mThread = new CallbackDispatcherThread(this);
mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_FOREGROUND);
}
@@ -358,7 +356,6 @@
OMXNodeInstance::CallbackDispatcher::~CallbackDispatcher() {
{
Mutex::Autolock autoLock(mLock);
-
mDone = true;
mQueueChanged.signal();
}
@@ -377,8 +374,11 @@
Mutex::Autolock autoLock(mLock);
mQueue.push_back(msg);
- if (realTime || mQueue.size() >= kMaxQueueSize) {
+ if (realTime) {
mQueueChanged.signal();
+ } else if (!mHasBatchedMessages) {
+ mHasBatchedMessages = true;
+ mQueueChanged.signal(); // The first non-realtime message is not batched.
}
}
@@ -393,11 +393,16 @@
bool OMXNodeInstance::CallbackDispatcher::loop() {
for (;;) {
std::list<omx_message> messages;
+ std::list<long long> messageTimestamps;
{
Mutex::Autolock autoLock(mLock);
while (!mDone && mQueue.empty()) {
- mQueueChanged.wait(mLock);
+ if (mHasBatchedMessages) {
+ mQueueChanged.waitRelative(mLock, kMaxBatchedDelayNs);
+ } else {
+ mQueueChanged.wait(mLock);
+ }
}
if (mDone) {
@@ -2447,7 +2452,7 @@
msg.type = omx_message::EMPTY_BUFFER_DONE;
msg.fenceFd = fenceFd;
msg.u.buffer_data.buffer = instance->findBufferID(pBuffer);
- instance->mDispatcher->post(msg);
+ instance->mDispatcher->post(msg, true /* realTime */);
return OMX_ErrorNone;
}
@@ -2475,7 +2480,7 @@
msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
msg.u.extended_buffer_data.flags = pBuffer->nFlags;
msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
- instance->mDispatcher->post(msg);
+ instance->mDispatcher->post(msg, true /* realTime */);
return OMX_ErrorNone;
}
diff --git a/media/libstagefright/omx/OMXStore.cpp b/media/libstagefright/omx/OMXStore.cpp
index 4827d9e..0906433 100644
--- a/media/libstagefright/omx/OMXStore.cpp
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -140,7 +140,8 @@
Vector<String8> roles;
OMX_ERRORTYPE err = plugin->getRolesOfComponent(name, &roles);
- if (err == OMX_ErrorNone) {
+ static_assert(std::string_view("OMX.google.").size() == 11);
+ if (err == OMX_ErrorNone && strncmp(name, "OMX.google.", 11) == 0) {
bool skip = false;
for (String8 role : roles) {
if (role.find("video_decoder") != -1 || role.find("video_encoder") != -1) {
diff --git a/media/libstagefright/renderfright/tests/RenderEngineTest.cpp b/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
index 2697ff4..3a67cc2 100644
--- a/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
+++ b/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
@@ -60,7 +60,7 @@
}
static sp<GraphicBuffer> allocateDefaultBuffer() {
- return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
+ return sp<GraphicBuffer>::make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
HAL_PIXEL_FORMAT_RGBA_8888, 1,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER,
@@ -69,7 +69,7 @@
// Allocates a 1x1 buffer to fill with a solid color
static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) {
- return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ return sp<GraphicBuffer>::make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_TEXTURE,
"input");
@@ -275,7 +275,7 @@
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
// Meaningless buffer since we don't do any drawing
- sp<GraphicBuffer> buffer = new GraphicBuffer();
+ sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
invokeDraw(settings, layers, buffer);
}
diff --git a/media/libstagefright/renderfright/tests/RenderEngineThreadedTest.cpp b/media/libstagefright/renderfright/tests/RenderEngineThreadedTest.cpp
index 97c7442..b82586b 100644
--- a/media/libstagefright/renderfright/tests/RenderEngineThreadedTest.cpp
+++ b/media/libstagefright/renderfright/tests/RenderEngineThreadedTest.cpp
@@ -70,7 +70,7 @@
}
TEST_F(RenderEngineThreadedTest, bindExternalBuffer_withBuffer) {
- sp<GraphicBuffer> buf = new GraphicBuffer();
+ sp<GraphicBuffer> buf = sp<GraphicBuffer>::make();
EXPECT_CALL(*mRenderEngine, bindExternalTextureBuffer(0, buf, Eq(nullptr)))
.WillOnce(Return(NO_ERROR));
status_t result = mThreadedRE->bindExternalTextureBuffer(0, buf, nullptr);
@@ -83,7 +83,7 @@
}
TEST_F(RenderEngineThreadedTest, cacheExternalTextureBuffer_withBuffer) {
- sp<GraphicBuffer> buf = new GraphicBuffer();
+ sp<GraphicBuffer> buf = sp<GraphicBuffer>::make();
EXPECT_CALL(*mRenderEngine, cacheExternalTextureBuffer(buf));
mThreadedRE->cacheExternalTextureBuffer(buf);
}
@@ -198,7 +198,7 @@
TEST_F(RenderEngineThreadedTest, drawLayers) {
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
- sp<GraphicBuffer> buffer = new GraphicBuffer();
+ sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
base::unique_fd bufferFence;
base::unique_fd drawFence;
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index 2f516d5..ddf797c 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -618,13 +618,14 @@
int32_t AAVCAssembler::pickStartSeq(const Queue *queue,
uint32_t first, int64_t play, int64_t jit) {
+ CHECK(!queue->empty());
// pick the first sequence number has the start bit.
sp<ABuffer> buffer = *(queue->begin());
int32_t firstSeqNo = buffer->int32Data();
// This only works for FU-A type & non-start sequence
- unsigned nalType = buffer->data()[0] & 0x1f;
- if (nalType != 28 || buffer->data()[1] & 0x80) {
+ int32_t nalType = buffer->size() >= 1 ? buffer->data()[0] & 0x1f : -1;
+ if (nalType != 28 || (buffer->size() >= 2 && buffer->data()[1] & 0x80)) {
return firstSeqNo;
}
@@ -634,7 +635,7 @@
if (rtpTime + jit >= play) {
break;
}
- if ((data[1] & 0x80)) {
+ if (it->size() >= 2 && (data[1] & 0x80)) {
const int32_t seqNo = it->int32Data();
ALOGE("finding [HEAD] pkt. \t Seq# (%d ~ )[%d", firstSeqNo, seqNo);
firstSeqNo = seqNo;
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/module/bqhelper/Android.bp
similarity index 97%
rename from media/libstagefright/bqhelper/Android.bp
rename to media/module/bqhelper/Android.bp
index a4f0fb3..c4dadd0 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/module/bqhelper/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_media_libstagefright_license"],
}
cc_defaults {
diff --git a/media/libstagefright/bqhelper/FrameDropper.cpp b/media/module/bqhelper/FrameDropper.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/FrameDropper.cpp
rename to media/module/bqhelper/FrameDropper.cpp
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/module/bqhelper/GraphicBufferSource.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/GraphicBufferSource.cpp
rename to media/module/bqhelper/GraphicBufferSource.cpp
diff --git a/media/libstagefright/bqhelper/TEST_MAPPING b/media/module/bqhelper/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/bqhelper/TEST_MAPPING
rename to media/module/bqhelper/TEST_MAPPING
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h b/media/module/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h b/media/module/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
diff --git a/media/libstagefright/bqhelper/tests/Android.bp b/media/module/bqhelper/tests/Android.bp
similarity index 88%
rename from media/libstagefright/bqhelper/tests/Android.bp
rename to media/module/bqhelper/tests/Android.bp
index 95953ee..3004ec4 100644
--- a/media/libstagefright/bqhelper/tests/Android.bp
+++ b/media/module/bqhelper/tests/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_media_libstagefright_license"],
}
cc_test {
diff --git a/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp b/media/module/bqhelper/tests/FrameDropper_test.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/tests/FrameDropper_test.cpp
rename to media/module/bqhelper/tests/FrameDropper_test.cpp
diff --git a/media/bufferpool/1.0/Accessor.cpp b/media/module/bufferpool/1.0/Accessor.cpp
similarity index 100%
rename from media/bufferpool/1.0/Accessor.cpp
rename to media/module/bufferpool/1.0/Accessor.cpp
diff --git a/media/bufferpool/1.0/Accessor.h b/media/module/bufferpool/1.0/Accessor.h
similarity index 100%
rename from media/bufferpool/1.0/Accessor.h
rename to media/module/bufferpool/1.0/Accessor.h
diff --git a/media/bufferpool/1.0/AccessorImpl.cpp b/media/module/bufferpool/1.0/AccessorImpl.cpp
similarity index 100%
rename from media/bufferpool/1.0/AccessorImpl.cpp
rename to media/module/bufferpool/1.0/AccessorImpl.cpp
diff --git a/media/bufferpool/1.0/AccessorImpl.h b/media/module/bufferpool/1.0/AccessorImpl.h
similarity index 100%
rename from media/bufferpool/1.0/AccessorImpl.h
rename to media/module/bufferpool/1.0/AccessorImpl.h
diff --git a/media/bufferpool/1.0/Android.bp b/media/module/bufferpool/1.0/Android.bp
similarity index 100%
rename from media/bufferpool/1.0/Android.bp
rename to media/module/bufferpool/1.0/Android.bp
diff --git a/media/bufferpool/1.0/BufferPoolClient.cpp b/media/module/bufferpool/1.0/BufferPoolClient.cpp
similarity index 100%
rename from media/bufferpool/1.0/BufferPoolClient.cpp
rename to media/module/bufferpool/1.0/BufferPoolClient.cpp
diff --git a/media/bufferpool/1.0/BufferPoolClient.h b/media/module/bufferpool/1.0/BufferPoolClient.h
similarity index 100%
rename from media/bufferpool/1.0/BufferPoolClient.h
rename to media/module/bufferpool/1.0/BufferPoolClient.h
diff --git a/media/bufferpool/1.0/BufferStatus.cpp b/media/module/bufferpool/1.0/BufferStatus.cpp
similarity index 100%
rename from media/bufferpool/1.0/BufferStatus.cpp
rename to media/module/bufferpool/1.0/BufferStatus.cpp
diff --git a/media/bufferpool/1.0/BufferStatus.h b/media/module/bufferpool/1.0/BufferStatus.h
similarity index 100%
rename from media/bufferpool/1.0/BufferStatus.h
rename to media/module/bufferpool/1.0/BufferStatus.h
diff --git a/media/bufferpool/1.0/ClientManager.cpp b/media/module/bufferpool/1.0/ClientManager.cpp
similarity index 100%
rename from media/bufferpool/1.0/ClientManager.cpp
rename to media/module/bufferpool/1.0/ClientManager.cpp
diff --git a/media/bufferpool/1.0/Connection.cpp b/media/module/bufferpool/1.0/Connection.cpp
similarity index 100%
rename from media/bufferpool/1.0/Connection.cpp
rename to media/module/bufferpool/1.0/Connection.cpp
diff --git a/media/bufferpool/1.0/Connection.h b/media/module/bufferpool/1.0/Connection.h
similarity index 100%
rename from media/bufferpool/1.0/Connection.h
rename to media/module/bufferpool/1.0/Connection.h
diff --git a/media/bufferpool/1.0/TEST_MAPPING b/media/module/bufferpool/1.0/TEST_MAPPING
similarity index 100%
rename from media/bufferpool/1.0/TEST_MAPPING
rename to media/module/bufferpool/1.0/TEST_MAPPING
diff --git a/media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h b/media/module/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
similarity index 100%
rename from media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
rename to media/module/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
diff --git a/media/bufferpool/1.0/include/bufferpool/ClientManager.h b/media/module/bufferpool/1.0/include/bufferpool/ClientManager.h
similarity index 100%
rename from media/bufferpool/1.0/include/bufferpool/ClientManager.h
rename to media/module/bufferpool/1.0/include/bufferpool/ClientManager.h
diff --git a/media/bufferpool/1.0/vts/Android.bp b/media/module/bufferpool/1.0/vts/Android.bp
similarity index 100%
rename from media/bufferpool/1.0/vts/Android.bp
rename to media/module/bufferpool/1.0/vts/Android.bp
diff --git a/media/bufferpool/1.0/vts/OWNERS b/media/module/bufferpool/1.0/vts/OWNERS
similarity index 100%
rename from media/bufferpool/1.0/vts/OWNERS
rename to media/module/bufferpool/1.0/vts/OWNERS
diff --git a/media/bufferpool/1.0/vts/allocator.cpp b/media/module/bufferpool/1.0/vts/allocator.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/allocator.cpp
rename to media/module/bufferpool/1.0/vts/allocator.cpp
diff --git a/media/bufferpool/1.0/vts/allocator.h b/media/module/bufferpool/1.0/vts/allocator.h
similarity index 100%
rename from media/bufferpool/1.0/vts/allocator.h
rename to media/module/bufferpool/1.0/vts/allocator.h
diff --git a/media/bufferpool/1.0/vts/multi.cpp b/media/module/bufferpool/1.0/vts/multi.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/multi.cpp
rename to media/module/bufferpool/1.0/vts/multi.cpp
diff --git a/media/bufferpool/1.0/vts/single.cpp b/media/module/bufferpool/1.0/vts/single.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/single.cpp
rename to media/module/bufferpool/1.0/vts/single.cpp
diff --git a/media/bufferpool/2.0/Accessor.cpp b/media/module/bufferpool/2.0/Accessor.cpp
similarity index 100%
rename from media/bufferpool/2.0/Accessor.cpp
rename to media/module/bufferpool/2.0/Accessor.cpp
diff --git a/media/bufferpool/2.0/Accessor.h b/media/module/bufferpool/2.0/Accessor.h
similarity index 100%
rename from media/bufferpool/2.0/Accessor.h
rename to media/module/bufferpool/2.0/Accessor.h
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/module/bufferpool/2.0/AccessorImpl.cpp
similarity index 100%
rename from media/bufferpool/2.0/AccessorImpl.cpp
rename to media/module/bufferpool/2.0/AccessorImpl.cpp
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/module/bufferpool/2.0/AccessorImpl.h
similarity index 100%
rename from media/bufferpool/2.0/AccessorImpl.h
rename to media/module/bufferpool/2.0/AccessorImpl.h
diff --git a/media/bufferpool/2.0/Android.bp b/media/module/bufferpool/2.0/Android.bp
similarity index 100%
rename from media/bufferpool/2.0/Android.bp
rename to media/module/bufferpool/2.0/Android.bp
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/module/bufferpool/2.0/BufferPoolClient.cpp
similarity index 100%
rename from media/bufferpool/2.0/BufferPoolClient.cpp
rename to media/module/bufferpool/2.0/BufferPoolClient.cpp
diff --git a/media/bufferpool/2.0/BufferPoolClient.h b/media/module/bufferpool/2.0/BufferPoolClient.h
similarity index 100%
rename from media/bufferpool/2.0/BufferPoolClient.h
rename to media/module/bufferpool/2.0/BufferPoolClient.h
diff --git a/media/bufferpool/2.0/BufferStatus.cpp b/media/module/bufferpool/2.0/BufferStatus.cpp
similarity index 100%
rename from media/bufferpool/2.0/BufferStatus.cpp
rename to media/module/bufferpool/2.0/BufferStatus.cpp
diff --git a/media/bufferpool/2.0/BufferStatus.h b/media/module/bufferpool/2.0/BufferStatus.h
similarity index 100%
rename from media/bufferpool/2.0/BufferStatus.h
rename to media/module/bufferpool/2.0/BufferStatus.h
diff --git a/media/bufferpool/2.0/ClientManager.cpp b/media/module/bufferpool/2.0/ClientManager.cpp
similarity index 100%
rename from media/bufferpool/2.0/ClientManager.cpp
rename to media/module/bufferpool/2.0/ClientManager.cpp
diff --git a/media/bufferpool/2.0/Connection.cpp b/media/module/bufferpool/2.0/Connection.cpp
similarity index 100%
rename from media/bufferpool/2.0/Connection.cpp
rename to media/module/bufferpool/2.0/Connection.cpp
diff --git a/media/bufferpool/2.0/Connection.h b/media/module/bufferpool/2.0/Connection.h
similarity index 100%
rename from media/bufferpool/2.0/Connection.h
rename to media/module/bufferpool/2.0/Connection.h
diff --git a/media/bufferpool/2.0/Observer.cpp b/media/module/bufferpool/2.0/Observer.cpp
similarity index 100%
rename from media/bufferpool/2.0/Observer.cpp
rename to media/module/bufferpool/2.0/Observer.cpp
diff --git a/media/bufferpool/2.0/Observer.h b/media/module/bufferpool/2.0/Observer.h
similarity index 100%
rename from media/bufferpool/2.0/Observer.h
rename to media/module/bufferpool/2.0/Observer.h
diff --git a/media/bufferpool/2.0/TEST_MAPPING b/media/module/bufferpool/2.0/TEST_MAPPING
similarity index 100%
rename from media/bufferpool/2.0/TEST_MAPPING
rename to media/module/bufferpool/2.0/TEST_MAPPING
diff --git a/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h b/media/module/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
similarity index 100%
rename from media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
rename to media/module/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
diff --git a/media/bufferpool/2.0/include/bufferpool/ClientManager.h b/media/module/bufferpool/2.0/include/bufferpool/ClientManager.h
similarity index 100%
rename from media/bufferpool/2.0/include/bufferpool/ClientManager.h
rename to media/module/bufferpool/2.0/include/bufferpool/ClientManager.h
diff --git a/media/bufferpool/2.0/tests/Android.bp b/media/module/bufferpool/2.0/tests/Android.bp
similarity index 100%
rename from media/bufferpool/2.0/tests/Android.bp
rename to media/module/bufferpool/2.0/tests/Android.bp
diff --git a/media/bufferpool/2.0/tests/AndroidTest.xml b/media/module/bufferpool/2.0/tests/AndroidTest.xml
similarity index 100%
rename from media/bufferpool/2.0/tests/AndroidTest.xml
rename to media/module/bufferpool/2.0/tests/AndroidTest.xml
diff --git a/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp b/media/module/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
rename to media/module/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
diff --git a/media/bufferpool/2.0/tests/OWNERS b/media/module/bufferpool/2.0/tests/OWNERS
similarity index 100%
rename from media/bufferpool/2.0/tests/OWNERS
rename to media/module/bufferpool/2.0/tests/OWNERS
diff --git a/media/bufferpool/2.0/tests/README.md b/media/module/bufferpool/2.0/tests/README.md
similarity index 100%
rename from media/bufferpool/2.0/tests/README.md
rename to media/module/bufferpool/2.0/tests/README.md
diff --git a/media/bufferpool/2.0/tests/allocator.cpp b/media/module/bufferpool/2.0/tests/allocator.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/allocator.cpp
rename to media/module/bufferpool/2.0/tests/allocator.cpp
diff --git a/media/bufferpool/2.0/tests/allocator.h b/media/module/bufferpool/2.0/tests/allocator.h
similarity index 100%
rename from media/bufferpool/2.0/tests/allocator.h
rename to media/module/bufferpool/2.0/tests/allocator.h
diff --git a/media/bufferpool/2.0/tests/cond.cpp b/media/module/bufferpool/2.0/tests/cond.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/cond.cpp
rename to media/module/bufferpool/2.0/tests/cond.cpp
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/module/bufferpool/2.0/tests/multi.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/multi.cpp
rename to media/module/bufferpool/2.0/tests/multi.cpp
diff --git a/media/bufferpool/2.0/tests/single.cpp b/media/module/bufferpool/2.0/tests/single.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/single.cpp
rename to media/module/bufferpool/2.0/tests/single.cpp
diff --git a/media/codecs/amrnb/TEST_MAPPING b/media/module/codecs/amrnb/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrnb/TEST_MAPPING
rename to media/module/codecs/amrnb/TEST_MAPPING
diff --git a/media/codecs/amrnb/common/Android.bp b/media/module/codecs/amrnb/common/Android.bp
similarity index 100%
rename from media/codecs/amrnb/common/Android.bp
rename to media/module/codecs/amrnb/common/Android.bp
diff --git a/media/codecs/amrnb/common/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/common/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/common/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/common/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/common/NOTICE b/media/module/codecs/amrnb/common/NOTICE
similarity index 100%
rename from media/codecs/amrnb/common/NOTICE
rename to media/module/codecs/amrnb/common/NOTICE
diff --git a/media/codecs/amrnb/common/include/abs_s.h b/media/module/codecs/amrnb/common/include/abs_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/abs_s.h
rename to media/module/codecs/amrnb/common/include/abs_s.h
diff --git a/media/codecs/amrnb/common/include/add.h b/media/module/codecs/amrnb/common/include/add.h
similarity index 100%
rename from media/codecs/amrnb/common/include/add.h
rename to media/module/codecs/amrnb/common/include/add.h
diff --git a/media/codecs/amrnb/common/include/az_lsp.h b/media/module/codecs/amrnb/common/include/az_lsp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/az_lsp.h
rename to media/module/codecs/amrnb/common/include/az_lsp.h
diff --git a/media/codecs/amrnb/common/include/basic_op.h b/media/module/codecs/amrnb/common/include/basic_op.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op.h
rename to media/module/codecs/amrnb/common/include/basic_op.h
diff --git a/media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h b/media/module/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
rename to media/module/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
diff --git a/media/codecs/amrnb/common/include/basic_op_arm_v5.h b/media/module/codecs/amrnb/common/include/basic_op_arm_v5.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_arm_v5.h
rename to media/module/codecs/amrnb/common/include/basic_op_arm_v5.h
diff --git a/media/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_c_equivalent.h
rename to media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
diff --git a/media/codecs/amrnb/common/include/basicop_malloc.h b/media/module/codecs/amrnb/common/include/basicop_malloc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basicop_malloc.h
rename to media/module/codecs/amrnb/common/include/basicop_malloc.h
diff --git a/media/codecs/amrnb/common/include/bitno_tab.h b/media/module/codecs/amrnb/common/include/bitno_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bitno_tab.h
rename to media/module/codecs/amrnb/common/include/bitno_tab.h
diff --git a/media/codecs/amrnb/common/include/bitreorder_tab.h b/media/module/codecs/amrnb/common/include/bitreorder_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bitreorder_tab.h
rename to media/module/codecs/amrnb/common/include/bitreorder_tab.h
diff --git a/media/codecs/amrnb/common/include/bits2prm.h b/media/module/codecs/amrnb/common/include/bits2prm.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bits2prm.h
rename to media/module/codecs/amrnb/common/include/bits2prm.h
diff --git a/media/codecs/amrnb/common/include/cnst.h b/media/module/codecs/amrnb/common/include/cnst.h
similarity index 100%
rename from media/codecs/amrnb/common/include/cnst.h
rename to media/module/codecs/amrnb/common/include/cnst.h
diff --git a/media/codecs/amrnb/common/include/cnst_vad.h b/media/module/codecs/amrnb/common/include/cnst_vad.h
similarity index 100%
rename from media/codecs/amrnb/common/include/cnst_vad.h
rename to media/module/codecs/amrnb/common/include/cnst_vad.h
diff --git a/media/codecs/amrnb/common/include/copy.h b/media/module/codecs/amrnb/common/include/copy.h
similarity index 100%
rename from media/codecs/amrnb/common/include/copy.h
rename to media/module/codecs/amrnb/common/include/copy.h
diff --git a/media/codecs/amrnb/common/include/d_gain_c.h b/media/module/codecs/amrnb/common/include/d_gain_c.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_gain_c.h
rename to media/module/codecs/amrnb/common/include/d_gain_c.h
diff --git a/media/codecs/amrnb/common/include/d_gain_p.h b/media/module/codecs/amrnb/common/include/d_gain_p.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_gain_p.h
rename to media/module/codecs/amrnb/common/include/d_gain_p.h
diff --git a/media/codecs/amrnb/common/include/d_plsf.h b/media/module/codecs/amrnb/common/include/d_plsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_plsf.h
rename to media/module/codecs/amrnb/common/include/d_plsf.h
diff --git a/media/codecs/amrnb/common/include/div_32.h b/media/module/codecs/amrnb/common/include/div_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/div_32.h
rename to media/module/codecs/amrnb/common/include/div_32.h
diff --git a/media/codecs/amrnb/common/include/div_s.h b/media/module/codecs/amrnb/common/include/div_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/div_s.h
rename to media/module/codecs/amrnb/common/include/div_s.h
diff --git a/media/codecs/amrnb/common/include/dtx_common_def.h b/media/module/codecs/amrnb/common/include/dtx_common_def.h
similarity index 100%
rename from media/codecs/amrnb/common/include/dtx_common_def.h
rename to media/module/codecs/amrnb/common/include/dtx_common_def.h
diff --git a/media/codecs/amrnb/common/include/extract_h.h b/media/module/codecs/amrnb/common/include/extract_h.h
similarity index 100%
rename from media/codecs/amrnb/common/include/extract_h.h
rename to media/module/codecs/amrnb/common/include/extract_h.h
diff --git a/media/codecs/amrnb/common/include/extract_l.h b/media/module/codecs/amrnb/common/include/extract_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/extract_l.h
rename to media/module/codecs/amrnb/common/include/extract_l.h
diff --git a/media/codecs/amrnb/common/include/frame.h b/media/module/codecs/amrnb/common/include/frame.h
similarity index 100%
rename from media/codecs/amrnb/common/include/frame.h
rename to media/module/codecs/amrnb/common/include/frame.h
diff --git a/media/codecs/amrnb/common/include/frame_type_3gpp.h b/media/module/codecs/amrnb/common/include/frame_type_3gpp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/frame_type_3gpp.h
rename to media/module/codecs/amrnb/common/include/frame_type_3gpp.h
diff --git a/media/codecs/amrnb/common/include/gc_pred.h b/media/module/codecs/amrnb/common/include/gc_pred.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gc_pred.h
rename to media/module/codecs/amrnb/common/include/gc_pred.h
diff --git a/media/codecs/amrnb/common/include/gmed_n.h b/media/module/codecs/amrnb/common/include/gmed_n.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gmed_n.h
rename to media/module/codecs/amrnb/common/include/gmed_n.h
diff --git a/media/codecs/amrnb/common/include/gsm_amr_typedefs.h b/media/module/codecs/amrnb/common/include/gsm_amr_typedefs.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gsm_amr_typedefs.h
rename to media/module/codecs/amrnb/common/include/gsm_amr_typedefs.h
diff --git a/media/codecs/amrnb/common/include/int_lpc.h b/media/module/codecs/amrnb/common/include/int_lpc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/int_lpc.h
rename to media/module/codecs/amrnb/common/include/int_lpc.h
diff --git a/media/codecs/amrnb/common/include/int_lsf.h b/media/module/codecs/amrnb/common/include/int_lsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/int_lsf.h
rename to media/module/codecs/amrnb/common/include/int_lsf.h
diff --git a/media/codecs/amrnb/common/include/inv_sqrt.h b/media/module/codecs/amrnb/common/include/inv_sqrt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/inv_sqrt.h
rename to media/module/codecs/amrnb/common/include/inv_sqrt.h
diff --git a/media/codecs/amrnb/common/include/l_abs.h b/media/module/codecs/amrnb/common/include/l_abs.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_abs.h
rename to media/module/codecs/amrnb/common/include/l_abs.h
diff --git a/media/codecs/amrnb/common/include/l_add.h b/media/module/codecs/amrnb/common/include/l_add.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_add.h
rename to media/module/codecs/amrnb/common/include/l_add.h
diff --git a/media/codecs/amrnb/common/include/l_add_c.h b/media/module/codecs/amrnb/common/include/l_add_c.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_add_c.h
rename to media/module/codecs/amrnb/common/include/l_add_c.h
diff --git a/media/codecs/amrnb/common/include/l_comp.h b/media/module/codecs/amrnb/common/include/l_comp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_comp.h
rename to media/module/codecs/amrnb/common/include/l_comp.h
diff --git a/media/codecs/amrnb/common/include/l_deposit_h.h b/media/module/codecs/amrnb/common/include/l_deposit_h.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_deposit_h.h
rename to media/module/codecs/amrnb/common/include/l_deposit_h.h
diff --git a/media/codecs/amrnb/common/include/l_deposit_l.h b/media/module/codecs/amrnb/common/include/l_deposit_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_deposit_l.h
rename to media/module/codecs/amrnb/common/include/l_deposit_l.h
diff --git a/media/codecs/amrnb/common/include/l_extract.h b/media/module/codecs/amrnb/common/include/l_extract.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_extract.h
rename to media/module/codecs/amrnb/common/include/l_extract.h
diff --git a/media/codecs/amrnb/common/include/l_mac.h b/media/module/codecs/amrnb/common/include/l_mac.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_mac.h
rename to media/module/codecs/amrnb/common/include/l_mac.h
diff --git a/media/codecs/amrnb/common/include/l_msu.h b/media/module/codecs/amrnb/common/include/l_msu.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_msu.h
rename to media/module/codecs/amrnb/common/include/l_msu.h
diff --git a/media/codecs/amrnb/common/include/l_mult.h b/media/module/codecs/amrnb/common/include/l_mult.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_mult.h
rename to media/module/codecs/amrnb/common/include/l_mult.h
diff --git a/media/codecs/amrnb/common/include/l_negate.h b/media/module/codecs/amrnb/common/include/l_negate.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_negate.h
rename to media/module/codecs/amrnb/common/include/l_negate.h
diff --git a/media/codecs/amrnb/common/include/l_shl.h b/media/module/codecs/amrnb/common/include/l_shl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shl.h
rename to media/module/codecs/amrnb/common/include/l_shl.h
diff --git a/media/codecs/amrnb/common/include/l_shr.h b/media/module/codecs/amrnb/common/include/l_shr.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shr.h
rename to media/module/codecs/amrnb/common/include/l_shr.h
diff --git a/media/codecs/amrnb/common/include/l_shr_r.h b/media/module/codecs/amrnb/common/include/l_shr_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shr_r.h
rename to media/module/codecs/amrnb/common/include/l_shr_r.h
diff --git a/media/codecs/amrnb/common/include/l_sub.h b/media/module/codecs/amrnb/common/include/l_sub.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_sub.h
rename to media/module/codecs/amrnb/common/include/l_sub.h
diff --git a/media/codecs/amrnb/common/include/log2.h b/media/module/codecs/amrnb/common/include/log2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/log2.h
rename to media/module/codecs/amrnb/common/include/log2.h
diff --git a/media/codecs/amrnb/common/include/log2_norm.h b/media/module/codecs/amrnb/common/include/log2_norm.h
similarity index 100%
rename from media/codecs/amrnb/common/include/log2_norm.h
rename to media/module/codecs/amrnb/common/include/log2_norm.h
diff --git a/media/codecs/amrnb/common/include/lsfwt.h b/media/module/codecs/amrnb/common/include/lsfwt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsfwt.h
rename to media/module/codecs/amrnb/common/include/lsfwt.h
diff --git a/media/codecs/amrnb/common/include/lsp.h b/media/module/codecs/amrnb/common/include/lsp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp.h
rename to media/module/codecs/amrnb/common/include/lsp.h
diff --git a/media/codecs/amrnb/common/include/lsp_az.h b/media/module/codecs/amrnb/common/include/lsp_az.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_az.h
rename to media/module/codecs/amrnb/common/include/lsp_az.h
diff --git a/media/codecs/amrnb/common/include/lsp_lsf.h b/media/module/codecs/amrnb/common/include/lsp_lsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_lsf.h
rename to media/module/codecs/amrnb/common/include/lsp_lsf.h
diff --git a/media/codecs/amrnb/common/include/lsp_tab.h b/media/module/codecs/amrnb/common/include/lsp_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_tab.h
rename to media/module/codecs/amrnb/common/include/lsp_tab.h
diff --git a/media/codecs/amrnb/common/include/mac_32.h b/media/module/codecs/amrnb/common/include/mac_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mac_32.h
rename to media/module/codecs/amrnb/common/include/mac_32.h
diff --git a/media/codecs/amrnb/common/include/mode.h b/media/module/codecs/amrnb/common/include/mode.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mode.h
rename to media/module/codecs/amrnb/common/include/mode.h
diff --git a/media/codecs/amrnb/common/include/mpy_32.h b/media/module/codecs/amrnb/common/include/mpy_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mpy_32.h
rename to media/module/codecs/amrnb/common/include/mpy_32.h
diff --git a/media/codecs/amrnb/common/include/mpy_32_16.h b/media/module/codecs/amrnb/common/include/mpy_32_16.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mpy_32_16.h
rename to media/module/codecs/amrnb/common/include/mpy_32_16.h
diff --git a/media/codecs/amrnb/common/include/mult.h b/media/module/codecs/amrnb/common/include/mult.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mult.h
rename to media/module/codecs/amrnb/common/include/mult.h
diff --git a/media/codecs/amrnb/common/include/mult_r.h b/media/module/codecs/amrnb/common/include/mult_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mult_r.h
rename to media/module/codecs/amrnb/common/include/mult_r.h
diff --git a/media/codecs/amrnb/common/include/n_proc.h b/media/module/codecs/amrnb/common/include/n_proc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/n_proc.h
rename to media/module/codecs/amrnb/common/include/n_proc.h
diff --git a/media/codecs/amrnb/common/include/negate.h b/media/module/codecs/amrnb/common/include/negate.h
similarity index 100%
rename from media/codecs/amrnb/common/include/negate.h
rename to media/module/codecs/amrnb/common/include/negate.h
diff --git a/media/codecs/amrnb/common/include/norm_l.h b/media/module/codecs/amrnb/common/include/norm_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/norm_l.h
rename to media/module/codecs/amrnb/common/include/norm_l.h
diff --git a/media/codecs/amrnb/common/include/norm_s.h b/media/module/codecs/amrnb/common/include/norm_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/norm_s.h
rename to media/module/codecs/amrnb/common/include/norm_s.h
diff --git a/media/codecs/amrnb/common/include/oper_32b.h b/media/module/codecs/amrnb/common/include/oper_32b.h
similarity index 100%
rename from media/codecs/amrnb/common/include/oper_32b.h
rename to media/module/codecs/amrnb/common/include/oper_32b.h
diff --git a/media/codecs/amrnb/common/include/p_ol_wgh.h b/media/module/codecs/amrnb/common/include/p_ol_wgh.h
similarity index 100%
rename from media/codecs/amrnb/common/include/p_ol_wgh.h
rename to media/module/codecs/amrnb/common/include/p_ol_wgh.h
diff --git a/media/codecs/amrnb/common/include/pow2.h b/media/module/codecs/amrnb/common/include/pow2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/pow2.h
rename to media/module/codecs/amrnb/common/include/pow2.h
diff --git a/media/codecs/amrnb/common/include/pred_lt.h b/media/module/codecs/amrnb/common/include/pred_lt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/pred_lt.h
rename to media/module/codecs/amrnb/common/include/pred_lt.h
diff --git a/media/codecs/amrnb/common/include/q_plsf.h b/media/module/codecs/amrnb/common/include/q_plsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf.h
rename to media/module/codecs/amrnb/common/include/q_plsf.h
diff --git a/media/codecs/amrnb/common/include/q_plsf_3_tbl.h b/media/module/codecs/amrnb/common/include/q_plsf_3_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf_3_tbl.h
rename to media/module/codecs/amrnb/common/include/q_plsf_3_tbl.h
diff --git a/media/codecs/amrnb/common/include/q_plsf_5_tbl.h b/media/module/codecs/amrnb/common/include/q_plsf_5_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf_5_tbl.h
rename to media/module/codecs/amrnb/common/include/q_plsf_5_tbl.h
diff --git a/media/codecs/amrnb/common/include/qgain475_tab.h b/media/module/codecs/amrnb/common/include/qgain475_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qgain475_tab.h
rename to media/module/codecs/amrnb/common/include/qgain475_tab.h
diff --git a/media/codecs/amrnb/common/include/qua_gain.h b/media/module/codecs/amrnb/common/include/qua_gain.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qua_gain.h
rename to media/module/codecs/amrnb/common/include/qua_gain.h
diff --git a/media/codecs/amrnb/common/include/qua_gain_tbl.h b/media/module/codecs/amrnb/common/include/qua_gain_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qua_gain_tbl.h
rename to media/module/codecs/amrnb/common/include/qua_gain_tbl.h
diff --git a/media/codecs/amrnb/common/include/reorder.h b/media/module/codecs/amrnb/common/include/reorder.h
similarity index 100%
rename from media/codecs/amrnb/common/include/reorder.h
rename to media/module/codecs/amrnb/common/include/reorder.h
diff --git a/media/codecs/amrnb/common/include/residu.h b/media/module/codecs/amrnb/common/include/residu.h
similarity index 100%
rename from media/codecs/amrnb/common/include/residu.h
rename to media/module/codecs/amrnb/common/include/residu.h
diff --git a/media/codecs/amrnb/common/include/reverse_bits.h b/media/module/codecs/amrnb/common/include/reverse_bits.h
similarity index 100%
rename from media/codecs/amrnb/common/include/reverse_bits.h
rename to media/module/codecs/amrnb/common/include/reverse_bits.h
diff --git a/media/codecs/amrnb/common/include/round.h b/media/module/codecs/amrnb/common/include/round.h
similarity index 100%
rename from media/codecs/amrnb/common/include/round.h
rename to media/module/codecs/amrnb/common/include/round.h
diff --git a/media/codecs/amrnb/common/include/set_zero.h b/media/module/codecs/amrnb/common/include/set_zero.h
similarity index 100%
rename from media/codecs/amrnb/common/include/set_zero.h
rename to media/module/codecs/amrnb/common/include/set_zero.h
diff --git a/media/codecs/amrnb/common/include/shl.h b/media/module/codecs/amrnb/common/include/shl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shl.h
rename to media/module/codecs/amrnb/common/include/shl.h
diff --git a/media/codecs/amrnb/common/include/shr.h b/media/module/codecs/amrnb/common/include/shr.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shr.h
rename to media/module/codecs/amrnb/common/include/shr.h
diff --git a/media/codecs/amrnb/common/include/shr_r.h b/media/module/codecs/amrnb/common/include/shr_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shr_r.h
rename to media/module/codecs/amrnb/common/include/shr_r.h
diff --git a/media/codecs/amrnb/common/include/sqrt_l.h b/media/module/codecs/amrnb/common/include/sqrt_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/sqrt_l.h
rename to media/module/codecs/amrnb/common/include/sqrt_l.h
diff --git a/media/codecs/amrnb/common/include/sub.h b/media/module/codecs/amrnb/common/include/sub.h
similarity index 100%
rename from media/codecs/amrnb/common/include/sub.h
rename to media/module/codecs/amrnb/common/include/sub.h
diff --git a/media/codecs/amrnb/common/include/syn_filt.h b/media/module/codecs/amrnb/common/include/syn_filt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/syn_filt.h
rename to media/module/codecs/amrnb/common/include/syn_filt.h
diff --git a/media/codecs/amrnb/common/include/typedef.h b/media/module/codecs/amrnb/common/include/typedef.h
similarity index 100%
rename from media/codecs/amrnb/common/include/typedef.h
rename to media/module/codecs/amrnb/common/include/typedef.h
diff --git a/media/codecs/amrnb/common/include/vad.h b/media/module/codecs/amrnb/common/include/vad.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad.h
rename to media/module/codecs/amrnb/common/include/vad.h
diff --git a/media/codecs/amrnb/common/include/vad1.h b/media/module/codecs/amrnb/common/include/vad1.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad1.h
rename to media/module/codecs/amrnb/common/include/vad1.h
diff --git a/media/codecs/amrnb/common/include/vad2.h b/media/module/codecs/amrnb/common/include/vad2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad2.h
rename to media/module/codecs/amrnb/common/include/vad2.h
diff --git a/media/codecs/amrnb/common/include/weight_a.h b/media/module/codecs/amrnb/common/include/weight_a.h
similarity index 100%
rename from media/codecs/amrnb/common/include/weight_a.h
rename to media/module/codecs/amrnb/common/include/weight_a.h
diff --git a/media/codecs/amrnb/common/include/window_tab.h b/media/module/codecs/amrnb/common/include/window_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/window_tab.h
rename to media/module/codecs/amrnb/common/include/window_tab.h
diff --git a/media/codecs/amrnb/common/include/wmf_to_ets.h b/media/module/codecs/amrnb/common/include/wmf_to_ets.h
similarity index 100%
rename from media/codecs/amrnb/common/include/wmf_to_ets.h
rename to media/module/codecs/amrnb/common/include/wmf_to_ets.h
diff --git a/media/codecs/amrnb/common/src/add.cpp b/media/module/codecs/amrnb/common/src/add.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/add.cpp
rename to media/module/codecs/amrnb/common/src/add.cpp
diff --git a/media/codecs/amrnb/common/src/az_lsp.cpp b/media/module/codecs/amrnb/common/src/az_lsp.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/az_lsp.cpp
rename to media/module/codecs/amrnb/common/src/az_lsp.cpp
diff --git a/media/codecs/amrnb/common/src/bitno_tab.cpp b/media/module/codecs/amrnb/common/src/bitno_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bitno_tab.cpp
rename to media/module/codecs/amrnb/common/src/bitno_tab.cpp
diff --git a/media/codecs/amrnb/common/src/bitreorder_tab.cpp b/media/module/codecs/amrnb/common/src/bitreorder_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bitreorder_tab.cpp
rename to media/module/codecs/amrnb/common/src/bitreorder_tab.cpp
diff --git a/media/codecs/amrnb/common/src/bits2prm.cpp b/media/module/codecs/amrnb/common/src/bits2prm.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bits2prm.cpp
rename to media/module/codecs/amrnb/common/src/bits2prm.cpp
diff --git a/media/codecs/amrnb/common/src/c2_9pf_tab.cpp b/media/module/codecs/amrnb/common/src/c2_9pf_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/c2_9pf_tab.cpp
rename to media/module/codecs/amrnb/common/src/c2_9pf_tab.cpp
diff --git a/media/codecs/amrnb/common/src/copy.cpp b/media/module/codecs/amrnb/common/src/copy.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/copy.cpp
rename to media/module/codecs/amrnb/common/src/copy.cpp
diff --git a/media/codecs/amrnb/common/src/div_32.cpp b/media/module/codecs/amrnb/common/src/div_32.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/div_32.cpp
rename to media/module/codecs/amrnb/common/src/div_32.cpp
diff --git a/media/codecs/amrnb/common/src/div_s.cpp b/media/module/codecs/amrnb/common/src/div_s.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/div_s.cpp
rename to media/module/codecs/amrnb/common/src/div_s.cpp
diff --git a/media/codecs/amrnb/common/src/extract_h.cpp b/media/module/codecs/amrnb/common/src/extract_h.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/extract_h.cpp
rename to media/module/codecs/amrnb/common/src/extract_h.cpp
diff --git a/media/codecs/amrnb/common/src/extract_l.cpp b/media/module/codecs/amrnb/common/src/extract_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/extract_l.cpp
rename to media/module/codecs/amrnb/common/src/extract_l.cpp
diff --git a/media/codecs/amrnb/common/src/gains_tbl.cpp b/media/module/codecs/amrnb/common/src/gains_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gains_tbl.cpp
rename to media/module/codecs/amrnb/common/src/gains_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/gc_pred.cpp b/media/module/codecs/amrnb/common/src/gc_pred.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gc_pred.cpp
rename to media/module/codecs/amrnb/common/src/gc_pred.cpp
diff --git a/media/codecs/amrnb/common/src/gmed_n.cpp b/media/module/codecs/amrnb/common/src/gmed_n.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gmed_n.cpp
rename to media/module/codecs/amrnb/common/src/gmed_n.cpp
diff --git a/media/codecs/amrnb/common/src/gray_tbl.cpp b/media/module/codecs/amrnb/common/src/gray_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gray_tbl.cpp
rename to media/module/codecs/amrnb/common/src/gray_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/grid_tbl.cpp b/media/module/codecs/amrnb/common/src/grid_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/grid_tbl.cpp
rename to media/module/codecs/amrnb/common/src/grid_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/int_lpc.cpp b/media/module/codecs/amrnb/common/src/int_lpc.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/int_lpc.cpp
rename to media/module/codecs/amrnb/common/src/int_lpc.cpp
diff --git a/media/codecs/amrnb/common/src/inv_sqrt.cpp b/media/module/codecs/amrnb/common/src/inv_sqrt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/inv_sqrt.cpp
rename to media/module/codecs/amrnb/common/src/inv_sqrt.cpp
diff --git a/media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp b/media/module/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
rename to media/module/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/l_abs.cpp b/media/module/codecs/amrnb/common/src/l_abs.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_abs.cpp
rename to media/module/codecs/amrnb/common/src/l_abs.cpp
diff --git a/media/codecs/amrnb/common/src/l_deposit_h.cpp b/media/module/codecs/amrnb/common/src/l_deposit_h.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_deposit_h.cpp
rename to media/module/codecs/amrnb/common/src/l_deposit_h.cpp
diff --git a/media/codecs/amrnb/common/src/l_deposit_l.cpp b/media/module/codecs/amrnb/common/src/l_deposit_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_deposit_l.cpp
rename to media/module/codecs/amrnb/common/src/l_deposit_l.cpp
diff --git a/media/codecs/amrnb/common/src/l_shr_r.cpp b/media/module/codecs/amrnb/common/src/l_shr_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_shr_r.cpp
rename to media/module/codecs/amrnb/common/src/l_shr_r.cpp
diff --git a/media/codecs/amrnb/common/src/log2.cpp b/media/module/codecs/amrnb/common/src/log2.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2.cpp
rename to media/module/codecs/amrnb/common/src/log2.cpp
diff --git a/media/codecs/amrnb/common/src/log2_norm.cpp b/media/module/codecs/amrnb/common/src/log2_norm.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2_norm.cpp
rename to media/module/codecs/amrnb/common/src/log2_norm.cpp
diff --git a/media/codecs/amrnb/common/src/log2_tbl.cpp b/media/module/codecs/amrnb/common/src/log2_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2_tbl.cpp
rename to media/module/codecs/amrnb/common/src/log2_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/lsfwt.cpp b/media/module/codecs/amrnb/common/src/lsfwt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsfwt.cpp
rename to media/module/codecs/amrnb/common/src/lsfwt.cpp
diff --git a/media/codecs/amrnb/common/src/lsp.cpp b/media/module/codecs/amrnb/common/src/lsp.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp.cpp
rename to media/module/codecs/amrnb/common/src/lsp.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_az.cpp b/media/module/codecs/amrnb/common/src/lsp_az.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_az.cpp
rename to media/module/codecs/amrnb/common/src/lsp_az.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_lsf.cpp b/media/module/codecs/amrnb/common/src/lsp_lsf.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_lsf.cpp
rename to media/module/codecs/amrnb/common/src/lsp_lsf.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp b/media/module/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
rename to media/module/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_tab.cpp b/media/module/codecs/amrnb/common/src/lsp_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_tab.cpp
rename to media/module/codecs/amrnb/common/src/lsp_tab.cpp
diff --git a/media/codecs/amrnb/common/src/mult_r.cpp b/media/module/codecs/amrnb/common/src/mult_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/mult_r.cpp
rename to media/module/codecs/amrnb/common/src/mult_r.cpp
diff --git a/media/codecs/amrnb/common/src/negate.cpp b/media/module/codecs/amrnb/common/src/negate.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/negate.cpp
rename to media/module/codecs/amrnb/common/src/negate.cpp
diff --git a/media/codecs/amrnb/common/src/norm_l.cpp b/media/module/codecs/amrnb/common/src/norm_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/norm_l.cpp
rename to media/module/codecs/amrnb/common/src/norm_l.cpp
diff --git a/media/codecs/amrnb/common/src/norm_s.cpp b/media/module/codecs/amrnb/common/src/norm_s.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/norm_s.cpp
rename to media/module/codecs/amrnb/common/src/norm_s.cpp
diff --git a/media/codecs/amrnb/common/src/ph_disp_tab.cpp b/media/module/codecs/amrnb/common/src/ph_disp_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/ph_disp_tab.cpp
rename to media/module/codecs/amrnb/common/src/ph_disp_tab.cpp
diff --git a/media/codecs/amrnb/common/src/pow2.cpp b/media/module/codecs/amrnb/common/src/pow2.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pow2.cpp
rename to media/module/codecs/amrnb/common/src/pow2.cpp
diff --git a/media/codecs/amrnb/common/src/pow2_tbl.cpp b/media/module/codecs/amrnb/common/src/pow2_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pow2_tbl.cpp
rename to media/module/codecs/amrnb/common/src/pow2_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/pred_lt.cpp b/media/module/codecs/amrnb/common/src/pred_lt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pred_lt.cpp
rename to media/module/codecs/amrnb/common/src/pred_lt.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf.cpp b/media/module/codecs/amrnb/common/src/q_plsf.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_3.cpp b/media/module/codecs/amrnb/common/src/q_plsf_3.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_3.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_3.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp b/media/module/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_5.cpp b/media/module/codecs/amrnb/common/src/q_plsf_5.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_5.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_5.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp b/media/module/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/qua_gain_tbl.cpp b/media/module/codecs/amrnb/common/src/qua_gain_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/qua_gain_tbl.cpp
rename to media/module/codecs/amrnb/common/src/qua_gain_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/reorder.cpp b/media/module/codecs/amrnb/common/src/reorder.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/reorder.cpp
rename to media/module/codecs/amrnb/common/src/reorder.cpp
diff --git a/media/codecs/amrnb/common/src/residu.cpp b/media/module/codecs/amrnb/common/src/residu.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/residu.cpp
rename to media/module/codecs/amrnb/common/src/residu.cpp
diff --git a/media/codecs/amrnb/common/src/round.cpp b/media/module/codecs/amrnb/common/src/round.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/round.cpp
rename to media/module/codecs/amrnb/common/src/round.cpp
diff --git a/media/codecs/amrnb/common/src/set_zero.cpp b/media/module/codecs/amrnb/common/src/set_zero.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/set_zero.cpp
rename to media/module/codecs/amrnb/common/src/set_zero.cpp
diff --git a/media/codecs/amrnb/common/src/shr.cpp b/media/module/codecs/amrnb/common/src/shr.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/shr.cpp
rename to media/module/codecs/amrnb/common/src/shr.cpp
diff --git a/media/codecs/amrnb/common/src/shr_r.cpp b/media/module/codecs/amrnb/common/src/shr_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/shr_r.cpp
rename to media/module/codecs/amrnb/common/src/shr_r.cpp
diff --git a/media/codecs/amrnb/common/src/sqrt_l.cpp b/media/module/codecs/amrnb/common/src/sqrt_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sqrt_l.cpp
rename to media/module/codecs/amrnb/common/src/sqrt_l.cpp
diff --git a/media/codecs/amrnb/common/src/sqrt_l_tbl.cpp b/media/module/codecs/amrnb/common/src/sqrt_l_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sqrt_l_tbl.cpp
rename to media/module/codecs/amrnb/common/src/sqrt_l_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/sub.cpp b/media/module/codecs/amrnb/common/src/sub.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sub.cpp
rename to media/module/codecs/amrnb/common/src/sub.cpp
diff --git a/media/codecs/amrnb/common/src/syn_filt.cpp b/media/module/codecs/amrnb/common/src/syn_filt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/syn_filt.cpp
rename to media/module/codecs/amrnb/common/src/syn_filt.cpp
diff --git a/media/codecs/amrnb/common/src/vad1.cpp b/media/module/codecs/amrnb/common/src/vad1.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/vad1.cpp
rename to media/module/codecs/amrnb/common/src/vad1.cpp
diff --git a/media/codecs/amrnb/common/src/weight_a.cpp b/media/module/codecs/amrnb/common/src/weight_a.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/weight_a.cpp
rename to media/module/codecs/amrnb/common/src/weight_a.cpp
diff --git a/media/codecs/amrnb/common/src/window_tab.cpp b/media/module/codecs/amrnb/common/src/window_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/window_tab.cpp
rename to media/module/codecs/amrnb/common/src/window_tab.cpp
diff --git a/media/codecs/amrnb/dec/Android.bp b/media/module/codecs/amrnb/dec/Android.bp
similarity index 100%
rename from media/codecs/amrnb/dec/Android.bp
rename to media/module/codecs/amrnb/dec/Android.bp
diff --git a/media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/dec/NOTICE b/media/module/codecs/amrnb/dec/NOTICE
similarity index 100%
rename from media/codecs/amrnb/dec/NOTICE
rename to media/module/codecs/amrnb/dec/NOTICE
diff --git a/media/codecs/amrnb/dec/src/a_refl.cpp b/media/module/codecs/amrnb/dec/src/a_refl.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/a_refl.cpp
rename to media/module/codecs/amrnb/dec/src/a_refl.cpp
diff --git a/media/codecs/amrnb/dec/src/a_refl.h b/media/module/codecs/amrnb/dec/src/a_refl.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/a_refl.h
rename to media/module/codecs/amrnb/dec/src/a_refl.h
diff --git a/media/codecs/amrnb/dec/src/agc.cpp b/media/module/codecs/amrnb/dec/src/agc.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/agc.cpp
rename to media/module/codecs/amrnb/dec/src/agc.cpp
diff --git a/media/codecs/amrnb/dec/src/agc.h b/media/module/codecs/amrnb/dec/src/agc.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/agc.h
rename to media/module/codecs/amrnb/dec/src/agc.h
diff --git a/media/codecs/amrnb/dec/src/amrdecode.cpp b/media/module/codecs/amrnb/dec/src/amrdecode.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/amrdecode.cpp
rename to media/module/codecs/amrnb/dec/src/amrdecode.cpp
diff --git a/media/codecs/amrnb/dec/src/amrdecode.h b/media/module/codecs/amrnb/dec/src/amrdecode.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/amrdecode.h
rename to media/module/codecs/amrnb/dec/src/amrdecode.h
diff --git a/media/codecs/amrnb/dec/src/b_cn_cod.cpp b/media/module/codecs/amrnb/dec/src/b_cn_cod.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/b_cn_cod.cpp
rename to media/module/codecs/amrnb/dec/src/b_cn_cod.cpp
diff --git a/media/codecs/amrnb/dec/src/b_cn_cod.h b/media/module/codecs/amrnb/dec/src/b_cn_cod.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/b_cn_cod.h
rename to media/module/codecs/amrnb/dec/src/b_cn_cod.h
diff --git a/media/codecs/amrnb/dec/src/bgnscd.cpp b/media/module/codecs/amrnb/dec/src/bgnscd.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/bgnscd.cpp
rename to media/module/codecs/amrnb/dec/src/bgnscd.cpp
diff --git a/media/codecs/amrnb/dec/src/bgnscd.h b/media/module/codecs/amrnb/dec/src/bgnscd.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/bgnscd.h
rename to media/module/codecs/amrnb/dec/src/bgnscd.h
diff --git a/media/codecs/amrnb/dec/src/c_g_aver.cpp b/media/module/codecs/amrnb/dec/src/c_g_aver.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/c_g_aver.cpp
rename to media/module/codecs/amrnb/dec/src/c_g_aver.cpp
diff --git a/media/codecs/amrnb/dec/src/c_g_aver.h b/media/module/codecs/amrnb/dec/src/c_g_aver.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/c_g_aver.h
rename to media/module/codecs/amrnb/dec/src/c_g_aver.h
diff --git a/media/codecs/amrnb/dec/src/d1035pf.cpp b/media/module/codecs/amrnb/dec/src/d1035pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d1035pf.cpp
rename to media/module/codecs/amrnb/dec/src/d1035pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d1035pf.h b/media/module/codecs/amrnb/dec/src/d1035pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d1035pf.h
rename to media/module/codecs/amrnb/dec/src/d1035pf.h
diff --git a/media/codecs/amrnb/dec/src/d2_11pf.cpp b/media/module/codecs/amrnb/dec/src/d2_11pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_11pf.cpp
rename to media/module/codecs/amrnb/dec/src/d2_11pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d2_11pf.h b/media/module/codecs/amrnb/dec/src/d2_11pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_11pf.h
rename to media/module/codecs/amrnb/dec/src/d2_11pf.h
diff --git a/media/codecs/amrnb/dec/src/d2_9pf.cpp b/media/module/codecs/amrnb/dec/src/d2_9pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_9pf.cpp
rename to media/module/codecs/amrnb/dec/src/d2_9pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d2_9pf.h b/media/module/codecs/amrnb/dec/src/d2_9pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_9pf.h
rename to media/module/codecs/amrnb/dec/src/d2_9pf.h
diff --git a/media/codecs/amrnb/dec/src/d3_14pf.cpp b/media/module/codecs/amrnb/dec/src/d3_14pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d3_14pf.cpp
rename to media/module/codecs/amrnb/dec/src/d3_14pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d3_14pf.h b/media/module/codecs/amrnb/dec/src/d3_14pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d3_14pf.h
rename to media/module/codecs/amrnb/dec/src/d3_14pf.h
diff --git a/media/codecs/amrnb/dec/src/d4_17pf.cpp b/media/module/codecs/amrnb/dec/src/d4_17pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d4_17pf.cpp
rename to media/module/codecs/amrnb/dec/src/d4_17pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d4_17pf.h b/media/module/codecs/amrnb/dec/src/d4_17pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d4_17pf.h
rename to media/module/codecs/amrnb/dec/src/d4_17pf.h
diff --git a/media/codecs/amrnb/dec/src/d8_31pf.cpp b/media/module/codecs/amrnb/dec/src/d8_31pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d8_31pf.cpp
rename to media/module/codecs/amrnb/dec/src/d8_31pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d8_31pf.h b/media/module/codecs/amrnb/dec/src/d8_31pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d8_31pf.h
rename to media/module/codecs/amrnb/dec/src/d8_31pf.h
diff --git a/media/codecs/amrnb/dec/src/d_gain_c.cpp b/media/module/codecs/amrnb/dec/src/d_gain_c.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_gain_c.cpp
rename to media/module/codecs/amrnb/dec/src/d_gain_c.cpp
diff --git a/media/codecs/amrnb/dec/src/d_gain_p.cpp b/media/module/codecs/amrnb/dec/src/d_gain_p.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_gain_p.cpp
rename to media/module/codecs/amrnb/dec/src/d_gain_p.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf.cpp b/media/module/codecs/amrnb/dec/src/d_plsf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf_3.cpp b/media/module/codecs/amrnb/dec/src/d_plsf_3.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf_3.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf_3.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf_5.cpp b/media/module/codecs/amrnb/dec/src/d_plsf_5.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf_5.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf_5.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_amr.cpp b/media/module/codecs/amrnb/dec/src/dec_amr.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_amr.cpp
rename to media/module/codecs/amrnb/dec/src/dec_amr.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_amr.h b/media/module/codecs/amrnb/dec/src/dec_amr.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_amr.h
rename to media/module/codecs/amrnb/dec/src/dec_amr.h
diff --git a/media/codecs/amrnb/dec/src/dec_gain.cpp b/media/module/codecs/amrnb/dec/src/dec_gain.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_gain.cpp
rename to media/module/codecs/amrnb/dec/src/dec_gain.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_gain.h b/media/module/codecs/amrnb/dec/src/dec_gain.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_gain.h
rename to media/module/codecs/amrnb/dec/src/dec_gain.h
diff --git a/media/codecs/amrnb/dec/src/dec_input_format_tab.cpp b/media/module/codecs/amrnb/dec/src/dec_input_format_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_input_format_tab.cpp
rename to media/module/codecs/amrnb/dec/src/dec_input_format_tab.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag3.cpp b/media/module/codecs/amrnb/dec/src/dec_lag3.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag3.cpp
rename to media/module/codecs/amrnb/dec/src/dec_lag3.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag3.h b/media/module/codecs/amrnb/dec/src/dec_lag3.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag3.h
rename to media/module/codecs/amrnb/dec/src/dec_lag3.h
diff --git a/media/codecs/amrnb/dec/src/dec_lag6.cpp b/media/module/codecs/amrnb/dec/src/dec_lag6.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag6.cpp
rename to media/module/codecs/amrnb/dec/src/dec_lag6.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag6.h b/media/module/codecs/amrnb/dec/src/dec_lag6.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag6.h
rename to media/module/codecs/amrnb/dec/src/dec_lag6.h
diff --git a/media/codecs/amrnb/dec/src/dtx_dec.cpp b/media/module/codecs/amrnb/dec/src/dtx_dec.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dtx_dec.cpp
rename to media/module/codecs/amrnb/dec/src/dtx_dec.cpp
diff --git a/media/codecs/amrnb/dec/src/dtx_dec.h b/media/module/codecs/amrnb/dec/src/dtx_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dtx_dec.h
rename to media/module/codecs/amrnb/dec/src/dtx_dec.h
diff --git a/media/codecs/amrnb/dec/src/ec_gains.cpp b/media/module/codecs/amrnb/dec/src/ec_gains.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ec_gains.cpp
rename to media/module/codecs/amrnb/dec/src/ec_gains.cpp
diff --git a/media/codecs/amrnb/dec/src/ec_gains.h b/media/module/codecs/amrnb/dec/src/ec_gains.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ec_gains.h
rename to media/module/codecs/amrnb/dec/src/ec_gains.h
diff --git a/media/codecs/amrnb/dec/src/ex_ctrl.cpp b/media/module/codecs/amrnb/dec/src/ex_ctrl.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ex_ctrl.cpp
rename to media/module/codecs/amrnb/dec/src/ex_ctrl.cpp
diff --git a/media/codecs/amrnb/dec/src/ex_ctrl.h b/media/module/codecs/amrnb/dec/src/ex_ctrl.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ex_ctrl.h
rename to media/module/codecs/amrnb/dec/src/ex_ctrl.h
diff --git a/media/codecs/amrnb/dec/src/gsmamr_dec.h b/media/module/codecs/amrnb/dec/src/gsmamr_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/gsmamr_dec.h
rename to media/module/codecs/amrnb/dec/src/gsmamr_dec.h
diff --git a/media/codecs/amrnb/dec/src/if2_to_ets.cpp b/media/module/codecs/amrnb/dec/src/if2_to_ets.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/if2_to_ets.cpp
rename to media/module/codecs/amrnb/dec/src/if2_to_ets.cpp
diff --git a/media/codecs/amrnb/dec/src/if2_to_ets.h b/media/module/codecs/amrnb/dec/src/if2_to_ets.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/if2_to_ets.h
rename to media/module/codecs/amrnb/dec/src/if2_to_ets.h
diff --git a/media/codecs/amrnb/dec/src/int_lsf.cpp b/media/module/codecs/amrnb/dec/src/int_lsf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/int_lsf.cpp
rename to media/module/codecs/amrnb/dec/src/int_lsf.cpp
diff --git a/media/codecs/amrnb/dec/src/lsp_avg.cpp b/media/module/codecs/amrnb/dec/src/lsp_avg.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/lsp_avg.cpp
rename to media/module/codecs/amrnb/dec/src/lsp_avg.cpp
diff --git a/media/codecs/amrnb/dec/src/lsp_avg.h b/media/module/codecs/amrnb/dec/src/lsp_avg.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/lsp_avg.h
rename to media/module/codecs/amrnb/dec/src/lsp_avg.h
diff --git a/media/codecs/amrnb/dec/src/ph_disp.cpp b/media/module/codecs/amrnb/dec/src/ph_disp.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ph_disp.cpp
rename to media/module/codecs/amrnb/dec/src/ph_disp.cpp
diff --git a/media/codecs/amrnb/dec/src/ph_disp.h b/media/module/codecs/amrnb/dec/src/ph_disp.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ph_disp.h
rename to media/module/codecs/amrnb/dec/src/ph_disp.h
diff --git a/media/codecs/amrnb/dec/src/post_pro.cpp b/media/module/codecs/amrnb/dec/src/post_pro.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/post_pro.cpp
rename to media/module/codecs/amrnb/dec/src/post_pro.cpp
diff --git a/media/codecs/amrnb/dec/src/post_pro.h b/media/module/codecs/amrnb/dec/src/post_pro.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/post_pro.h
rename to media/module/codecs/amrnb/dec/src/post_pro.h
diff --git a/media/codecs/amrnb/dec/src/preemph.cpp b/media/module/codecs/amrnb/dec/src/preemph.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/preemph.cpp
rename to media/module/codecs/amrnb/dec/src/preemph.cpp
diff --git a/media/codecs/amrnb/dec/src/preemph.h b/media/module/codecs/amrnb/dec/src/preemph.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/preemph.h
rename to media/module/codecs/amrnb/dec/src/preemph.h
diff --git a/media/codecs/amrnb/dec/src/pstfilt.cpp b/media/module/codecs/amrnb/dec/src/pstfilt.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/pstfilt.cpp
rename to media/module/codecs/amrnb/dec/src/pstfilt.cpp
diff --git a/media/codecs/amrnb/dec/src/pstfilt.h b/media/module/codecs/amrnb/dec/src/pstfilt.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/pstfilt.h
rename to media/module/codecs/amrnb/dec/src/pstfilt.h
diff --git a/media/codecs/amrnb/dec/src/qgain475_tab.cpp b/media/module/codecs/amrnb/dec/src/qgain475_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/qgain475_tab.cpp
rename to media/module/codecs/amrnb/dec/src/qgain475_tab.cpp
diff --git a/media/codecs/amrnb/dec/src/sp_dec.cpp b/media/module/codecs/amrnb/dec/src/sp_dec.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/sp_dec.cpp
rename to media/module/codecs/amrnb/dec/src/sp_dec.cpp
diff --git a/media/codecs/amrnb/dec/src/sp_dec.h b/media/module/codecs/amrnb/dec/src/sp_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/sp_dec.h
rename to media/module/codecs/amrnb/dec/src/sp_dec.h
diff --git a/media/codecs/amrnb/dec/src/wmf_to_ets.cpp b/media/module/codecs/amrnb/dec/src/wmf_to_ets.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/wmf_to_ets.cpp
rename to media/module/codecs/amrnb/dec/src/wmf_to_ets.cpp
diff --git a/media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h b/media/module/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
similarity index 100%
rename from media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
rename to media/module/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
diff --git a/media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp b/media/module/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
rename to media/module/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
diff --git a/media/codecs/amrnb/dec/test/Android.bp b/media/module/codecs/amrnb/dec/test/Android.bp
similarity index 100%
rename from media/codecs/amrnb/dec/test/Android.bp
rename to media/module/codecs/amrnb/dec/test/Android.bp
diff --git a/media/codecs/amrnb/dec/test/AndroidTest.xml b/media/module/codecs/amrnb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrnb/dec/test/AndroidTest.xml
rename to media/module/codecs/amrnb/dec/test/AndroidTest.xml
diff --git a/media/codecs/amrnb/dec/test/README.md b/media/module/codecs/amrnb/dec/test/README.md
similarity index 100%
rename from media/codecs/amrnb/dec/test/README.md
rename to media/module/codecs/amrnb/dec/test/README.md
diff --git a/media/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/module/codecs/amrnb/dec/test/amrnbdec_test.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/test/amrnbdec_test.cpp
rename to media/module/codecs/amrnb/dec/test/amrnbdec_test.cpp
diff --git a/media/codecs/amrnb/enc/Android.bp b/media/module/codecs/amrnb/enc/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/Android.bp
rename to media/module/codecs/amrnb/enc/Android.bp
diff --git a/media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/enc/NOTICE b/media/module/codecs/amrnb/enc/NOTICE
similarity index 100%
rename from media/codecs/amrnb/enc/NOTICE
rename to media/module/codecs/amrnb/enc/NOTICE
diff --git a/media/codecs/amrnb/enc/fuzzer/Android.bp b/media/module/codecs/amrnb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/Android.bp
rename to media/module/codecs/amrnb/enc/fuzzer/Android.bp
diff --git a/media/codecs/amrnb/enc/fuzzer/README.md b/media/module/codecs/amrnb/enc/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/README.md
rename to media/module/codecs/amrnb/enc/fuzzer/README.md
diff --git a/media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp b/media/module/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
rename to media/module/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
diff --git a/media/codecs/amrnb/enc/src/amrencode.cpp b/media/module/codecs/amrnb/enc/src/amrencode.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/amrencode.cpp
rename to media/module/codecs/amrnb/enc/src/amrencode.cpp
diff --git a/media/codecs/amrnb/enc/src/amrencode.h b/media/module/codecs/amrnb/enc/src/amrencode.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/amrencode.h
rename to media/module/codecs/amrnb/enc/src/amrencode.h
diff --git a/media/codecs/amrnb/enc/src/autocorr.cpp b/media/module/codecs/amrnb/enc/src/autocorr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/autocorr.cpp
rename to media/module/codecs/amrnb/enc/src/autocorr.cpp
diff --git a/media/codecs/amrnb/enc/src/autocorr.h b/media/module/codecs/amrnb/enc/src/autocorr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/autocorr.h
rename to media/module/codecs/amrnb/enc/src/autocorr.h
diff --git a/media/codecs/amrnb/enc/src/c1035pf.cpp b/media/module/codecs/amrnb/enc/src/c1035pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c1035pf.cpp
rename to media/module/codecs/amrnb/enc/src/c1035pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c1035pf.h b/media/module/codecs/amrnb/enc/src/c1035pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c1035pf.h
rename to media/module/codecs/amrnb/enc/src/c1035pf.h
diff --git a/media/codecs/amrnb/enc/src/c2_11pf.cpp b/media/module/codecs/amrnb/enc/src/c2_11pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_11pf.cpp
rename to media/module/codecs/amrnb/enc/src/c2_11pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c2_11pf.h b/media/module/codecs/amrnb/enc/src/c2_11pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_11pf.h
rename to media/module/codecs/amrnb/enc/src/c2_11pf.h
diff --git a/media/codecs/amrnb/enc/src/c2_9pf.cpp b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_9pf.cpp
rename to media/module/codecs/amrnb/enc/src/c2_9pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c2_9pf.h b/media/module/codecs/amrnb/enc/src/c2_9pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_9pf.h
rename to media/module/codecs/amrnb/enc/src/c2_9pf.h
diff --git a/media/codecs/amrnb/enc/src/c3_14pf.cpp b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c3_14pf.cpp
rename to media/module/codecs/amrnb/enc/src/c3_14pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c3_14pf.h b/media/module/codecs/amrnb/enc/src/c3_14pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c3_14pf.h
rename to media/module/codecs/amrnb/enc/src/c3_14pf.h
diff --git a/media/codecs/amrnb/enc/src/c4_17pf.cpp b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c4_17pf.cpp
rename to media/module/codecs/amrnb/enc/src/c4_17pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c4_17pf.h b/media/module/codecs/amrnb/enc/src/c4_17pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c4_17pf.h
rename to media/module/codecs/amrnb/enc/src/c4_17pf.h
diff --git a/media/codecs/amrnb/enc/src/c8_31pf.cpp b/media/module/codecs/amrnb/enc/src/c8_31pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c8_31pf.cpp
rename to media/module/codecs/amrnb/enc/src/c8_31pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c8_31pf.h b/media/module/codecs/amrnb/enc/src/c8_31pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c8_31pf.h
rename to media/module/codecs/amrnb/enc/src/c8_31pf.h
diff --git a/media/codecs/amrnb/enc/src/calc_cor.cpp b/media/module/codecs/amrnb/enc/src/calc_cor.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_cor.cpp
rename to media/module/codecs/amrnb/enc/src/calc_cor.cpp
diff --git a/media/codecs/amrnb/enc/src/calc_cor.h b/media/module/codecs/amrnb/enc/src/calc_cor.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_cor.h
rename to media/module/codecs/amrnb/enc/src/calc_cor.h
diff --git a/media/codecs/amrnb/enc/src/calc_en.cpp b/media/module/codecs/amrnb/enc/src/calc_en.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_en.cpp
rename to media/module/codecs/amrnb/enc/src/calc_en.cpp
diff --git a/media/codecs/amrnb/enc/src/calc_en.h b/media/module/codecs/amrnb/enc/src/calc_en.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_en.h
rename to media/module/codecs/amrnb/enc/src/calc_en.h
diff --git a/media/codecs/amrnb/enc/src/cbsearch.cpp b/media/module/codecs/amrnb/enc/src/cbsearch.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cbsearch.cpp
rename to media/module/codecs/amrnb/enc/src/cbsearch.cpp
diff --git a/media/codecs/amrnb/enc/src/cbsearch.h b/media/module/codecs/amrnb/enc/src/cbsearch.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cbsearch.h
rename to media/module/codecs/amrnb/enc/src/cbsearch.h
diff --git a/media/codecs/amrnb/enc/src/cl_ltp.cpp b/media/module/codecs/amrnb/enc/src/cl_ltp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cl_ltp.cpp
rename to media/module/codecs/amrnb/enc/src/cl_ltp.cpp
diff --git a/media/codecs/amrnb/enc/src/cl_ltp.h b/media/module/codecs/amrnb/enc/src/cl_ltp.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cl_ltp.h
rename to media/module/codecs/amrnb/enc/src/cl_ltp.h
diff --git a/media/codecs/amrnb/enc/src/cod_amr.cpp b/media/module/codecs/amrnb/enc/src/cod_amr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cod_amr.cpp
rename to media/module/codecs/amrnb/enc/src/cod_amr.cpp
diff --git a/media/codecs/amrnb/enc/src/cod_amr.h b/media/module/codecs/amrnb/enc/src/cod_amr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cod_amr.h
rename to media/module/codecs/amrnb/enc/src/cod_amr.h
diff --git a/media/codecs/amrnb/enc/src/convolve.cpp b/media/module/codecs/amrnb/enc/src/convolve.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/convolve.cpp
rename to media/module/codecs/amrnb/enc/src/convolve.cpp
diff --git a/media/codecs/amrnb/enc/src/convolve.h b/media/module/codecs/amrnb/enc/src/convolve.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/convolve.h
rename to media/module/codecs/amrnb/enc/src/convolve.h
diff --git a/media/codecs/amrnb/enc/src/cor_h.cpp b/media/module/codecs/amrnb/enc/src/cor_h.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h.h b/media/module/codecs/amrnb/enc/src/cor_h.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h.h
rename to media/module/codecs/amrnb/enc/src/cor_h.h
diff --git a/media/codecs/amrnb/enc/src/cor_h_x.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h_x.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h_x.h b/media/module/codecs/amrnb/enc/src/cor_h_x.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x.h
rename to media/module/codecs/amrnb/enc/src/cor_h_x.h
diff --git a/media/codecs/amrnb/enc/src/cor_h_x2.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x2.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h_x2.h b/media/module/codecs/amrnb/enc/src/cor_h_x2.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x2.h
rename to media/module/codecs/amrnb/enc/src/cor_h_x2.h
diff --git a/media/codecs/amrnb/enc/src/corrwght_tab.cpp b/media/module/codecs/amrnb/enc/src/corrwght_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/corrwght_tab.cpp
rename to media/module/codecs/amrnb/enc/src/corrwght_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/dtx_enc.cpp b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/dtx_enc.cpp
rename to media/module/codecs/amrnb/enc/src/dtx_enc.cpp
diff --git a/media/codecs/amrnb/enc/src/dtx_enc.h b/media/module/codecs/amrnb/enc/src/dtx_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/dtx_enc.h
rename to media/module/codecs/amrnb/enc/src/dtx_enc.h
diff --git a/media/codecs/amrnb/enc/src/enc_lag3.cpp b/media/module/codecs/amrnb/enc/src/enc_lag3.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag3.cpp
rename to media/module/codecs/amrnb/enc/src/enc_lag3.cpp
diff --git a/media/codecs/amrnb/enc/src/enc_lag3.h b/media/module/codecs/amrnb/enc/src/enc_lag3.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag3.h
rename to media/module/codecs/amrnb/enc/src/enc_lag3.h
diff --git a/media/codecs/amrnb/enc/src/enc_lag6.cpp b/media/module/codecs/amrnb/enc/src/enc_lag6.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag6.cpp
rename to media/module/codecs/amrnb/enc/src/enc_lag6.cpp
diff --git a/media/codecs/amrnb/enc/src/enc_lag6.h b/media/module/codecs/amrnb/enc/src/enc_lag6.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag6.h
rename to media/module/codecs/amrnb/enc/src/enc_lag6.h
diff --git a/media/codecs/amrnb/enc/src/enc_output_format_tab.cpp b/media/module/codecs/amrnb/enc/src/enc_output_format_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_output_format_tab.cpp
rename to media/module/codecs/amrnb/enc/src/enc_output_format_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_if2.cpp b/media/module/codecs/amrnb/enc/src/ets_to_if2.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_if2.cpp
rename to media/module/codecs/amrnb/enc/src/ets_to_if2.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_if2.h b/media/module/codecs/amrnb/enc/src/ets_to_if2.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_if2.h
rename to media/module/codecs/amrnb/enc/src/ets_to_if2.h
diff --git a/media/codecs/amrnb/enc/src/ets_to_wmf.cpp b/media/module/codecs/amrnb/enc/src/ets_to_wmf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_wmf.cpp
rename to media/module/codecs/amrnb/enc/src/ets_to_wmf.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_wmf.h b/media/module/codecs/amrnb/enc/src/ets_to_wmf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_wmf.h
rename to media/module/codecs/amrnb/enc/src/ets_to_wmf.h
diff --git a/media/codecs/amrnb/enc/src/g_adapt.cpp b/media/module/codecs/amrnb/enc/src/g_adapt.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_adapt.cpp
rename to media/module/codecs/amrnb/enc/src/g_adapt.cpp
diff --git a/media/codecs/amrnb/enc/src/g_adapt.h b/media/module/codecs/amrnb/enc/src/g_adapt.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_adapt.h
rename to media/module/codecs/amrnb/enc/src/g_adapt.h
diff --git a/media/codecs/amrnb/enc/src/g_code.cpp b/media/module/codecs/amrnb/enc/src/g_code.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_code.cpp
rename to media/module/codecs/amrnb/enc/src/g_code.cpp
diff --git a/media/codecs/amrnb/enc/src/g_code.h b/media/module/codecs/amrnb/enc/src/g_code.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_code.h
rename to media/module/codecs/amrnb/enc/src/g_code.h
diff --git a/media/codecs/amrnb/enc/src/g_pitch.cpp b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_pitch.cpp
rename to media/module/codecs/amrnb/enc/src/g_pitch.cpp
diff --git a/media/codecs/amrnb/enc/src/g_pitch.h b/media/module/codecs/amrnb/enc/src/g_pitch.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_pitch.h
rename to media/module/codecs/amrnb/enc/src/g_pitch.h
diff --git a/media/codecs/amrnb/enc/src/gain_q.cpp b/media/module/codecs/amrnb/enc/src/gain_q.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/gain_q.cpp
rename to media/module/codecs/amrnb/enc/src/gain_q.cpp
diff --git a/media/codecs/amrnb/enc/src/gain_q.h b/media/module/codecs/amrnb/enc/src/gain_q.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/gain_q.h
rename to media/module/codecs/amrnb/enc/src/gain_q.h
diff --git a/media/codecs/amrnb/enc/src/gsmamr_enc.h b/media/module/codecs/amrnb/enc/src/gsmamr_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/gsmamr_enc.h
rename to media/module/codecs/amrnb/enc/src/gsmamr_enc.h
diff --git a/media/codecs/amrnb/enc/src/hp_max.cpp b/media/module/codecs/amrnb/enc/src/hp_max.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/hp_max.cpp
rename to media/module/codecs/amrnb/enc/src/hp_max.cpp
diff --git a/media/codecs/amrnb/enc/src/hp_max.h b/media/module/codecs/amrnb/enc/src/hp_max.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/hp_max.h
rename to media/module/codecs/amrnb/enc/src/hp_max.h
diff --git a/media/codecs/amrnb/enc/src/inter_36.cpp b/media/module/codecs/amrnb/enc/src/inter_36.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36.cpp
rename to media/module/codecs/amrnb/enc/src/inter_36.cpp
diff --git a/media/codecs/amrnb/enc/src/inter_36.h b/media/module/codecs/amrnb/enc/src/inter_36.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36.h
rename to media/module/codecs/amrnb/enc/src/inter_36.h
diff --git a/media/codecs/amrnb/enc/src/inter_36_tab.cpp b/media/module/codecs/amrnb/enc/src/inter_36_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36_tab.cpp
rename to media/module/codecs/amrnb/enc/src/inter_36_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/inter_36_tab.h b/media/module/codecs/amrnb/enc/src/inter_36_tab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36_tab.h
rename to media/module/codecs/amrnb/enc/src/inter_36_tab.h
diff --git a/media/codecs/amrnb/enc/src/l_comp.cpp b/media/module/codecs/amrnb/enc/src/l_comp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_comp.cpp
rename to media/module/codecs/amrnb/enc/src/l_comp.cpp
diff --git a/media/codecs/amrnb/enc/src/l_extract.cpp b/media/module/codecs/amrnb/enc/src/l_extract.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_extract.cpp
rename to media/module/codecs/amrnb/enc/src/l_extract.cpp
diff --git a/media/codecs/amrnb/enc/src/l_negate.cpp b/media/module/codecs/amrnb/enc/src/l_negate.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_negate.cpp
rename to media/module/codecs/amrnb/enc/src/l_negate.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind.cpp b/media/module/codecs/amrnb/enc/src/lag_wind.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind.cpp
rename to media/module/codecs/amrnb/enc/src/lag_wind.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind.h b/media/module/codecs/amrnb/enc/src/lag_wind.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind.h
rename to media/module/codecs/amrnb/enc/src/lag_wind.h
diff --git a/media/codecs/amrnb/enc/src/lag_wind_tab.cpp b/media/module/codecs/amrnb/enc/src/lag_wind_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind_tab.cpp
rename to media/module/codecs/amrnb/enc/src/lag_wind_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind_tab.h b/media/module/codecs/amrnb/enc/src/lag_wind_tab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind_tab.h
rename to media/module/codecs/amrnb/enc/src/lag_wind_tab.h
diff --git a/media/codecs/amrnb/enc/src/levinson.cpp b/media/module/codecs/amrnb/enc/src/levinson.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/levinson.cpp
rename to media/module/codecs/amrnb/enc/src/levinson.cpp
diff --git a/media/codecs/amrnb/enc/src/levinson.h b/media/module/codecs/amrnb/enc/src/levinson.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/levinson.h
rename to media/module/codecs/amrnb/enc/src/levinson.h
diff --git a/media/codecs/amrnb/enc/src/lpc.cpp b/media/module/codecs/amrnb/enc/src/lpc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lpc.cpp
rename to media/module/codecs/amrnb/enc/src/lpc.cpp
diff --git a/media/codecs/amrnb/enc/src/lpc.h b/media/module/codecs/amrnb/enc/src/lpc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lpc.h
rename to media/module/codecs/amrnb/enc/src/lpc.h
diff --git a/media/codecs/amrnb/enc/src/ol_ltp.cpp b/media/module/codecs/amrnb/enc/src/ol_ltp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ol_ltp.cpp
rename to media/module/codecs/amrnb/enc/src/ol_ltp.cpp
diff --git a/media/codecs/amrnb/enc/src/ol_ltp.h b/media/module/codecs/amrnb/enc/src/ol_ltp.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ol_ltp.h
rename to media/module/codecs/amrnb/enc/src/ol_ltp.h
diff --git a/media/codecs/amrnb/enc/src/p_ol_wgh.cpp b/media/module/codecs/amrnb/enc/src/p_ol_wgh.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/p_ol_wgh.cpp
rename to media/module/codecs/amrnb/enc/src/p_ol_wgh.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_fr.cpp b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_fr.cpp
rename to media/module/codecs/amrnb/enc/src/pitch_fr.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_fr.h b/media/module/codecs/amrnb/enc/src/pitch_fr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_fr.h
rename to media/module/codecs/amrnb/enc/src/pitch_fr.h
diff --git a/media/codecs/amrnb/enc/src/pitch_ol.cpp b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_ol.cpp
rename to media/module/codecs/amrnb/enc/src/pitch_ol.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_ol.h b/media/module/codecs/amrnb/enc/src/pitch_ol.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_ol.h
rename to media/module/codecs/amrnb/enc/src/pitch_ol.h
diff --git a/media/codecs/amrnb/enc/src/pre_big.cpp b/media/module/codecs/amrnb/enc/src/pre_big.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_big.cpp
rename to media/module/codecs/amrnb/enc/src/pre_big.cpp
diff --git a/media/codecs/amrnb/enc/src/pre_big.h b/media/module/codecs/amrnb/enc/src/pre_big.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_big.h
rename to media/module/codecs/amrnb/enc/src/pre_big.h
diff --git a/media/codecs/amrnb/enc/src/pre_proc.cpp b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_proc.cpp
rename to media/module/codecs/amrnb/enc/src/pre_proc.cpp
diff --git a/media/codecs/amrnb/enc/src/pre_proc.h b/media/module/codecs/amrnb/enc/src/pre_proc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_proc.h
rename to media/module/codecs/amrnb/enc/src/pre_proc.h
diff --git a/media/codecs/amrnb/enc/src/prm2bits.cpp b/media/module/codecs/amrnb/enc/src/prm2bits.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/prm2bits.cpp
rename to media/module/codecs/amrnb/enc/src/prm2bits.cpp
diff --git a/media/codecs/amrnb/enc/src/prm2bits.h b/media/module/codecs/amrnb/enc/src/prm2bits.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/prm2bits.h
rename to media/module/codecs/amrnb/enc/src/prm2bits.h
diff --git a/media/codecs/amrnb/enc/src/q_gain_c.cpp b/media/module/codecs/amrnb/enc/src/q_gain_c.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_c.cpp
rename to media/module/codecs/amrnb/enc/src/q_gain_c.cpp
diff --git a/media/codecs/amrnb/enc/src/q_gain_c.h b/media/module/codecs/amrnb/enc/src/q_gain_c.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_c.h
rename to media/module/codecs/amrnb/enc/src/q_gain_c.h
diff --git a/media/codecs/amrnb/enc/src/q_gain_p.cpp b/media/module/codecs/amrnb/enc/src/q_gain_p.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_p.cpp
rename to media/module/codecs/amrnb/enc/src/q_gain_p.cpp
diff --git a/media/codecs/amrnb/enc/src/q_gain_p.h b/media/module/codecs/amrnb/enc/src/q_gain_p.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_p.h
rename to media/module/codecs/amrnb/enc/src/q_gain_p.h
diff --git a/media/codecs/amrnb/enc/src/qgain475.cpp b/media/module/codecs/amrnb/enc/src/qgain475.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain475.cpp
rename to media/module/codecs/amrnb/enc/src/qgain475.cpp
diff --git a/media/codecs/amrnb/enc/src/qgain475.h b/media/module/codecs/amrnb/enc/src/qgain475.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain475.h
rename to media/module/codecs/amrnb/enc/src/qgain475.h
diff --git a/media/codecs/amrnb/enc/src/qgain795.cpp b/media/module/codecs/amrnb/enc/src/qgain795.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain795.cpp
rename to media/module/codecs/amrnb/enc/src/qgain795.cpp
diff --git a/media/codecs/amrnb/enc/src/qgain795.h b/media/module/codecs/amrnb/enc/src/qgain795.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain795.h
rename to media/module/codecs/amrnb/enc/src/qgain795.h
diff --git a/media/codecs/amrnb/enc/src/qua_gain.cpp b/media/module/codecs/amrnb/enc/src/qua_gain.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qua_gain.cpp
rename to media/module/codecs/amrnb/enc/src/qua_gain.cpp
diff --git a/media/codecs/amrnb/enc/src/s10_8pf.cpp b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/s10_8pf.cpp
rename to media/module/codecs/amrnb/enc/src/s10_8pf.cpp
diff --git a/media/codecs/amrnb/enc/src/s10_8pf.h b/media/module/codecs/amrnb/enc/src/s10_8pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/s10_8pf.h
rename to media/module/codecs/amrnb/enc/src/s10_8pf.h
diff --git a/media/codecs/amrnb/enc/src/set_sign.cpp b/media/module/codecs/amrnb/enc/src/set_sign.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/set_sign.cpp
rename to media/module/codecs/amrnb/enc/src/set_sign.cpp
diff --git a/media/codecs/amrnb/enc/src/set_sign.h b/media/module/codecs/amrnb/enc/src/set_sign.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/set_sign.h
rename to media/module/codecs/amrnb/enc/src/set_sign.h
diff --git a/media/codecs/amrnb/enc/src/sid_sync.cpp b/media/module/codecs/amrnb/enc/src/sid_sync.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/sid_sync.cpp
rename to media/module/codecs/amrnb/enc/src/sid_sync.cpp
diff --git a/media/codecs/amrnb/enc/src/sid_sync.h b/media/module/codecs/amrnb/enc/src/sid_sync.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/sid_sync.h
rename to media/module/codecs/amrnb/enc/src/sid_sync.h
diff --git a/media/codecs/amrnb/enc/src/sp_enc.cpp b/media/module/codecs/amrnb/enc/src/sp_enc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/sp_enc.cpp
rename to media/module/codecs/amrnb/enc/src/sp_enc.cpp
diff --git a/media/codecs/amrnb/enc/src/sp_enc.h b/media/module/codecs/amrnb/enc/src/sp_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/sp_enc.h
rename to media/module/codecs/amrnb/enc/src/sp_enc.h
diff --git a/media/codecs/amrnb/enc/src/spreproc.cpp b/media/module/codecs/amrnb/enc/src/spreproc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/spreproc.cpp
rename to media/module/codecs/amrnb/enc/src/spreproc.cpp
diff --git a/media/codecs/amrnb/enc/src/spreproc.h b/media/module/codecs/amrnb/enc/src/spreproc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/spreproc.h
rename to media/module/codecs/amrnb/enc/src/spreproc.h
diff --git a/media/codecs/amrnb/enc/src/spstproc.cpp b/media/module/codecs/amrnb/enc/src/spstproc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/spstproc.cpp
rename to media/module/codecs/amrnb/enc/src/spstproc.cpp
diff --git a/media/codecs/amrnb/enc/src/spstproc.h b/media/module/codecs/amrnb/enc/src/spstproc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/spstproc.h
rename to media/module/codecs/amrnb/enc/src/spstproc.h
diff --git a/media/codecs/amrnb/enc/src/ton_stab.cpp b/media/module/codecs/amrnb/enc/src/ton_stab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ton_stab.cpp
rename to media/module/codecs/amrnb/enc/src/ton_stab.cpp
diff --git a/media/codecs/amrnb/enc/src/ton_stab.h b/media/module/codecs/amrnb/enc/src/ton_stab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ton_stab.h
rename to media/module/codecs/amrnb/enc/src/ton_stab.h
diff --git a/media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h b/media/module/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
similarity index 100%
rename from media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
rename to media/module/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
diff --git a/media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp b/media/module/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
rename to media/module/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
diff --git a/media/codecs/amrnb/enc/test/Android.bp b/media/module/codecs/amrnb/enc/test/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/test/Android.bp
rename to media/module/codecs/amrnb/enc/test/Android.bp
diff --git a/media/codecs/amrnb/enc/test/AndroidTest.xml b/media/module/codecs/amrnb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrnb/enc/test/AndroidTest.xml
rename to media/module/codecs/amrnb/enc/test/AndroidTest.xml
diff --git a/media/codecs/amrnb/enc/test/README.md b/media/module/codecs/amrnb/enc/test/README.md
similarity index 100%
rename from media/codecs/amrnb/enc/test/README.md
rename to media/module/codecs/amrnb/enc/test/README.md
diff --git a/media/codecs/amrnb/enc/test/amrnb_enc_test.cpp b/media/module/codecs/amrnb/enc/test/amrnb_enc_test.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/test/amrnb_enc_test.cpp
rename to media/module/codecs/amrnb/enc/test/amrnb_enc_test.cpp
diff --git a/media/codecs/amrnb/fuzzer/Android.bp b/media/module/codecs/amrnb/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrnb/fuzzer/Android.bp
rename to media/module/codecs/amrnb/fuzzer/Android.bp
diff --git a/media/codecs/amrnb/fuzzer/README.md b/media/module/codecs/amrnb/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrnb/fuzzer/README.md
rename to media/module/codecs/amrnb/fuzzer/README.md
diff --git a/media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/module/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
rename to media/module/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
diff --git a/media/codecs/amrnb/patent_disclaimer.txt b/media/module/codecs/amrnb/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrnb/patent_disclaimer.txt
rename to media/module/codecs/amrnb/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/dec/Android.bp b/media/module/codecs/amrwb/dec/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/Android.bp
rename to media/module/codecs/amrwb/dec/Android.bp
diff --git a/media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/dec/NOTICE b/media/module/codecs/amrwb/dec/NOTICE
similarity index 100%
rename from media/codecs/amrwb/dec/NOTICE
rename to media/module/codecs/amrwb/dec/NOTICE
diff --git a/media/codecs/amrwb/dec/TEST_MAPPING b/media/module/codecs/amrwb/dec/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrwb/dec/TEST_MAPPING
rename to media/module/codecs/amrwb/dec/TEST_MAPPING
diff --git a/media/codecs/amrwb/dec/fuzzer/Android.bp b/media/module/codecs/amrwb/dec/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/Android.bp
rename to media/module/codecs/amrwb/dec/fuzzer/Android.bp
diff --git a/media/codecs/amrwb/dec/fuzzer/README.md b/media/module/codecs/amrwb/dec/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/README.md
rename to media/module/codecs/amrwb/dec/fuzzer/README.md
diff --git a/media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp b/media/module/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
rename to media/module/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
diff --git a/media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h b/media/module/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
similarity index 100%
rename from media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
rename to media/module/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
diff --git a/media/codecs/amrwb/dec/patent_disclaimer.txt b/media/module/codecs/amrwb/dec/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrwb/dec/patent_disclaimer.txt
rename to media/module/codecs/amrwb/dec/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/dec/src/agc2_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/agc2_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/agc2_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/agc2_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp b/media/module/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
rename to media/module/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp b/media/module/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
rename to media/module/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp b/media/module/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
rename to media/module/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_alg_codebook.cpp b/media/module/codecs/amrwb/dec/src/dec_alg_codebook.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_alg_codebook.cpp
rename to media/module/codecs/amrwb/dec/src/dec_alg_codebook.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/deemphasis_32.cpp b/media/module/codecs/amrwb/dec/src/deemphasis_32.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/deemphasis_32.cpp
rename to media/module/codecs/amrwb/dec/src/deemphasis_32.cpp
diff --git a/media/codecs/amrwb/dec/src/dtx.h b/media/module/codecs/amrwb/dec/src/dtx.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/dtx.h
rename to media/module/codecs/amrwb/dec/src/dtx.h
diff --git a/media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/e_pv_amrwbdec.h b/media/module/codecs/amrwb/dec/src/e_pv_amrwbdec.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/e_pv_amrwbdec.h
rename to media/module/codecs/amrwb/dec/src/e_pv_amrwbdec.h
diff --git a/media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp b/media/module/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
rename to media/module/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
diff --git a/media/codecs/amrwb/dec/src/get_amr_wb_bits.h b/media/module/codecs/amrwb/dec/src/get_amr_wb_bits.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/get_amr_wb_bits.h
rename to media/module/codecs/amrwb/dec/src/get_amr_wb_bits.h
diff --git a/media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp b/media/module/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
rename to media/module/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
diff --git a/media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp b/media/module/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
rename to media/module/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
diff --git a/media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp b/media/module/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
rename to media/module/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
diff --git a/media/codecs/amrwb/dec/src/interpolate_isp.cpp b/media/module/codecs/amrwb/dec/src/interpolate_isp.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/interpolate_isp.cpp
rename to media/module/codecs/amrwb/dec/src/interpolate_isp.cpp
diff --git a/media/codecs/amrwb/dec/src/isf_extrapolation.cpp b/media/module/codecs/amrwb/dec/src/isf_extrapolation.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isf_extrapolation.cpp
rename to media/module/codecs/amrwb/dec/src/isf_extrapolation.cpp
diff --git a/media/codecs/amrwb/dec/src/isp_az.cpp b/media/module/codecs/amrwb/dec/src/isp_az.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isp_az.cpp
rename to media/module/codecs/amrwb/dec/src/isp_az.cpp
diff --git a/media/codecs/amrwb/dec/src/isp_isf.cpp b/media/module/codecs/amrwb/dec/src/isp_isf.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isp_isf.cpp
rename to media/module/codecs/amrwb/dec/src/isp_isf.cpp
diff --git a/media/codecs/amrwb/dec/src/lagconceal.cpp b/media/module/codecs/amrwb/dec/src/lagconceal.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/lagconceal.cpp
rename to media/module/codecs/amrwb/dec/src/lagconceal.cpp
diff --git a/media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp b/media/module/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
rename to media/module/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
diff --git a/media/codecs/amrwb/dec/src/median5.cpp b/media/module/codecs/amrwb/dec/src/median5.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/median5.cpp
rename to media/module/codecs/amrwb/dec/src/median5.cpp
diff --git a/media/codecs/amrwb/dec/src/mime_io.cpp b/media/module/codecs/amrwb/dec/src/mime_io.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/mime_io.cpp
rename to media/module/codecs/amrwb/dec/src/mime_io.cpp
diff --git a/media/codecs/amrwb/dec/src/mime_io.h b/media/module/codecs/amrwb/dec/src/mime_io.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/mime_io.h
rename to media/module/codecs/amrwb/dec/src/mime_io.h
diff --git a/media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp b/media/module/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
rename to media/module/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
diff --git a/media/codecs/amrwb/dec/src/normalize_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/normalize_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/normalize_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/normalize_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/normalize_amr_wb.h b/media/module/codecs/amrwb/dec/src/normalize_amr_wb.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/normalize_amr_wb.h
rename to media/module/codecs/amrwb/dec/src/normalize_amr_wb.h
diff --git a/media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp b/media/module/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
rename to media/module/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
diff --git a/media/codecs/amrwb/dec/src/phase_dispersion.cpp b/media/module/codecs/amrwb/dec/src/phase_dispersion.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/phase_dispersion.cpp
rename to media/module/codecs/amrwb/dec/src/phase_dispersion.cpp
diff --git a/media/codecs/amrwb/dec/src/pit_shrp.cpp b/media/module/codecs/amrwb/dec/src/pit_shrp.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pit_shrp.cpp
rename to media/module/codecs/amrwb/dec/src/pit_shrp.cpp
diff --git a/media/codecs/amrwb/dec/src/pred_lt4.cpp b/media/module/codecs/amrwb/dec/src/pred_lt4.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pred_lt4.cpp
rename to media/module/codecs/amrwb/dec/src/pred_lt4.cpp
diff --git a/media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp b/media/module/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
rename to media/module/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
diff --git a/media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h b/media/module/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
rename to media/module/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp b/media/module/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
rename to media/module/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
diff --git a/media/codecs/amrwb/dec/src/pvamrwb_math_op.h b/media/module/codecs/amrwb/dec/src/pvamrwb_math_op.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwb_math_op.h
rename to media/module/codecs/amrwb/dec/src/pvamrwb_math_op.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
diff --git a/media/codecs/amrwb/dec/src/q_gain2_tab.cpp b/media/module/codecs/amrwb/dec/src/q_gain2_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/q_gain2_tab.cpp
rename to media/module/codecs/amrwb/dec/src/q_gain2_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/q_pulse.h b/media/module/codecs/amrwb/dec/src/q_pulse.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/q_pulse.h
rename to media/module/codecs/amrwb/dec/src/q_pulse.h
diff --git a/media/codecs/amrwb/dec/src/qisf_ns.cpp b/media/module/codecs/amrwb/dec/src/qisf_ns.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns.cpp
rename to media/module/codecs/amrwb/dec/src/qisf_ns.cpp
diff --git a/media/codecs/amrwb/dec/src/qisf_ns.h b/media/module/codecs/amrwb/dec/src/qisf_ns.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns.h
rename to media/module/codecs/amrwb/dec/src/qisf_ns.h
diff --git a/media/codecs/amrwb/dec/src/qisf_ns_tab.cpp b/media/module/codecs/amrwb/dec/src/qisf_ns_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns_tab.cpp
rename to media/module/codecs/amrwb/dec/src/qisf_ns_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s.cpp b/media/module/codecs/amrwb/dec/src/qpisf_2s.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s.cpp
rename to media/module/codecs/amrwb/dec/src/qpisf_2s.cpp
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s.h b/media/module/codecs/amrwb/dec/src/qpisf_2s.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s.h
rename to media/module/codecs/amrwb/dec/src/qpisf_2s.h
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp b/media/module/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
rename to media/module/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/scale_signal.cpp b/media/module/codecs/amrwb/dec/src/scale_signal.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/scale_signal.cpp
rename to media/module/codecs/amrwb/dec/src/scale_signal.cpp
diff --git a/media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/synthesis_amr_wb.h b/media/module/codecs/amrwb/dec/src/synthesis_amr_wb.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/synthesis_amr_wb.h
rename to media/module/codecs/amrwb/dec/src/synthesis_amr_wb.h
diff --git a/media/codecs/amrwb/dec/src/voice_factor.cpp b/media/module/codecs/amrwb/dec/src/voice_factor.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/voice_factor.cpp
rename to media/module/codecs/amrwb/dec/src/voice_factor.cpp
diff --git a/media/codecs/amrwb/dec/src/wb_syn_filt.cpp b/media/module/codecs/amrwb/dec/src/wb_syn_filt.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/wb_syn_filt.cpp
rename to media/module/codecs/amrwb/dec/src/wb_syn_filt.cpp
diff --git a/media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp b/media/module/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
rename to media/module/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
diff --git a/media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h b/media/module/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
similarity index 100%
rename from media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
rename to media/module/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
diff --git a/media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp b/media/module/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
rename to media/module/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
diff --git a/media/codecs/amrwb/dec/test/Android.bp b/media/module/codecs/amrwb/dec/test/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/test/Android.bp
rename to media/module/codecs/amrwb/dec/test/Android.bp
diff --git a/media/codecs/amrwb/dec/test/AndroidTest.xml b/media/module/codecs/amrwb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrwb/dec/test/AndroidTest.xml
rename to media/module/codecs/amrwb/dec/test/AndroidTest.xml
diff --git a/media/codecs/amrwb/dec/test/README.md b/media/module/codecs/amrwb/dec/test/README.md
similarity index 100%
rename from media/codecs/amrwb/dec/test/README.md
rename to media/module/codecs/amrwb/dec/test/README.md
diff --git a/media/codecs/amrwb/dec/test/amrwbdec_test.cpp b/media/module/codecs/amrwb/dec/test/amrwbdec_test.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/test/amrwbdec_test.cpp
rename to media/module/codecs/amrwb/dec/test/amrwbdec_test.cpp
diff --git a/media/codecs/amrwb/enc/Android.bp b/media/module/codecs/amrwb/enc/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/Android.bp
rename to media/module/codecs/amrwb/enc/Android.bp
diff --git a/media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/enc/NOTICE b/media/module/codecs/amrwb/enc/NOTICE
similarity index 100%
rename from media/codecs/amrwb/enc/NOTICE
rename to media/module/codecs/amrwb/enc/NOTICE
diff --git a/media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c b/media/module/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
rename to media/module/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
diff --git a/media/codecs/amrwb/enc/SampleCode/Android.bp b/media/module/codecs/amrwb/enc/SampleCode/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/Android.bp
rename to media/module/codecs/amrwb/enc/SampleCode/Android.bp
diff --git a/media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/enc/SampleCode/NOTICE b/media/module/codecs/amrwb/enc/SampleCode/NOTICE
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/NOTICE
rename to media/module/codecs/amrwb/enc/SampleCode/NOTICE
diff --git a/media/codecs/amrwb/enc/TEST_MAPPING b/media/module/codecs/amrwb/enc/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrwb/enc/TEST_MAPPING
rename to media/module/codecs/amrwb/enc/TEST_MAPPING
diff --git a/media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf b/media/module/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
similarity index 100%
rename from media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
rename to media/module/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
Binary files differ
diff --git a/media/codecs/amrwb/enc/fuzzer/Android.bp b/media/module/codecs/amrwb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/Android.bp
rename to media/module/codecs/amrwb/enc/fuzzer/Android.bp
diff --git a/media/codecs/amrwb/enc/fuzzer/README.md b/media/module/codecs/amrwb/enc/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/README.md
rename to media/module/codecs/amrwb/enc/fuzzer/README.md
diff --git a/media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp b/media/module/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
rename to media/module/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
diff --git a/media/codecs/amrwb/enc/inc/acelp.h b/media/module/codecs/amrwb/enc/inc/acelp.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/acelp.h
rename to media/module/codecs/amrwb/enc/inc/acelp.h
diff --git a/media/codecs/amrwb/enc/inc/basic_op.h b/media/module/codecs/amrwb/enc/inc/basic_op.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/basic_op.h
rename to media/module/codecs/amrwb/enc/inc/basic_op.h
diff --git a/media/codecs/amrwb/enc/inc/bits.h b/media/module/codecs/amrwb/enc/inc/bits.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/bits.h
rename to media/module/codecs/amrwb/enc/inc/bits.h
diff --git a/media/codecs/amrwb/enc/inc/cnst.h b/media/module/codecs/amrwb/enc/inc/cnst.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/cnst.h
rename to media/module/codecs/amrwb/enc/inc/cnst.h
diff --git a/media/codecs/amrwb/enc/inc/cod_main.h b/media/module/codecs/amrwb/enc/inc/cod_main.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/cod_main.h
rename to media/module/codecs/amrwb/enc/inc/cod_main.h
diff --git a/media/codecs/amrwb/enc/inc/dtx.h b/media/module/codecs/amrwb/enc/inc/dtx.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/dtx.h
rename to media/module/codecs/amrwb/enc/inc/dtx.h
diff --git a/media/codecs/amrwb/enc/inc/grid100.tab b/media/module/codecs/amrwb/enc/inc/grid100.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/grid100.tab
rename to media/module/codecs/amrwb/enc/inc/grid100.tab
diff --git a/media/codecs/amrwb/enc/inc/ham_wind.tab b/media/module/codecs/amrwb/enc/inc/ham_wind.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/ham_wind.tab
rename to media/module/codecs/amrwb/enc/inc/ham_wind.tab
diff --git a/media/codecs/amrwb/enc/inc/homing.tab b/media/module/codecs/amrwb/enc/inc/homing.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/homing.tab
rename to media/module/codecs/amrwb/enc/inc/homing.tab
diff --git a/media/codecs/amrwb/enc/inc/isp_isf.tab b/media/module/codecs/amrwb/enc/inc/isp_isf.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/isp_isf.tab
rename to media/module/codecs/amrwb/enc/inc/isp_isf.tab
diff --git a/media/codecs/amrwb/enc/inc/lag_wind.tab b/media/module/codecs/amrwb/enc/inc/lag_wind.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/lag_wind.tab
rename to media/module/codecs/amrwb/enc/inc/lag_wind.tab
diff --git a/media/codecs/amrwb/enc/inc/log2.h b/media/module/codecs/amrwb/enc/inc/log2.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/log2.h
rename to media/module/codecs/amrwb/enc/inc/log2.h
diff --git a/media/codecs/amrwb/enc/inc/log2_tab.h b/media/module/codecs/amrwb/enc/inc/log2_tab.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/log2_tab.h
rename to media/module/codecs/amrwb/enc/inc/log2_tab.h
diff --git a/media/codecs/amrwb/enc/inc/main.h b/media/module/codecs/amrwb/enc/inc/main.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/main.h
rename to media/module/codecs/amrwb/enc/inc/main.h
diff --git a/media/codecs/amrwb/enc/inc/math_op.h b/media/module/codecs/amrwb/enc/inc/math_op.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/math_op.h
rename to media/module/codecs/amrwb/enc/inc/math_op.h
diff --git a/media/codecs/amrwb/enc/inc/mem_align.h b/media/module/codecs/amrwb/enc/inc/mem_align.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/mem_align.h
rename to media/module/codecs/amrwb/enc/inc/mem_align.h
diff --git a/media/codecs/amrwb/enc/inc/mime_io.tab b/media/module/codecs/amrwb/enc/inc/mime_io.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/mime_io.tab
rename to media/module/codecs/amrwb/enc/inc/mime_io.tab
diff --git a/media/codecs/amrwb/enc/inc/oper_32b.h b/media/module/codecs/amrwb/enc/inc/oper_32b.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/oper_32b.h
rename to media/module/codecs/amrwb/enc/inc/oper_32b.h
diff --git a/media/codecs/amrwb/enc/inc/p_med_o.h b/media/module/codecs/amrwb/enc/inc/p_med_o.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/p_med_o.h
rename to media/module/codecs/amrwb/enc/inc/p_med_o.h
diff --git a/media/codecs/amrwb/enc/inc/p_med_ol.tab b/media/module/codecs/amrwb/enc/inc/p_med_ol.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/p_med_ol.tab
rename to media/module/codecs/amrwb/enc/inc/p_med_ol.tab
diff --git a/media/codecs/amrwb/enc/inc/q_gain2.tab b/media/module/codecs/amrwb/enc/inc/q_gain2.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/q_gain2.tab
rename to media/module/codecs/amrwb/enc/inc/q_gain2.tab
diff --git a/media/codecs/amrwb/enc/inc/q_pulse.h b/media/module/codecs/amrwb/enc/inc/q_pulse.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/q_pulse.h
rename to media/module/codecs/amrwb/enc/inc/q_pulse.h
diff --git a/media/codecs/amrwb/enc/inc/qisf_ns.tab b/media/module/codecs/amrwb/enc/inc/qisf_ns.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/qisf_ns.tab
rename to media/module/codecs/amrwb/enc/inc/qisf_ns.tab
diff --git a/media/codecs/amrwb/enc/inc/qpisf_2s.tab b/media/module/codecs/amrwb/enc/inc/qpisf_2s.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/qpisf_2s.tab
rename to media/module/codecs/amrwb/enc/inc/qpisf_2s.tab
diff --git a/media/codecs/amrwb/enc/inc/stream.h b/media/module/codecs/amrwb/enc/inc/stream.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/stream.h
rename to media/module/codecs/amrwb/enc/inc/stream.h
diff --git a/media/codecs/amrwb/enc/inc/typedef.h b/media/module/codecs/amrwb/enc/inc/typedef.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/typedef.h
rename to media/module/codecs/amrwb/enc/inc/typedef.h
diff --git a/media/codecs/amrwb/enc/inc/typedefs.h b/media/module/codecs/amrwb/enc/inc/typedefs.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/typedefs.h
rename to media/module/codecs/amrwb/enc/inc/typedefs.h
diff --git a/media/codecs/amrwb/enc/inc/wb_vad.h b/media/module/codecs/amrwb/enc/inc/wb_vad.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/wb_vad.h
rename to media/module/codecs/amrwb/enc/inc/wb_vad.h
diff --git a/media/codecs/amrwb/enc/inc/wb_vad_c.h b/media/module/codecs/amrwb/enc/inc/wb_vad_c.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/wb_vad_c.h
rename to media/module/codecs/amrwb/enc/inc/wb_vad_c.h
diff --git a/media/codecs/amrwb/enc/patent_disclaimer.txt b/media/module/codecs/amrwb/enc/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrwb/enc/patent_disclaimer.txt
rename to media/module/codecs/amrwb/enc/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
diff --git a/media/codecs/amrwb/enc/src/autocorr.c b/media/module/codecs/amrwb/enc/src/autocorr.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/autocorr.c
rename to media/module/codecs/amrwb/enc/src/autocorr.c
diff --git a/media/codecs/amrwb/enc/src/az_isp.c b/media/module/codecs/amrwb/enc/src/az_isp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/az_isp.c
rename to media/module/codecs/amrwb/enc/src/az_isp.c
diff --git a/media/codecs/amrwb/enc/src/bits.c b/media/module/codecs/amrwb/enc/src/bits.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/bits.c
rename to media/module/codecs/amrwb/enc/src/bits.c
diff --git a/media/codecs/amrwb/enc/src/c2t64fx.c b/media/module/codecs/amrwb/enc/src/c2t64fx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/c2t64fx.c
rename to media/module/codecs/amrwb/enc/src/c2t64fx.c
diff --git a/media/codecs/amrwb/enc/src/c4t64fx.c b/media/module/codecs/amrwb/enc/src/c4t64fx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/c4t64fx.c
rename to media/module/codecs/amrwb/enc/src/c4t64fx.c
diff --git a/media/codecs/amrwb/enc/src/convolve.c b/media/module/codecs/amrwb/enc/src/convolve.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/convolve.c
rename to media/module/codecs/amrwb/enc/src/convolve.c
diff --git a/media/codecs/amrwb/enc/src/cor_h_x.c b/media/module/codecs/amrwb/enc/src/cor_h_x.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/cor_h_x.c
rename to media/module/codecs/amrwb/enc/src/cor_h_x.c
diff --git a/media/codecs/amrwb/enc/src/decim54.c b/media/module/codecs/amrwb/enc/src/decim54.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/decim54.c
rename to media/module/codecs/amrwb/enc/src/decim54.c
diff --git a/media/codecs/amrwb/enc/src/deemph.c b/media/module/codecs/amrwb/enc/src/deemph.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/deemph.c
rename to media/module/codecs/amrwb/enc/src/deemph.c
diff --git a/media/codecs/amrwb/enc/src/dtx.c b/media/module/codecs/amrwb/enc/src/dtx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/dtx.c
rename to media/module/codecs/amrwb/enc/src/dtx.c
diff --git a/media/codecs/amrwb/enc/src/g_pitch.c b/media/module/codecs/amrwb/enc/src/g_pitch.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/g_pitch.c
rename to media/module/codecs/amrwb/enc/src/g_pitch.c
diff --git a/media/codecs/amrwb/enc/src/gpclip.c b/media/module/codecs/amrwb/enc/src/gpclip.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/gpclip.c
rename to media/module/codecs/amrwb/enc/src/gpclip.c
diff --git a/media/codecs/amrwb/enc/src/homing.c b/media/module/codecs/amrwb/enc/src/homing.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/homing.c
rename to media/module/codecs/amrwb/enc/src/homing.c
diff --git a/media/codecs/amrwb/enc/src/hp400.c b/media/module/codecs/amrwb/enc/src/hp400.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp400.c
rename to media/module/codecs/amrwb/enc/src/hp400.c
diff --git a/media/codecs/amrwb/enc/src/hp50.c b/media/module/codecs/amrwb/enc/src/hp50.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp50.c
rename to media/module/codecs/amrwb/enc/src/hp50.c
diff --git a/media/codecs/amrwb/enc/src/hp6k.c b/media/module/codecs/amrwb/enc/src/hp6k.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp6k.c
rename to media/module/codecs/amrwb/enc/src/hp6k.c
diff --git a/media/codecs/amrwb/enc/src/hp_wsp.c b/media/module/codecs/amrwb/enc/src/hp_wsp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp_wsp.c
rename to media/module/codecs/amrwb/enc/src/hp_wsp.c
diff --git a/media/codecs/amrwb/enc/src/int_lpc.c b/media/module/codecs/amrwb/enc/src/int_lpc.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/int_lpc.c
rename to media/module/codecs/amrwb/enc/src/int_lpc.c
diff --git a/media/codecs/amrwb/enc/src/isp_az.c b/media/module/codecs/amrwb/enc/src/isp_az.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/isp_az.c
rename to media/module/codecs/amrwb/enc/src/isp_az.c
diff --git a/media/codecs/amrwb/enc/src/isp_isf.c b/media/module/codecs/amrwb/enc/src/isp_isf.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/isp_isf.c
rename to media/module/codecs/amrwb/enc/src/isp_isf.c
diff --git a/media/codecs/amrwb/enc/src/lag_wind.c b/media/module/codecs/amrwb/enc/src/lag_wind.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/lag_wind.c
rename to media/module/codecs/amrwb/enc/src/lag_wind.c
diff --git a/media/codecs/amrwb/enc/src/levinson.c b/media/module/codecs/amrwb/enc/src/levinson.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/levinson.c
rename to media/module/codecs/amrwb/enc/src/levinson.c
diff --git a/media/codecs/amrwb/enc/src/log2.c b/media/module/codecs/amrwb/enc/src/log2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/log2.c
rename to media/module/codecs/amrwb/enc/src/log2.c
diff --git a/media/codecs/amrwb/enc/src/lp_dec2.c b/media/module/codecs/amrwb/enc/src/lp_dec2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/lp_dec2.c
rename to media/module/codecs/amrwb/enc/src/lp_dec2.c
diff --git a/media/codecs/amrwb/enc/src/math_op.c b/media/module/codecs/amrwb/enc/src/math_op.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/math_op.c
rename to media/module/codecs/amrwb/enc/src/math_op.c
diff --git a/media/codecs/amrwb/enc/src/mem_align.c b/media/module/codecs/amrwb/enc/src/mem_align.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/mem_align.c
rename to media/module/codecs/amrwb/enc/src/mem_align.c
diff --git a/media/codecs/amrwb/enc/src/oper_32b.c b/media/module/codecs/amrwb/enc/src/oper_32b.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/oper_32b.c
rename to media/module/codecs/amrwb/enc/src/oper_32b.c
diff --git a/media/codecs/amrwb/enc/src/p_med_ol.c b/media/module/codecs/amrwb/enc/src/p_med_ol.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/p_med_ol.c
rename to media/module/codecs/amrwb/enc/src/p_med_ol.c
diff --git a/media/codecs/amrwb/enc/src/pit_shrp.c b/media/module/codecs/amrwb/enc/src/pit_shrp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pit_shrp.c
rename to media/module/codecs/amrwb/enc/src/pit_shrp.c
diff --git a/media/codecs/amrwb/enc/src/pitch_f4.c b/media/module/codecs/amrwb/enc/src/pitch_f4.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pitch_f4.c
rename to media/module/codecs/amrwb/enc/src/pitch_f4.c
diff --git a/media/codecs/amrwb/enc/src/pred_lt4.c b/media/module/codecs/amrwb/enc/src/pred_lt4.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pred_lt4.c
rename to media/module/codecs/amrwb/enc/src/pred_lt4.c
diff --git a/media/codecs/amrwb/enc/src/preemph.c b/media/module/codecs/amrwb/enc/src/preemph.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/preemph.c
rename to media/module/codecs/amrwb/enc/src/preemph.c
diff --git a/media/codecs/amrwb/enc/src/q_gain2.c b/media/module/codecs/amrwb/enc/src/q_gain2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/q_gain2.c
rename to media/module/codecs/amrwb/enc/src/q_gain2.c
diff --git a/media/codecs/amrwb/enc/src/q_pulse.c b/media/module/codecs/amrwb/enc/src/q_pulse.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/q_pulse.c
rename to media/module/codecs/amrwb/enc/src/q_pulse.c
diff --git a/media/codecs/amrwb/enc/src/qisf_ns.c b/media/module/codecs/amrwb/enc/src/qisf_ns.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/qisf_ns.c
rename to media/module/codecs/amrwb/enc/src/qisf_ns.c
diff --git a/media/codecs/amrwb/enc/src/qpisf_2s.c b/media/module/codecs/amrwb/enc/src/qpisf_2s.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/qpisf_2s.c
rename to media/module/codecs/amrwb/enc/src/qpisf_2s.c
diff --git a/media/codecs/amrwb/enc/src/random.c b/media/module/codecs/amrwb/enc/src/random.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/random.c
rename to media/module/codecs/amrwb/enc/src/random.c
diff --git a/media/codecs/amrwb/enc/src/residu.c b/media/module/codecs/amrwb/enc/src/residu.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/residu.c
rename to media/module/codecs/amrwb/enc/src/residu.c
diff --git a/media/codecs/amrwb/enc/src/scale.c b/media/module/codecs/amrwb/enc/src/scale.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/scale.c
rename to media/module/codecs/amrwb/enc/src/scale.c
diff --git a/media/codecs/amrwb/enc/src/stream.c b/media/module/codecs/amrwb/enc/src/stream.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/stream.c
rename to media/module/codecs/amrwb/enc/src/stream.c
diff --git a/media/codecs/amrwb/enc/src/syn_filt.c b/media/module/codecs/amrwb/enc/src/syn_filt.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/syn_filt.c
rename to media/module/codecs/amrwb/enc/src/syn_filt.c
diff --git a/media/codecs/amrwb/enc/src/updt_tar.c b/media/module/codecs/amrwb/enc/src/updt_tar.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/updt_tar.c
rename to media/module/codecs/amrwb/enc/src/updt_tar.c
diff --git a/media/codecs/amrwb/enc/src/util.c b/media/module/codecs/amrwb/enc/src/util.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/util.c
rename to media/module/codecs/amrwb/enc/src/util.c
diff --git a/media/codecs/amrwb/enc/src/voAMRWBEnc.c b/media/module/codecs/amrwb/enc/src/voAMRWBEnc.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/voAMRWBEnc.c
rename to media/module/codecs/amrwb/enc/src/voAMRWBEnc.c
diff --git a/media/codecs/amrwb/enc/src/voicefac.c b/media/module/codecs/amrwb/enc/src/voicefac.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/voicefac.c
rename to media/module/codecs/amrwb/enc/src/voicefac.c
diff --git a/media/codecs/amrwb/enc/src/wb_vad.c b/media/module/codecs/amrwb/enc/src/wb_vad.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/wb_vad.c
rename to media/module/codecs/amrwb/enc/src/wb_vad.c
diff --git a/media/codecs/amrwb/enc/src/weight_a.c b/media/module/codecs/amrwb/enc/src/weight_a.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/weight_a.c
rename to media/module/codecs/amrwb/enc/src/weight_a.c
diff --git a/media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h b/media/module/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
similarity index 100%
rename from media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
rename to media/module/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
diff --git a/media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp b/media/module/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
similarity index 100%
rename from media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
rename to media/module/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
diff --git a/media/codecs/amrwb/enc/test/Android.bp b/media/module/codecs/amrwb/enc/test/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/test/Android.bp
rename to media/module/codecs/amrwb/enc/test/Android.bp
diff --git a/media/codecs/amrwb/enc/test/AndroidTest.xml b/media/module/codecs/amrwb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrwb/enc/test/AndroidTest.xml
rename to media/module/codecs/amrwb/enc/test/AndroidTest.xml
diff --git a/media/codecs/amrwb/enc/test/README.md b/media/module/codecs/amrwb/enc/test/README.md
similarity index 100%
rename from media/codecs/amrwb/enc/test/README.md
rename to media/module/codecs/amrwb/enc/test/README.md
diff --git a/media/libstagefright/codecs/common/Android.bp b/media/module/codecs/common/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/common/Android.bp
rename to media/module/codecs/common/Android.bp
diff --git a/media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2 b/media/module/codecs/common/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2
rename to media/module/codecs/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/common/NOTICE b/media/module/codecs/common/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/common/NOTICE
rename to media/module/codecs/common/NOTICE
diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/module/codecs/common/cmnMemory.c
similarity index 100%
rename from media/libstagefright/codecs/common/cmnMemory.c
rename to media/module/codecs/common/cmnMemory.c
diff --git a/media/libstagefright/codecs/common/include/cmnMemory.h b/media/module/codecs/common/include/cmnMemory.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/cmnMemory.h
rename to media/module/codecs/common/include/cmnMemory.h
diff --git a/media/libstagefright/codecs/common/include/voAAC.h b/media/module/codecs/common/include/voAAC.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAAC.h
rename to media/module/codecs/common/include/voAAC.h
diff --git a/media/libstagefright/codecs/common/include/voAMRWB.h b/media/module/codecs/common/include/voAMRWB.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAMRWB.h
rename to media/module/codecs/common/include/voAMRWB.h
diff --git a/media/libstagefright/codecs/common/include/voAudio.h b/media/module/codecs/common/include/voAudio.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAudio.h
rename to media/module/codecs/common/include/voAudio.h
diff --git a/media/libstagefright/codecs/common/include/voIndex.h b/media/module/codecs/common/include/voIndex.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voIndex.h
rename to media/module/codecs/common/include/voIndex.h
diff --git a/media/libstagefright/codecs/common/include/voMem.h b/media/module/codecs/common/include/voMem.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voMem.h
rename to media/module/codecs/common/include/voMem.h
diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/module/codecs/common/include/voType.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voType.h
rename to media/module/codecs/common/include/voType.h
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/module/codecs/flac/dec/Android.bp
similarity index 100%
rename from media/libstagefright/flac/dec/Android.bp
rename to media/module/codecs/flac/dec/Android.bp
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/module/codecs/flac/dec/FLACDecoder.cpp
similarity index 100%
rename from media/libstagefright/flac/dec/FLACDecoder.cpp
rename to media/module/codecs/flac/dec/FLACDecoder.cpp
diff --git a/media/libstagefright/flac/dec/FLACDecoder.h b/media/module/codecs/flac/dec/FLACDecoder.h
similarity index 100%
rename from media/libstagefright/flac/dec/FLACDecoder.h
rename to media/module/codecs/flac/dec/FLACDecoder.h
diff --git a/media/libstagefright/flac/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/flac/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/flac/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/flac/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/flac/dec/NOTICE b/media/module/codecs/flac/dec/NOTICE
similarity index 100%
rename from media/libstagefright/flac/dec/NOTICE
rename to media/module/codecs/flac/dec/NOTICE
diff --git a/media/libstagefright/flac/dec/test/Android.bp b/media/module/codecs/flac/dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/flac/dec/test/Android.bp
rename to media/module/codecs/flac/dec/test/Android.bp
diff --git a/media/libstagefright/flac/dec/test/AndroidTest.xml b/media/module/codecs/flac/dec/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/flac/dec/test/AndroidTest.xml
rename to media/module/codecs/flac/dec/test/AndroidTest.xml
diff --git a/media/libstagefright/flac/dec/test/FlacDecoderTest.cpp b/media/module/codecs/flac/dec/test/FlacDecoderTest.cpp
similarity index 100%
rename from media/libstagefright/flac/dec/test/FlacDecoderTest.cpp
rename to media/module/codecs/flac/dec/test/FlacDecoderTest.cpp
diff --git a/media/libstagefright/flac/dec/test/FlacDecoderTestEnvironment.h b/media/module/codecs/flac/dec/test/FlacDecoderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/flac/dec/test/FlacDecoderTestEnvironment.h
rename to media/module/codecs/flac/dec/test/FlacDecoderTestEnvironment.h
diff --git a/media/libstagefright/flac/dec/test/README.md b/media/module/codecs/flac/dec/test/README.md
similarity index 100%
rename from media/libstagefright/flac/dec/test/README.md
rename to media/module/codecs/flac/dec/test/README.md
diff --git a/media/codecs/g711/decoder/Android.bp b/media/module/codecs/g711/decoder/Android.bp
similarity index 100%
rename from media/codecs/g711/decoder/Android.bp
rename to media/module/codecs/g711/decoder/Android.bp
diff --git a/media/codecs/g711/decoder/g711Dec.h b/media/module/codecs/g711/decoder/g711Dec.h
similarity index 100%
rename from media/codecs/g711/decoder/g711Dec.h
rename to media/module/codecs/g711/decoder/g711Dec.h
diff --git a/media/codecs/g711/decoder/g711DecAlaw.cpp b/media/module/codecs/g711/decoder/g711DecAlaw.cpp
similarity index 100%
rename from media/codecs/g711/decoder/g711DecAlaw.cpp
rename to media/module/codecs/g711/decoder/g711DecAlaw.cpp
diff --git a/media/codecs/g711/decoder/g711DecMlaw.cpp b/media/module/codecs/g711/decoder/g711DecMlaw.cpp
similarity index 100%
rename from media/codecs/g711/decoder/g711DecMlaw.cpp
rename to media/module/codecs/g711/decoder/g711DecMlaw.cpp
diff --git a/media/codecs/g711/fuzzer/Android.bp b/media/module/codecs/g711/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/g711/fuzzer/Android.bp
rename to media/module/codecs/g711/fuzzer/Android.bp
diff --git a/media/codecs/g711/fuzzer/README.md b/media/module/codecs/g711/fuzzer/README.md
similarity index 100%
rename from media/codecs/g711/fuzzer/README.md
rename to media/module/codecs/g711/fuzzer/README.md
diff --git a/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp b/media/module/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
rename to media/module/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/TEST_MAPPING b/media/module/codecs/m4v_h263/TEST_MAPPING
similarity index 100%
rename from media/codecs/m4v_h263/TEST_MAPPING
rename to media/module/codecs/m4v_h263/TEST_MAPPING
diff --git a/media/codecs/m4v_h263/dec/Android.bp b/media/module/codecs/m4v_h263/dec/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/dec/Android.bp
rename to media/module/codecs/m4v_h263/dec/Android.bp
diff --git a/media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/m4v_h263/dec/NOTICE b/media/module/codecs/m4v_h263/dec/NOTICE
similarity index 100%
rename from media/codecs/m4v_h263/dec/NOTICE
rename to media/module/codecs/m4v_h263/dec/NOTICE
diff --git a/media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h b/media/module/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
rename to media/module/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
diff --git a/media/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/module/codecs/m4v_h263/dec/include/mp4dec_api.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/mp4dec_api.h
rename to media/module/codecs/m4v_h263/dec/include/mp4dec_api.h
diff --git a/media/codecs/m4v_h263/dec/include/visual_header.h b/media/module/codecs/m4v_h263/dec/include/visual_header.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/visual_header.h
rename to media/module/codecs/m4v_h263/dec/include/visual_header.h
diff --git a/media/codecs/m4v_h263/dec/src/bitstream.cpp b/media/module/codecs/m4v_h263/dec/src/bitstream.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/bitstream.cpp
rename to media/module/codecs/m4v_h263/dec/src/bitstream.cpp
diff --git a/media/codecs/m4v_h263/dec/src/bitstream.h b/media/module/codecs/m4v_h263/dec/src/bitstream.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/bitstream.h
rename to media/module/codecs/m4v_h263/dec/src/bitstream.h
diff --git a/media/codecs/m4v_h263/dec/src/block_idct.cpp b/media/module/codecs/m4v_h263/dec/src/block_idct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/block_idct.cpp
rename to media/module/codecs/m4v_h263/dec/src/block_idct.cpp
diff --git a/media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp b/media/module/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
rename to media/module/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
diff --git a/media/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/module/codecs/m4v_h263/dec/src/combined_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/combined_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/combined_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/conceal.cpp b/media/module/codecs/m4v_h263/dec/src/conceal.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/conceal.cpp
rename to media/module/codecs/m4v_h263/dec/src/conceal.cpp
diff --git a/media/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/module/codecs/m4v_h263/dec/src/datapart_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/datapart_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/datapart_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/dcac_prediction.cpp b/media/module/codecs/m4v_h263/dec/src/dcac_prediction.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/dcac_prediction.cpp
rename to media/module/codecs/m4v_h263/dec/src/dcac_prediction.cpp
diff --git a/media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp b/media/module/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
rename to media/module/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
diff --git a/media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/module/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
rename to media/module/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
diff --git a/media/codecs/m4v_h263/dec/src/get_pred_outside.cpp b/media/module/codecs/m4v_h263/dec/src/get_pred_outside.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/get_pred_outside.cpp
rename to media/module/codecs/m4v_h263/dec/src/get_pred_outside.cpp
diff --git a/media/codecs/m4v_h263/dec/src/idct.cpp b/media/module/codecs/m4v_h263/dec/src/idct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct.cpp
rename to media/module/codecs/m4v_h263/dec/src/idct.cpp
diff --git a/media/codecs/m4v_h263/dec/src/idct.h b/media/module/codecs/m4v_h263/dec/src/idct.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct.h
rename to media/module/codecs/m4v_h263/dec/src/idct.h
diff --git a/media/codecs/m4v_h263/dec/src/idct_vca.cpp b/media/module/codecs/m4v_h263/dec/src/idct_vca.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct_vca.cpp
rename to media/module/codecs/m4v_h263/dec/src/idct_vca.cpp
diff --git a/media/codecs/m4v_h263/dec/src/max_level.h b/media/module/codecs/m4v_h263/dec/src/max_level.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/max_level.h
rename to media/module/codecs/m4v_h263/dec/src/max_level.h
diff --git a/media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/module/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
rename to media/module/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
diff --git a/media/codecs/m4v_h263/dec/src/mb_utils.cpp b/media/module/codecs/m4v_h263/dec/src/mb_utils.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mb_utils.cpp
rename to media/module/codecs/m4v_h263/dec/src/mb_utils.cpp
diff --git a/media/codecs/m4v_h263/dec/src/mbtype_mode.h b/media/module/codecs/m4v_h263/dec/src/mbtype_mode.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mbtype_mode.h
rename to media/module/codecs/m4v_h263/dec/src/mbtype_mode.h
diff --git a/media/codecs/m4v_h263/dec/src/motion_comp.h b/media/module/codecs/m4v_h263/dec/src/motion_comp.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/motion_comp.h
rename to media/module/codecs/m4v_h263/dec/src/motion_comp.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/module/codecs/m4v_h263/dec/src/mp4dec_lib.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4dec_lib.h
rename to media/module/codecs/m4v_h263/dec/src/mp4dec_lib.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4def.h b/media/module/codecs/m4v_h263/dec/src/mp4def.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4def.h
rename to media/module/codecs/m4v_h263/dec/src/mp4def.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4lib_int.h b/media/module/codecs/m4v_h263/dec/src/mp4lib_int.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4lib_int.h
rename to media/module/codecs/m4v_h263/dec/src/mp4lib_int.h
diff --git a/media/codecs/m4v_h263/dec/src/packet_util.cpp b/media/module/codecs/m4v_h263/dec/src/packet_util.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/packet_util.cpp
rename to media/module/codecs/m4v_h263/dec/src/packet_util.cpp
diff --git a/media/codecs/m4v_h263/dec/src/post_filter.cpp b/media/module/codecs/m4v_h263/dec/src/post_filter.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/post_filter.cpp
rename to media/module/codecs/m4v_h263/dec/src/post_filter.cpp
diff --git a/media/codecs/m4v_h263/dec/src/post_proc.h b/media/module/codecs/m4v_h263/dec/src/post_proc.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/post_proc.h
rename to media/module/codecs/m4v_h263/dec/src/post_proc.h
diff --git a/media/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/module/codecs/m4v_h263/dec/src/pvdec_api.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/pvdec_api.cpp
rename to media/module/codecs/m4v_h263/dec/src/pvdec_api.cpp
diff --git a/media/codecs/m4v_h263/dec/src/scaling.h b/media/module/codecs/m4v_h263/dec/src/scaling.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/scaling.h
rename to media/module/codecs/m4v_h263/dec/src/scaling.h
diff --git a/media/codecs/m4v_h263/dec/src/scaling_tab.cpp b/media/module/codecs/m4v_h263/dec/src/scaling_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/scaling_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/scaling_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_dec_tab.h b/media/module/codecs/m4v_h263/dec/src/vlc_dec_tab.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_dec_tab.h
rename to media/module/codecs/m4v_h263/dec/src/vlc_dec_tab.h
diff --git a/media/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_decode.h b/media/module/codecs/m4v_h263/dec/src/vlc_decode.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_decode.h
rename to media/module/codecs/m4v_h263/dec/src/vlc_decode.h
diff --git a/media/codecs/m4v_h263/dec/src/vlc_dequant.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_dequant.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_dequant.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_dequant.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_tab.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vop.cpp b/media/module/codecs/m4v_h263/dec/src/vop.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vop.cpp
rename to media/module/codecs/m4v_h263/dec/src/vop.cpp
diff --git a/media/codecs/m4v_h263/dec/src/zigzag.h b/media/module/codecs/m4v_h263/dec/src/zigzag.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/zigzag.h
rename to media/module/codecs/m4v_h263/dec/src/zigzag.h
diff --git a/media/codecs/m4v_h263/dec/src/zigzag_tab.cpp b/media/module/codecs/m4v_h263/dec/src/zigzag_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/zigzag_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/zigzag_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/test/Android.bp b/media/module/codecs/m4v_h263/dec/test/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Android.bp
rename to media/module/codecs/m4v_h263/dec/test/Android.bp
diff --git a/media/codecs/m4v_h263/dec/test/AndroidTest.xml b/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/AndroidTest.xml
rename to media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
diff --git a/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp b/media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
rename to media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
diff --git a/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h b/media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
rename to media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
diff --git a/media/codecs/m4v_h263/dec/test/README.md b/media/module/codecs/m4v_h263/dec/test/README.md
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/README.md
rename to media/module/codecs/m4v_h263/dec/test/README.md
diff --git a/media/codecs/m4v_h263/enc/Android.bp b/media/module/codecs/m4v_h263/enc/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/enc/Android.bp
rename to media/module/codecs/m4v_h263/enc/Android.bp
diff --git a/media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/m4v_h263/enc/NOTICE b/media/module/codecs/m4v_h263/enc/NOTICE
similarity index 100%
rename from media/codecs/m4v_h263/enc/NOTICE
rename to media/module/codecs/m4v_h263/enc/NOTICE
diff --git a/media/codecs/m4v_h263/enc/include/cvei.h b/media/module/codecs/m4v_h263/enc/include/cvei.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/include/cvei.h
rename to media/module/codecs/m4v_h263/enc/include/cvei.h
diff --git a/media/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/module/codecs/m4v_h263/enc/include/mp4enc_api.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/include/mp4enc_api.h
rename to media/module/codecs/m4v_h263/enc/include/mp4enc_api.h
diff --git a/media/codecs/m4v_h263/enc/src/bitstream_io.cpp b/media/module/codecs/m4v_h263/enc/src/bitstream_io.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/bitstream_io.cpp
rename to media/module/codecs/m4v_h263/enc/src/bitstream_io.cpp
diff --git a/media/codecs/m4v_h263/enc/src/bitstream_io.h b/media/module/codecs/m4v_h263/enc/src/bitstream_io.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/bitstream_io.h
rename to media/module/codecs/m4v_h263/enc/src/bitstream_io.h
diff --git a/media/codecs/m4v_h263/enc/src/combined_encode.cpp b/media/module/codecs/m4v_h263/enc/src/combined_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/combined_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/combined_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/datapart_encode.cpp b/media/module/codecs/m4v_h263/enc/src/datapart_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/datapart_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/datapart_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/dct.cpp b/media/module/codecs/m4v_h263/enc/src/dct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct.cpp
rename to media/module/codecs/m4v_h263/enc/src/dct.cpp
diff --git a/media/codecs/m4v_h263/enc/src/dct.h b/media/module/codecs/m4v_h263/enc/src/dct.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct.h
rename to media/module/codecs/m4v_h263/enc/src/dct.h
diff --git a/media/codecs/m4v_h263/enc/src/dct_inline.h b/media/module/codecs/m4v_h263/enc/src/dct_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct_inline.h
rename to media/module/codecs/m4v_h263/enc/src/dct_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/fastcodemb.cpp b/media/module/codecs/m4v_h263/enc/src/fastcodemb.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastcodemb.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastcodemb.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastcodemb.h b/media/module/codecs/m4v_h263/enc/src/fastcodemb.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastcodemb.h
rename to media/module/codecs/m4v_h263/enc/src/fastcodemb.h
diff --git a/media/codecs/m4v_h263/enc/src/fastidct.cpp b/media/module/codecs/m4v_h263/enc/src/fastidct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastidct.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastidct.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastquant.cpp b/media/module/codecs/m4v_h263/enc/src/fastquant.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastquant.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastquant.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastquant_inline.h b/media/module/codecs/m4v_h263/enc/src/fastquant_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastquant_inline.h
rename to media/module/codecs/m4v_h263/enc/src/fastquant_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/findhalfpel.cpp b/media/module/codecs/m4v_h263/enc/src/findhalfpel.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/findhalfpel.cpp
rename to media/module/codecs/m4v_h263/enc/src/findhalfpel.cpp
diff --git a/media/codecs/m4v_h263/enc/src/m4venc_oscl.h b/media/module/codecs/m4v_h263/enc/src/m4venc_oscl.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/m4venc_oscl.h
rename to media/module/codecs/m4v_h263/enc/src/m4venc_oscl.h
diff --git a/media/codecs/m4v_h263/enc/src/me_utils.cpp b/media/module/codecs/m4v_h263/enc/src/me_utils.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/me_utils.cpp
rename to media/module/codecs/m4v_h263/enc/src/me_utils.cpp
diff --git a/media/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/module/codecs/m4v_h263/enc/src/motion_comp.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/motion_comp.cpp
rename to media/module/codecs/m4v_h263/enc/src/motion_comp.cpp
diff --git a/media/codecs/m4v_h263/enc/src/motion_est.cpp b/media/module/codecs/m4v_h263/enc/src/motion_est.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/motion_est.cpp
rename to media/module/codecs/m4v_h263/enc/src/motion_est.cpp
diff --git a/media/codecs/m4v_h263/enc/src/mp4def.h b/media/module/codecs/m4v_h263/enc/src/mp4def.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4def.h
rename to media/module/codecs/m4v_h263/enc/src/mp4def.h
diff --git a/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp b/media/module/codecs/m4v_h263/enc/src/mp4enc_api.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
rename to media/module/codecs/m4v_h263/enc/src/mp4enc_api.cpp
diff --git a/media/codecs/m4v_h263/enc/src/mp4enc_lib.h b/media/module/codecs/m4v_h263/enc/src/mp4enc_lib.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4enc_lib.h
rename to media/module/codecs/m4v_h263/enc/src/mp4enc_lib.h
diff --git a/media/codecs/m4v_h263/enc/src/mp4lib_int.h b/media/module/codecs/m4v_h263/enc/src/mp4lib_int.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4lib_int.h
rename to media/module/codecs/m4v_h263/enc/src/mp4lib_int.h
diff --git a/media/codecs/m4v_h263/enc/src/rate_control.cpp b/media/module/codecs/m4v_h263/enc/src/rate_control.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/rate_control.cpp
rename to media/module/codecs/m4v_h263/enc/src/rate_control.cpp
diff --git a/media/codecs/m4v_h263/enc/src/rate_control.h b/media/module/codecs/m4v_h263/enc/src/rate_control.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/rate_control.h
rename to media/module/codecs/m4v_h263/enc/src/rate_control.h
diff --git a/media/codecs/m4v_h263/enc/src/sad.cpp b/media/module/codecs/m4v_h263/enc/src/sad.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad.cpp
rename to media/module/codecs/m4v_h263/enc/src/sad.cpp
diff --git a/media/codecs/m4v_h263/enc/src/sad_halfpel.cpp b/media/module/codecs/m4v_h263/enc/src/sad_halfpel.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_halfpel.cpp
rename to media/module/codecs/m4v_h263/enc/src/sad_halfpel.cpp
diff --git a/media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h b/media/module/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
rename to media/module/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/sad_inline.h b/media/module/codecs/m4v_h263/enc/src/sad_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_inline.h
rename to media/module/codecs/m4v_h263/enc/src/sad_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/sad_mb_offset.h b/media/module/codecs/m4v_h263/enc/src/sad_mb_offset.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_mb_offset.h
rename to media/module/codecs/m4v_h263/enc/src/sad_mb_offset.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_enc_tab.h b/media/module/codecs/m4v_h263/enc/src/vlc_enc_tab.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_enc_tab.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_enc_tab.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode.cpp b/media/module/codecs/m4v_h263/enc/src/vlc_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode.h b/media/module/codecs/m4v_h263/enc/src/vlc_encode.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode_inline.h b/media/module/codecs/m4v_h263/enc/src/vlc_encode_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode_inline.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/vop.cpp b/media/module/codecs/m4v_h263/enc/src/vop.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vop.cpp
rename to media/module/codecs/m4v_h263/enc/src/vop.cpp
diff --git a/media/codecs/m4v_h263/enc/test/Android.bp b/media/module/codecs/m4v_h263/enc/test/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Android.bp
rename to media/module/codecs/m4v_h263/enc/test/Android.bp
diff --git a/media/codecs/m4v_h263/enc/test/AndroidTest.xml b/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/AndroidTest.xml
rename to media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
diff --git a/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp b/media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
rename to media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
diff --git a/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h b/media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
rename to media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
diff --git a/media/codecs/m4v_h263/enc/test/README.md b/media/module/codecs/m4v_h263/enc/test/README.md
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/README.md
rename to media/module/codecs/m4v_h263/enc/test/README.md
diff --git a/media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/module/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
rename to media/module/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
diff --git a/media/codecs/m4v_h263/fuzzer/Android.bp b/media/module/codecs/m4v_h263/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/Android.bp
rename to media/module/codecs/m4v_h263/fuzzer/Android.bp
diff --git a/media/codecs/m4v_h263/fuzzer/README.md b/media/module/codecs/m4v_h263/fuzzer/README.md
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/README.md
rename to media/module/codecs/m4v_h263/fuzzer/README.md
diff --git a/media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict b/media/module/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
rename to media/module/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict b/media/module/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp b/media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp b/media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/patent_disclaimer.txt b/media/module/codecs/m4v_h263/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/m4v_h263/patent_disclaimer.txt
rename to media/module/codecs/m4v_h263/patent_disclaimer.txt
diff --git a/media/codecs/mp3dec/Android.bp b/media/module/codecs/mp3dec/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/Android.bp
rename to media/module/codecs/mp3dec/Android.bp
diff --git a/media/codecs/mp3dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/mp3dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/mp3dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/mp3dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/mp3dec/NOTICE b/media/module/codecs/mp3dec/NOTICE
similarity index 100%
rename from media/codecs/mp3dec/NOTICE
rename to media/module/codecs/mp3dec/NOTICE
diff --git a/media/codecs/mp3dec/TEST_MAPPING b/media/module/codecs/mp3dec/TEST_MAPPING
similarity index 100%
rename from media/codecs/mp3dec/TEST_MAPPING
rename to media/module/codecs/mp3dec/TEST_MAPPING
diff --git a/media/codecs/mp3dec/fuzzer/Android.bp b/media/module/codecs/mp3dec/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/Android.bp
rename to media/module/codecs/mp3dec/fuzzer/Android.bp
diff --git a/media/codecs/mp3dec/fuzzer/README.md b/media/module/codecs/mp3dec/fuzzer/README.md
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/README.md
rename to media/module/codecs/mp3dec/fuzzer/README.md
diff --git a/media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp b/media/module/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
rename to media/module/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
diff --git a/media/codecs/mp3dec/include/mp3_decoder_selection.h b/media/module/codecs/mp3dec/include/mp3_decoder_selection.h
similarity index 100%
rename from media/codecs/mp3dec/include/mp3_decoder_selection.h
rename to media/module/codecs/mp3dec/include/mp3_decoder_selection.h
diff --git a/media/codecs/mp3dec/include/pvmp3_audio_type_defs.h b/media/module/codecs/mp3dec/include/pvmp3_audio_type_defs.h
similarity index 100%
rename from media/codecs/mp3dec/include/pvmp3_audio_type_defs.h
rename to media/module/codecs/mp3dec/include/pvmp3_audio_type_defs.h
diff --git a/media/codecs/mp3dec/include/pvmp3decoder_api.h b/media/module/codecs/mp3dec/include/pvmp3decoder_api.h
similarity index 100%
rename from media/codecs/mp3dec/include/pvmp3decoder_api.h
rename to media/module/codecs/mp3dec/include/pvmp3decoder_api.h
diff --git a/media/codecs/mp3dec/patent_disclaimer.txt b/media/module/codecs/mp3dec/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/mp3dec/patent_disclaimer.txt
rename to media/module/codecs/mp3dec/patent_disclaimer.txt
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
diff --git a/media/codecs/mp3dec/src/mp3_mem_funcs.h b/media/module/codecs/mp3dec/src/mp3_mem_funcs.h
similarity index 100%
rename from media/codecs/mp3dec/src/mp3_mem_funcs.h
rename to media/module/codecs/mp3dec/src/mp3_mem_funcs.h
diff --git a/media/codecs/mp3dec/src/pv_mp3_huffman.h b/media/module/codecs/mp3dec/src/pv_mp3_huffman.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3_huffman.h
rename to media/module/codecs/mp3dec/src/pv_mp3_huffman.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp b/media/module/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_alias_reduction.h b/media/module/codecs/mp3dec/src/pvmp3_alias_reduction.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_alias_reduction.h
rename to media/module/codecs/mp3dec/src/pvmp3_alias_reduction.h
diff --git a/media/codecs/mp3dec/src/pvmp3_crc.cpp b/media/module/codecs/mp3dec/src/pvmp3_crc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_crc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_crc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_crc.h b/media/module/codecs/mp3dec/src/pvmp3_crc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_crc.h
rename to media/module/codecs/mp3dec/src/pvmp3_crc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_16.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_16.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_16.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_16.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_16.h b/media/module/codecs/mp3dec/src/pvmp3_dct_16.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_16.h
rename to media/module/codecs/mp3dec/src/pvmp3_dct_16.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_6.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_6.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_6.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_6.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_9.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_9.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_9.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_9.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dec_defs.h b/media/module/codecs/mp3dec/src/pvmp3_dec_defs.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dec_defs.h
rename to media/module/codecs/mp3dec/src/pvmp3_dec_defs.h
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/module/codecs/mp3dec/src/pvmp3_decode_header.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_header.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_decode_header.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_header.h b/media/module/codecs/mp3dec/src/pvmp3_decode_header.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_header.h
rename to media/module/codecs/mp3dec/src/pvmp3_decode_header.h
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp b/media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h b/media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
rename to media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp b/media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dequantize_sample.h b/media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dequantize_sample.h
rename to media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.h
diff --git a/media/codecs/mp3dec/src/pvmp3_equalizer.cpp b/media/module/codecs/mp3dec/src/pvmp3_equalizer.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_equalizer.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_equalizer.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_equalizer.h b/media/module/codecs/mp3dec/src/pvmp3_equalizer.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_equalizer.h
rename to media/module/codecs/mp3dec/src/pvmp3_equalizer.h
diff --git a/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/module/codecs/mp3dec/src/pvmp3_framedecoder.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_framedecoder.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_framedecoder.h b/media/module/codecs/mp3dec/src/pvmp3_framedecoder.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_framedecoder.h
rename to media/module/codecs/mp3dec/src/pvmp3_framedecoder.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_main_data_size.h b/media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_main_data_size.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_scale_factors.h b/media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_scale_factors.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_side_info.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_side_info.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_side_info.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_side_info.h b/media/module/codecs/mp3dec/src/pvmp3_get_side_info.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_side_info.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_side_info.h
diff --git a/media/codecs/mp3dec/src/pvmp3_getbits.cpp b/media/module/codecs/mp3dec/src/pvmp3_getbits.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_getbits.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_getbits.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_getbits.h b/media/module/codecs/mp3dec/src/pvmp3_getbits.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_getbits.h
rename to media/module/codecs/mp3dec/src/pvmp3_getbits.h
diff --git a/media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp b/media/module/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp b/media/module/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp b/media/module/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_imdct_synth.h b/media/module/codecs/mp3dec/src/pvmp3_imdct_synth.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_imdct_synth.h
rename to media/module/codecs/mp3dec/src/pvmp3_imdct_synth.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_18.cpp b/media/module/codecs/mp3dec/src/pvmp3_mdct_18.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_18.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_18.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_18.h b/media/module/codecs/mp3dec/src/pvmp3_mdct_18.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_18.h
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_18.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_6.cpp b/media/module/codecs/mp3dec/src/pvmp3_mdct_6.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_6.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_6.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_6.h b/media/module/codecs/mp3dec/src/pvmp3_mdct_6.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_6.h
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_6.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_normalize.cpp b/media/module/codecs/mp3dec/src/pvmp3_normalize.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_normalize.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_normalize.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_normalize.h b/media/module/codecs/mp3dec/src/pvmp3_normalize.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_normalize.h
rename to media/module/codecs/mp3dec/src/pvmp3_normalize.h
diff --git a/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp b/media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h b/media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
rename to media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
diff --git a/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp b/media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h b/media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
rename to media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
diff --git a/media/codecs/mp3dec/src/pvmp3_reorder.cpp b/media/module/codecs/mp3dec/src/pvmp3_reorder.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_reorder.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_reorder.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_reorder.h b/media/module/codecs/mp3dec/src/pvmp3_reorder.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_reorder.h
rename to media/module/codecs/mp3dec/src/pvmp3_reorder.h
diff --git a/media/codecs/mp3dec/src/pvmp3_seek_synch.cpp b/media/module/codecs/mp3dec/src/pvmp3_seek_synch.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_seek_synch.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_seek_synch.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_seek_synch.h b/media/module/codecs/mp3dec/src/pvmp3_seek_synch.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_seek_synch.h
rename to media/module/codecs/mp3dec/src/pvmp3_seek_synch.h
diff --git a/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp b/media/module/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_stereo_proc.h b/media/module/codecs/mp3dec/src/pvmp3_stereo_proc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_stereo_proc.h
rename to media/module/codecs/mp3dec/src/pvmp3_stereo_proc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_tables.cpp b/media/module/codecs/mp3dec/src/pvmp3_tables.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_tables.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_tables.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_tables.h b/media/module/codecs/mp3dec/src/pvmp3_tables.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_tables.h
rename to media/module/codecs/mp3dec/src/pvmp3_tables.h
diff --git a/media/codecs/mp3dec/src/s_huffcodetab.h b/media/module/codecs/mp3dec/src/s_huffcodetab.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_huffcodetab.h
rename to media/module/codecs/mp3dec/src/s_huffcodetab.h
diff --git a/media/codecs/mp3dec/src/s_mp3bits.h b/media/module/codecs/mp3dec/src/s_mp3bits.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_mp3bits.h
rename to media/module/codecs/mp3dec/src/s_mp3bits.h
diff --git a/media/codecs/mp3dec/src/s_tmp3dec_chan.h b/media/module/codecs/mp3dec/src/s_tmp3dec_chan.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_tmp3dec_chan.h
rename to media/module/codecs/mp3dec/src/s_tmp3dec_chan.h
diff --git a/media/codecs/mp3dec/src/s_tmp3dec_file.h b/media/module/codecs/mp3dec/src/s_tmp3dec_file.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_tmp3dec_file.h
rename to media/module/codecs/mp3dec/src/s_tmp3dec_file.h
diff --git a/media/codecs/mp3dec/test/Android.bp b/media/module/codecs/mp3dec/test/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/test/Android.bp
rename to media/module/codecs/mp3dec/test/Android.bp
diff --git a/media/codecs/mp3dec/test/AndroidTest.xml b/media/module/codecs/mp3dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/mp3dec/test/AndroidTest.xml
rename to media/module/codecs/mp3dec/test/AndroidTest.xml
diff --git a/media/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/module/codecs/mp3dec/test/Mp3DecoderTest.cpp
similarity index 100%
rename from media/codecs/mp3dec/test/Mp3DecoderTest.cpp
rename to media/module/codecs/mp3dec/test/Mp3DecoderTest.cpp
diff --git a/media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h b/media/module/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
similarity index 100%
rename from media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
rename to media/module/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
diff --git a/media/codecs/mp3dec/test/README.md b/media/module/codecs/mp3dec/test/README.md
similarity index 100%
rename from media/codecs/mp3dec/test/README.md
rename to media/module/codecs/mp3dec/test/README.md
diff --git a/media/codecs/mp3dec/test/mp3dec_test.cpp b/media/module/codecs/mp3dec/test/mp3dec_test.cpp
similarity index 100%
rename from media/codecs/mp3dec/test/mp3dec_test.cpp
rename to media/module/codecs/mp3dec/test/mp3dec_test.cpp
diff --git a/media/codecs/mp3dec/test/mp3reader.cpp b/media/module/codecs/mp3dec/test/mp3reader.cpp
similarity index 100%
rename from media/codecs/mp3dec/test/mp3reader.cpp
rename to media/module/codecs/mp3dec/test/mp3reader.cpp
diff --git a/media/codecs/mp3dec/test/mp3reader.h b/media/module/codecs/mp3dec/test/mp3reader.h
similarity index 100%
rename from media/codecs/mp3dec/test/mp3reader.h
rename to media/module/codecs/mp3dec/test/mp3reader.h
diff --git a/services/mediacodec/registrant/Android.bp b/media/module/codecserviceregistrant/Android.bp
similarity index 95%
rename from services/mediacodec/registrant/Android.bp
rename to media/module/codecserviceregistrant/Android.bp
index 12cc32a..5637b37 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/media/module/codecserviceregistrant/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_services_mediacodec_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
}
cc_library {
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
similarity index 100%
rename from services/mediacodec/registrant/CodecServiceRegistrant.cpp
rename to media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
diff --git a/services/mediacodec/registrant/fuzzer/Android.bp b/media/module/codecserviceregistrant/fuzzer/Android.bp
similarity index 94%
rename from services/mediacodec/registrant/fuzzer/Android.bp
rename to media/module/codecserviceregistrant/fuzzer/Android.bp
index 43afbf1..0b9affd 100644
--- a/services/mediacodec/registrant/fuzzer/Android.bp
+++ b/media/module/codecserviceregistrant/fuzzer/Android.bp
@@ -20,7 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_services_mediacodec_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
}
cc_fuzz {
diff --git a/services/mediacodec/registrant/fuzzer/README.md b/media/module/codecserviceregistrant/fuzzer/README.md
similarity index 100%
rename from services/mediacodec/registrant/fuzzer/README.md
rename to media/module/codecserviceregistrant/fuzzer/README.md
diff --git a/services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp b/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
similarity index 100%
rename from services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
rename to media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
diff --git a/media/module/esds/Android.bp b/media/module/esds/Android.bp
new file mode 100644
index 0000000..272d4d7
--- /dev/null
+++ b/media/module/esds/Android.bp
@@ -0,0 +1,44 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library_static {
+ name: "libstagefright_esds",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ min_sdk_version: "29",
+
+ export_include_dirs: ["include"],
+
+ local_include_dirs: ["include"],
+
+ srcs: ["ESDS.cpp"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+ shared_libs: [
+ "libstagefright_foundation",
+ "libutils"
+ ],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/media/libstagefright/ESDS.cpp b/media/module/esds/ESDS.cpp
similarity index 99%
rename from media/libstagefright/ESDS.cpp
rename to media/module/esds/ESDS.cpp
index ea059e8..906250b 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/module/esds/ESDS.cpp
@@ -20,7 +20,7 @@
#include <media/stagefright/foundation/ByteUtils.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include <string.h>
diff --git a/media/libstagefright/include/ESDS.h b/media/module/esds/include/media/esds/ESDS.h
similarity index 100%
rename from media/libstagefright/include/ESDS.h
rename to media/module/esds/include/media/esds/ESDS.h
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/module/esds/tests/Android.bp
similarity index 93%
rename from media/libstagefright/tests/ESDS/Android.bp
rename to media/module/esds/tests/Android.bp
index 04e9b29..aea611e 100644
--- a/media/libstagefright/tests/ESDS/Android.bp
+++ b/media/module/esds/tests/Android.bp
@@ -20,9 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_tests_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "frameworks_av_media_libstagefright_tests_license",
- ],
}
cc_test {
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/module/esds/tests/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/tests/ESDS/AndroidTest.xml
rename to media/module/esds/tests/AndroidTest.xml
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/module/esds/tests/ESDSTest.cpp
similarity index 99%
rename from media/libstagefright/tests/ESDS/ESDSTest.cpp
rename to media/module/esds/tests/ESDSTest.cpp
index 101e00c..ea9a888 100644
--- a/media/libstagefright/tests/ESDS/ESDSTest.cpp
+++ b/media/module/esds/tests/ESDSTest.cpp
@@ -22,7 +22,7 @@
#include <string.h>
#include <fstream>
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <binder/ProcessState.h>
#include <datasource/FileSource.h>
#include <media/stagefright/MediaExtractorFactory.h>
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/module/esds/tests/ESDSTestEnvironment.h
similarity index 100%
rename from media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
rename to media/module/esds/tests/ESDSTestEnvironment.h
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/module/esds/tests/README.md
similarity index 100%
rename from media/libstagefright/tests/ESDS/README.md
rename to media/module/esds/tests/README.md
diff --git a/media/extractors/Android.bp b/media/module/extractors/Android.bp
similarity index 100%
rename from media/extractors/Android.bp
rename to media/module/extractors/Android.bp
diff --git a/media/extractors/TEST_MAPPING b/media/module/extractors/TEST_MAPPING
similarity index 100%
rename from media/extractors/TEST_MAPPING
rename to media/module/extractors/TEST_MAPPING
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/module/extractors/aac/AACExtractor.cpp
similarity index 100%
rename from media/extractors/aac/AACExtractor.cpp
rename to media/module/extractors/aac/AACExtractor.cpp
diff --git a/media/extractors/aac/Android.bp b/media/module/extractors/aac/Android.bp
similarity index 100%
rename from media/extractors/aac/Android.bp
rename to media/module/extractors/aac/Android.bp
diff --git a/media/extractors/aac/MODULE_LICENSE_APACHE2 b/media/module/extractors/aac/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/aac/MODULE_LICENSE_APACHE2
rename to media/module/extractors/aac/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/aac/NOTICE b/media/module/extractors/aac/NOTICE
similarity index 100%
rename from media/extractors/aac/NOTICE
rename to media/module/extractors/aac/NOTICE
diff --git a/media/extractors/aac/exports.lds b/media/module/extractors/aac/exports.lds
similarity index 100%
rename from media/extractors/aac/exports.lds
rename to media/module/extractors/aac/exports.lds
diff --git a/media/extractors/aac/include/AACExtractor.h b/media/module/extractors/aac/include/AACExtractor.h
similarity index 100%
rename from media/extractors/aac/include/AACExtractor.h
rename to media/module/extractors/aac/include/AACExtractor.h
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/module/extractors/amr/AMRExtractor.cpp
similarity index 100%
rename from media/extractors/amr/AMRExtractor.cpp
rename to media/module/extractors/amr/AMRExtractor.cpp
diff --git a/media/extractors/amr/Android.bp b/media/module/extractors/amr/Android.bp
similarity index 100%
rename from media/extractors/amr/Android.bp
rename to media/module/extractors/amr/Android.bp
diff --git a/media/extractors/amr/MODULE_LICENSE_APACHE2 b/media/module/extractors/amr/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/amr/MODULE_LICENSE_APACHE2
rename to media/module/extractors/amr/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/amr/NOTICE b/media/module/extractors/amr/NOTICE
similarity index 100%
rename from media/extractors/amr/NOTICE
rename to media/module/extractors/amr/NOTICE
diff --git a/media/extractors/amr/exports.lds b/media/module/extractors/amr/exports.lds
similarity index 100%
rename from media/extractors/amr/exports.lds
rename to media/module/extractors/amr/exports.lds
diff --git a/media/extractors/amr/include/AMRExtractor.h b/media/module/extractors/amr/include/AMRExtractor.h
similarity index 100%
rename from media/extractors/amr/include/AMRExtractor.h
rename to media/module/extractors/amr/include/AMRExtractor.h
diff --git a/media/extractors/flac/Android.bp b/media/module/extractors/flac/Android.bp
similarity index 100%
rename from media/extractors/flac/Android.bp
rename to media/module/extractors/flac/Android.bp
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/module/extractors/flac/FLACExtractor.cpp
similarity index 100%
rename from media/extractors/flac/FLACExtractor.cpp
rename to media/module/extractors/flac/FLACExtractor.cpp
diff --git a/media/extractors/flac/MODULE_LICENSE_APACHE2 b/media/module/extractors/flac/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/flac/MODULE_LICENSE_APACHE2
rename to media/module/extractors/flac/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/flac/NOTICE b/media/module/extractors/flac/NOTICE
similarity index 100%
rename from media/extractors/flac/NOTICE
rename to media/module/extractors/flac/NOTICE
diff --git a/media/extractors/flac/exports.lds b/media/module/extractors/flac/exports.lds
similarity index 100%
rename from media/extractors/flac/exports.lds
rename to media/module/extractors/flac/exports.lds
diff --git a/media/extractors/flac/include/FLACExtractor.h b/media/module/extractors/flac/include/FLACExtractor.h
similarity index 100%
rename from media/extractors/flac/include/FLACExtractor.h
rename to media/module/extractors/flac/include/FLACExtractor.h
diff --git a/media/extractors/fuzzers/Android.bp b/media/module/extractors/fuzzers/Android.bp
similarity index 100%
rename from media/extractors/fuzzers/Android.bp
rename to media/module/extractors/fuzzers/Android.bp
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/module/extractors/fuzzers/ExtractorFuzzerBase.cpp
similarity index 100%
rename from media/extractors/fuzzers/ExtractorFuzzerBase.cpp
rename to media/module/extractors/fuzzers/ExtractorFuzzerBase.cpp
diff --git a/media/extractors/fuzzers/README.md b/media/module/extractors/fuzzers/README.md
similarity index 100%
rename from media/extractors/fuzzers/README.md
rename to media/module/extractors/fuzzers/README.md
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/aac_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/aac_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/aac_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/amr_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/amr_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/amr_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.dict b/media/module/extractors/fuzzers/amr_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/amr_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/amr_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/flac_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/flac_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/flac_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.dict b/media/module/extractors/fuzzers/flac_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/flac_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/flac_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/module/extractors/fuzzers/include/ExtractorFuzzerBase.h
similarity index 100%
rename from media/extractors/fuzzers/include/ExtractorFuzzerBase.h
rename to media/module/extractors/fuzzers/include/ExtractorFuzzerBase.h
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/midi_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/midi_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/midi_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.dict b/media/module/extractors/fuzzers/midi_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/midi_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/midi_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mkv_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mkv_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mkv_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mkv_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mkv_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mp3_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mp3_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mp4_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mp4_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mp4_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mp4_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mp4_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/ogg_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/ogg_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.dict b/media/module/extractors/fuzzers/ogg_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/ogg_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/ogg_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/wav_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/wav_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/wav_extractor_fuzzer.cpp
diff --git a/media/extractors/midi/Android.bp b/media/module/extractors/midi/Android.bp
similarity index 100%
rename from media/extractors/midi/Android.bp
rename to media/module/extractors/midi/Android.bp
diff --git a/media/extractors/midi/MODULE_LICENSE_APACHE2 b/media/module/extractors/midi/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/midi/MODULE_LICENSE_APACHE2
rename to media/module/extractors/midi/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/module/extractors/midi/MidiExtractor.cpp
similarity index 100%
rename from media/extractors/midi/MidiExtractor.cpp
rename to media/module/extractors/midi/MidiExtractor.cpp
diff --git a/media/extractors/midi/NOTICE b/media/module/extractors/midi/NOTICE
similarity index 100%
rename from media/extractors/midi/NOTICE
rename to media/module/extractors/midi/NOTICE
diff --git a/media/extractors/midi/exports.lds b/media/module/extractors/midi/exports.lds
similarity index 100%
rename from media/extractors/midi/exports.lds
rename to media/module/extractors/midi/exports.lds
diff --git a/media/extractors/midi/include/MidiExtractor.h b/media/module/extractors/midi/include/MidiExtractor.h
similarity index 100%
rename from media/extractors/midi/include/MidiExtractor.h
rename to media/module/extractors/midi/include/MidiExtractor.h
diff --git a/media/extractors/mkv/Android.bp b/media/module/extractors/mkv/Android.bp
similarity index 100%
rename from media/extractors/mkv/Android.bp
rename to media/module/extractors/mkv/Android.bp
diff --git a/media/extractors/mkv/MODULE_LICENSE_APACHE2 b/media/module/extractors/mkv/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mkv/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mkv/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/module/extractors/mkv/MatroskaExtractor.cpp
similarity index 100%
rename from media/extractors/mkv/MatroskaExtractor.cpp
rename to media/module/extractors/mkv/MatroskaExtractor.cpp
diff --git a/media/extractors/mkv/NOTICE b/media/module/extractors/mkv/NOTICE
similarity index 100%
rename from media/extractors/mkv/NOTICE
rename to media/module/extractors/mkv/NOTICE
diff --git a/media/extractors/mkv/exports.lds b/media/module/extractors/mkv/exports.lds
similarity index 100%
rename from media/extractors/mkv/exports.lds
rename to media/module/extractors/mkv/exports.lds
diff --git a/media/extractors/mkv/include/MatroskaExtractor.h b/media/module/extractors/mkv/include/MatroskaExtractor.h
similarity index 100%
rename from media/extractors/mkv/include/MatroskaExtractor.h
rename to media/module/extractors/mkv/include/MatroskaExtractor.h
diff --git a/media/extractors/mp3/Android.bp b/media/module/extractors/mp3/Android.bp
similarity index 100%
rename from media/extractors/mp3/Android.bp
rename to media/module/extractors/mp3/Android.bp
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/module/extractors/mp3/MP3Extractor.cpp
similarity index 100%
rename from media/extractors/mp3/MP3Extractor.cpp
rename to media/module/extractors/mp3/MP3Extractor.cpp
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/module/extractors/mp3/VBRISeeker.cpp
similarity index 100%
rename from media/extractors/mp3/VBRISeeker.cpp
rename to media/module/extractors/mp3/VBRISeeker.cpp
diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/module/extractors/mp3/XINGSeeker.cpp
similarity index 100%
rename from media/extractors/mp3/XINGSeeker.cpp
rename to media/module/extractors/mp3/XINGSeeker.cpp
diff --git a/media/extractors/mp3/exports.lds b/media/module/extractors/mp3/exports.lds
similarity index 100%
rename from media/extractors/mp3/exports.lds
rename to media/module/extractors/mp3/exports.lds
diff --git a/media/extractors/mp3/include/MP3Extractor.h b/media/module/extractors/mp3/include/MP3Extractor.h
similarity index 100%
rename from media/extractors/mp3/include/MP3Extractor.h
rename to media/module/extractors/mp3/include/MP3Extractor.h
diff --git a/media/extractors/mp3/include/MP3Seeker.h b/media/module/extractors/mp3/include/MP3Seeker.h
similarity index 100%
rename from media/extractors/mp3/include/MP3Seeker.h
rename to media/module/extractors/mp3/include/MP3Seeker.h
diff --git a/media/extractors/mp3/include/VBRISeeker.h b/media/module/extractors/mp3/include/VBRISeeker.h
similarity index 100%
rename from media/extractors/mp3/include/VBRISeeker.h
rename to media/module/extractors/mp3/include/VBRISeeker.h
diff --git a/media/extractors/mp3/include/XINGSeeker.h b/media/module/extractors/mp3/include/XINGSeeker.h
similarity index 100%
rename from media/extractors/mp3/include/XINGSeeker.h
rename to media/module/extractors/mp3/include/XINGSeeker.h
diff --git a/media/extractors/mp4/AC4Parser.cpp b/media/module/extractors/mp4/AC4Parser.cpp
similarity index 100%
rename from media/extractors/mp4/AC4Parser.cpp
rename to media/module/extractors/mp4/AC4Parser.cpp
diff --git a/media/extractors/mp4/Android.bp b/media/module/extractors/mp4/Android.bp
similarity index 100%
rename from media/extractors/mp4/Android.bp
rename to media/module/extractors/mp4/Android.bp
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/module/extractors/mp4/ItemTable.cpp
similarity index 100%
rename from media/extractors/mp4/ItemTable.cpp
rename to media/module/extractors/mp4/ItemTable.cpp
diff --git a/media/extractors/mp4/MODULE_LICENSE_APACHE2 b/media/module/extractors/mp4/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mp4/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mp4/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
similarity index 99%
rename from media/extractors/mp4/MPEG4Extractor.cpp
rename to media/module/extractors/mp4/MPEG4Extractor.cpp
index 5a03992..374f8d3 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -34,7 +34,7 @@
#include "SampleTable.h"
#include "ItemTable.h"
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <ID3.h>
#include <media/stagefright/DataSourceBase.h>
#include <media/ExtractorUtils.h>
diff --git a/media/extractors/mp4/NOTICE b/media/module/extractors/mp4/NOTICE
similarity index 100%
rename from media/extractors/mp4/NOTICE
rename to media/module/extractors/mp4/NOTICE
diff --git a/media/extractors/mp4/SampleIterator.cpp b/media/module/extractors/mp4/SampleIterator.cpp
similarity index 100%
rename from media/extractors/mp4/SampleIterator.cpp
rename to media/module/extractors/mp4/SampleIterator.cpp
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/module/extractors/mp4/SampleTable.cpp
similarity index 100%
rename from media/extractors/mp4/SampleTable.cpp
rename to media/module/extractors/mp4/SampleTable.cpp
diff --git a/media/extractors/mp4/exports.lds b/media/module/extractors/mp4/exports.lds
similarity index 100%
rename from media/extractors/mp4/exports.lds
rename to media/module/extractors/mp4/exports.lds
diff --git a/media/extractors/mp4/include/AC4Parser.h b/media/module/extractors/mp4/include/AC4Parser.h
similarity index 100%
rename from media/extractors/mp4/include/AC4Parser.h
rename to media/module/extractors/mp4/include/AC4Parser.h
diff --git a/media/extractors/mp4/include/ItemTable.h b/media/module/extractors/mp4/include/ItemTable.h
similarity index 100%
rename from media/extractors/mp4/include/ItemTable.h
rename to media/module/extractors/mp4/include/ItemTable.h
diff --git a/media/extractors/mp4/include/MPEG4Extractor.h b/media/module/extractors/mp4/include/MPEG4Extractor.h
similarity index 100%
rename from media/extractors/mp4/include/MPEG4Extractor.h
rename to media/module/extractors/mp4/include/MPEG4Extractor.h
diff --git a/media/extractors/mp4/include/SampleIterator.h b/media/module/extractors/mp4/include/SampleIterator.h
similarity index 100%
rename from media/extractors/mp4/include/SampleIterator.h
rename to media/module/extractors/mp4/include/SampleIterator.h
diff --git a/media/extractors/mp4/include/SampleTable.h b/media/module/extractors/mp4/include/SampleTable.h
similarity index 100%
rename from media/extractors/mp4/include/SampleTable.h
rename to media/module/extractors/mp4/include/SampleTable.h
diff --git a/media/extractors/mpeg2/Android.bp b/media/module/extractors/mpeg2/Android.bp
similarity index 100%
rename from media/extractors/mpeg2/Android.bp
rename to media/module/extractors/mpeg2/Android.bp
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/module/extractors/mpeg2/ExtractorBundle.cpp
similarity index 100%
rename from media/extractors/mpeg2/ExtractorBundle.cpp
rename to media/module/extractors/mpeg2/ExtractorBundle.cpp
diff --git a/media/extractors/mpeg2/MODULE_LICENSE_APACHE2 b/media/module/extractors/mpeg2/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mpeg2/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mpeg2/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
similarity index 100%
rename from media/extractors/mpeg2/MPEG2PSExtractor.cpp
rename to media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
similarity index 100%
rename from media/extractors/mpeg2/MPEG2TSExtractor.cpp
rename to media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
diff --git a/media/extractors/mpeg2/NOTICE b/media/module/extractors/mpeg2/NOTICE
similarity index 100%
rename from media/extractors/mpeg2/NOTICE
rename to media/module/extractors/mpeg2/NOTICE
diff --git a/media/extractors/mpeg2/exports.lds b/media/module/extractors/mpeg2/exports.lds
similarity index 100%
rename from media/extractors/mpeg2/exports.lds
rename to media/module/extractors/mpeg2/exports.lds
diff --git a/media/extractors/mpeg2/include/MPEG2PSExtractor.h b/media/module/extractors/mpeg2/include/MPEG2PSExtractor.h
similarity index 100%
rename from media/extractors/mpeg2/include/MPEG2PSExtractor.h
rename to media/module/extractors/mpeg2/include/MPEG2PSExtractor.h
diff --git a/media/extractors/mpeg2/include/MPEG2TSExtractor.h b/media/module/extractors/mpeg2/include/MPEG2TSExtractor.h
similarity index 100%
rename from media/extractors/mpeg2/include/MPEG2TSExtractor.h
rename to media/module/extractors/mpeg2/include/MPEG2TSExtractor.h
diff --git a/media/extractors/ogg/Android.bp b/media/module/extractors/ogg/Android.bp
similarity index 100%
rename from media/extractors/ogg/Android.bp
rename to media/module/extractors/ogg/Android.bp
diff --git a/media/extractors/ogg/MODULE_LICENSE_APACHE2 b/media/module/extractors/ogg/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/ogg/MODULE_LICENSE_APACHE2
rename to media/module/extractors/ogg/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/ogg/NOTICE b/media/module/extractors/ogg/NOTICE
similarity index 100%
rename from media/extractors/ogg/NOTICE
rename to media/module/extractors/ogg/NOTICE
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/module/extractors/ogg/OggExtractor.cpp
similarity index 100%
rename from media/extractors/ogg/OggExtractor.cpp
rename to media/module/extractors/ogg/OggExtractor.cpp
diff --git a/media/extractors/ogg/exports.lds b/media/module/extractors/ogg/exports.lds
similarity index 100%
rename from media/extractors/ogg/exports.lds
rename to media/module/extractors/ogg/exports.lds
diff --git a/media/extractors/ogg/include/OggExtractor.h b/media/module/extractors/ogg/include/OggExtractor.h
similarity index 100%
rename from media/extractors/ogg/include/OggExtractor.h
rename to media/module/extractors/ogg/include/OggExtractor.h
diff --git a/media/extractors/tests/Android.bp b/media/module/extractors/tests/Android.bp
similarity index 100%
rename from media/extractors/tests/Android.bp
rename to media/module/extractors/tests/Android.bp
diff --git a/media/extractors/tests/AndroidTest.xml b/media/module/extractors/tests/AndroidTest.xml
similarity index 100%
rename from media/extractors/tests/AndroidTest.xml
rename to media/module/extractors/tests/AndroidTest.xml
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/module/extractors/tests/ExtractorUnitTest.cpp
similarity index 100%
rename from media/extractors/tests/ExtractorUnitTest.cpp
rename to media/module/extractors/tests/ExtractorUnitTest.cpp
diff --git a/media/extractors/tests/ExtractorUnitTestEnvironment.h b/media/module/extractors/tests/ExtractorUnitTestEnvironment.h
similarity index 100%
rename from media/extractors/tests/ExtractorUnitTestEnvironment.h
rename to media/module/extractors/tests/ExtractorUnitTestEnvironment.h
diff --git a/media/extractors/tests/README.md b/media/module/extractors/tests/README.md
similarity index 100%
rename from media/extractors/tests/README.md
rename to media/module/extractors/tests/README.md
diff --git a/media/extractors/wav/Android.bp b/media/module/extractors/wav/Android.bp
similarity index 100%
rename from media/extractors/wav/Android.bp
rename to media/module/extractors/wav/Android.bp
diff --git a/media/extractors/wav/MODULE_LICENSE_APACHE2 b/media/module/extractors/wav/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/wav/MODULE_LICENSE_APACHE2
rename to media/module/extractors/wav/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/wav/NOTICE b/media/module/extractors/wav/NOTICE
similarity index 100%
rename from media/extractors/wav/NOTICE
rename to media/module/extractors/wav/NOTICE
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/module/extractors/wav/WAVExtractor.cpp
similarity index 100%
rename from media/extractors/wav/WAVExtractor.cpp
rename to media/module/extractors/wav/WAVExtractor.cpp
diff --git a/media/extractors/wav/exports.lds b/media/module/extractors/wav/exports.lds
similarity index 100%
rename from media/extractors/wav/exports.lds
rename to media/module/extractors/wav/exports.lds
diff --git a/media/extractors/wav/include/WAVExtractor.h b/media/module/extractors/wav/include/WAVExtractor.h
similarity index 100%
rename from media/extractors/wav/include/WAVExtractor.h
rename to media/module/extractors/wav/include/WAVExtractor.h
diff --git a/media/libstagefright/foundation/AAtomizer.cpp b/media/module/foundation/AAtomizer.cpp
similarity index 100%
rename from media/libstagefright/foundation/AAtomizer.cpp
rename to media/module/foundation/AAtomizer.cpp
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/module/foundation/ABitReader.cpp
similarity index 100%
rename from media/libstagefright/foundation/ABitReader.cpp
rename to media/module/foundation/ABitReader.cpp
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/module/foundation/ABuffer.cpp
similarity index 100%
rename from media/libstagefright/foundation/ABuffer.cpp
rename to media/module/foundation/ABuffer.cpp
diff --git a/media/libstagefright/foundation/ADebug.cpp b/media/module/foundation/ADebug.cpp
similarity index 100%
rename from media/libstagefright/foundation/ADebug.cpp
rename to media/module/foundation/ADebug.cpp
diff --git a/media/libstagefright/foundation/AHandler.cpp b/media/module/foundation/AHandler.cpp
similarity index 100%
rename from media/libstagefright/foundation/AHandler.cpp
rename to media/module/foundation/AHandler.cpp
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/module/foundation/ALooper.cpp
similarity index 100%
rename from media/libstagefright/foundation/ALooper.cpp
rename to media/module/foundation/ALooper.cpp
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/module/foundation/ALooperRoster.cpp
similarity index 100%
rename from media/libstagefright/foundation/ALooperRoster.cpp
rename to media/module/foundation/ALooperRoster.cpp
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/module/foundation/AMessage.cpp
similarity index 100%
rename from media/libstagefright/foundation/AMessage.cpp
rename to media/module/foundation/AMessage.cpp
diff --git a/media/libstagefright/foundation/AString.cpp b/media/module/foundation/AString.cpp
similarity index 100%
rename from media/libstagefright/foundation/AString.cpp
rename to media/module/foundation/AString.cpp
diff --git a/media/libstagefright/foundation/AStringUtils.cpp b/media/module/foundation/AStringUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/AStringUtils.cpp
rename to media/module/foundation/AStringUtils.cpp
diff --git a/media/libstagefright/foundation/Android.bp b/media/module/foundation/Android.bp
similarity index 97%
rename from media/libstagefright/foundation/Android.bp
rename to media/module/foundation/Android.bp
index ca17117..dc8384d 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/module/foundation/Android.bp
@@ -110,6 +110,11 @@
"-DNO_IMEMORY",
],
},
+ host: {
+ sanitize: {
+ cfi: false,
+ },
+ },
apex: {
exclude_shared_libs: [
"libbinder",
diff --git a/media/libstagefright/foundation/AudioPresentationInfo.cpp b/media/module/foundation/AudioPresentationInfo.cpp
similarity index 100%
rename from media/libstagefright/foundation/AudioPresentationInfo.cpp
rename to media/module/foundation/AudioPresentationInfo.cpp
diff --git a/media/libstagefright/foundation/ByteUtils.cpp b/media/module/foundation/ByteUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/ByteUtils.cpp
rename to media/module/foundation/ByteUtils.cpp
diff --git a/media/libstagefright/foundation/ColorUtils.cpp b/media/module/foundation/ColorUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils.cpp
rename to media/module/foundation/ColorUtils.cpp
diff --git a/media/libstagefright/foundation/ColorUtils_fill.cpp b/media/module/foundation/ColorUtils_fill.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils_fill.cpp
rename to media/module/foundation/ColorUtils_fill.cpp
diff --git a/media/libstagefright/foundation/ColorUtils_ndk.cpp b/media/module/foundation/ColorUtils_ndk.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils_ndk.cpp
rename to media/module/foundation/ColorUtils_ndk.cpp
diff --git a/media/libstagefright/foundation/FoundationUtils.cpp b/media/module/foundation/FoundationUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/FoundationUtils.cpp
rename to media/module/foundation/FoundationUtils.cpp
diff --git a/media/libstagefright/foundation/MODULE_LICENSE_APACHE2 b/media/module/foundation/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/foundation/MODULE_LICENSE_APACHE2
rename to media/module/foundation/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/foundation/MediaBuffer.cpp b/media/module/foundation/MediaBuffer.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBuffer.cpp
rename to media/module/foundation/MediaBuffer.cpp
diff --git a/media/libstagefright/foundation/MediaBufferBase.cpp b/media/module/foundation/MediaBufferBase.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBufferBase.cpp
rename to media/module/foundation/MediaBufferBase.cpp
diff --git a/media/libstagefright/foundation/MediaBufferGroup.cpp b/media/module/foundation/MediaBufferGroup.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBufferGroup.cpp
rename to media/module/foundation/MediaBufferGroup.cpp
diff --git a/media/libstagefright/foundation/MediaDefs.cpp b/media/module/foundation/MediaDefs.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaDefs.cpp
rename to media/module/foundation/MediaDefs.cpp
diff --git a/media/libstagefright/foundation/MediaKeys.cpp b/media/module/foundation/MediaKeys.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaKeys.cpp
rename to media/module/foundation/MediaKeys.cpp
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/module/foundation/MetaData.cpp
similarity index 100%
rename from media/libstagefright/foundation/MetaData.cpp
rename to media/module/foundation/MetaData.cpp
diff --git a/media/libstagefright/foundation/MetaDataBase.cpp b/media/module/foundation/MetaDataBase.cpp
similarity index 100%
rename from media/libstagefright/foundation/MetaDataBase.cpp
rename to media/module/foundation/MetaDataBase.cpp
diff --git a/media/libstagefright/foundation/NOTICE b/media/module/foundation/NOTICE
similarity index 100%
rename from media/libstagefright/foundation/NOTICE
rename to media/module/foundation/NOTICE
diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/module/foundation/OpusHeader.cpp
similarity index 100%
rename from media/libstagefright/foundation/OpusHeader.cpp
rename to media/module/foundation/OpusHeader.cpp
diff --git a/media/libstagefright/foundation/TEST_MAPPING b/media/module/foundation/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/foundation/TEST_MAPPING
rename to media/module/foundation/TEST_MAPPING
diff --git a/media/libstagefright/foundation/avc_utils.cpp b/media/module/foundation/avc_utils.cpp
similarity index 100%
rename from media/libstagefright/foundation/avc_utils.cpp
rename to media/module/foundation/avc_utils.cpp
diff --git a/media/libstagefright/foundation/base64.cpp b/media/module/foundation/base64.cpp
similarity index 100%
rename from media/libstagefright/foundation/base64.cpp
rename to media/module/foundation/base64.cpp
diff --git a/media/libstagefright/foundation/hexdump.cpp b/media/module/foundation/hexdump.cpp
similarity index 100%
rename from media/libstagefright/foundation/hexdump.cpp
rename to media/module/foundation/hexdump.cpp
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AAtomizer.h b/media/module/foundation/include/media/stagefright/foundation/AAtomizer.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AAtomizer.h
rename to media/module/foundation/include/media/stagefright/foundation/AAtomizer.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABase.h b/media/module/foundation/include/media/stagefright/foundation/ABase.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABase.h
rename to media/module/foundation/include/media/stagefright/foundation/ABase.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABitReader.h b/media/module/foundation/include/media/stagefright/foundation/ABitReader.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABitReader.h
rename to media/module/foundation/include/media/stagefright/foundation/ABitReader.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABuffer.h b/media/module/foundation/include/media/stagefright/foundation/ABuffer.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABuffer.h
rename to media/module/foundation/include/media/stagefright/foundation/ABuffer.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h b/media/module/foundation/include/media/stagefright/foundation/AData.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
rename to media/module/foundation/include/media/stagefright/foundation/AData.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/module/foundation/include/media/stagefright/foundation/ADebug.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
rename to media/module/foundation/include/media/stagefright/foundation/ADebug.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h b/media/module/foundation/include/media/stagefright/foundation/AHandler.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h
rename to media/module/foundation/include/media/stagefright/foundation/AHandler.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandlerReflector.h b/media/module/foundation/include/media/stagefright/foundation/AHandlerReflector.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AHandlerReflector.h
rename to media/module/foundation/include/media/stagefright/foundation/AHandlerReflector.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALookup.h b/media/module/foundation/include/media/stagefright/foundation/ALookup.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALookup.h
rename to media/module/foundation/include/media/stagefright/foundation/ALookup.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALooper.h b/media/module/foundation/include/media/stagefright/foundation/ALooper.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALooper.h
rename to media/module/foundation/include/media/stagefright/foundation/ALooper.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALooperRoster.h b/media/module/foundation/include/media/stagefright/foundation/ALooperRoster.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALooperRoster.h
rename to media/module/foundation/include/media/stagefright/foundation/ALooperRoster.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h b/media/module/foundation/include/media/stagefright/foundation/AMessage.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
rename to media/module/foundation/include/media/stagefright/foundation/AMessage.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h b/media/module/foundation/include/media/stagefright/foundation/AString.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
rename to media/module/foundation/include/media/stagefright/foundation/AString.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AStringUtils.h b/media/module/foundation/include/media/stagefright/foundation/AStringUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AStringUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/AStringUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h b/media/module/foundation/include/media/stagefright/foundation/AUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/AUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h b/media/module/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
rename to media/module/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ByteUtils.h b/media/module/foundation/include/media/stagefright/foundation/ByteUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ByteUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/ByteUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h b/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/FileDescriptor.h b/media/module/foundation/include/media/stagefright/foundation/FileDescriptor.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/FileDescriptor.h
rename to media/module/foundation/include/media/stagefright/foundation/FileDescriptor.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/Flagged.h b/media/module/foundation/include/media/stagefright/foundation/Flagged.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/Flagged.h
rename to media/module/foundation/include/media/stagefright/foundation/Flagged.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
rename to media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaKeys.h b/media/module/foundation/include/media/stagefright/foundation/MediaKeys.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/MediaKeys.h
rename to media/module/foundation/include/media/stagefright/foundation/MediaKeys.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h b/media/module/foundation/include/media/stagefright/foundation/Mutexed.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h
rename to media/module/foundation/include/media/stagefright/foundation/Mutexed.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h b/media/module/foundation/include/media/stagefright/foundation/OpusHeader.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h
rename to media/module/foundation/include/media/stagefright/foundation/OpusHeader.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/TypeTraits.h b/media/module/foundation/include/media/stagefright/foundation/TypeTraits.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/TypeTraits.h
rename to media/module/foundation/include/media/stagefright/foundation/TypeTraits.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/avc_utils.h b/media/module/foundation/include/media/stagefright/foundation/avc_utils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/avc_utils.h
rename to media/module/foundation/include/media/stagefright/foundation/avc_utils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h b/media/module/foundation/include/media/stagefright/foundation/base64.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
rename to media/module/foundation/include/media/stagefright/foundation/base64.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/hexdump.h b/media/module/foundation/include/media/stagefright/foundation/hexdump.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/hexdump.h
rename to media/module/foundation/include/media/stagefright/foundation/hexdump.h
diff --git a/media/libstagefright/foundation/tests/AData_test.cpp b/media/module/foundation/tests/AData_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/AData_test.cpp
rename to media/module/foundation/tests/AData_test.cpp
diff --git a/media/libstagefright/foundation/tests/AMessage_test.cpp b/media/module/foundation/tests/AMessage_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/AMessage_test.cpp
rename to media/module/foundation/tests/AMessage_test.cpp
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h b/media/module/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
rename to media/module/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp b/media/module/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
rename to media/module/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
diff --git a/media/libstagefright/foundation/tests/AVCUtils/Android.bp b/media/module/foundation/tests/AVCUtils/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/Android.bp
rename to media/module/foundation/tests/AVCUtils/Android.bp
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
rename to media/module/foundation/tests/AVCUtils/AndroidTest.xml
diff --git a/media/libstagefright/foundation/tests/AVCUtils/README.md b/media/module/foundation/tests/AVCUtils/README.md
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/README.md
rename to media/module/foundation/tests/AVCUtils/README.md
diff --git a/media/libstagefright/foundation/tests/Android.bp b/media/module/foundation/tests/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/Android.bp
rename to media/module/foundation/tests/Android.bp
diff --git a/media/libstagefright/foundation/tests/Base64_test.cpp b/media/module/foundation/tests/Base64_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Base64_test.cpp
rename to media/module/foundation/tests/Base64_test.cpp
diff --git a/media/libstagefright/foundation/tests/Flagged_test.cpp b/media/module/foundation/tests/Flagged_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Flagged_test.cpp
rename to media/module/foundation/tests/Flagged_test.cpp
diff --git a/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp b/media/module/foundation/tests/MetaDataBaseUnitTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp
rename to media/module/foundation/tests/MetaDataBaseUnitTest.cpp
diff --git a/media/libstagefright/foundation/tests/OpusHeader/Android.bp b/media/module/foundation/tests/OpusHeader/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/Android.bp
rename to media/module/foundation/tests/OpusHeader/Android.bp
diff --git a/media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml b/media/module/foundation/tests/OpusHeader/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml
rename to media/module/foundation/tests/OpusHeader/AndroidTest.xml
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp b/media/module/foundation/tests/OpusHeader/OpusHeaderTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
rename to media/module/foundation/tests/OpusHeader/OpusHeaderTest.cpp
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h b/media/module/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
rename to media/module/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
diff --git a/media/libstagefright/foundation/tests/OpusHeader/README.md b/media/module/foundation/tests/OpusHeader/README.md
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/README.md
rename to media/module/foundation/tests/OpusHeader/README.md
diff --git a/media/libstagefright/foundation/tests/TypeTraits_test.cpp b/media/module/foundation/tests/TypeTraits_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/TypeTraits_test.cpp
rename to media/module/foundation/tests/TypeTraits_test.cpp
diff --git a/media/libstagefright/foundation/tests/Utils_test.cpp b/media/module/foundation/tests/Utils_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Utils_test.cpp
rename to media/module/foundation/tests/Utils_test.cpp
diff --git a/media/libstagefright/foundation/tests/colorutils/Android.bp b/media/module/foundation/tests/colorutils/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/colorutils/Android.bp
rename to media/module/foundation/tests/colorutils/Android.bp
diff --git a/media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp b/media/module/foundation/tests/colorutils/ColorUtilsTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp
rename to media/module/foundation/tests/colorutils/ColorUtilsTest.cpp
diff --git a/media/libstagefright/id3/Android.bp b/media/module/id3/Android.bp
similarity index 100%
rename from media/libstagefright/id3/Android.bp
rename to media/module/id3/Android.bp
diff --git a/media/libstagefright/id3/ID3.cpp b/media/module/id3/ID3.cpp
similarity index 100%
rename from media/libstagefright/id3/ID3.cpp
rename to media/module/id3/ID3.cpp
diff --git a/media/libstagefright/id3/MODULE_LICENSE_APACHE2 b/media/module/id3/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/id3/MODULE_LICENSE_APACHE2
rename to media/module/id3/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/id3/NOTICE b/media/module/id3/NOTICE
similarity index 100%
rename from media/libstagefright/id3/NOTICE
rename to media/module/id3/NOTICE
diff --git a/media/libstagefright/id3/TEST_MAPPING b/media/module/id3/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/id3/TEST_MAPPING
rename to media/module/id3/TEST_MAPPING
diff --git a/media/libstagefright/id3/test/Android.bp b/media/module/id3/test/Android.bp
similarity index 100%
rename from media/libstagefright/id3/test/Android.bp
rename to media/module/id3/test/Android.bp
diff --git a/media/libstagefright/id3/test/AndroidTest.xml b/media/module/id3/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/id3/test/AndroidTest.xml
rename to media/module/id3/test/AndroidTest.xml
diff --git a/media/libstagefright/id3/test/ID3Test.cpp b/media/module/id3/test/ID3Test.cpp
similarity index 100%
rename from media/libstagefright/id3/test/ID3Test.cpp
rename to media/module/id3/test/ID3Test.cpp
diff --git a/media/libstagefright/id3/test/ID3TestEnvironment.h b/media/module/id3/test/ID3TestEnvironment.h
similarity index 100%
rename from media/libstagefright/id3/test/ID3TestEnvironment.h
rename to media/module/id3/test/ID3TestEnvironment.h
diff --git a/media/libstagefright/id3/test/README.md b/media/module/id3/test/README.md
similarity index 100%
rename from media/libstagefright/id3/test/README.md
rename to media/module/id3/test/README.md
diff --git a/media/libstagefright/id3/testid3.cpp b/media/module/id3/testid3.cpp
similarity index 100%
rename from media/libstagefright/id3/testid3.cpp
rename to media/module/id3/testid3.cpp
diff --git a/media/libmediaformatshaper/Android.bp b/media/module/libmediaformatshaper/Android.bp
similarity index 100%
rename from media/libmediaformatshaper/Android.bp
rename to media/module/libmediaformatshaper/Android.bp
diff --git a/media/libmediaformatshaper/CodecProperties.cpp b/media/module/libmediaformatshaper/CodecProperties.cpp
similarity index 100%
rename from media/libmediaformatshaper/CodecProperties.cpp
rename to media/module/libmediaformatshaper/CodecProperties.cpp
diff --git a/media/libmediaformatshaper/CodecProperties.h b/media/module/libmediaformatshaper/CodecProperties.h
similarity index 100%
rename from media/libmediaformatshaper/CodecProperties.h
rename to media/module/libmediaformatshaper/CodecProperties.h
diff --git a/media/libmediaformatshaper/CodecSeeding.cpp b/media/module/libmediaformatshaper/CodecSeeding.cpp
similarity index 100%
rename from media/libmediaformatshaper/CodecSeeding.cpp
rename to media/module/libmediaformatshaper/CodecSeeding.cpp
diff --git a/media/libmediaformatshaper/FormatShaper.cpp b/media/module/libmediaformatshaper/FormatShaper.cpp
similarity index 100%
rename from media/libmediaformatshaper/FormatShaper.cpp
rename to media/module/libmediaformatshaper/FormatShaper.cpp
diff --git a/media/libmediaformatshaper/ManageShapingCodecs.cpp b/media/module/libmediaformatshaper/ManageShapingCodecs.cpp
similarity index 100%
rename from media/libmediaformatshaper/ManageShapingCodecs.cpp
rename to media/module/libmediaformatshaper/ManageShapingCodecs.cpp
diff --git a/media/libmediaformatshaper/VQApply.cpp b/media/module/libmediaformatshaper/VQApply.cpp
similarity index 100%
rename from media/libmediaformatshaper/VQApply.cpp
rename to media/module/libmediaformatshaper/VQApply.cpp
diff --git a/media/libmediaformatshaper/VQops.h b/media/module/libmediaformatshaper/VQops.h
similarity index 100%
rename from media/libmediaformatshaper/VQops.h
rename to media/module/libmediaformatshaper/VQops.h
diff --git a/media/libmediaformatshaper/VideoShaper.cpp b/media/module/libmediaformatshaper/VideoShaper.cpp
similarity index 100%
rename from media/libmediaformatshaper/VideoShaper.cpp
rename to media/module/libmediaformatshaper/VideoShaper.cpp
diff --git a/media/libmediaformatshaper/VideoShaper.h b/media/module/libmediaformatshaper/VideoShaper.h
similarity index 100%
rename from media/libmediaformatshaper/VideoShaper.h
rename to media/module/libmediaformatshaper/VideoShaper.h
diff --git a/media/libmediaformatshaper/exports.lds b/media/module/libmediaformatshaper/exports.lds
similarity index 100%
rename from media/libmediaformatshaper/exports.lds
rename to media/module/libmediaformatshaper/exports.lds
diff --git a/media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h b/media/module/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
similarity index 100%
rename from media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
rename to media/module/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
diff --git a/media/libmediatranscoding/.clang-format b/media/module/libmediatranscoding/.clang-format
similarity index 100%
rename from media/libmediatranscoding/.clang-format
rename to media/module/libmediatranscoding/.clang-format
diff --git a/media/libmediatranscoding/Android.bp b/media/module/libmediatranscoding/Android.bp
similarity index 100%
rename from media/libmediatranscoding/Android.bp
rename to media/module/libmediatranscoding/Android.bp
diff --git a/media/libmediatranscoding/OWNERS b/media/module/libmediatranscoding/OWNERS
similarity index 100%
rename from media/libmediatranscoding/OWNERS
rename to media/module/libmediatranscoding/OWNERS
diff --git a/media/libmediatranscoding/TEST_MAPPING b/media/module/libmediatranscoding/TEST_MAPPING
similarity index 100%
rename from media/libmediatranscoding/TEST_MAPPING
rename to media/module/libmediatranscoding/TEST_MAPPING
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/module/libmediatranscoding/TranscoderWrapper.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscoderWrapper.cpp
rename to media/module/libmediatranscoding/TranscoderWrapper.cpp
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/module/libmediatranscoding/TranscodingClientManager.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingClientManager.cpp
rename to media/module/libmediatranscoding/TranscodingClientManager.cpp
diff --git a/media/libmediatranscoding/TranscodingLogger.cpp b/media/module/libmediatranscoding/TranscodingLogger.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingLogger.cpp
rename to media/module/libmediatranscoding/TranscodingLogger.cpp
diff --git a/media/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingResourcePolicy.cpp
rename to media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
diff --git a/media/libmediatranscoding/TranscodingSessionController.cpp b/media/module/libmediatranscoding/TranscodingSessionController.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingSessionController.cpp
rename to media/module/libmediatranscoding/TranscodingSessionController.cpp
diff --git a/media/libmediatranscoding/TranscodingThermalPolicy.cpp b/media/module/libmediatranscoding/TranscodingThermalPolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingThermalPolicy.cpp
rename to media/module/libmediatranscoding/TranscodingThermalPolicy.cpp
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/module/libmediatranscoding/TranscodingUidPolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingUidPolicy.cpp
rename to media/module/libmediatranscoding/TranscodingUidPolicy.cpp
diff --git a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl b/media/module/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
rename to media/module/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl b/media/module/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
rename to media/module/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl b/media/module/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
rename to media/module/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingType.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingType.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingType.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingType.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
diff --git a/media/libmediatranscoding/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h b/media/module/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
similarity index 100%
rename from media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
rename to media/module/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
diff --git a/media/libmediatranscoding/include/media/ControllerClientInterface.h b/media/module/libmediatranscoding/include/media/ControllerClientInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ControllerClientInterface.h
rename to media/module/libmediatranscoding/include/media/ControllerClientInterface.h
diff --git a/media/libmediatranscoding/include/media/ResourcePolicyInterface.h b/media/module/libmediatranscoding/include/media/ResourcePolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ResourcePolicyInterface.h
rename to media/module/libmediatranscoding/include/media/ResourcePolicyInterface.h
diff --git a/media/libmediatranscoding/include/media/ThermalPolicyInterface.h b/media/module/libmediatranscoding/include/media/ThermalPolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ThermalPolicyInterface.h
rename to media/module/libmediatranscoding/include/media/ThermalPolicyInterface.h
diff --git a/media/libmediatranscoding/include/media/TranscoderInterface.h b/media/module/libmediatranscoding/include/media/TranscoderInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscoderInterface.h
rename to media/module/libmediatranscoding/include/media/TranscoderInterface.h
diff --git a/media/libmediatranscoding/include/media/TranscoderWrapper.h b/media/module/libmediatranscoding/include/media/TranscoderWrapper.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscoderWrapper.h
rename to media/module/libmediatranscoding/include/media/TranscoderWrapper.h
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/module/libmediatranscoding/include/media/TranscodingClientManager.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingClientManager.h
rename to media/module/libmediatranscoding/include/media/TranscodingClientManager.h
diff --git a/media/libmediatranscoding/include/media/TranscodingDefs.h b/media/module/libmediatranscoding/include/media/TranscodingDefs.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingDefs.h
rename to media/module/libmediatranscoding/include/media/TranscodingDefs.h
diff --git a/media/libmediatranscoding/include/media/TranscodingLogger.h b/media/module/libmediatranscoding/include/media/TranscodingLogger.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingLogger.h
rename to media/module/libmediatranscoding/include/media/TranscodingLogger.h
diff --git a/media/libmediatranscoding/include/media/TranscodingRequest.h b/media/module/libmediatranscoding/include/media/TranscodingRequest.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingRequest.h
rename to media/module/libmediatranscoding/include/media/TranscodingRequest.h
diff --git a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingResourcePolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
diff --git a/media/libmediatranscoding/include/media/TranscodingSessionController.h b/media/module/libmediatranscoding/include/media/TranscodingSessionController.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingSessionController.h
rename to media/module/libmediatranscoding/include/media/TranscodingSessionController.h
diff --git a/media/libmediatranscoding/include/media/TranscodingThermalPolicy.h b/media/module/libmediatranscoding/include/media/TranscodingThermalPolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingThermalPolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingThermalPolicy.h
diff --git a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h b/media/module/libmediatranscoding/include/media/TranscodingUidPolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingUidPolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingUidPolicy.h
diff --git a/media/libmediatranscoding/include/media/UidPolicyInterface.h b/media/module/libmediatranscoding/include/media/UidPolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/UidPolicyInterface.h
rename to media/module/libmediatranscoding/include/media/UidPolicyInterface.h
diff --git a/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp b/media/module/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
rename to media/module/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/module/libmediatranscoding/tests/Android.bp
similarity index 100%
rename from media/libmediatranscoding/tests/Android.bp
rename to media/module/libmediatranscoding/tests/Android.bp
diff --git a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
diff --git a/media/libmediatranscoding/tests/TranscodingLogger_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingLogger_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/TranscodingLogger_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingLogger_tests.cpp
diff --git a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/tests/push_assets.sh b/media/module/libmediatranscoding/tests/push_assets.sh
similarity index 100%
rename from media/libmediatranscoding/tests/push_assets.sh
rename to media/module/libmediatranscoding/tests/push_assets.sh
diff --git a/media/libmediatranscoding/transcoder/Android.bp b/media/module/libmediatranscoding/transcoder/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/Android.bp
rename to media/module/libmediatranscoding/transcoder/Android.bp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleQueue.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleQueue.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleQueue.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleQueue.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleWriter.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleWriter.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/module/libmediatranscoding/transcoder/MediaTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/MediaTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/NdkCommon.cpp b/media/module/libmediatranscoding/transcoder/NdkCommon.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/NdkCommon.cpp
rename to media/module/libmediatranscoding/transcoder/NdkCommon.cpp
diff --git a/media/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/Android.bp b/media/module/libmediatranscoding/transcoder/benchmark/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/Android.bp
rename to media/module/libmediatranscoding/transcoder/benchmark/Android.bp
diff --git a/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml b/media/module/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
rename to media/module/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSample.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSample.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSample.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSample.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleReader.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/NdkCommon.h b/media/module/libmediatranscoding/transcoder/include/media/NdkCommon.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/NdkCommon.h
rename to media/module/libmediatranscoding/transcoder/include/media/NdkCommon.h
diff --git a/media/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/setloglevel.sh b/media/module/libmediatranscoding/transcoder/setloglevel.sh
similarity index 100%
rename from media/libmediatranscoding/transcoder/setloglevel.sh
rename to media/module/libmediatranscoding/transcoder/setloglevel.sh
diff --git a/media/libmediatranscoding/transcoder/tests/Android.bp b/media/module/libmediatranscoding/transcoder/tests/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/Android.bp
rename to media/module/libmediatranscoding/transcoder/tests/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/module/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
rename to media/module/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
diff --git a/media/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp b/media/module/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/README.md b/media/module/libmediatranscoding/transcoder/tests/README.md
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/README.md
rename to media/module/libmediatranscoding/transcoder/tests/README.md
diff --git a/media/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h b/media/module/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
rename to media/module/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
diff --git a/media/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp b/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/README.md b/media/module/libmediatranscoding/transcoder/tests/fuzzer/README.md
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/README.md
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/README.md
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp b/media/module/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
diff --git a/media/libmediatranscoding/transcoder/tools/Android.bp b/media/module/libmediatranscoding/transcoder/tools/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tools/Android.bp
rename to media/module/libmediatranscoding/transcoder/tools/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tools/Transcode.cpp b/media/module/libmediatranscoding/transcoder/tools/Transcode.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tools/Transcode.cpp
rename to media/module/libmediatranscoding/transcoder/tools/Transcode.cpp
diff --git a/media/libwatchdog/Android.bp b/media/module/libwatchdog/Android.bp
similarity index 100%
rename from media/libwatchdog/Android.bp
rename to media/module/libwatchdog/Android.bp
diff --git a/media/libwatchdog/Watchdog.cpp b/media/module/libwatchdog/Watchdog.cpp
similarity index 100%
rename from media/libwatchdog/Watchdog.cpp
rename to media/module/libwatchdog/Watchdog.cpp
diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/module/libwatchdog/include/watchdog/Watchdog.h
similarity index 100%
rename from media/libwatchdog/include/watchdog/Watchdog.h
rename to media/module/libwatchdog/include/watchdog/Watchdog.h
diff --git a/media/module/metadatautils/Android.bp b/media/module/metadatautils/Android.bp
new file mode 100644
index 0000000..c77474f
--- /dev/null
+++ b/media/module/metadatautils/Android.bp
@@ -0,0 +1,46 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library_static {
+ name: "libstagefright_metadatautils",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ min_sdk_version: "29",
+
+ srcs: ["MetaDataUtils.cpp"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+
+ header_libs: [
+ "libaudioclient_headers",
+ "libstagefright_headers",
+ "libstagefright_foundation_headers",
+ "media_ndk_headers",
+ ],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
+ export_include_dirs: ["include"],
+}
diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/module/metadatautils/MetaDataUtils.cpp
similarity index 100%
rename from media/libstagefright/MetaDataUtils.cpp
rename to media/module/metadatautils/MetaDataUtils.cpp
diff --git a/media/libstagefright/include/media/stagefright/MetaDataUtils.h b/media/module/metadatautils/include/media/stagefright/MetaDataUtils.h
similarity index 100%
rename from media/libstagefright/include/media/stagefright/MetaDataUtils.h
rename to media/module/metadatautils/include/media/stagefright/MetaDataUtils.h
diff --git a/media/libstagefright/tests/metadatautils/Android.bp b/media/module/metadatautils/test/Android.bp
similarity index 93%
rename from media/libstagefright/tests/metadatautils/Android.bp
rename to media/module/metadatautils/test/Android.bp
index ecdf89b..21f38f6 100644
--- a/media/libstagefright/tests/metadatautils/Android.bp
+++ b/media/module/metadatautils/test/Android.bp
@@ -20,9 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_tests_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "frameworks_av_media_libstagefright_tests_license",
- ],
}
cc_test {
diff --git a/media/libstagefright/tests/metadatautils/AndroidTest.xml b/media/module/metadatautils/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/tests/metadatautils/AndroidTest.xml
rename to media/module/metadatautils/test/AndroidTest.xml
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp b/media/module/metadatautils/test/MetaDataUtilsTest.cpp
similarity index 99%
rename from media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
rename to media/module/metadatautils/test/MetaDataUtilsTest.cpp
index 9fd5fdb..08c9284 100644
--- a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
+++ b/media/module/metadatautils/test/MetaDataUtilsTest.cpp
@@ -21,7 +21,7 @@
#include <fstream>
#include <string>
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <media/NdkMediaFormat.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h b/media/module/metadatautils/test/MetaDataUtilsTestEnvironment.h
similarity index 100%
rename from media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
rename to media/module/metadatautils/test/MetaDataUtilsTestEnvironment.h
diff --git a/media/libstagefright/tests/metadatautils/README.md b/media/module/metadatautils/test/README.md
similarity index 100%
rename from media/libstagefright/tests/metadatautils/README.md
rename to media/module/metadatautils/test/README.md
diff --git a/services/minijail/Android.bp b/media/module/minijail/Android.bp
similarity index 100%
rename from services/minijail/Android.bp
rename to media/module/minijail/Android.bp
diff --git a/services/minijail/OWNERS b/media/module/minijail/OWNERS
similarity index 100%
rename from services/minijail/OWNERS
rename to media/module/minijail/OWNERS
diff --git a/services/minijail/TEST_MAPPING b/media/module/minijail/TEST_MAPPING
similarity index 100%
rename from services/minijail/TEST_MAPPING
rename to media/module/minijail/TEST_MAPPING
diff --git a/services/minijail/av_services_minijail_unittest.cpp b/media/module/minijail/av_services_minijail_unittest.cpp
similarity index 100%
rename from services/minijail/av_services_minijail_unittest.cpp
rename to media/module/minijail/av_services_minijail_unittest.cpp
diff --git a/services/minijail/minijail.cpp b/media/module/minijail/minijail.cpp
similarity index 100%
rename from services/minijail/minijail.cpp
rename to media/module/minijail/minijail.cpp
diff --git a/services/minijail/minijail.h b/media/module/minijail/minijail.h
similarity index 100%
rename from services/minijail/minijail.h
rename to media/module/minijail/minijail.h
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/ATSParser.cpp
rename to media/module/mpeg2ts/ATSParser.cpp
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/module/mpeg2ts/Android.bp
similarity index 98%
rename from media/libstagefright/mpeg2ts/Android.bp
rename to media/module/mpeg2ts/Android.bp
index 283df1e..bf762c6 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/module/mpeg2ts/Android.bp
@@ -51,6 +51,7 @@
"libmedia_datasource_headers",
"libaudioclient_headers",
"media_ndk_headers",
+ "libstagefright_headers",
"libstagefright_foundation_headers",
],
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/module/mpeg2ts/AnotherPacketSource.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
rename to media/module/mpeg2ts/AnotherPacketSource.cpp
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/module/mpeg2ts/CasManager.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/CasManager.cpp
rename to media/module/mpeg2ts/CasManager.cpp
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/module/mpeg2ts/ESQueue.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/ESQueue.cpp
rename to media/module/mpeg2ts/ESQueue.cpp
diff --git a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp b/media/module/mpeg2ts/HlsSampleDecryptor.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp
rename to media/module/mpeg2ts/HlsSampleDecryptor.cpp
diff --git a/media/libstagefright/mpeg2ts/MODULE_LICENSE_APACHE2 b/media/module/mpeg2ts/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/mpeg2ts/MODULE_LICENSE_APACHE2
rename to media/module/mpeg2ts/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/mpeg2ts/NOTICE b/media/module/mpeg2ts/NOTICE
similarity index 100%
rename from media/libstagefright/mpeg2ts/NOTICE
rename to media/module/mpeg2ts/NOTICE
diff --git a/media/libstagefright/mpeg2ts/TEST_MAPPING b/media/module/mpeg2ts/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/mpeg2ts/TEST_MAPPING
rename to media/module/mpeg2ts/TEST_MAPPING
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/ATSParser.h b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/ATSParser.h
rename to media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h b/media/module/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
rename to media/module/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/CasManager.h b/media/module/mpeg2ts/include/mpeg2ts/CasManager.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/CasManager.h
rename to media/module/mpeg2ts/include/mpeg2ts/CasManager.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/ESQueue.h b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/ESQueue.h
rename to media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h b/media/module/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
rename to media/module/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/SampleDecryptor.h b/media/module/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
rename to media/module/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
diff --git a/media/libstagefright/mpeg2ts/test/Android.bp b/media/module/mpeg2ts/test/Android.bp
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Android.bp
rename to media/module/mpeg2ts/test/Android.bp
diff --git a/media/libstagefright/mpeg2ts/test/AndroidTest.xml b/media/module/mpeg2ts/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/AndroidTest.xml
rename to media/module/mpeg2ts/test/AndroidTest.xml
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp b/media/module/mpeg2ts/test/Mpeg2tsUnitTest.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
rename to media/module/mpeg2ts/test/Mpeg2tsUnitTest.cpp
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h b/media/module/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
rename to media/module/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
diff --git a/media/libstagefright/mpeg2ts/test/README.md b/media/module/mpeg2ts/test/README.md
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/README.md
rename to media/module/mpeg2ts/test/README.md
diff --git a/services/mediatranscoding/.clang-format b/media/module/service.mediatranscoding/.clang-format
similarity index 100%
rename from services/mediatranscoding/.clang-format
rename to media/module/service.mediatranscoding/.clang-format
diff --git a/services/mediatranscoding/Android.bp b/media/module/service.mediatranscoding/Android.bp
similarity index 96%
rename from services/mediatranscoding/Android.bp
rename to media/module/service.mediatranscoding/Android.bp
index fa5eb4e..37f354b 100644
--- a/services/mediatranscoding/Android.bp
+++ b/media/module/service.mediatranscoding/Android.bp
@@ -26,6 +26,10 @@
"SimulatedTranscoder.cpp",
],
+ export_include_dirs: [
+ ".",
+ ],
+
min_sdk_version: "29",
apex_available: [
"com.android.media",
diff --git a/services/mediatranscoding/MODULE_LICENSE_APACHE2 b/media/module/service.mediatranscoding/MODULE_LICENSE_APACHE2
similarity index 100%
rename from services/mediatranscoding/MODULE_LICENSE_APACHE2
rename to media/module/service.mediatranscoding/MODULE_LICENSE_APACHE2
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/media/module/service.mediatranscoding/MediaTranscodingService.cpp
similarity index 100%
rename from services/mediatranscoding/MediaTranscodingService.cpp
rename to media/module/service.mediatranscoding/MediaTranscodingService.cpp
diff --git a/services/mediatranscoding/MediaTranscodingService.h b/media/module/service.mediatranscoding/MediaTranscodingService.h
similarity index 100%
rename from services/mediatranscoding/MediaTranscodingService.h
rename to media/module/service.mediatranscoding/MediaTranscodingService.h
diff --git a/services/mediatranscoding/NOTICE b/media/module/service.mediatranscoding/NOTICE
similarity index 100%
rename from services/mediatranscoding/NOTICE
rename to media/module/service.mediatranscoding/NOTICE
diff --git a/services/mediatranscoding/OWNERS b/media/module/service.mediatranscoding/OWNERS
similarity index 100%
rename from services/mediatranscoding/OWNERS
rename to media/module/service.mediatranscoding/OWNERS
diff --git a/services/mediatranscoding/SimulatedTranscoder.cpp b/media/module/service.mediatranscoding/SimulatedTranscoder.cpp
similarity index 100%
rename from services/mediatranscoding/SimulatedTranscoder.cpp
rename to media/module/service.mediatranscoding/SimulatedTranscoder.cpp
diff --git a/services/mediatranscoding/SimulatedTranscoder.h b/media/module/service.mediatranscoding/SimulatedTranscoder.h
similarity index 100%
rename from services/mediatranscoding/SimulatedTranscoder.h
rename to media/module/service.mediatranscoding/SimulatedTranscoder.h
diff --git a/services/mediatranscoding/main_mediatranscodingservice.cpp b/media/module/service.mediatranscoding/main_mediatranscodingservice.cpp
similarity index 100%
rename from services/mediatranscoding/main_mediatranscodingservice.cpp
rename to media/module/service.mediatranscoding/main_mediatranscodingservice.cpp
diff --git a/services/mediatranscoding/tests/Android.bp b/media/module/service.mediatranscoding/tests/Android.bp
similarity index 95%
rename from services/mediatranscoding/tests/Android.bp
rename to media/module/service.mediatranscoding/tests/Android.bp
index ae13656..97fbd4c 100644
--- a/services/mediatranscoding/tests/Android.bp
+++ b/media/module/service.mediatranscoding/tests/Android.bp
@@ -20,10 +20,6 @@
"-Wextra",
],
- include_dirs: [
- "frameworks/av/services/mediatranscoding",
- ],
-
shared_libs: [
"libactivitymanager_aidl",
"libbinder",
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
similarity index 100%
rename from services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
rename to media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
diff --git a/services/mediatranscoding/tests/README.txt b/media/module/service.mediatranscoding/tests/README.txt
similarity index 100%
rename from services/mediatranscoding/tests/README.txt
rename to media/module/service.mediatranscoding/tests/README.txt
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
diff --git a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/module/service.mediatranscoding/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
rename to media/module/service.mediatranscoding/tests/build_and_run_all_unit_tests.sh
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 97e2a22..719d05a 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -31,8 +31,8 @@
],
}
-cc_library_shared {
- name: "libmtp",
+cc_defaults {
+ name: "libmtp_defaults",
srcs: [
"MtpDataPacket.cpp",
"MtpDebug.cpp",
@@ -71,3 +71,14 @@
],
header_libs: ["libcutils_headers"],
}
+
+cc_library_shared {
+ name: "libmtp",
+ defaults: ["libmtp_defaults"],
+}
+
+cc_library_shared {
+ name: "libmtp_fuzz",
+ defaults: ["libmtp_defaults"],
+ cflags: ["-DMTP_FUZZER"],
+}
diff --git a/media/mtp/MtpDescriptors.h b/media/mtp/MtpDescriptors.h
index d600a24..9b98a71 100644
--- a/media/mtp/MtpDescriptors.h
+++ b/media/mtp/MtpDescriptors.h
@@ -23,6 +23,17 @@
namespace android {
+#ifdef MTP_FUZZER
+constexpr char FFS_MTP_EP0[] = "/data/local/tmp/usb-ffs/mtp/ep0";
+constexpr char FFS_MTP_EP_IN[] = "/data/local/tmp/usb-ffs/mtp/ep1";
+constexpr char FFS_MTP_EP_OUT[] = "/data/local/tmp/usb-ffs/mtp/ep2";
+constexpr char FFS_MTP_EP_INTR[] = "/data/local/tmp/usb-ffs/mtp/ep3";
+
+constexpr char FFS_PTP_EP0[] = "/data/local/tmp/usb-ffs/ptp/ep0";
+constexpr char FFS_PTP_EP_IN[] = "/data/local/tmp/usb-ffs/ptp/ep1";
+constexpr char FFS_PTP_EP_OUT[] = "/data/local/tmp/usb-ffs/ptp/ep2";
+constexpr char FFS_PTP_EP_INTR[] = "/data/local/tmp/usb-ffs/ptp/ep3";
+#else
constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
@@ -32,6 +43,7 @@
constexpr char FFS_PTP_EP_IN[] = "/dev/usb-ffs/ptp/ep1";
constexpr char FFS_PTP_EP_OUT[] = "/dev/usb-ffs/ptp/ep2";
constexpr char FFS_PTP_EP_INTR[] = "/dev/usb-ffs/ptp/ep3";
+#endif
constexpr int MAX_PACKET_SIZE_FS = 64;
constexpr int MAX_PACKET_SIZE_HS = 512;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 6fcf119..d917772 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -985,7 +985,7 @@
int type = storage->getType();
if (type == MTP_STORAGE_REMOVABLE_RAM) {
- std::string str = android::base::Trim((const char*)name);
+ std::string str = android::base::Trim(name);
name.set(str.c_str());
}
ALOGV("name: %s format: 0x%04X (%s)\n", (const char*)name, format,
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index 4cec58a..30d1bc1 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -20,6 +20,7 @@
#include <log/log.h>
#include <stdint.h>
#include <string>
+#include <string_view>
// Max Character number of a MTP String
#define MTP_STRING_MAX_CHARACTER_NUMBER 255
@@ -55,6 +56,7 @@
inline int size() const { return mString.length(); }
inline operator const char*() const { return mString.c_str(); }
+ operator std::string_view() const { return mString; }
};
inline void MtpStringBuffer::append(const char* other) {
diff --git a/media/mtp/tests/MtpFuzzer/Android.bp b/media/mtp/tests/MtpFuzzer/Android.bp
index 5365f4b..9e41680 100644
--- a/media/mtp/tests/MtpFuzzer/Android.bp
+++ b/media/mtp/tests/MtpFuzzer/Android.bp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -6,29 +22,20 @@
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_av_media_mtp_license"],
}
-
-cc_fuzz {
- name: "mtp_fuzzer",
- srcs: [
- "mtp_fuzzer.cpp",
- "MtpMockDatabase.cpp",
- ],
+cc_defaults {
+ name: "mtp_fuzzer_defaults",
shared_libs: [
- "libmtp",
- "libbase",
- "liblog",
- "libutils",
+ "libbase",
+ "liblog",
+ "libutils",
],
+ static_libs: ["libc++fs",],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
- "-DMTP_DEVICE",
"-Wno-unused-parameter",
],
- dictionary: "mtp_fuzzer.dict",
- corpus: ["corpus/*"],
-
fuzz_config: {
cc: ["jameswei@google.com"],
@@ -38,3 +45,107 @@
],
},
}
+cc_fuzz {
+ name: "mtp_fuzzer",
+ srcs: [
+ "mtp_fuzzer.cpp",
+ "MtpMockDatabase.cpp",
+ ],
+ cflags: ["-DMTP_DEVICE",],
+ shared_libs: ["libmtp",],
+ defaults: ["mtp_fuzzer_defaults"],
+ dictionary: "mtp_fuzzer.dict",
+ corpus: ["corpus/*"],
+}
+
+cc_defaults {
+ name: "mtp_property_fuzzer_defaults",
+ srcs: ["mtp_property_fuzzer.cpp"],
+ shared_libs: [
+ "libmtp",
+ "libasyncio",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_device_property_fuzzer",
+ defaults: ["mtp_property_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_host_property_fuzzer",
+ defaults: ["mtp_property_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_HOST",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_handle_fuzzer",
+ srcs: ["mtp_handle_fuzzer.cpp"],
+ shared_libs: ["libmtp_fuzz"],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: ["-DMTP_FUZZER"],
+}
+
+cc_defaults {
+ name: "mtp_packet_defaults",
+ shared_libs: [
+ "libmtp",
+ "libasyncio",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_HOST",
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_packet_fuzzer",
+ srcs: ["mtp_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_device_fuzzer",
+ srcs: ["mtp_device_fuzzer.cpp"],
+ shared_libs: [
+ "libmtp",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_request_packet_fuzzer",
+ srcs: ["mtp_request_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_event_packet_fuzzer",
+ srcs: ["mtp_event_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_response_packet_fuzzer",
+ srcs: ["mtp_response_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_data_packet_fuzzer",
+ srcs: ["mtp_data_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
diff --git a/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
new file mode 100644
index 0000000..87fea9f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 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 <MtpStringBuffer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usbdevice_fs.h>
+#include <sys/mman.h>
+#include <usbhost/usbhost.h>
+#include <MtpTypes.h>
+
+using namespace android;
+constexpr UrbPacketDivisionMode kUrbPacketDivisionModes[] = {FIRST_PACKET_ONLY_HEADER,
+ FIRST_PACKET_HAS_PAYLOAD};
+
+constexpr size_t kMinSize = 0;
+constexpr size_t kMaxSize = 1000;
+constexpr size_t kMaxLength = 1000;
+
+class MtpPacketFuzzerUtils {
+ protected:
+ struct usb_request mUsbRequest;
+ struct usbdevfs_urb* mUsbDevFsUrb;
+ std::string mPath;
+
+ void fillFd(int32_t& fd, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ std::string text = fdp->ConsumeRandomLengthString(kMaxLength);
+ write(fd, text.c_str(), text.length());
+ }
+ };
+
+ void fillFilePath(FuzzedDataProvider* fdp) {
+ mPath= fdp->ConsumeRandomLengthString(kMaxLength);
+ };
+
+ void fillUsbDevFsUrb(FuzzedDataProvider* fdp) {
+ mUsbDevFsUrb->type = fdp->ConsumeIntegral<unsigned char>();
+ mUsbDevFsUrb->endpoint = fdp->ConsumeIntegral<unsigned char>();
+ mUsbDevFsUrb->flags = fdp->ConsumeIntegral<uint32_t>();
+ std::vector<uint8_t> buffer =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mUsbDevFsUrb->buffer = static_cast<void*>(buffer.data());
+ mUsbDevFsUrb->buffer_length = buffer.size();
+ mUsbDevFsUrb->actual_length = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->start_frame = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->number_of_packets = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->stream_id = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->error_count = fdp->ConsumeIntegral<size_t>();
+ mUsbDevFsUrb->signr = fdp->ConsumeIntegral<uint32_t>();
+ std::vector<uint8_t> userBuffer = (fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+ mUsbDevFsUrb->usercontext = static_cast<void*>(userBuffer.data());
+ mUsbDevFsUrb->iso_frame_desc[0].length = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->iso_frame_desc[0].actual_length = fdp->ConsumeIntegral<uint32_t>();
+ };
+
+ void fillUsbRequest(int32_t& fd, FuzzedDataProvider* fdp) {
+ fillUsbDevFsUrb(fdp);
+ fillFd(fd, fdp);
+ std::vector<uint8_t> buffer =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mUsbRequest.buffer = static_cast<void*>(buffer.data());
+ mUsbRequest.buffer_length = buffer.size();
+ mUsbRequest.actual_length = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ mUsbRequest.max_packet_size = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ mUsbRequest.private_data = static_cast<void*>(mUsbDevFsUrb);
+ mUsbRequest.endpoint = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ std::vector<uint8_t> clientBuffer = (fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+ mUsbRequest.client_data = static_cast<void*>(clientBuffer.data());
+ };
+
+ template <typename Object>
+ void writeHandle(Object obj, FuzzedDataProvider* fdp) {
+ MtpDevHandle handle;
+ std::vector<uint8_t> initData =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ handle.write(initData.data(), initData.size());
+ obj->write(&handle);
+ };
+};
diff --git a/media/mtp/tests/MtpFuzzer/README.md b/media/mtp/tests/MtpFuzzer/README.md
new file mode 100644
index 0000000..7efaf67
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/README.md
@@ -0,0 +1,210 @@
+# Fuzzers for libmtp
+
+## Table of contents
++ [mtp_fuzzer](#MtpServer)
++ [mtp_host_property_fuzzer](#MtpHostProperty)
++ [mtp_device_property_fuzzer](#MtpDeviceProperty)
++ [mtp_handle_fuzzer](#MtpHandle)
++ [mtp_packet_fuzzer](#MtpPacket)
+ + [mtp_device_fuzzer](#MtpDevice)
++ [mtp_request_packet_fuzzer](#MtpRequestPacket)
++ [mtp_event_packet_fuzzer](#MtpEventPacket)
++ [mtp_response_packet_fuzzer](#MtpResponsePacket)
++ [mtp_data_packet_fuzzer](#MtpDataPacket)
+
+# <a name="MtpServer"></a> Fuzzer for MtpServer
+
+MtpServer supports the following parameters:
+1. PacketData (parameter name: "packetData")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`packetData`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_fuzzer/mtp_fuzzer corpus/ -dict=mtp_fuzzer.dict
+```
+
+# <a name="MtpHostProperty"></a> Fuzzer for MtpHostProperty
+
+MtpHostProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleTypes")
+2. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_host_property_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_host_property_fuzzer/mtp_host_property_fuzzer
+```
+
+# <a name="MtpDeviceProperty"></a> Fuzzer for MtpDeviceProperty
+
+MtpDeviceProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleType")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_device_property_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_device_property_fuzzer/mtp_device_property_fuzzer
+```
+
+# <a name="MtpHandle"></a>Fuzzer for MtpHandle
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_handle_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_handle_fuzzer/mtp_handle_fuzzer
+```
+
+# <a name="MtpPacket"></a> Fuzzer for MtpPacket
+
+MtpPacket supports the following parameters:
+1. bufferSize (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`bufferSize`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_packet_fuzzer/mtp_packet_fuzzer
+```
+
+# <a name="MtpDevice"></a> Fuzzer for MtpDevice
+
+MtpDevice supports the following parameters:
+1. Device Name (parameter name: "deviceName")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`deviceName`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_device_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_device_fuzzer/mtp_device_fuzzer
+```
+
+# <a name="MtpRequestPacket"></a> Fuzzer for MtpRequestPacket
+
+MtpRequestPacket supports the following parameters:
+1. Data (parameter name: "data")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`data`| Vector of positive Integer |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_request_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_request_packet_fuzzer/mtp_request_packet_fuzzer
+```
+
+# <a name="MtpEventPacket"></a> Fuzzer for MtpEventPacket
+
+MtpEventPacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_event_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_event_packet_fuzzer/mtp_event_packet_fuzzer
+```
+
+# <a name="MtpResponsePacket"></a> Fuzzer for MtpResponsePacket
+
+MtpResponsePacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_response_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_response_packet_fuzzer/mtp_response_packet_fuzzer
+```
+
+# <a name="MtpDataPacket"></a> Fuzzer for MtpDataPacket
+
+MtpDataPacket supports the following parameters:
+1. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+2. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_data_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_data_packet_fuzzer/mtp_data_packet_fuzzer
+```
diff --git a/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt b/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt
new file mode 100644
index 0000000..71f2836
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
new file mode 100644
index 0000000..f5faf77
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2022 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 <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+class MtpDataPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpDataPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpDataPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpDataPacketFuzzer::process() {
+ MtpDataPacket mtpDataPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpDataAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mtpDataPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+ [&]() { mtpDataPacket.reset(); },
+ [&]() {
+ mtpDataPacket.setOperationCode(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpDataPacket.setTransactionID(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() {
+ Int8List* result = mtpDataPacket.getAInt8();
+ delete result;
+ },
+ [&]() {
+ Int16List* result = mtpDataPacket.getAInt16();
+ delete result;
+ },
+ [&]() {
+ Int32List* result = mtpDataPacket.getAInt32();
+ delete result;
+ },
+ [&]() {
+ Int64List* result = mtpDataPacket.getAInt64();
+ delete result;
+ },
+ [&]() {
+ UInt8List* result = mtpDataPacket.getAUInt8();
+ delete result;
+ },
+ [&]() {
+ UInt16List* result = mtpDataPacket.getAUInt16();
+ delete result;
+ },
+ [&]() {
+ UInt32List* result = mtpDataPacket.getAUInt32();
+ delete result;
+ },
+ [&]() {
+ UInt64List* result = mtpDataPacket.getAUInt64();
+ delete result;
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint8_t> initData =
+ mFdp.ConsumeBytes<uint8_t>(mFdp.ConsumeIntegral<uint8_t>());
+ mtpDataPacket.putAUInt8(initData.data(), initData.size());
+ } else {
+ mtpDataPacket.putAUInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint16_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint16_t>();
+ }
+ mtpDataPacket.putAUInt16(arr, size);
+ } else {
+ mtpDataPacket.putAUInt16(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint32_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+ }
+ mtpDataPacket.putAUInt32(arr, size);
+ } else {
+ mtpDataPacket.putAUInt32(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint64_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint64_t>();
+ }
+ mtpDataPacket.putAUInt64(arr, size);
+ } else {
+ mtpDataPacket.putAUInt64(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ int64_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int64_t>();
+ }
+ mtpDataPacket.putAInt64(arr, size);
+ } else {
+ mtpDataPacket.putAInt64(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint16_t> arr;
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr.push_back(mFdp.ConsumeIntegral<uint16_t>());
+ }
+ mtpDataPacket.putAUInt16(&arr);
+ } else {
+ mtpDataPacket.putAUInt16(nullptr);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint32_t> arr;
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr.push_back(mFdp.ConsumeIntegral<uint32_t>());
+ }
+ mtpDataPacket.putAUInt32(&arr);
+ } else {
+ mtpDataPacket.putAUInt32(nullptr);
+ }
+ },
+
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ int32_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+ }
+ mtpDataPacket.putAInt32(arr, size);
+ } else {
+ mtpDataPacket.putAInt32(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.putString(
+ (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+ } else {
+ mtpDataPacket.putString(static_cast<char*>(nullptr));
+ }
+ },
+ [&]() {
+ android::MtpStringBuffer sBuffer(
+ (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.getString(sBuffer);
+ } else {
+ mtpDataPacket.putString(sBuffer);
+ }
+ },
+ [&]() {
+ MtpDevHandle handle;
+ handle.start(mFdp.ConsumeBool());
+ std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* data = const_cast<char*>(text.c_str());
+ handle.read(static_cast<void*>(data), text.length());
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.read(&handle);
+ } else if (mFdp.ConsumeBool()) {
+ mtpDataPacket.write(&handle);
+ } else {
+ std::string textData = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* Data = const_cast<char*>(textData.c_str());
+ mtpDataPacket.writeData(&handle, static_cast<void*>(Data),
+ textData.length());
+ }
+ handle.close();
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+ android::String16 s(str.c_str());
+ char16_t* data = const_cast<char16_t*>(s.string());
+ mtpDataPacket.putString(reinterpret_cast<uint16_t*>(data));
+ } else {
+ mtpDataPacket.putString(static_cast<uint16_t*>(nullptr));
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.putAInt8(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.putAUInt8(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAUInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.readData(&mUsbRequest, data.data(), data.size());
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.write(
+ &mUsbRequest,
+ mFdp.PickValueInArray<UrbPacketDivisionMode>(kUrbPacketDivisionModes),
+ fd, mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.read(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.write(&mUsbRequest, mFdp.PickValueInArray<UrbPacketDivisionMode>(
+ kUrbPacketDivisionModes));
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataHeader(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataAsync(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataWait(mUsbRequest.dev);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<int16_t> data;
+ for (size_t idx = 0;
+ idx < mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); ++idx) {
+ data.push_back(mFdp.ConsumeIntegral<int16_t>());
+ }
+ mtpDataPacket.putAInt16(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAInt16(nullptr, 0);
+ }
+ },
+ [&]() {
+ int32_t arr[4];
+ for (size_t idx = 0; idx < 4; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+ }
+ mtpDataPacket.putInt128(arr);
+ },
+ [&]() { mtpDataPacket.putInt64(mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() {
+ int16_t out;
+ mtpDataPacket.getInt16(out);
+ },
+ [&]() {
+ int32_t out;
+ mtpDataPacket.getInt32(out);
+ },
+ [&]() {
+ int8_t out;
+ mtpDataPacket.getInt8(out);
+ },
+ [&]() {
+ uint32_t arr[4];
+ for (size_t idx = 0; idx < 4; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+ }
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.putUInt128(arr);
+ } else {
+ mtpDataPacket.getUInt128(arr);
+ }
+ },
+ [&]() { mtpDataPacket.putUInt64(mFdp.ConsumeIntegral<uint64_t>()); },
+ [&]() {
+ uint64_t out;
+ mtpDataPacket.getUInt64(out);
+ },
+ [&]() { mtpDataPacket.putInt128(mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() { mtpDataPacket.putUInt128(mFdp.ConsumeIntegral<uint64_t>()); },
+ [&]() {
+ int32_t length;
+ void* data = mtpDataPacket.getData(&length);
+ free(data);
+ },
+ });
+ mtpDataAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpDataPacketFuzzer mtpDataPacketFuzzer(data, size);
+ mtpDataPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
new file mode 100644
index 0000000..c4dd564
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpDevice.h>
+#include <MtpDeviceInfo.h>
+#include <MtpObjectInfo.h>
+#include <MtpProperty.h>
+#include <MtpStorageInfo.h>
+#include <MtpStringBuffer.h>
+#include <android-base/unique_fd.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usb/ch9.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <usbhost/usbhost.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 20;
+constexpr int32_t kMaxBytes = 200;
+constexpr int32_t kMaxDataSize = 20;
+constexpr uint16_t kWMaxPacketSize = 64;
+constexpr uint16_t kEndpointsCount = 3;
+const std::string kInputFile = "/dev/null";
+const std::string kConfigFilePath = "/data/local/tmp/config";
+
+static bool readCallback(void* data, uint32_t offset, uint32_t length, void* clientData) {
+ return true;
+}
+
+struct fdDescriptors {
+ struct usb_interface_descriptor interface;
+ struct usb_endpoint_descriptor ep[kEndpointsCount];
+};
+
+fdDescriptors writeDescriptorsToFd(int32_t fd, FuzzedDataProvider& fdp) {
+ fdDescriptors desc;
+ desc.interface.bLength = sizeof(desc.interface);
+ desc.interface.bDescriptorType = USB_DT_INTERFACE;
+ desc.interface.bInterfaceNumber = fdp.ConsumeIntegral<uint8_t>();
+ desc.interface.bNumEndpoints = kEndpointsCount;
+ desc.interface.bInterfaceClass =
+ fdp.ConsumeBool() ? USB_CLASS_STILL_IMAGE : USB_CLASS_VENDOR_SPEC;
+ desc.interface.bInterfaceSubClass = fdp.ConsumeBool() ? 1 : 0xFF;
+ desc.interface.bInterfaceProtocol = fdp.ConsumeBool() ? 1 : 0;
+ desc.interface.iInterface = fdp.ConsumeIntegral<uint8_t>();
+ for (uint16_t idx = 0; idx < kEndpointsCount; ++idx) {
+ desc.ep[idx].bLength = sizeof(desc.ep[idx]);
+ desc.ep[idx].bDescriptorType = USB_DT_ENDPOINT;
+ desc.ep[idx].bEndpointAddress = idx | (fdp.ConsumeBool() ? USB_DIR_OUT : USB_DIR_IN);
+ desc.ep[idx].bmAttributes =
+ fdp.ConsumeBool() ? USB_ENDPOINT_XFER_BULK : USB_ENDPOINT_XFER_INT;
+ desc.ep[idx].wMaxPacketSize = kWMaxPacketSize;
+ }
+ write(fd, &desc, sizeof(fdDescriptors));
+ return desc;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ int32_t fd = memfd_create(kConfigFilePath.c_str(), MFD_ALLOW_SEALING);
+ fdDescriptors descriptor = writeDescriptorsToFd(fd, fdp);
+ std::string deviceName = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ usb_device* device = usb_device_new(deviceName.c_str(), fd);
+ MtpDevice mtpDevice(device, fdp.ConsumeIntegral<int32_t>(), &descriptor.ep[0],
+ &descriptor.ep[1], &descriptor.ep[2]);
+ MtpObjectInfo objectinfo(fdp.ConsumeIntegral<uint32_t>());
+ MtpStorageInfo storageInfo(fdp.ConsumeIntegral<uint32_t>());
+ while (fdp.remaining_bytes()) {
+ auto mtpDeviceFunction = fdp.PickValueInArray<const std::function<void()>>(
+ {[&]() { mtpDevice.getStorageIDs(); },
+ [&]() {
+ mtpDevice.getStorageInfo(fdp.ConsumeIntegral<int32_t>() /* storageID */);
+ },
+ [&]() {
+ mtpDevice.getObjectHandles(fdp.ConsumeIntegral<uint32_t>() /* storageID */,
+ fdp.ConsumeIntegral<uint16_t>() /* format */,
+ fdp.ConsumeIntegral<uint32_t>() /* parent */);
+ },
+ [&]() { mtpDevice.initialize(); },
+ [&]() {
+ int32_t outLength = 0;
+ mtpDevice.getThumbnail(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ outLength);
+ },
+ [&]() {
+ MtpObjectInfo mtpObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */);
+ std::string name = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ std::string keywords = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ mtpObjectInfo.mName = strdup(name.c_str());
+ mtpObjectInfo.mKeywords = strdup(keywords.c_str());
+ mtpDevice.sendObjectInfo(&mtpObjectInfo);
+ },
+ [&]() {
+ mtpDevice.sendObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */, fd);
+ },
+ [&]() { mtpDevice.deleteObject(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() {
+ mtpDevice.getObjectPropsSupported(
+ fdp.ConsumeIntegral<uint16_t>() /* format */);
+ },
+ [&]() {
+ MtpDataType dataType = fdp.ConsumeIntegral<int16_t>();
+ MtpProperty mtpProperty(fdp.ConsumeIntegral<int16_t>() /* propCode */,
+ dataType, fdp.ConsumeBool() /* writeable */,
+ fdp.ConsumeIntegral<int32_t>() /* defaultValue */);
+ if (dataType == MTP_TYPE_STR) {
+ mtpProperty.setCurrentValue(
+ fdp.ConsumeRandomLengthString(kMaxStringLength).c_str());
+ }
+ mtpDevice.setDevicePropValueStr(&mtpProperty);
+ },
+ [&]() {
+ mtpDevice.getObjectPropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */,
+ fdp.ConsumeIntegral<uint16_t>() /* format */);
+ },
+ [&]() {
+ MtpProperty property;
+ mtpDevice.getObjectPropValue(fdp.ConsumeIntegral<uint16_t>() /* handle */,
+ &property);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ mtpDevice.readObject(
+ fdp.ConsumeIntegral<uint32_t>() /* handle */, readCallback,
+ fdp.ConsumeIntegral<uint32_t>() /* objectSize */, &clientData);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ uint32_t writtenSize = 0;
+ mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint32_t>() /* offset */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */,
+ &writtenSize, readCallback, &clientData);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ uint32_t writtenSize = 0;
+ mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint64_t>() /* offset */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */,
+ &writtenSize, readCallback, &clientData);
+ },
+ [&]() {
+ if (mtpDevice.submitEventRequest() != -1) {
+ uint32_t parameters[3];
+ mtpDevice.reapEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */,
+ ¶meters);
+ }
+ },
+ [&]() {
+ mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /*handle*/);
+ },
+ [&]() {
+ mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */);
+ },
+ [&]() { mtpDevice.print(); },
+ [&]() { mtpDevice.getDeviceName(); },
+ [&]() { mtpDevice.getObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getParent(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getStorageID(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getDevicePropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */); },
+ [&]() {
+ mtpDevice.readObject(
+ fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeRandomLengthString(kMaxStringLength).c_str() /* destPath */,
+ fdp.ConsumeIntegral<int32_t>() /* group */,
+ fdp.ConsumeIntegral<int32_t>() /* perm */);
+ },
+ [&]() {
+ int32_t filefd = open(kConfigFilePath.c_str(), O_CREAT | O_RDWR);
+ mtpDevice.readObject(fdp.ConsumeIntegral<uint16_t>() /* handle */, filefd);
+ close(filefd);
+ },
+ [&]() { MtpDevice::open(deviceName.c_str(), fd); },
+ [&]() {
+ MtpDataPacket mtpDataPacket;
+ MtpDevHandle devHandle;
+ std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+ objectinfo.read(mtpDataPacket);
+ objectinfo.print();
+ },
+ [&]() {
+ MtpDataPacket mtpDataPacket;
+ MtpDevHandle devHandle;
+ std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+ storageInfo.read(mtpDataPacket);
+ storageInfo.print();
+ }});
+ mtpDeviceFunction();
+ }
+ close(fd);
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
new file mode 100644
index 0000000..3bd3be2
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpEventPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpEventPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpEventPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpEventPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpEventPacketFuzzer::process() {
+ MtpEventPacket mtpEventPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpEventAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mtpEventPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+ [&]() { mtpEventPacket.reset(); },
+ [&]() { writeHandle(&mtpEventPacket, &mFdp); },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpEventPacket.sendRequest(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillFd(fd, &mFdp);
+ struct usb_device* device = usb_device_new(mPath.c_str(), fd);
+ mtpEventPacket.readResponse(device);
+ usb_device_close(device);
+ },
+ });
+ mtpEventAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpEventPacketFuzzer mtpEventPacketFuzzer(data, size);
+ mtpEventPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
index f578462..e886816 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
@@ -14,12 +14,15 @@
* limitations under the License.
*/
+#include <android-base/properties.h>
#include <android-base/unique_fd.h>
+#include <fuzzer/FuzzedDataProvider.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
-
+#include <filesystem>
+#include <fstream>
#include <string>
#define LOG_TAG "MtpFuzzer"
@@ -32,38 +35,40 @@
#include "MtpStorage.h"
#include "MtpUtils.h"
-const char* storage_desc = "Fuzz Storage";
+constexpr int32_t kMinFiles = 0;
+constexpr int32_t kMaxFiles = 5;
+constexpr int32_t kMaxBytes = 128;
+constexpr float kMinDataSizeFactor = 0.8;
// prefer tmpfs for file operations to avoid wearing out flash
const char* storage_path = "/storage/fuzzer/0";
-const char* source_database = "srcdb/";
+const char* source_database = "/data/local/tmp/srcdb/";
+const std::string test_path = std::string(source_database) + "TestDir/";
+const std::string kPropertyKey = "sys.fuse.transcode_mtp";
namespace android {
class MtpMockServer {
-public:
- std::unique_ptr<MtpMockHandle> mHandle;
- std::unique_ptr<MtpStorage> mStorage;
- std::unique_ptr<MtpMockDatabase> mDatabase;
- std::unique_ptr<MtpServer> mMtp;
- int mStorageId;
-
- MtpMockServer(const char* storage_path) : mStorageId(0) {
- bool ptp = false;
- const char* manu = "Google";
- const char* model = "Pixel 3XL";
- const char* version = "1.0";
- const char* serial = "ABDEF1231";
-
+ public:
+ MtpMockServer(const uint8_t* data, size_t size) : mFdp(data, size) {
// This is unused in our harness
int controlFd = -1;
mHandle = std::make_unique<MtpMockHandle>();
- mStorage = std::make_unique<MtpStorage>(mStorageId, storage_path, storage_desc, true,
- 0x200000000L);
+ mStorage = std::make_unique<MtpStorage>(
+ mFdp.ConsumeIntegral<uint32_t>() /* storageId */, storage_path,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* descriptor */,
+ mFdp.ConsumeBool() /* removable */,
+ mFdp.ConsumeIntegral<uint64_t>() /* maxFileSize */);
mDatabase = std::make_unique<MtpMockDatabase>();
mDatabase->addStorage(mStorage.get());
- mMtp = std::make_unique<MtpServer>(mDatabase.get(), controlFd, ptp, manu, model, version,
- serial);
+ init(data, size);
+
+ mMtp = std::make_unique<MtpServer>(
+ mDatabase.get(), controlFd, mFdp.ConsumeBool() /* ptp */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* manu */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* model */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* version */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* serial */);
mMtp->addStorage(mStorage.get());
// clear the old handle first, so we don't leak memory
@@ -71,7 +76,76 @@
mMtp->mHandle = mHandle.get();
}
- void run() { mMtp->run(); }
+ void process() {
+ if (mFdp.ConsumeBool()) {
+ createDatabaseFromSourceDir(source_database, storage_path, MTP_PARENT_ROOT);
+ }
+
+ while (mFdp.remaining_bytes()) {
+ MtpStorage storage(mFdp.ConsumeIntegral<uint32_t>() /* id */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* filePath */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* description */,
+ mFdp.ConsumeBool() /* removable */,
+ mFdp.ConsumeIntegral<uint64_t>() /* maxFileSize */);
+
+ auto invokeMtpServerAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mMtp->run(); },
+ [&]() { mMtp->sendObjectAdded(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendObjectRemoved(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendObjectInfoChanged(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendDevicePropertyChanged(mFdp.ConsumeIntegral<uint16_t>()); },
+ [&]() { mMtp->addStorage(&storage); },
+ [&]() { mMtp->removeStorage(&storage); },
+ });
+
+ invokeMtpServerAPI();
+ }
+
+ std::filesystem::remove_all(source_database);
+ }
+
+ private:
+ void createFiles(std::string path, size_t fileCount) {
+ std::ofstream file;
+ for (size_t idx = 0; idx < fileCount; ++idx) {
+ file.open(path.append(std::to_string(idx)));
+ file.close();
+ }
+ }
+
+ void addPackets(const uint8_t* data, size_t size) {
+ size_t off = 0;
+ for (size_t i = 0; i < size; ++i) {
+ // A longer delimiter could be used, but this worked in practice
+ if (data[i] == '@') {
+ size_t pktsz = i - off;
+ if (pktsz > 0) {
+ packet_t pkt = packet_t((unsigned char*)data + off, (unsigned char*)data + i);
+ // insert into packet buffer
+ mHandle->add_packet(pkt);
+ off = i;
+ }
+ }
+ }
+ }
+
+ void init(const uint8_t* data, size_t size) {
+ std::vector<uint8_t> packetData = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinDataSizeFactor * size, size));
+
+ // Packetize the input stream
+ addPackets(packetData.data(), packetData.size());
+
+ // Setting the property to true/false to randomly fuzz the PoC depended on it
+ base::SetProperty(kPropertyKey, mFdp.ConsumeBool() ? "true" : "false");
+
+ std::filesystem::create_directories(source_database);
+ if (mFdp.ConsumeBool()) {
+ std::filesystem::create_directories(test_path);
+ createFiles(test_path, mFdp.ConsumeIntegralInRange<size_t>(kMinFiles, kMaxFiles));
+ }
+ createFiles(source_database, mFdp.ConsumeIntegralInRange<size_t>(kMinFiles, kMaxFiles));
+ }
int createDatabaseFromSourceDir(const char* fromPath, const char* toPath,
MtpObjectHandle parentHandle) {
@@ -130,8 +204,14 @@
closedir(dir);
return ret;
}
+
+ FuzzedDataProvider mFdp;
+ std::unique_ptr<MtpMockHandle> mHandle;
+ std::unique_ptr<MtpStorage> mStorage;
+ std::unique_ptr<MtpMockDatabase> mDatabase;
+ std::unique_ptr<MtpServer> mMtp;
};
-}; // namespace android
+}; // namespace android
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) __attribute__((optnone)) {
// reset our storage (from MtpUtils.h)
@@ -140,26 +220,9 @@
android::makeFolder(storage_path);
std::unique_ptr<android::MtpMockServer> mtp =
- std::make_unique<android::MtpMockServer>(storage_path);
+ std::make_unique<android::MtpMockServer>(data, size);
+ mtp->process();
- size_t off = 0;
-
- // Packetize the input stream
- for (size_t i = 0; i < size; i++) {
- // A longer delimiter could be used, but this worked in practice
- if (data[i] == '@') {
- size_t pktsz = i - off;
- if (pktsz > 0) {
- packet_t pkt = packet_t((unsigned char*)data + off, (unsigned char*)data + i);
- // insert into packet buffer
- mtp->mHandle->add_packet(pkt);
- off = i;
- }
- }
- }
-
- mtp->createDatabaseFromSourceDir(source_database, storage_path, MTP_PARENT_ROOT);
- mtp->run();
-
+ std::filesystem::remove_all("/storage/fuzzer");
return 0;
}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
new file mode 100644
index 0000000..676345a
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 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 <MtpDescriptors.h>
+#include <MtpFfsCompatHandle.h>
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <mtp.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 64;
+constexpr int32_t kMinAPICase = 0;
+constexpr int32_t kMaxMtpHandleAPI = 5;
+constexpr int32_t kMinBufferSize = 0;
+constexpr uint32_t kMaxMtpFileSize = 0xFFFFFFFF;
+constexpr float kDataSizeFactor = 0.1;
+
+const std::string kTempPath = "/data/local/tmp/";
+const std::string kFuzzerUsbDirPath = kTempPath + "usb-ffs";
+const std::string kFuzzerMtpPath = kFuzzerUsbDirPath + "/mtp";
+const std::string kFuzzerPtpPath = kFuzzerUsbDirPath + "/ptp";
+const std::string kFuzzerTestFile = kTempPath + "FuzzerTestDescriptorFile";
+const std::string kFuzzerMtpInputFile = kTempPath + "FuzzerMtpInputFile";
+const std::string kFuzzerMtpOutputFile = kTempPath + "FuzzerMtpOutputFile";
+
+const std::string kDeviceFilePaths[] = {FFS_MTP_EP0, FFS_MTP_EP_IN, FFS_MTP_EP_INTR,
+ FFS_PTP_EP0, FFS_PTP_EP_IN, FFS_PTP_EP_INTR,
+ FFS_MTP_EP_OUT, FFS_PTP_EP_OUT};
+
+class MtpFfsHandleFuzzer {
+ public:
+ MtpFfsHandleFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mDataSize = kDataSizeFactor * size;
+ createFiles();
+ };
+ void process();
+
+ ~MtpFfsHandleFuzzer() { removeFiles(); };
+
+ private:
+ FuzzedDataProvider mFdp;
+ void invokeWriteDescriptor();
+ void invokeMtpFfsHandle();
+ void createFiles();
+ void removeFiles();
+ void createDeviceFile(const char* file);
+ void writeDeviceFile(const char* file);
+ int32_t writeInputFile(int32_t fd);
+ uint32_t mDataSize = 0;
+};
+
+int32_t MtpFfsHandleFuzzer::writeInputFile(int32_t fd) {
+ uint32_t minFileSize = std::min((uint32_t)MTP_BUFFER_SIZE, mDataSize);
+ uint32_t maxFileSize = std::min(mDataSize, kMaxMtpFileSize);
+ std::vector<char> dataBuffer = mFdp.ConsumeBytes<char>(
+ mFdp.ConsumeIntegralInRange<uint32_t>(minFileSize, maxFileSize));
+ write(fd, dataBuffer.data(), dataBuffer.size());
+ lseek(fd, 0, SEEK_SET);
+ return dataBuffer.size();
+}
+
+void MtpFfsHandleFuzzer::createDeviceFile(const char* file) {
+ int32_t fd = open(file, O_CREAT | O_RDWR | O_NONBLOCK);
+ close(fd);
+}
+
+void MtpFfsHandleFuzzer::writeDeviceFile(const char* file) {
+ int32_t fd = open(file, O_RDWR | O_NONBLOCK);
+ writeInputFile(fd);
+ close(fd);
+}
+
+void MtpFfsHandleFuzzer::createFiles() {
+ mkdir(kFuzzerUsbDirPath.c_str(), 0755);
+ mkdir(kFuzzerMtpPath.c_str(), 0755);
+ mkdir(kFuzzerPtpPath.c_str(), 0755);
+
+ for (auto path : kDeviceFilePaths) {
+ createDeviceFile(path.c_str());
+ }
+
+ writeDeviceFile(FFS_MTP_EP_OUT);
+ writeDeviceFile(FFS_PTP_EP_OUT);
+}
+
+void MtpFfsHandleFuzzer::removeFiles() {
+ for (auto path : kDeviceFilePaths) {
+ remove(path.c_str());
+ }
+
+ rmdir(kFuzzerMtpPath.c_str());
+ rmdir(kFuzzerPtpPath.c_str());
+ rmdir(kFuzzerUsbDirPath.c_str());
+}
+
+void MtpFfsHandleFuzzer::invokeWriteDescriptor() {
+ while (mFdp.remaining_bytes() > 0) {
+ int32_t controlFd = mFdp.ConsumeBool()
+ ? -1 /* Invalid fd*/
+ : open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ std::unique_ptr<MtpFfsHandle> handle(new MtpFfsHandle(controlFd));
+ handle->writeDescriptors(mFdp.ConsumeBool());
+ handle->close();
+ close(controlFd);
+ remove(kFuzzerTestFile.c_str());
+ }
+}
+
+void MtpFfsHandleFuzzer::invokeMtpFfsHandle() {
+ while (mFdp.remaining_bytes() > 0) {
+ int32_t controlFd = open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ writeInputFile(controlFd);
+
+ std::unique_ptr<IMtpHandle> handle;
+ if (mFdp.ConsumeBool()) {
+ std::unique_ptr<IMtpHandle> mtpCompactHandle(new MtpFfsCompatHandle(controlFd));
+ handle = move(mtpCompactHandle);
+ } else {
+ std::unique_ptr<IMtpHandle> mtpHandle(new MtpFfsHandle(controlFd));
+ handle = move(mtpHandle);
+ }
+
+ int32_t mtpHandle = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxMtpHandleAPI);
+ switch (mtpHandle) {
+ case 0: {
+ handle->start(mFdp.ConsumeBool());
+ break;
+ }
+ case 1: {
+ std::string data = mFdp.ConsumeRandomLengthString(MTP_BUFFER_SIZE);
+ handle->write(data.c_str(), data.length());
+ break;
+ }
+ case 2: {
+ int32_t bufferSize =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBufferSize, MTP_BUFFER_SIZE);
+ uint8_t buffer[bufferSize + 1];
+ handle->read(buffer, bufferSize);
+ break;
+ }
+ case 3: {
+ mtp_file_range mfr;
+ mfr.fd = open(kFuzzerMtpInputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ mfr.length = writeInputFile(mfr.fd);
+ mfr.offset = 0; /* Offset point to the start of the file */
+ mfr.command = mFdp.ConsumeIntegral<uint16_t>();
+ mfr.transaction_id = mFdp.ConsumeIntegral<uint32_t>();
+ handle->sendFile(mfr);
+ close(mfr.fd);
+ remove(kFuzzerMtpInputFile.c_str());
+ break;
+ }
+ case 4: {
+ struct mtp_event event;
+ std::string dataValue = mFdp.ConsumeRandomLengthString(kMaxStringLength);
+ event.data = const_cast<char*>(dataValue.c_str());
+ event.length = dataValue.length();
+ handle->sendEvent(event);
+ break;
+ }
+ case 5:
+ default: {
+ mtp_file_range mfr;
+ mfr.fd = open(kFuzzerMtpOutputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ mfr.offset = 0; /* Offset point to the start of the file */
+ mfr.length = kMaxMtpFileSize;
+ handle->receiveFile(mfr, mFdp.ConsumeBool());
+ close(mfr.fd);
+ remove(kFuzzerMtpOutputFile.c_str());
+ break;
+ }
+ }
+ handle->close();
+ close(controlFd);
+ remove(kFuzzerTestFile.c_str());
+ }
+}
+
+void MtpFfsHandleFuzzer::process() {
+ if (mFdp.ConsumeBool()) {
+ invokeMtpFfsHandle();
+ } else {
+ invokeWriteDescriptor();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpFfsHandleFuzzer mtpFfsHandleFuzzer(data, size);
+ mtpFfsHandleFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
new file mode 100644
index 0000000..6fc2a96
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpPacketFuzzer::process() {
+ MtpPacket mtpPacket(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); /*bufferSize*/
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpPacketAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpPacket.allocate(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ },
+ [&]() { mtpPacket.reset(); },
+ [&]() { mtpPacket.getContainerType(); },
+ [&]() { mtpPacket.getContainerCode(); },
+ [&]() { mtpPacket.dump(); },
+ [&]() { mtpPacket.getTransactionID(); },
+ [&]() {
+ mtpPacket.setContainerCode(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.setTransactionID(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.getParameter(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.setParameter(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize),
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ MtpPacket testMtpPacket(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ testMtpPacket.copyFrom(mtpPacket);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpPacket.transfer(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpPacketAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpPacketFuzzer mtpPacketFuzzer(data, size);
+ mtpPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
new file mode 100644
index 0000000..8577e62
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 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 <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpProperty.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+constexpr uint16_t kFeasibleTypes[] = {
+ MTP_TYPE_UNDEFINED, MTP_TYPE_INT8, MTP_TYPE_UINT8, MTP_TYPE_INT16, MTP_TYPE_UINT16,
+ MTP_TYPE_INT32, MTP_TYPE_UINT32, MTP_TYPE_INT64, MTP_TYPE_UINT64, MTP_TYPE_INT128,
+ MTP_TYPE_UINT128, MTP_TYPE_AINT8, MTP_TYPE_AUINT8, MTP_TYPE_AINT16, MTP_TYPE_AUINT16,
+ MTP_TYPE_AINT32, MTP_TYPE_AUINT32, MTP_TYPE_AINT64, MTP_TYPE_AUINT64, MTP_TYPE_AINT128,
+ MTP_TYPE_AUINT128, MTP_TYPE_STR,
+};
+
+class MtpPropertyFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpPropertyFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpPropertyFuzzer::process() {
+ MtpProperty* mtpProperty;
+ if (mFdp.ConsumeBool()) {
+ mtpProperty = new MtpProperty();
+ } else {
+ uint16_t type = mFdp.ConsumeBool() ? mFdp.ConsumeIntegral<uint16_t>()
+ : mFdp.PickValueInArray<uint16_t>(kFeasibleTypes);
+ mtpProperty = new MtpProperty(mFdp.ConsumeIntegral<uint16_t>(), type, mFdp.ConsumeBool(),
+ mFdp.ConsumeIntegral<uint16_t>());
+ }
+
+ while (mFdp.remaining_bytes() > 0) {
+ auto invokeMtpPropertyFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ MtpDataPacket mtpDataPacket;
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->read(mtpDataPacket);
+
+ } else {
+ if (mFdp.ConsumeBool()) {
+#ifdef MTP_DEVICE
+ android::IMtpHandle* h = new MtpDevHandle();
+ h->start(mFdp.ConsumeBool());
+ std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* data = const_cast<char*>(text.c_str());
+ h->read(static_cast<void*>(data), text.length());
+ mtpDataPacket.write(h);
+ h->close();
+ delete h;
+#endif
+
+#ifdef MTP_HOST
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mtpDataPacket.write(&mUsbRequest,
+ mFdp.PickValueInArray<UrbPacketDivisionMode>(
+ kUrbPacketDivisionModes),
+ fd,
+ mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ usb_device_close(mUsbRequest.dev);
+#endif
+ }
+
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->write(mtpDataPacket);
+ } else {
+ mtpProperty->setCurrentValue(mtpDataPacket);
+ }
+ }
+ },
+ [&]() {
+ char16_t* data = nullptr;
+ std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+ android::String16 s(str.c_str());
+ if (mFdp.ConsumeBool()) {
+ data = const_cast<char16_t*>(s.string());
+ }
+
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->setDefaultValue(reinterpret_cast<uint16_t*>(data));
+ } else if (mFdp.ConsumeBool()) {
+ mtpProperty->setCurrentValue(reinterpret_cast<uint16_t*>(data));
+ } else {
+ mtpProperty->setCurrentValue(str.c_str());
+ }
+ },
+ [&]() {
+ mtpProperty->setFormRange(mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<int32_t>());
+ },
+ [&]() {
+ std::vector<int32_t> init;
+ for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize);
+ ++idx) {
+ init.push_back(mFdp.ConsumeIntegral<int32_t>());
+ }
+ mtpProperty->setFormEnum(init.data(), init.size());
+ },
+ });
+ invokeMtpPropertyFuzzer();
+ }
+
+ delete (mtpProperty);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpPropertyFuzzer mtpPropertyFuzzer(data, size);
+ mtpPropertyFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
new file mode 100644
index 0000000..19fbc5b
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpRequestPacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <fstream>
+
+using namespace android;
+
+std::string kMtpDevPath = "/dev/mtp_usb";
+constexpr int32_t kMaxBytes = 100000;
+
+class MtpRequestPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpRequestPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpRequestPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+ void makeFile(std::string s);
+};
+
+void MtpRequestPacketFuzzer::process() {
+ MtpRequestPacket mtpRequestPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpRequestAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpRequestPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() { mtpRequestPacket.reset(); },
+ [&]() {
+ MtpDevHandle handle;
+ makeFile(kMtpDevPath);
+ handle.start(mFdp.ConsumeBool());
+ std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ handle.write(data.data(), data.size());
+ mtpRequestPacket.read(&handle);
+ handle.close();
+ remove(kMtpDevPath.c_str());
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpRequestPacket.write(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpRequestAPI();
+ }
+}
+
+void MtpRequestPacketFuzzer::makeFile(std::string s) {
+ std::ofstream out;
+ out.open(s, std::ios::binary | std::ofstream::trunc);
+ for (int32_t idx = 0; idx < mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); ++idx) {
+ out << mFdp.ConsumeRandomLengthString(kMaxBytes) << "\n";
+ }
+ out.close();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpRequestPacketFuzzer mtpRequestPacketFuzzer(data, size);
+ mtpRequestPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
new file mode 100644
index 0000000..697785f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpResponsePacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpResponsePacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpResponsePacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpResponsePacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpResponsePacketFuzzer::process() {
+ MtpResponsePacket mtpResponsePacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpResponseAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpResponsePacket.allocate(
+ mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); /*size*/
+ },
+ [&]() { mtpResponsePacket.reset(); },
+ [&]() { writeHandle(&mtpResponsePacket, &mFdp); },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpResponsePacket.read(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpResponseAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpResponsePacketFuzzer mtpResponsePacketFuzzer(data, size);
+ mtpResponsePacketFuzzer.process();
+ return 0;
+}
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 38e422d..ed31c02 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <charconv>
#include <inttypes.h>
#include <mutex>
#include <set>
@@ -324,29 +325,61 @@
}
AMessage::Type type;
- int64_t mediaTimeUs, systemNano;
- size_t index = 0;
+ size_t n = data->countEntries();
- // TODO. This code has dependency with MediaCodec::CreateFramesRenderedMessage.
- for (size_t ix = 0; ix < data->countEntries(); ix++) {
- AString name = data->getEntryNameAt(ix, &type);
- if (name.startsWith(AStringPrintf("%zu-media-time-us", index).c_str())) {
- AMessage::ItemData data = msg->getEntryAt(index);
- data.find(&mediaTimeUs);
- } else if (name.startsWith(AStringPrintf("%zu-system-nano", index).c_str())) {
- AMessage::ItemData data = msg->getEntryAt(index);
- data.find(&systemNano);
+ thread_local std::vector<std::optional<int64_t>> mediaTimesInUs;
+ thread_local std::vector<std::optional<int64_t>> systemTimesInNs;
+ mediaTimesInUs.resize(n);
+ systemTimesInNs.resize(n);
+ std::fill_n(mediaTimesInUs.begin(), n, std::nullopt);
+ std::fill_n(systemTimesInNs.begin(), n, std::nullopt);
+ for (size_t i = 0; i < n; i++) {
+ AString name = data->getEntryNameAt(i, &type);
+ if (name.endsWith("-media-time-us")) {
+ int64_t mediaTimeUs;
+ AMessage::ItemData itemData = data->getEntryAt(i);
+ itemData.find(&mediaTimeUs);
- Mutex::Autolock _l(mCodec->mFrameRenderedCallbackLock);
- if (mCodec->mFrameRenderedCallback != NULL) {
+ int index = -1;
+ std::from_chars_result result = std::from_chars(
+ name.c_str(), name.c_str() + name.find("-"), index);
+ if (result.ec == std::errc() && 0 <= index && index < n) {
+ mediaTimesInUs[index] = mediaTimeUs;
+ } else {
+ std::error_code ec = std::make_error_code(result.ec);
+ ALOGE("Unexpected media time index: #%d with value %lldus (err=%d %s)",
+ index, (long long)mediaTimeUs, ec.value(), ec.message().c_str());
+ }
+ } else if (name.endsWith("-system-nano")) {
+ int64_t systemNano;
+ AMessage::ItemData itemData = data->getEntryAt(i);
+ itemData.find(&systemNano);
+
+ int index = -1;
+ std::from_chars_result result = std::from_chars(
+ name.c_str(), name.c_str() + name.find("-"), index);
+ if (result.ec == std::errc() && 0 <= index && index < n) {
+ systemTimesInNs[index] = systemNano;
+ } else {
+ std::error_code ec = std::make_error_code(result.ec);
+ ALOGE("Unexpected system time index: #%d with value %lldns (err=%d %s)",
+ index, (long long)systemNano, ec.value(), ec.message().c_str());
+ }
+ }
+ }
+
+ Mutex::Autolock _l(mCodec->mFrameRenderedCallbackLock);
+ if (mCodec->mFrameRenderedCallback != NULL) {
+ for (size_t i = 0; i < n; ++i) {
+ if (mediaTimesInUs[i] && systemTimesInNs[i]) {
mCodec->mFrameRenderedCallback(
mCodec,
mCodec->mFrameRenderedCallbackUserData,
- mediaTimeUs,
- systemNano);
+ mediaTimesInUs[i].value(),
+ systemTimesInNs[i].value());
+ } else {
+ break;
}
-
- index++;
}
}
break;
@@ -529,22 +562,31 @@
AMediaCodecOnAsyncNotifyCallback callback,
void *userdata) {
- Mutex::Autolock _l(mData->mAsyncCallbackLock);
-
- if (mData->mAsyncNotify == NULL) {
- mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
+ {
+ Mutex::Autolock _l(mData->mAsyncCallbackLock);
+ if (mData->mAsyncNotify == NULL) {
+ mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
+ }
+ // we set this ahead so that we can be ready
+ // to receive callbacks as soon as the next call is a
+ // success.
+ mData->mAsyncCallback = callback;
+ mData->mAsyncCallbackUserData = userdata;
}
// always call, codec may have been reset/re-configured since last call.
status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
if (err != OK) {
+ {
+ //The setup gone wrong. clean up the pointers.
+ Mutex::Autolock _l(mData->mAsyncCallbackLock);
+ mData->mAsyncCallback = {};
+ mData->mAsyncCallbackUserData = nullptr;
+ }
ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
return translate_error(err);
}
- mData->mAsyncCallback = callback;
- mData->mAsyncCallbackUserData = userdata;
-
return AMEDIA_OK;
}
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 59c1103..f4674de 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -183,7 +183,7 @@
AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
int32_t dataSize = data.size();
const uint8_t *dataPtr = data.data();
- if (dataSize > 0) {
+ if (dataSize >= 0) {
(*mEventListener)(mObj, &asid, ndkEventType, 0, dataPtr, dataSize);
} else {
ALOGE("invalid event data size=%d", dataSize);
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 923453a..a95e874 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -147,38 +147,80 @@
EXPORT
bool AMediaFormat_getInt32(AMediaFormat* format, const char *name, int32_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findInt32(name, out);
}
EXPORT
bool AMediaFormat_getInt64(AMediaFormat* format, const char *name, int64_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findInt64(name, out);
}
EXPORT
bool AMediaFormat_getFloat(AMediaFormat* format, const char *name, float *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findFloat(name, out);
}
EXPORT
bool AMediaFormat_getDouble(AMediaFormat* format, const char *name, double *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findDouble(name, out);
}
EXPORT
bool AMediaFormat_getSize(AMediaFormat* format, const char *name, size_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findSize(name, out);
}
EXPORT
bool AMediaFormat_getRect(AMediaFormat* format, const char *name,
int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findRect(name, left, top, right, bottom);
}
EXPORT
bool AMediaFormat_getBuffer(AMediaFormat* format, const char *name, void** data, size_t *outsize) {
sp<ABuffer> buf;
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
if (format->mFormat->findBuffer(name, &buf)) {
*data = buf->data() + buf->offset();
*outsize = buf->size();
@@ -189,7 +231,12 @@
EXPORT
bool AMediaFormat_getString(AMediaFormat* mData, const char *name, const char **out) {
-
+ if (mData == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
for (size_t i = 0; i < mData->mStringCache.size(); i++) {
if (strcmp(mData->mStringCache.keyAt(i).string(), name) == 0) {
mData->mStringCache.removeItemsAt(i, 1);
@@ -212,43 +259,91 @@
EXPORT
void AMediaFormat_setInt32(AMediaFormat* format, const char *name, int32_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setInt32(name, value);
}
EXPORT
void AMediaFormat_setInt64(AMediaFormat* format, const char *name, int64_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setInt64(name, value);
}
EXPORT
void AMediaFormat_setFloat(AMediaFormat* format, const char* name, float value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setFloat(name, value);
}
EXPORT
void AMediaFormat_setDouble(AMediaFormat* format, const char* name, double value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setDouble(name, value);
}
EXPORT
void AMediaFormat_setSize(AMediaFormat* format, const char* name, size_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setSize(name, value);
}
EXPORT
void AMediaFormat_setRect(AMediaFormat* format, const char *name,
int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setRect(name, left, top, right, bottom);
}
EXPORT
void AMediaFormat_setString(AMediaFormat* format, const char* name, const char* value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
// AMessage::setString() makes a copy of the string
format->mFormat->setString(name, value, strlen(value));
}
EXPORT
void AMediaFormat_setBuffer(AMediaFormat* format, const char* name, const void* data, size_t size) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
// the ABuffer(void*, size_t) constructor doesn't take ownership of the data, so create
// a new buffer and copy the data into it
sp<ABuffer> buf = new ABuffer(size);
diff --git a/media/ndk/fuzzer/Android.bp b/media/ndk/fuzzer/Android.bp
index b2ae220..a3d6a96 100644
--- a/media/ndk/fuzzer/Android.bp
+++ b/media/ndk/fuzzer/Android.bp
@@ -64,3 +64,55 @@
srcs: ["ndk_crypto_fuzzer.cpp"],
defaults: ["libmediandk_fuzzer_defaults"],
}
+
+cc_fuzz {
+ name: "ndk_image_reader_fuzzer",
+ srcs: [
+ "ndk_image_reader_fuzzer.cpp",
+ ],
+ shared_libs: [
+ "android.hidl.token@1.0-utils",
+ "android.hardware.graphics.bufferqueue@1.0",
+ ],
+ cflags: [
+ "-D__ANDROID_VNDK__",
+ ],
+ defaults: ["libmediandk_fuzzer_defaults"],
+}
+
+cc_fuzz {
+ name: "ndk_extractor_fuzzer",
+ srcs: ["ndk_extractor_fuzzer.cpp"],
+ defaults: ["libmediandk_fuzzer_defaults"],
+ shared_libs: ["libbinder_ndk",],
+ corpus: ["corpus/*"],
+}
+
+cc_fuzz {
+ name: "ndk_mediaformat_fuzzer",
+ srcs: ["ndk_mediaformat_fuzzer.cpp"],
+ defaults: ["libmediandk_fuzzer_defaults",],
+}
+
+cc_fuzz {
+ name: "ndk_drm_fuzzer",
+ srcs: ["ndk_drm_fuzzer.cpp"],
+ defaults: ["libmediandk_fuzzer_defaults",],
+}
+
+cc_fuzz {
+ name: "ndk_mediamuxer_fuzzer",
+ srcs: ["ndk_mediamuxer_fuzzer.cpp"],
+ defaults: ["libmediandk_fuzzer_defaults"],
+ shared_libs: ["libbinder_ndk",],
+}
+
+cc_fuzz {
+ name: "ndk_sync_codec_fuzzer",
+ srcs: [
+ "ndk_sync_codec_fuzzer.cpp",
+ "NdkMediaCodecFuzzerBase.cpp",
+ ],
+ header_libs: ["libnativewindow_headers",],
+ defaults: ["libmediandk_fuzzer_defaults",],
+}
diff --git a/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp
new file mode 100644
index 0000000..c7ce950
--- /dev/null
+++ b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2022 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 <NdkMediaCodecFuzzerBase.h>
+
+static const std::string kMimeTypes[] = {
+ MIMETYPE_AUDIO_AMR_NB, MIMETYPE_AUDIO_AMR_WB, MIMETYPE_AUDIO_MPEG,
+ MIMETYPE_AUDIO_AAC, MIMETYPE_AUDIO_FLAC, MIMETYPE_AUDIO_VORBIS,
+ MIMETYPE_AUDIO_OPUS, MIMETYPE_AUDIO_RAW, MIMETYPE_AUDIO_MSGSM,
+ MIMETYPE_AUDIO_EAC3, MIMETYPE_AUDIO_SCRAMBLED, MIMETYPE_VIDEO_VP8,
+ MIMETYPE_VIDEO_VP9, MIMETYPE_VIDEO_AV1, MIMETYPE_VIDEO_AVC,
+ MIMETYPE_VIDEO_HEVC, MIMETYPE_VIDEO_MPEG4, MIMETYPE_VIDEO_H263,
+ MIMETYPE_VIDEO_MPEG2, MIMETYPE_VIDEO_RAW, MIMETYPE_VIDEO_SCRAMBLED};
+
+static const std::string kEncoderNames[] = {
+ "c2.android.avc.encoder", "c2.android.vp8.encoder", "c2.android.vp9.encoder",
+ "c2.android.hevc.encoder", "c2.android.mpeg2.encoder", "c2.android.mpeg4.encoder",
+ "c2.android.opus.encoder", "c2.android.amrnb.encoder", "c2.android.flac.encoder",
+ "c2.android.av1-aom.encoder"};
+
+static const std::string kDecoderNames[] = {"c2.android.avc.decoder",
+ "c2.android.vp8.decoder",
+ "c2.android.vp9.decoder"
+ "c2.android.hevc.decoder",
+ "c2.android.mpeg2.decoder",
+ "c2.android.mpeg4.decoder",
+ "c2.android.opus.decoder",
+ "c2.android.amrnb.decoder",
+ "c2.android.flac.decoder",
+ "c2.android.av1-aom.decoder"};
+
+static const std::string kFormatIntKeys[] = {AMEDIAFORMAT_KEY_BIT_RATE,
+ AMEDIAFORMAT_KEY_SAMPLE_RATE,
+ AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
+ AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_WIDTH,
+ AMEDIAFORMAT_KEY_HEIGHT,
+ AMEDIAFORMAT_KEY_FRAME_RATE,
+ AMEDIAFORMAT_KEY_COLOR_FORMAT,
+ AMEDIAFORMAT_VIDEO_QP_P_MIN,
+ AMEDIAFORMAT_VIDEO_QP_P_MAX,
+ AMEDIAFORMAT_VIDEO_QP_MIN,
+ AMEDIAFORMAT_VIDEO_QP_MAX,
+ AMEDIAFORMAT_VIDEO_QP_I_MIN,
+ AMEDIAFORMAT_VIDEO_QP_I_MAX,
+ AMEDIAFORMAT_VIDEO_QP_B_MIN,
+ AMEDIAFORMAT_VIDEO_QP_B_MAX,
+ AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE,
+ AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL,
+ AMEDIAFORMAT_KEY_VALID_SAMPLES,
+ AMEDIAFORMAT_KEY_TRACK_INDEX,
+ AMEDIAFORMAT_KEY_TRACK_ID,
+ AMEDIAFORMAT_KEY_TILE_WIDTH,
+ AMEDIAFORMAT_KEY_TILE_HEIGHT,
+ AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH,
+ AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT,
+ AMEDIAFORMAT_KEY_STRIDE,
+ AMEDIAFORMAT_KEY_SLICE_HEIGHT,
+ AMEDIAFORMAT_KEY_SAR_WIDTH,
+ AMEDIAFORMAT_KEY_SAR_HEIGHT,
+ AMEDIAFORMAT_KEY_ROTATION,
+ AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN,
+ AMEDIAFORMAT_KEY_PROFILE,
+ AMEDIAFORMAT_KEY_PRIORITY,
+ AMEDIAFORMAT_KEY_PICTURE_TYPE,
+ AMEDIAFORMAT_KEY_PCM_ENCODING,
+ AMEDIAFORMAT_KEY_OPERATING_RATE,
+ AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
+ AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
+ AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
+ AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
+ AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
+ AMEDIAFORMAT_KEY_LOW_LATENCY,
+ AMEDIAFORMAT_KEY_LOOP,
+ AMEDIAFORMAT_KEY_LEVEL,
+ AMEDIAFORMAT_KEY_LATENCY,
+ AMEDIAFORMAT_KEY_IS_SYNC_FRAME,
+ AMEDIAFORMAT_KEY_IS_DEFAULT,
+ AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
+ AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_GRID_ROWS,
+ AMEDIAFORMAT_KEY_GRID_COLUMNS,
+ AMEDIAFORMAT_KEY_FRAME_COUNT,
+ AMEDIAFORMAT_KEY_ENCODER_PADDING,
+ AMEDIAFORMAT_KEY_ENCODER_DELAY,
+ AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
+ AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
+ AMEDIAFORMAT_KEY_DISPLAY_CROP,
+ AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
+ AMEDIAFORMAT_KEY_CRYPTO_MODE,
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+ AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+ AMEDIAFORMAT_KEY_COLOR_TRANSFER,
+ AMEDIAFORMAT_KEY_COLOR_STANDARD,
+ AMEDIAFORMAT_KEY_COLOR_RANGE,
+ AMEDIAFORMAT_KEY_CHANNEL_MASK,
+ AMEDIAFORMAT_KEY_BITS_PER_SAMPLE,
+ AMEDIAFORMAT_KEY_BITRATE_MODE,
+ AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID,
+ AMEDIAFORMAT_KEY_AAC_SBR_MODE,
+ AMEDIAFORMAT_KEY_AAC_PROFILE,
+ AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
+ AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+ AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
+ AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
+ AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
+ AMEDIAFORMAT_KEY_XMP_SIZE,
+ AMEDIAFORMAT_KEY_XMP_OFFSET,
+ AMEDIAFORMAT_KEY_TIME_US,
+ AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
+ AMEDIAFORMAT_KEY_TARGET_TIME,
+ AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND,
+ AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET,
+ AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK,
+ AMEDIAFORMAT_KEY_EXIF_SIZE,
+ AMEDIAFORMAT_KEY_EXIF_OFFSET,
+ AMEDIAFORMAT_KEY_DURATION};
+
+static const std::string kFormatBufferKeys[] = {
+ AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+ AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C,
+ AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+ AMEDIAFORMAT_KEY_SEI,
+ AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
+ AMEDIAFORMAT_KEY_PSSH,
+ AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
+ AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER,
+ AMEDIAFORMAT_KEY_MPEG_USER_DATA,
+ AMEDIAFORMAT_KEY_ICC_PROFILE,
+ AMEDIAFORMAT_KEY_HDR10_PLUS_INFO,
+ AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
+ AMEDIAFORMAT_KEY_ESDS,
+ AMEDIAFORMAT_KEY_D263,
+ AMEDIAFORMAT_KEY_CSD_HEVC,
+ AMEDIAFORMAT_KEY_CSD_AVC,
+ AMEDIAFORMAT_KEY_CSD_2,
+ AMEDIAFORMAT_KEY_CSD_1,
+ AMEDIAFORMAT_KEY_CSD_0,
+ AMEDIAFORMAT_KEY_CSD,
+ AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+ AMEDIAFORMAT_KEY_CRYPTO_KEY,
+ AMEDIAFORMAT_KEY_CRYPTO_IV,
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+ AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+ AMEDIAFORMAT_KEY_ALBUMART,
+};
+
+static const std::string kFormatFloatKeys[] = {AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+ AMEDIAFORMAT_KEY_CAPTURE_RATE};
+
+static const std::string kFormatStringKeys[] = {AMEDIAFORMAT_KEY_YEAR,
+ AMEDIAFORMAT_KEY_TITLE,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
+ AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS,
+ AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
+ AMEDIAFORMAT_KEY_MANUFACTURER,
+ AMEDIAFORMAT_KEY_LYRICIST,
+ AMEDIAFORMAT_KEY_LOCATION,
+ AMEDIAFORMAT_KEY_LANGUAGE,
+ AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
+ AMEDIAFORMAT_KEY_IS_AUTOSELECT,
+ AMEDIAFORMAT_KEY_IS_ADTS,
+ AMEDIAFORMAT_KEY_GENRE,
+ AMEDIAFORMAT_KEY_DISCNUMBER,
+ AMEDIAFORMAT_KEY_DATE,
+ AMEDIAFORMAT_KEY_COMPOSER,
+ AMEDIAFORMAT_KEY_COMPILATION,
+ AMEDIAFORMAT_KEY_COMPLEXITY,
+ AMEDIAFORMAT_KEY_CDTRACKNUMBER,
+ AMEDIAFORMAT_KEY_AUTHOR,
+ AMEDIAFORMAT_KEY_ARTIST,
+ AMEDIAFORMAT_KEY_ALBUMARTIST,
+ AMEDIAFORMAT_KEY_ALBUM};
+
+void formatSetString(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ std::string keyValue = fdp->ConsumeRandomLengthString(kMaxBytes);
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY, keyValue.c_str());
+ }
+}
+
+void formatSetInt(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ int32_t keyValue = fdp->ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue);
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY, keyValue);
+ }
+}
+
+void formatSetFloat(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ float keyValue =
+ fdp->ConsumeFloatingPointInRange<float>(kMinFloatKeyValue, kMaxFloatKeyValue);
+ AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY, keyValue);
+ }
+}
+
+void formatSetBuffer(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ std::vector<uint8_t> buffer = fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaFormat_setBuffer(format, AMEDIAFORMAT_KEY, buffer.data(), buffer.size());
+ }
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByname(bool isEncoder,
+ bool isCodecForClient) {
+ std::string name;
+ if (isEncoder) {
+ name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kEncoderNames)
+ : mFdp->ConsumeRandomLengthString(kMaxBytes);
+ } else {
+ name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kDecoderNames)
+ : mFdp->ConsumeRandomLengthString(kMaxBytes);
+ }
+
+ if (isCodecForClient) {
+ pid_t pid = mFdp->ConsumeIntegral<pid_t>();
+ uid_t uid = mFdp->ConsumeIntegral<uid_t>();
+ return AMediaCodec_createCodecByNameForClient(name.c_str(), pid, uid);
+
+ } else {
+ return AMediaCodec_createCodecByName(name.c_str());
+ }
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByType(bool isEncoder,
+ bool isCodecForClient) {
+ std::string mimeType;
+ const char* mime = nullptr;
+
+ if (mFdp->ConsumeBool()) {
+ mimeType = mFdp->ConsumeRandomLengthString(kMaxBytes);
+ mime = mimeType.c_str();
+ } else {
+ AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+ }
+
+ if (isCodecForClient) {
+ pid_t pid = mFdp->ConsumeIntegral<pid_t>();
+ uid_t uid = mFdp->ConsumeIntegral<uid_t>();
+ return isEncoder ? AMediaCodec_createEncoderByTypeForClient(mime, pid, uid)
+ : AMediaCodec_createDecoderByTypeForClient(mime, pid, uid);
+ } else {
+ return isEncoder ? AMediaCodec_createEncoderByType(mime)
+ : AMediaCodec_createDecoderByType(mime);
+ }
+}
+
+AMediaFormat* NdkMediaCodecFuzzerBase::getSampleCodecFormat() {
+ AMediaFormat* format = AMediaFormat_new();
+ std::string value;
+ int32_t count = 0;
+ int32_t maxFormatKeys = 0;
+
+ /*set mimeType*/
+ if (mFdp->ConsumeBool()) {
+ value = mFdp->ConsumeRandomLengthString(kMaxBytes);
+ } else {
+ value = mFdp->PickValueInArray(kMimeTypes);
+ }
+ if (mFdp->ConsumeBool()) {
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, value.c_str());
+ }
+
+ maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatStringKeys));
+ for (count = 0; count < maxFormatKeys; ++count) {
+ std::string formatKey = mFdp->PickValueInArray(kFormatStringKeys);
+ formatSetString(format, formatKey.c_str(), mFdp);
+ }
+
+ maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatIntKeys));
+ for (count = 0; count < maxFormatKeys; ++count) {
+ std::string formatKey = mFdp->PickValueInArray(kFormatIntKeys);
+ formatSetInt(format, formatKey.c_str(), mFdp);
+ }
+
+ maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatFloatKeys));
+ for (count = 0; count < maxFormatKeys; ++count) {
+ std::string formatKey = mFdp->PickValueInArray(kFormatFloatKeys);
+ formatSetFloat(format, formatKey.c_str(), mFdp);
+ }
+
+ maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatBufferKeys));
+ for (count = 0; count < maxFormatKeys; ++count) {
+ std::string formatKey = mFdp->PickValueInArray(kFormatBufferKeys);
+ formatSetBuffer(format, formatKey.c_str(), mFdp);
+ }
+ return format;
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createCodec(bool isEncoder, bool isCodecForClient) {
+ mFormat = getSampleCodecFormat();
+ return (mFdp->ConsumeBool() ? createAMediaCodecByname(isEncoder, isCodecForClient)
+ : createAMediaCodecByType(isEncoder, isCodecForClient));
+}
+
+void NdkMediaCodecFuzzerBase::invokeCodecFormatAPI(AMediaCodec* codec) {
+ AMediaFormat* codecFormat = nullptr;
+ size_t codecFormatAPI = mFdp->ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxCodecFormatAPIs);
+ switch (codecFormatAPI) {
+ case 0: {
+ codecFormat = AMediaCodec_getInputFormat(codec);
+ break;
+ }
+ case 1: {
+ codecFormat = AMediaCodec_getOutputFormat(codec);
+ break;
+ }
+ case 2:
+ default: {
+ AMediaCodecBufferInfo info;
+ int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+ ssize_t bufferIndex = 0;
+ if (mFdp->ConsumeBool()) {
+ bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs);
+ } else {
+ bufferIndex =
+ mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+ }
+ codecFormat = AMediaCodec_getBufferFormat(codec, bufferIndex);
+ break;
+ }
+ }
+ if (codecFormat) {
+ AMediaFormat_delete(codecFormat);
+ }
+}
+
+void NdkMediaCodecFuzzerBase::invokeInputBufferOperationAPI(AMediaCodec* codec) {
+ size_t bufferSize = 0;
+ ssize_t bufferIndex = 0;
+ int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+ if (mFdp->ConsumeBool()) {
+ bufferIndex = AMediaCodec_dequeueInputBuffer(codec, timeOutUs);
+ } else {
+ bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+ }
+
+ uint8_t* buffer = AMediaCodec_getInputBuffer(codec, bufferIndex, &bufferSize);
+ if (buffer) {
+ std::vector<uint8_t> bytesRead = mFdp->ConsumeBytes<uint8_t>(
+ std::min(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes), bufferSize));
+ memcpy(buffer, bytesRead.data(), bytesRead.size());
+ bufferSize = bytesRead.size();
+ }
+
+ int32_t flag = mFdp->ConsumeIntegralInRange<size_t>(AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG,
+ AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME);
+ if (mFdp->ConsumeBool()) {
+ AMediaCodec_queueInputBuffer(codec, bufferIndex, 0 /* offset */, bufferSize, 0 /* time */,
+ flag);
+ } else {
+ AMediaCodecCryptoInfo* cryptoInfo = getAMediaCodecCryptoInfo();
+ AMediaCodec_queueSecureInputBuffer(codec, bufferIndex, 0 /* offset */, cryptoInfo,
+ 0 /* time */, flag);
+ AMediaCodecCryptoInfo_delete(cryptoInfo);
+ }
+}
+
+void NdkMediaCodecFuzzerBase::invokeOutputBufferOperationAPI(AMediaCodec* codec) {
+ ssize_t bufferIndex = 0;
+ int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+ if (mFdp->ConsumeBool()) {
+ AMediaCodecBufferInfo info;
+ bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs);
+ } else {
+ bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+ }
+
+ if (mFdp->ConsumeBool()) {
+ size_t bufferSize = 0;
+ (void)AMediaCodec_getOutputBuffer(codec, bufferIndex, &bufferSize);
+ }
+
+ if (mFdp->ConsumeBool()) {
+ AMediaCodec_releaseOutputBuffer(codec, bufferIndex, mFdp->ConsumeBool());
+ } else {
+ AMediaCodec_releaseOutputBufferAtTime(codec, bufferIndex, timeOutUs);
+ }
+}
+
+AMediaCodecCryptoInfo* NdkMediaCodecFuzzerBase::getAMediaCodecCryptoInfo() {
+ uint8_t key[kMaxCryptoKey];
+ uint8_t iv[kMaxCryptoKey];
+ size_t clearBytes[kMaxCryptoKey];
+ size_t encryptedBytes[kMaxCryptoKey];
+
+ for (int32_t i = 0; i < kMaxCryptoKey; ++i) {
+ key[i] = mFdp->ConsumeIntegral<uint8_t>();
+ iv[i] = mFdp->ConsumeIntegral<uint8_t>();
+ clearBytes[i] = mFdp->ConsumeIntegral<size_t>();
+ encryptedBytes[i] = mFdp->ConsumeIntegral<size_t>();
+ }
+
+ return AMediaCodecCryptoInfo_new(kMaxCryptoKey, key, iv, AMEDIACODECRYPTOINFO_MODE_CLEAR,
+ clearBytes, encryptedBytes);
+}
diff --git a/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h
new file mode 100644
index 0000000..e810e55
--- /dev/null
+++ b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 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 <android/native_window.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaCodecPlatform.h>
+#include <media/NdkMediaFormat.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+constexpr int32_t kMinBytes = 1;
+constexpr int32_t kMaxBytes = 256;
+constexpr int32_t kMinIntKeyValue = 0;
+constexpr int32_t kMaxIntKeyValue = 6000000;
+constexpr int32_t kMinFloatKeyValue = 1.0f;
+constexpr int32_t kMaxFloatKeyValue = 500.f;
+constexpr int32_t kMinTimeOutUs = 0;
+constexpr int32_t kMaxTimeOutUs = 5000;
+constexpr int32_t kMinAPICase = 0;
+constexpr int32_t kMaxCodecFormatAPIs = 2;
+constexpr int32_t kMaxCryptoKey = 16;
+constexpr int32_t kMinIterations = 10;
+constexpr int32_t kMaxIterations = 100;
+constexpr size_t kMinBufferIndex = 1;
+constexpr size_t kMaxBufferIndex = 128;
+
+class NdkMediaCodecFuzzerBase {
+ public:
+ void invokeCodecFormatAPI(AMediaCodec* codec);
+ void invokeInputBufferOperationAPI(AMediaCodec* codec);
+ void invokeOutputBufferOperationAPI(AMediaCodec* codec);
+ AMediaCodecCryptoInfo* getAMediaCodecCryptoInfo();
+ AMediaCodec* createCodec(bool isEncoder, bool isCodecForClient);
+ AMediaFormat* getCodecFormat() { return mFormat; };
+ void setFdp(FuzzedDataProvider* fdp) { mFdp = fdp; }
+ ~NdkMediaCodecFuzzerBase() {
+ if (mFormat) {
+ AMediaFormat_delete(mFormat);
+ }
+ }
+
+ private:
+ AMediaCodec* createAMediaCodecByname(bool isEncoder, bool isCodecForClient);
+ AMediaCodec* createAMediaCodecByType(bool isEncoder, bool isCodecForClient);
+ AMediaFormat* getSampleAudioFormat();
+ AMediaFormat* getSampleVideoFormat();
+ AMediaFormat* getSampleCodecFormat();
+ AMediaFormat* mFormat = nullptr;
+ FuzzedDataProvider* mFdp = nullptr;
+};
diff --git a/media/ndk/fuzzer/README.md b/media/ndk/fuzzer/README.md
index 4f78e4a..0fd08b0 100644
--- a/media/ndk/fuzzer/README.md
+++ b/media/ndk/fuzzer/README.md
@@ -2,6 +2,12 @@
## Table of contents
+ [ndk_crypto_fuzzer](#NdkCrypto)
++ [ndk_image_reader_fuzzer](#NdkImageReader)
++ [ndk_extractor_fuzzer](#NdkExtractor)
++ [ndk_mediaformat_fuzzer](#NdkMediaFormat)
++ [ndk_drm_fuzzer](#NdkDrm)
++ [ndk_mediamuxer_fuzzer](#NdkMediaMuxer)
++ [ndk_sync_codec_fuzzer](#NdkSyncCodec)
# <a name="NdkCrypto"></a> Fuzzer for NdkCrypto
@@ -22,3 +28,131 @@
$ adb sync data
$ adb shell /data/fuzz/arm64/ndk_crypto_fuzzer/ndk_crypto_fuzzer
```
+
+# <a name="NdkImageReader"></a> Fuzzer for NdkImageReader
+
+NdkImageReader supports the following parameters:
+1. Width (parameter name: "imageWidth")
+2. Height (parameter name: "imageHeight")
+3. Format (parameter name: "imageFormat")
+4. Usage (parameter name: "imageUsage")
+5. Max images (parameter name: "imageMaxCount")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `width`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `height`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `format`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `usage`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `maxImages`| `1 to android::BufferQueue::MAX_MAX_ACQUIRED_BUFFERS`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_image_reader_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_image_reader_fuzzer/ndk_image_reader_fuzzer
+```
+
+# <a name="NdkExtractor"></a>Fuzzer for NdkExtractor
+
+NdkExtractor supports the following parameters:
+1. SeekMode (parameter name: "mode")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`mode`|0.`AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC`,<br/>1.`AMEDIAEXTRACTOR_SEEK_NEXT_SYNC`,<br/>2.`AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_extractor_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_extractor_fuzzer/ndk_extractor_fuzzer /data/fuzz/${TARGET_ARCH}/ndk_extractor_fuzzer/corpus
+```
+
+
+# <a name="NdkMediaFormat"></a>Fuzzer for NdkMediaFormat
+
+NdkMediaFormat supports the following parameters:
+1. Name (parameter name: "name")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`name`|1.`AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR`, 2.`AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR`, 3.`AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION`, 4.`AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL`, 5.`AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL`, 6.`AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT`, 7.`AMEDIAFORMAT_KEY_AAC_PROFILE`, 8.`AMEDIAFORMAT_KEY_AAC_SBR_MODE`, 9.`AMEDIAFORMAT_KEY_ALBUM`, 10.`AMEDIAFORMAT_KEY_ALBUMART`, 11.`AMEDIAFORMAT_KEY_ALBUMARTIST`, 12.`AMEDIAFORMAT_KEY_ARTIST`, 13.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO`, 14.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID`, 15.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID`, 16.`AMEDIAFORMAT_KEY_AUDIO_SESSION_ID`, 17.`AMEDIAFORMAT_KEY_AUTHOR`, 18.`AMEDIAFORMAT_KEY_BITRATE_MODE`, 19.`AMEDIAFORMAT_KEY_BIT_RATE`, 20.`AMEDIAFORMAT_KEY_BITS_PER_SAMPLE`, 21.`AMEDIAFORMAT_KEY_CAPTURE_RATE`, 22.`AMEDIAFORMAT_KEY_CDTRACKNUMBER`, 23.`AMEDIAFORMAT_KEY_CHANNEL_COUNT`, 24.`AMEDIAFORMAT_KEY_CHANNEL_MASK`, 25.`AMEDIAFORMAT_KEY_COLOR_FORMAT`, 26.`AMEDIAFORMAT_KEY_COLOR_RANGE`, 27.`AMEDIAFORMAT_KEY_COLOR_STANDARD`, 28.`AMEDIAFORMAT_KEY_COLOR_TRANSFER`, 29.`AMEDIAFORMAT_KEY_COMPILATION`, 30.`AMEDIAFORMAT_KEY_COMPLEXITY`, 31.`AMEDIAFORMAT_KEY_COMPOSER`, 32.`AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED`, 33.`AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE`, 34.`AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK`, 35.`AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES`, 36.`AMEDIAFORMAT_KEY_CRYPTO_IV`, 37.`AMEDIAFORMAT_KEY_CRYPTO_KEY`, 38.`AMEDIAFORMAT_KEY_CRYPTO_MODE`, 39.`AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES`, 40.`AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK`, 41.`AMEDIAFORMAT_KEY_CSD`, 42.`AMEDIAFORMAT_KEY_CSD_0`, 43.`AMEDIAFORMAT_KEY_CSD_1`, 44.`AMEDIAFORMAT_KEY_CSD_2`, 45.`AMEDIAFORMAT_KEY_CSD_AVC`, 46.`AMEDIAFORMAT_KEY_CSD_HEVC`, 47.`AMEDIAFORMAT_KEY_D263`, 48.`AMEDIAFORMAT_KEY_DATE`, 49.`AMEDIAFORMAT_KEY_DISCNUMBER`, 50.`AMEDIAFORMAT_KEY_DISPLAY_CROP`, 51.`AMEDIAFORMAT_KEY_DISPLAY_HEIGHT`, 52.`AMEDIAFORMAT_KEY_DISPLAY_WIDTH`, 53.`AMEDIAFORMAT_KEY_DURATION`, 54.`AMEDIAFORMAT_KEY_ENCODER_DELAY`, 55.`AMEDIAFORMAT_KEY_ENCODER_PADDING`, 56.`AMEDIAFORMAT_KEY_ESDS`, 57.`AMEDIAFORMAT_KEY_EXIF_OFFSET`, 58.`AMEDIAFORMAT_KEY_EXIF_SIZE`, 59.`AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL`, 60.`AMEDIAFORMAT_KEY_FRAME_COUNT`, 61.`AMEDIAFORMAT_KEY_FRAME_RATE`, 62.`AMEDIAFORMAT_KEY_GENRE`, 63.`AMEDIAFORMAT_KEY_GRID_COLUMNS`, 64.`AMEDIAFORMAT_KEY_GRID_ROWS`, 65.`AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT`, 66.`AMEDIAFORMAT_KEY_HDR_STATIC_INFO`, 67.`AMEDIAFORMAT_KEY_HDR10_PLUS_INFO`, 68.`AMEDIAFORMAT_KEY_HEIGHT`, 69.`AMEDIAFORMAT_KEY_ICC_PROFILE`, 70.`AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD`, 71.`AMEDIAFORMAT_KEY_IS_ADTS`, 72.`AMEDIAFORMAT_KEY_IS_AUTOSELECT`, 73.`AMEDIAFORMAT_KEY_IS_DEFAULT`, 74.`AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE`, 75.`AMEDIAFORMAT_KEY_IS_SYNC_FRAME`, 76.`AMEDIAFORMAT_KEY_I_FRAME_INTERVAL`, 77.`AMEDIAFORMAT_KEY_LANGUAGE`, 78.`AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK`, 79.`AMEDIAFORMAT_KEY_LATENCY`, 80.`AMEDIAFORMAT_KEY_LEVEL`, 81.`AMEDIAFORMAT_KEY_LOCATION`, 82.`AMEDIAFORMAT_KEY_LOOP`, 83.`AMEDIAFORMAT_KEY_LOW_LATENCY`, 84.`AMEDIAFORMAT_KEY_LYRICIST`, 85.`AMEDIAFORMAT_KEY_MANUFACTURER`, 86.`AMEDIAFORMAT_KEY_MAX_BIT_RATE`, 87.`AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER`, 88.`AMEDIAFORMAT_KEY_MAX_HEIGHT`, 89.`AMEDIAFORMAT_KEY_MAX_INPUT_SIZE`, 90.`AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER`, 91.`AMEDIAFORMAT_KEY_MAX_WIDTH`, 92.`AMEDIAFORMAT_KEY_MIME`, 93.`AMEDIAFORMAT_KEY_MPEG_USER_DATA`, 94.`AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER`, 95.`AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS`, 96.`AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION`, 97.`AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT`, 98.`AMEDIAFORMAT_KEY_OPERATING_RATE`, 99.`AMEDIAFORMAT_KEY_PCM_ENCODING`, 100.`AMEDIAFORMAT_KEY_PICTURE_TYPE`, 101.`AMEDIAFORMAT_KEY_PRIORITY`, 102.`AMEDIAFORMAT_KEY_PROFILE`, 103.`AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN`, 104.`AMEDIAFORMAT_KEY_PSSH`, 105.`AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP`, 106.`AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER`, 107.`AMEDIAFORMAT_KEY_ROTATION`, 108.`AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET`, 109.`AMEDIAFORMAT_KEY_SAMPLE_RATE`, 110.`AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND`, 111.`AMEDIAFORMAT_KEY_SAR_HEIGHT`, 112.`AMEDIAFORMAT_KEY_SAR_WIDTH`, 113.`AMEDIAFORMAT_KEY_SEI`, 114.`AMEDIAFORMAT_KEY_SLICE_HEIGHT`, 115.`AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS`, 116.`AMEDIAFORMAT_KEY_STRIDE`, 117.`AMEDIAFORMAT_KEY_TARGET_TIME`, 118.`AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT`, 119.`AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID`, 120.`AMEDIAFORMAT_KEY_TEMPORAL_LAYERING`, 121.`AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA`, 122.`AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C`, 123.`AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC`, 124.`AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT`, 125.`AMEDIAFORMAT_KEY_THUMBNAIL_TIME`, 126.`AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH`, 127.`AMEDIAFORMAT_KEY_TILE_HEIGHT`, 128.`AMEDIAFORMAT_KEY_TILE_WIDTH`, 129.`AMEDIAFORMAT_KEY_TIME_US`, 130.`AMEDIAFORMAT_KEY_TITLE`, 131.`AMEDIAFORMAT_KEY_TRACK_ID`, 132.`AMEDIAFORMAT_KEY_TRACK_INDEX`, 133.`AMEDIAFORMAT_KEY_VALID_SAMPLES`, 134.`AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL`, 135.`AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE`, 136.`AMEDIAFORMAT_VIDEO_QP_B_MAX`, 137.`AMEDIAFORMAT_VIDEO_QP_B_MIN`, 138.`AMEDIAFORMAT_VIDEO_QP_I_MAX`, 139.`AMEDIAFORMAT_VIDEO_QP_I_MIN`, 140.`AMEDIAFORMAT_VIDEO_QP_MAX`, 141.`AMEDIAFORMAT_VIDEO_QP_MIN`, 142.`AMEDIAFORMAT_VIDEO_QP_P_MAX`, 143.`AMEDIAFORMAT_VIDEO_QP_P_MIN`, 144.`AMEDIAFORMAT_KEY_WIDTH`, 145.`AMEDIAFORMAT_KEY_XMP_OFFSET`, 146.`AMEDIAFORMAT_KEY_XMP_SIZE`, 147.`AMEDIAFORMAT_KEY_YEAR`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_mediaformat_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/${TARGET_ARCH}/ndk_mediaformat_fuzzer/ndk_mediaformat_fuzzer /data/fuzz/${TARGET_ARCH}/ndk_mediaformat_fuzzer/corpus
+```
+
+# <a name="NdkDrm"></a> Fuzzer for NdkDrm
+
+NdkDrm supports the following parameters:
+1. ValidUUID(parameter name: "kCommonPsshBoxUUID" and "kClearKeyUUID")
+2. MimeType(parameter name: "kMimeType")
+3. MediaUUID(parameter name: "MediaUUID")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`ValidUUID`| 0.`kCommonPsshBoxUUID`,<br/> 1.`kClearKeyUUID`,<br/> 2.`kInvalidUUID`|Value obtained from FuzzedDataProvider|
+|`kMimeType`| 0.`video/mp4`,<br/> 1.`audio/mp4`|Value obtained from FuzzedDataProvider|
+|`MediaUUID`| 0.`INVALID_UUID`,<br/> 1.`PSSH_BOX_UUID`,<br/> 2.`CLEARKEY_UUID`|Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_drm_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_drm_fuzzer/ndk_drm_fuzzer
+```
+
+# <a name="NdkMediaMuxer"></a>Fuzzer for NdkMediaMuxer
+
+NdkMediaMuxer supports the following parameters:
+1. OutputFormat (parameter name: "outputFormat")
+2. AppendMode (parameter name: "appendMode")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`outputFormat`|0.`AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4`,<br/>1.`AMEDIAMUXER_OUTPUT_FORMAT_WEBM`,<br/>2.`AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP`| Value obtained from FuzzedDataProvider|
+|`appendMode`|0.`AMEDIAMUXER_APPEND_IGNORE_LAST_VIDEO_GOP`,<br/>1.`AMEDIAMUXER_APPEND_TO_EXISTING_DATA`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_mediamuxer_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_mediamuxer_fuzzer/ndk_mediamuxer_fuzzer
+```
+
+# <a name="NdkSyncCodec"></a>Fuzzer for NdkSyncCodec
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_sync_codec_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_sync_codec_fuzzer/ndk_sync_codec_fuzzer
+```
diff --git a/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738 b/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738
new file mode 100755
index 0000000..47d79c8
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6 b/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6
new file mode 100755
index 0000000..17c934c
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce b/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce
new file mode 100755
index 0000000..00a32e2
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950 b/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950
new file mode 100755
index 0000000..86d4001
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d b/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d
new file mode 100755
index 0000000..496c7f3
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a b/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a
new file mode 100755
index 0000000..55437ac
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a
Binary files differ
diff --git a/media/ndk/fuzzer/ndk_drm_fuzzer.cpp b/media/ndk/fuzzer/ndk_drm_fuzzer.cpp
new file mode 100644
index 0000000..8c11c9d
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_drm_fuzzer.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2022 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 <media/NdkMediaCrypto.h>
+#include <media/NdkMediaDrm.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+constexpr int32_t kMinBytes = 1;
+constexpr int32_t kMaxBytes = 256;
+constexpr int32_t kMinParamVal = 0;
+constexpr int32_t kMaxParamVal = 3;
+constexpr int32_t kMediaUUIdSize = sizeof(AMediaUUID);
+constexpr int32_t kMinProvisionResponseSize = 0;
+constexpr int32_t kMaxProvisionResponseSize = 16;
+constexpr int32_t kMessageSize = 16;
+constexpr int32_t kMinAPIcase = 0;
+constexpr int32_t kMaxdecryptEncryptAPIs = 10;
+constexpr int32_t kMaxpropertyAPIs = 3;
+constexpr int32_t kMaxsetListenerAPIs = 2;
+constexpr int32_t kMaxndkDrmAPIs = 3;
+uint8_t signature[kMessageSize];
+
+enum MediaUUID { INVALID_UUID = 0, PSSH_BOX_UUID, CLEARKEY_UUID, kMaxValue = CLEARKEY_UUID };
+
+constexpr uint8_t kCommonPsshBoxUUID[] = {0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
+ 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B};
+
+constexpr uint8_t kClearKeyUUID[] = {0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
+ 0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E};
+
+constexpr uint8_t kInvalidUUID[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
+ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
+
+uint8_t kClearkeyPssh[] = {
+ // BMFF box header (4 bytes size + 'pssh')
+ 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
+ // full box header (version = 1 flags = 0)
+ 0x01, 0x00, 0x00, 0x00,
+ // system id
+ 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
+ 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
+ // number of key ids
+ 0x00, 0x00, 0x00, 0x01,
+ // key id
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ // size of data, must be zero
+ 0x00, 0x00, 0x00, 0x00};
+
+std::string kPropertyName = "clientId";
+std::string kMimeType[] = {"video/mp4", "audio/mp4"};
+std::string kCipherAlgorithm[] = {"AES/CBC/NoPadding", ""};
+std::string kMacAlgorithm[] = {"HmacSHA256", ""};
+
+class NdkMediaDrmFuzzer {
+ public:
+ NdkMediaDrmFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void invokeNdkDrm();
+ static void KeysChangeListener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+ const AMediaDrmKeyStatus* keysStatus, size_t numKeys,
+ bool hasNewUsableKey) {
+ (void)drm;
+ (void)sessionId;
+ (void)keysStatus;
+ (void)numKeys;
+ (void)hasNewUsableKey;
+ };
+
+ static void ExpirationUpdateListener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+ int64_t expiryTimeInMS) {
+ (void)drm;
+ (void)sessionId;
+ (void)expiryTimeInMS;
+ };
+
+ static void listener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+ AMediaDrmEventType eventType, int extra, const uint8_t* data,
+ size_t dataSize) {
+ (void)drm;
+ (void)sessionId;
+ (void)eventType;
+ (void)extra;
+ (void)data;
+ (void)dataSize;
+ }
+
+ private:
+ FuzzedDataProvider mFdp;
+ void invokeDrmCreatePlugin();
+ void invokeDrmSetListener();
+ void invokeDrmPropertyAPI();
+ void invokeDrmDecryptEncryptAPI();
+ void invokeDrmSecureStopAPI();
+ AMediaDrmSessionId mSessionId = {};
+ AMediaDrm* mDrm = nullptr;
+};
+
+void NdkMediaDrmFuzzer::invokeDrmCreatePlugin() {
+ const uint8_t* mediaUUID = nullptr;
+ uint32_t uuidEnum = mFdp.ConsumeEnum<MediaUUID>();
+ switch (uuidEnum) {
+ case INVALID_UUID: {
+ mediaUUID = kInvalidUUID;
+ break;
+ }
+ case PSSH_BOX_UUID: {
+ mediaUUID = kCommonPsshBoxUUID;
+ break;
+ }
+ case CLEARKEY_UUID:
+ default: {
+ mediaUUID = kClearKeyUUID;
+ break;
+ }
+ }
+ mDrm = AMediaDrm_createByUUID(mediaUUID);
+}
+
+void NdkMediaDrmFuzzer::invokeDrmSecureStopAPI() {
+ // get maximum number of secure stops
+ AMediaDrmSecureStop secureStops;
+ size_t numSecureStops = kMaxParamVal;
+ // The API behavior could change based on the drm object (clearkey or
+ // psshbox) This API detects secure stops msg and release them.
+ AMediaDrm_getSecureStops(mDrm, &secureStops, &numSecureStops);
+ AMediaDrm_releaseSecureStops(mDrm, &secureStops);
+}
+
+void NdkMediaDrmFuzzer::invokeDrmSetListener() {
+ int32_t setListenerAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxsetListenerAPIs);
+ switch (setListenerAPI) {
+ case 0: { // set on key change listener
+ AMediaDrm_setOnKeysChangeListener(mDrm, KeysChangeListener);
+ break;
+ }
+ case 1: { // set on expiration on update listener
+ AMediaDrm_setOnExpirationUpdateListener(mDrm, ExpirationUpdateListener);
+ break;
+ }
+ case 2:
+ default: { // set on event listener
+ AMediaDrm_setOnEventListener(mDrm, listener);
+ break;
+ }
+ }
+}
+
+void NdkMediaDrmFuzzer::invokeDrmPropertyAPI() {
+ int32_t propertyAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxpropertyAPIs);
+ switch (propertyAPI) {
+ case 0: { // set property byte array
+ uint8_t value[kMediaUUIdSize];
+ std::string name =
+ mFdp.ConsumeBool() ? kPropertyName : mFdp.ConsumeRandomLengthString(kMaxBytes);
+ const char* propertyName = name.c_str();
+ AMediaDrm_setPropertyByteArray(mDrm, propertyName, value, sizeof(value));
+ break;
+ }
+ case 1: { // get property in byte array
+ AMediaDrmByteArray array;
+ std::string name =
+ mFdp.ConsumeBool() ? kPropertyName : mFdp.ConsumeRandomLengthString(kMaxBytes);
+ const char* propertyName = name.c_str();
+ AMediaDrm_getPropertyByteArray(mDrm, propertyName, &array);
+ break;
+ }
+ case 2: { // set string type property
+ std::string propertyName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ std::string value = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ AMediaDrm_setPropertyString(mDrm, propertyName.c_str(), value.c_str());
+ break;
+ }
+ case 3:
+ default: { // get property in string
+ const char* stringValue = nullptr;
+ std::string propertyName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ AMediaDrm_getPropertyString(mDrm, propertyName.c_str(), &stringValue);
+ break;
+ }
+ }
+}
+
+void NdkMediaDrmFuzzer::invokeDrmDecryptEncryptAPI() {
+ int32_t decryptEncryptAPI =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxdecryptEncryptAPIs);
+ switch (decryptEncryptAPI) {
+ case 0: { // Check if crypto scheme is supported
+ std::string mimeType = mFdp.ConsumeBool() ? mFdp.PickValueInArray(kMimeType)
+ : mFdp.ConsumeRandomLengthString(kMaxBytes);
+ AMediaDrm_isCryptoSchemeSupported(kClearKeyUUID, mimeType.c_str());
+ break;
+ }
+ case 1: { // get a provision request byte array
+ const uint8_t* legacyRequest;
+ size_t legacyRequestSize = 1;
+ const char* legacyDefaultUrl;
+ AMediaDrm_getProvisionRequest(mDrm, &legacyRequest, &legacyRequestSize,
+ &legacyDefaultUrl);
+ break;
+ }
+ case 2: { // provide a response to the DRM engine plugin
+ const int32_t provisionresponseSize = mFdp.ConsumeIntegralInRange<size_t>(
+ kMinProvisionResponseSize, kMaxProvisionResponseSize);
+ uint8_t provisionResponse[provisionresponseSize];
+ AMediaDrm_provideProvisionResponse(mDrm, provisionResponse, sizeof(provisionResponse));
+ break;
+ }
+ case 3: { // get key request
+ const uint8_t* keyRequest = nullptr;
+ size_t keyRequestSize = 0;
+ std::string mimeType = mFdp.ConsumeBool() ? mFdp.PickValueInArray(kMimeType)
+ : mFdp.ConsumeRandomLengthString(kMaxBytes);
+ size_t numOptionalParameters =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinParamVal, kMaxParamVal);
+ AMediaDrmKeyValue optionalParameters[numOptionalParameters];
+ std::string keys[numOptionalParameters];
+ std::string values[numOptionalParameters];
+ for (int i = 0; i < numOptionalParameters; ++i) {
+ keys[i] = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ values[i] = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ optionalParameters[i].mKey = keys[i].c_str();
+ optionalParameters[i].mValue = values[i].c_str();
+ }
+ AMediaDrmKeyType keyType = (AMediaDrmKeyType)mFdp.ConsumeIntegralInRange<int>(
+ KEY_TYPE_STREAMING, KEY_TYPE_RELEASE);
+ AMediaDrm_getKeyRequest(mDrm, &mSessionId, kClearkeyPssh, sizeof(kClearkeyPssh),
+ mimeType.c_str(), keyType, optionalParameters,
+ numOptionalParameters, &keyRequest, &keyRequestSize);
+ break;
+ }
+ case 4: { // query key status
+ size_t numPairs = mFdp.ConsumeIntegralInRange<size_t>(kMinParamVal, kMaxParamVal);
+ AMediaDrmKeyValue keyStatus[numPairs];
+ AMediaDrm_queryKeyStatus(mDrm, &mSessionId, keyStatus, &numPairs);
+ break;
+ }
+ case 5: { // provide key response
+ std::string key = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ const char* keyResponse = key.c_str();
+ AMediaDrmKeySetId keySetId;
+ AMediaDrm_provideKeyResponse(mDrm, &mSessionId,
+ reinterpret_cast<const uint8_t*>(keyResponse),
+ sizeof(keyResponse), &keySetId);
+ break;
+ }
+ case 6: { // restore key
+ AMediaDrmKeySetId keySetId;
+ AMediaDrm_restoreKeys(mDrm, &mSessionId, &keySetId);
+ break;
+ }
+
+ case 7: { // Check signature verification using the specified Algorithm
+ std::string algorithm = kMacAlgorithm[mFdp.ConsumeBool()];
+ std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> message = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaDrm_verify(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), message.data(),
+ message.size(), signature, sizeof(signature));
+ break;
+ }
+ case 8: { // Generate a signature using the specified Algorithm
+ std::string algorithm = kMacAlgorithm[mFdp.ConsumeBool()];
+ std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> message = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ size_t signatureSize = sizeof(signature);
+ AMediaDrm_sign(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), message.data(),
+ message.size(), signature, &signatureSize);
+ break;
+ }
+ case 9: { // Decrypt the data using algorithm
+ std::string algorithm = kCipherAlgorithm[mFdp.ConsumeBool()];
+ std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> iv = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> input = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ uint8_t output[kMessageSize];
+ AMediaDrm_decrypt(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), iv.data(),
+ input.data(), output, input.size());
+ break;
+ }
+ case 10:
+ default: { // Encrypt the data using algorithm
+ std::string algorithm = kCipherAlgorithm[mFdp.ConsumeBool()];
+ std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> iv = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> input = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ uint8_t output[kMessageSize];
+ AMediaDrm_encrypt(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), iv.data(),
+ input.data(), output, input.size());
+ break;
+ }
+ }
+ AMediaDrm_removeKeys(mDrm, &mSessionId);
+}
+
+void NdkMediaDrmFuzzer::invokeNdkDrm() {
+ while (mFdp.remaining_bytes() > 0) {
+ // The API is called at start as it creates a AMediaDrm Object.
+ // mDrm AMediaDrm object is used in the below APIs.
+ invokeDrmCreatePlugin();
+ if (mDrm) {
+ // The API opens session and returns "mSessionId" session Id.
+ // "mSessionId" is required in the below APIs.
+ AMediaDrm_openSession(mDrm, &mSessionId);
+ int32_t ndkDrmAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxndkDrmAPIs);
+ switch (ndkDrmAPI) {
+ case 0: {
+ invokeDrmDecryptEncryptAPI();
+ break;
+ }
+ case 1: {
+ invokeDrmPropertyAPI();
+ break;
+ }
+ case 2: {
+ invokeDrmSetListener();
+ break;
+ }
+ case 3:
+ default: {
+ invokeDrmSecureStopAPI();
+ break;
+ }
+ }
+ AMediaDrm_closeSession(mDrm, &mSessionId);
+ AMediaDrm_release(mDrm);
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ NdkMediaDrmFuzzer ndkMediaDrmFuzzer(data, size);
+ ndkMediaDrmFuzzer.invokeNdkDrm();
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp b/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp
new file mode 100644
index 0000000..9bbb79c
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_process.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaExtractor.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+constexpr int32_t kCaseStart = 0;
+constexpr int32_t kCaseEnd = 8;
+constexpr float kMinDataSizeFactor = 0.5;
+constexpr int32_t kMaxIterations = 1000;
+const std::string kPathPrefix = "file://";
+
+constexpr SeekMode kSeekMode[] = {AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC,
+ AMEDIAEXTRACTOR_SEEK_NEXT_SYNC,
+ AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC};
+
+class NdkExtractorFuzzer {
+ public:
+ NdkExtractorFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mDataSourceFd = mkstemp(mTestPath);
+ std::vector<char> dataBuffer = mFdp.ConsumeBytes<char>(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinDataSizeFactor * size, size));
+ mDataSize = dataBuffer.size();
+ write(mDataSourceFd, dataBuffer.data(), dataBuffer.size());
+ };
+
+ ~NdkExtractorFuzzer() {
+ close(mDataSourceFd);
+ remove(mTestPath);
+ };
+
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+ int32_t mDataSourceFd = 0;
+ int32_t mDataSize = 0;
+
+ // Defined a mutable TestSource file path for mkstemp().
+ char mTestPath[64] = "/data/local/tmp/TestSource_XXXXXX";
+};
+
+void NdkExtractorFuzzer::process() {
+ AMediaExtractor* mMediaExtractor = AMediaExtractor_new();
+ AMediaDataSource* mDataSource = nullptr;
+
+ if (mFdp.ConsumeBool()) {
+ AMediaExtractor_setDataSourceFd(mMediaExtractor, mDataSourceFd, 0, mDataSize);
+ } else {
+ mDataSource = AMediaDataSource_newUri((kPathPrefix + mTestPath).c_str(), 0 /* numkeys */,
+ nullptr /* keyvalues */);
+ AMediaExtractor_setDataSourceCustom(mMediaExtractor, mDataSource);
+ }
+
+ /**
+ * Limiting the number of iterations of while loop
+ * to prevent a possible timeout.
+ */
+ int32_t count = 0;
+ while (mFdp.remaining_bytes() && count++ < kMaxIterations) {
+ switch (mFdp.ConsumeIntegralInRange<int32_t>(kCaseStart, kCaseEnd)) {
+ case 0:{
+ AMediaExtractor_selectTrack(mMediaExtractor,
+ mFdp.ConsumeIntegral<size_t>() /* idx */);
+ break;
+ }
+ case 1:{
+ AMediaExtractor_unselectTrack(mMediaExtractor,
+ mFdp.ConsumeIntegral<size_t>() /* idx */);
+ break;
+ }
+ case 2:{
+ int32_t sampleSize = AMediaExtractor_getSampleSize(mMediaExtractor);
+ if (sampleSize > 0) {
+ std::vector<uint8_t> buffer(sampleSize);
+ AMediaExtractor_readSampleData(
+ mMediaExtractor, buffer.data(),
+ mFdp.ConsumeIntegralInRange<size_t>(0, sampleSize) /* capacity */);
+ }
+ break;
+ }
+ case 3:{
+ AMediaExtractor_getSampleFlags(mMediaExtractor);
+ break;
+ }
+ case 4:{
+ AMediaExtractor_getSampleCryptoInfo(mMediaExtractor);
+ break;
+ }
+ case 5:{
+ AMediaExtractor_getPsshInfo(mMediaExtractor);
+ break;
+ }
+ case 6:{
+ AMediaExtractor_advance(mMediaExtractor);
+ break;
+ }
+ case 7:{
+ AMediaFormat* mediaFormat = mFdp.ConsumeBool() ? AMediaFormat_new() : nullptr;
+ AMediaExtractor_getSampleFormat(mMediaExtractor, mediaFormat);
+ AMediaFormat_delete(mediaFormat);
+ break;
+ }
+ case 8:{
+ AMediaExtractor_seekTo(mMediaExtractor,
+ mFdp.ConsumeIntegral<int64_t>() /* seekPosUs */,
+ mFdp.PickValueInArray(kSeekMode) /* mode */);
+ break;
+ }
+ };
+ }
+
+ AMediaDataSource_delete(mDataSource);
+ AMediaExtractor_delete(mMediaExtractor);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ /**
+ * Create a threadpool for incoming binder transactions,
+ * without this extractor results in a DoS after few instances.
+ */
+ ABinderProcess_startThreadPool();
+
+ NdkExtractorFuzzer ndkExtractorFuzzer(data, size);
+ ndkExtractorFuzzer.process();
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp b/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp
new file mode 100644
index 0000000..6c11798
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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 <cutils/native_handle.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gui/BufferQueue.h>
+#include <media/NdkImageReader.h>
+
+constexpr int32_t kMaxSize = INT_MAX;
+constexpr int32_t kMinSize = 1;
+constexpr int32_t kMinImages = 1;
+
+class NdkImageReaderFuzzer {
+ public:
+ NdkImageReaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+ static void onImageAvailable(void*, AImageReader*){};
+ static void onBufferRemoved(void*, AImageReader*, AHardwareBuffer*){};
+};
+
+void NdkImageReaderFuzzer::process() {
+ AImageReader* reader = nullptr;
+ AImage* img = nullptr;
+ native_handle_t* handle = nullptr;
+ int32_t* acquireFenceFd = nullptr;
+ int32_t imageWidth = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ int32_t imageHeight = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ int32_t imageFormat = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ int32_t imageUsage = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ int32_t imageMaxCount = mFdp.ConsumeIntegralInRange<int32_t>(
+ kMinImages, android::BufferQueue::MAX_MAX_ACQUIRED_BUFFERS);
+ AImageReader_ImageListener readerAvailableCb{this, NdkImageReaderFuzzer::onImageAvailable};
+ AImageReader_BufferRemovedListener readerDetachedCb{this, onBufferRemoved};
+
+ if (mFdp.ConsumeBool()) {
+ AImageReader_new(imageWidth, imageHeight, imageFormat, imageMaxCount, &reader);
+ } else {
+ AImageReader_newWithUsage(imageWidth, imageHeight, imageFormat, imageUsage, imageMaxCount,
+ &reader);
+ }
+ while (mFdp.remaining_bytes()) {
+ auto ndkImageFunction = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { AImageReader_acquireNextImage(reader, &img); },
+ [&]() { AImageReader_acquireLatestImage(reader, &img); },
+ [&]() { AImageReader_setImageListener(reader, &readerAvailableCb); },
+ [&]() { AImageReader_acquireNextImageAsync(reader, &img, acquireFenceFd); },
+ [&]() { AImageReader_acquireLatestImageAsync(reader, &img, acquireFenceFd); },
+ [&]() { AImageReader_setBufferRemovedListener(reader, &readerDetachedCb); },
+ [&]() { AImageReader_getWindowNativeHandle(reader, &handle); },
+ });
+ ndkImageFunction();
+ }
+ AImageReader_delete(reader);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ NdkImageReaderFuzzer ndkImageReaderFuzzer(data, size);
+ ndkImageReaderFuzzer.process();
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
new file mode 100644
index 0000000..c19ea13
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2022 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 <datasource/FileSource.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaFormat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <fstream>
+
+const char* kValidKeys[] = {
+ AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
+ AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
+ AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
+ AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+ AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
+ AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_AAC_PROFILE,
+ AMEDIAFORMAT_KEY_AAC_SBR_MODE,
+ AMEDIAFORMAT_KEY_ALBUM,
+ AMEDIAFORMAT_KEY_ALBUMART,
+ AMEDIAFORMAT_KEY_ALBUMARTIST,
+ AMEDIAFORMAT_KEY_ARTIST,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID,
+ AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID,
+ AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
+ AMEDIAFORMAT_KEY_AUTHOR,
+ AMEDIAFORMAT_KEY_BITRATE_MODE,
+ AMEDIAFORMAT_KEY_BIT_RATE,
+ AMEDIAFORMAT_KEY_BITS_PER_SAMPLE,
+ AMEDIAFORMAT_KEY_CAPTURE_RATE,
+ AMEDIAFORMAT_KEY_CDTRACKNUMBER,
+ AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_CHANNEL_MASK,
+ AMEDIAFORMAT_KEY_COLOR_FORMAT,
+ AMEDIAFORMAT_KEY_COLOR_RANGE,
+ AMEDIAFORMAT_KEY_COLOR_STANDARD,
+ AMEDIAFORMAT_KEY_COLOR_TRANSFER,
+ AMEDIAFORMAT_KEY_COMPILATION,
+ AMEDIAFORMAT_KEY_COMPLEXITY,
+ AMEDIAFORMAT_KEY_COMPOSER,
+ AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+ AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+ AMEDIAFORMAT_KEY_CRYPTO_IV,
+ AMEDIAFORMAT_KEY_CRYPTO_KEY,
+ AMEDIAFORMAT_KEY_CRYPTO_MODE,
+ AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+ AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
+ AMEDIAFORMAT_KEY_CSD,
+ AMEDIAFORMAT_KEY_CSD_0,
+ AMEDIAFORMAT_KEY_CSD_1,
+ AMEDIAFORMAT_KEY_CSD_2,
+ AMEDIAFORMAT_KEY_CSD_AVC,
+ AMEDIAFORMAT_KEY_CSD_HEVC,
+ AMEDIAFORMAT_KEY_D263,
+ AMEDIAFORMAT_KEY_DATE,
+ AMEDIAFORMAT_KEY_DISCNUMBER,
+ AMEDIAFORMAT_KEY_DISPLAY_CROP,
+ AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
+ AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
+ AMEDIAFORMAT_KEY_DURATION,
+ AMEDIAFORMAT_KEY_ENCODER_DELAY,
+ AMEDIAFORMAT_KEY_ENCODER_PADDING,
+ AMEDIAFORMAT_KEY_ESDS,
+ AMEDIAFORMAT_KEY_EXIF_OFFSET,
+ AMEDIAFORMAT_KEY_EXIF_SIZE,
+ AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
+ AMEDIAFORMAT_KEY_FRAME_COUNT,
+ AMEDIAFORMAT_KEY_FRAME_RATE,
+ AMEDIAFORMAT_KEY_GENRE,
+ AMEDIAFORMAT_KEY_GRID_COLUMNS,
+ AMEDIAFORMAT_KEY_GRID_ROWS,
+ AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
+ AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
+ AMEDIAFORMAT_KEY_HDR10_PLUS_INFO,
+ AMEDIAFORMAT_KEY_HEIGHT,
+ AMEDIAFORMAT_KEY_ICC_PROFILE,
+ AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
+ AMEDIAFORMAT_KEY_IS_ADTS,
+ AMEDIAFORMAT_KEY_IS_AUTOSELECT,
+ AMEDIAFORMAT_KEY_IS_DEFAULT,
+ AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
+ AMEDIAFORMAT_KEY_IS_SYNC_FRAME,
+ AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+ AMEDIAFORMAT_KEY_LANGUAGE,
+ AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK,
+ AMEDIAFORMAT_KEY_LATENCY,
+ AMEDIAFORMAT_KEY_LEVEL,
+ AMEDIAFORMAT_KEY_LOCATION,
+ AMEDIAFORMAT_KEY_LOOP,
+ AMEDIAFORMAT_KEY_LOW_LATENCY,
+ AMEDIAFORMAT_KEY_LYRICIST,
+ AMEDIAFORMAT_KEY_MANUFACTURER,
+ AMEDIAFORMAT_KEY_MAX_BIT_RATE,
+ AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
+ AMEDIAFORMAT_KEY_MAX_HEIGHT,
+ AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
+ AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
+ AMEDIAFORMAT_KEY_MAX_WIDTH,
+ AMEDIAFORMAT_KEY_MIME,
+ AMEDIAFORMAT_KEY_MPEG_USER_DATA,
+ AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER,
+ AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
+ AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
+ AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
+ AMEDIAFORMAT_KEY_OPERATING_RATE,
+ AMEDIAFORMAT_KEY_PCM_ENCODING,
+ AMEDIAFORMAT_KEY_PICTURE_TYPE,
+ AMEDIAFORMAT_KEY_PRIORITY,
+ AMEDIAFORMAT_KEY_PROFILE,
+ AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN,
+ AMEDIAFORMAT_KEY_PSSH,
+ AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
+ AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
+ AMEDIAFORMAT_KEY_ROTATION,
+ AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET,
+ AMEDIAFORMAT_KEY_SAMPLE_RATE,
+ AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND,
+ AMEDIAFORMAT_KEY_SAR_HEIGHT,
+ AMEDIAFORMAT_KEY_SAR_WIDTH,
+ AMEDIAFORMAT_KEY_SEI,
+ AMEDIAFORMAT_KEY_SLICE_HEIGHT,
+ AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS,
+ AMEDIAFORMAT_KEY_STRIDE,
+ AMEDIAFORMAT_KEY_TARGET_TIME,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
+ AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
+ AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+ AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C,
+ AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+ AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT,
+ AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
+ AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH,
+ AMEDIAFORMAT_KEY_TILE_HEIGHT,
+ AMEDIAFORMAT_KEY_TILE_WIDTH,
+ AMEDIAFORMAT_KEY_TIME_US,
+ AMEDIAFORMAT_KEY_TITLE,
+ AMEDIAFORMAT_KEY_TRACK_ID,
+ AMEDIAFORMAT_KEY_TRACK_INDEX,
+ AMEDIAFORMAT_KEY_VALID_SAMPLES,
+ AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL,
+ AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE,
+ AMEDIAFORMAT_VIDEO_QP_B_MAX,
+ AMEDIAFORMAT_VIDEO_QP_B_MIN,
+ AMEDIAFORMAT_VIDEO_QP_I_MAX,
+ AMEDIAFORMAT_VIDEO_QP_I_MIN,
+ AMEDIAFORMAT_VIDEO_QP_MAX,
+ AMEDIAFORMAT_VIDEO_QP_MIN,
+ AMEDIAFORMAT_VIDEO_QP_P_MAX,
+ AMEDIAFORMAT_VIDEO_QP_P_MIN,
+ AMEDIAFORMAT_KEY_WIDTH,
+ AMEDIAFORMAT_KEY_XMP_OFFSET,
+ AMEDIAFORMAT_KEY_XMP_SIZE,
+ AMEDIAFORMAT_KEY_YEAR,
+};
+constexpr size_t kMinBytes = 0;
+constexpr size_t kMaxBytes = 1000;
+constexpr size_t kMinChoice = 0;
+constexpr size_t kMaxChoice = 9;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ AMediaFormat* mediaFormat = AMediaFormat_new();
+ while (fdp.remaining_bytes()) {
+ const char* name = nullptr;
+ std::string nameString;
+ if (fdp.ConsumeBool()) {
+ nameString =
+ fdp.ConsumeBool()
+ ? fdp.PickValueInArray(kValidKeys)
+ : fdp.ConsumeRandomLengthString(
+ fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ name = nameString.c_str();
+ }
+ switch (fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice)) {
+ case 0: {
+ AMediaFormat_setInt32(mediaFormat, name,
+ fdp.ConsumeIntegral<int32_t>() /* value */);
+ break;
+ }
+ case 1: {
+ AMediaFormat_setInt64(mediaFormat, name,
+ fdp.ConsumeIntegral<int64_t>() /* value */);
+ break;
+ }
+ case 2: {
+ AMediaFormat_setFloat(mediaFormat, name,
+ fdp.ConsumeFloatingPoint<float>() /* value */);
+ break;
+ }
+ case 3: {
+ AMediaFormat_setDouble(mediaFormat, name,
+ fdp.ConsumeFloatingPoint<double>() /* value */);
+ break;
+ }
+ case 4: {
+ AMediaFormat_setSize(mediaFormat, name, fdp.ConsumeIntegral<size_t>() /* value */);
+ break;
+ }
+ case 5: {
+ std::string value;
+ if (fdp.ConsumeBool()) {
+ value = fdp.ConsumeRandomLengthString(
+ fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ }
+ AMediaFormat_setString(mediaFormat, name,
+ fdp.ConsumeBool() ? nullptr : value.c_str());
+ break;
+ }
+ case 6: {
+ AMediaFormat_setRect(mediaFormat, name, fdp.ConsumeIntegral<int32_t>() /* left */,
+ fdp.ConsumeIntegral<int32_t>() /* top */,
+ fdp.ConsumeIntegral<int32_t>() /* bottom */,
+ fdp.ConsumeIntegral<int32_t>() /* right */);
+ break;
+ }
+ case 7: {
+ std::vector<uint8_t> bufferData = fdp.ConsumeBytes<uint8_t>(
+ fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaFormat_setBuffer(mediaFormat, name, bufferData.data(), bufferData.size());
+ break;
+ }
+ case 8: {
+ AMediaFormat_toString(mediaFormat);
+ break;
+ }
+ default: {
+ AMediaFormat* format = fdp.ConsumeBool() ? nullptr : AMediaFormat_new();
+ AMediaFormat_copy(format, mediaFormat);
+ AMediaFormat_delete(format);
+ break;
+ }
+ }
+ }
+ AMediaFormat_clear(mediaFormat);
+ AMediaFormat_delete(mediaFormat);
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp
new file mode 100644
index 0000000..8c49d28
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_process.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaMuxer.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+const std::string kMuxerFile = "mediaMuxer";
+const std::string kAppendFile = "mediaAppend";
+constexpr size_t kMinBytes = 0;
+constexpr size_t kMaxBytes = 1000;
+constexpr size_t kMinChoice = 0;
+constexpr size_t kMaxChoice = 7;
+constexpr size_t kMaxStringLength = 20;
+constexpr size_t kOffset = 0;
+
+constexpr OutputFormat kOutputFormat[] = {AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4,
+ AMEDIAMUXER_OUTPUT_FORMAT_WEBM,
+ AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP};
+constexpr AppendMode kAppendMode[] = {AMEDIAMUXER_APPEND_IGNORE_LAST_VIDEO_GOP,
+ AMEDIAMUXER_APPEND_TO_EXISTING_DATA};
+
+const std::string kAudioMimeType[] = {"audio/3gpp", "audio/amr-wb", "audio/mp4a-latm",
+ "audio/flac", "audio/vorbis", "audio/opus"};
+
+const std::string kVideoMimeType[] = {"video/x-vnd.on2.vp8", "video/x-vnd.on2.vp9", "video/av01",
+ "video/avc", "video/hevc", "video/mp4v-es",
+ "video/3gpp"};
+
+void getSampleAudioFormat(FuzzedDataProvider& fdp, AMediaFormat* format) {
+ std::string mimeType = fdp.ConsumeBool() ? fdp.ConsumeRandomLengthString(kMaxStringLength)
+ : fdp.PickValueInArray(kAudioMimeType);
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mimeType.c_str());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt64(format, AMEDIAFORMAT_KEY_DURATION, fdp.ConsumeIntegral<int64_t>());
+}
+
+void getSampleVideoFormat(FuzzedDataProvider& fdp, AMediaFormat* format) {
+ std::string mimeType = fdp.ConsumeBool() ? fdp.ConsumeRandomLengthString(kMaxStringLength)
+ : fdp.PickValueInArray(kAudioMimeType);
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mimeType.c_str());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, fdp.ConsumeIntegral<int32_t>());
+ AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+ fdp.ConsumeFloatingPoint<float>());
+ AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_CAPTURE_RATE, fdp.ConsumeFloatingPoint<float>());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, fdp.ConsumeIntegral<int32_t>());
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ /**
+ * Create a threadpool for incoming binder transactions,
+ * without this muxer results in a DoS after few instances.
+ */
+ ABinderProcess_startThreadPool();
+ FuzzedDataProvider fdp(data, size);
+ /**
+ * memfd_create() creates an anonymous file and returns a file
+ * descriptor that refers to it. MFD_ALLOW_SEALING allow sealing
+ * operations on this file.
+ */
+ int32_t fd = -1;
+ AMediaMuxer* muxer = nullptr;
+ if (fdp.ConsumeBool()) {
+ fd = memfd_create(kMuxerFile.c_str(), MFD_ALLOW_SEALING);
+ muxer = AMediaMuxer_new(fd, fdp.ConsumeBool()
+ ? fdp.PickValueInArray(kOutputFormat)
+ : (OutputFormat)fdp.ConsumeIntegral<int32_t>());
+ } else {
+ fd = memfd_create(kAppendFile.c_str(), MFD_ALLOW_SEALING);
+ std::vector<uint8_t> appendData =
+ fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ write(fd, appendData.data(), appendData.size());
+ muxer = AMediaMuxer_append(fd, fdp.PickValueInArray(kAppendMode) /* mode */);
+ }
+ if (!muxer) {
+ close(fd);
+ return 0;
+ }
+ AMediaFormat* mediaFormat = nullptr;
+ ssize_t trackIdx = 0;
+ while (fdp.remaining_bytes()) {
+ int32_t kSwitchChoice = fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice);
+ switch (kSwitchChoice) {
+ case 0: {
+ AMediaMuxer_setLocation(muxer, fdp.ConsumeFloatingPoint<float>() /* latitude */,
+ fdp.ConsumeFloatingPoint<float>() /* longitude */);
+ break;
+ }
+ case 1: {
+ AMediaMuxer_setOrientationHint(muxer, fdp.ConsumeIntegral<int32_t>() /* degrees */);
+ break;
+ }
+ case 2: {
+ AMediaMuxer_start(muxer);
+ break;
+ }
+ case 3: {
+ AMediaMuxer_stop(muxer);
+ break;
+ }
+ case 4: {
+ AMediaMuxer_getTrackCount(muxer);
+ break;
+ }
+ case 5: {
+ AMediaFormat* getFormat =
+ AMediaMuxer_getTrackFormat(muxer, fdp.ConsumeIntegral<size_t>() /* idx */);
+ AMediaFormat_delete(getFormat);
+ break;
+ }
+ case 6: {
+ mediaFormat = AMediaFormat_new();
+ fdp.ConsumeBool() ? getSampleAudioFormat(fdp, mediaFormat)
+ : getSampleVideoFormat(fdp, mediaFormat);
+ trackIdx = AMediaMuxer_addTrack(muxer, mediaFormat);
+ AMediaFormat_delete(mediaFormat);
+ break;
+ }
+ default: {
+ std::vector<uint8_t> sampleData = fdp.ConsumeBytes<uint8_t>(
+ fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaCodecBufferInfo codecBuffer;
+ codecBuffer.size = sampleData.size();
+ codecBuffer.offset = kOffset;
+ codecBuffer.presentationTimeUs = fdp.ConsumeIntegral<int64_t>();
+ codecBuffer.flags = fdp.ConsumeIntegral<uint32_t>();
+ AMediaMuxer_writeSampleData(
+ muxer,
+ fdp.ConsumeBool() ? trackIdx : fdp.ConsumeIntegral<size_t>() /* trackIdx */,
+ sampleData.data(), &codecBuffer);
+ break;
+ }
+ }
+ }
+ AMediaMuxer_delete(muxer);
+ close(fd);
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp b/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp
new file mode 100644
index 0000000..d348f66
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 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 <NdkMediaCodecFuzzerBase.h>
+
+constexpr int32_t kMaxNdkCodecAPIs = 12;
+
+class NdkSyncCodecFuzzer : public NdkMediaCodecFuzzerBase {
+ public:
+ NdkSyncCodecFuzzer(const uint8_t* data, size_t size)
+ : NdkMediaCodecFuzzerBase(), mFdp(data, size) {
+ setFdp(&mFdp);
+ };
+ void invokeSyncCodeConfigAPI();
+
+ static void CodecOnFrameRendered(AMediaCodec* codec, void* userdata, int64_t mediaTimeUs,
+ int64_t systemNano) {
+ (void)codec;
+ (void)userdata;
+ (void)mediaTimeUs;
+ (void)systemNano;
+ };
+
+ private:
+ FuzzedDataProvider mFdp;
+ AMediaCodec* mCodec = nullptr;
+ void invokekSyncCodecAPIs(bool isEncoder);
+};
+
+void NdkSyncCodecFuzzer::invokekSyncCodecAPIs(bool isEncoder) {
+ ANativeWindow* nativeWindow = nullptr;
+ int32_t numOfFrames = mFdp.ConsumeIntegralInRange<size_t>(kMinIterations, kMaxIterations);
+ int32_t count = 0;
+ while (++count <= numOfFrames) {
+ int32_t ndkcodecAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxNdkCodecAPIs);
+ switch (ndkcodecAPI) {
+ case 0: { // configure the codec
+ AMediaCodec_configure(mCodec, getCodecFormat(), nativeWindow, nullptr /* crypto */,
+ (isEncoder ? AMEDIACODEC_CONFIGURE_FLAG_ENCODE : 0));
+ break;
+ }
+ case 1: { // start codec
+ AMediaCodec_start(mCodec);
+ break;
+ }
+ case 2: { // stop codec
+ AMediaCodec_stop(mCodec);
+ break;
+ }
+ case 3: { // create persistent input surface
+ AMediaCodec_createPersistentInputSurface(&nativeWindow);
+ break;
+ }
+ case 4: { // buffer operation APIs
+ invokeInputBufferOperationAPI(mCodec);
+ break;
+ }
+ case 5: {
+ invokeOutputBufferOperationAPI(mCodec);
+ break;
+ }
+ case 6: { // get input and output Format
+ invokeCodecFormatAPI(mCodec);
+ break;
+ }
+ case 7: {
+ AMediaCodec_signalEndOfInputStream(mCodec);
+ break;
+ }
+ case 8: { // set parameters
+ // Create a new parameter and set
+ AMediaFormat* params = AMediaFormat_new();
+ AMediaFormat_setInt32(
+ params, "video-bitrate",
+ mFdp.ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue));
+ AMediaCodec_setParameters(mCodec, params);
+ AMediaFormat_delete(params);
+ break;
+ }
+ case 9: { // flush codec
+ AMediaCodec_flush(mCodec);
+ if (mFdp.ConsumeBool()) {
+ AMediaCodec_start(mCodec);
+ }
+ break;
+ }
+ case 10: { // get the codec name
+ char* name = nullptr;
+ AMediaCodec_getName(mCodec, &name);
+ AMediaCodec_releaseName(mCodec, name);
+ break;
+ }
+ case 11: { // set callback API for frame render output
+ std::vector<uint8_t> userData = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaCodecOnFrameRendered callback = CodecOnFrameRendered;
+ AMediaCodec_setOnFrameRenderedCallback(mCodec, callback, userData.data());
+ break;
+ }
+ case 12:
+ default: { // set persistent input surface
+ AMediaCodec_setInputSurface(mCodec, nativeWindow);
+ }
+ }
+ }
+ if (nativeWindow) {
+ ANativeWindow_release(nativeWindow);
+ }
+}
+
+void NdkSyncCodecFuzzer::invokeSyncCodeConfigAPI() {
+ while (mFdp.remaining_bytes() > 0) {
+ bool isEncoder = mFdp.ConsumeBool();
+ mCodec = createCodec(isEncoder, mFdp.ConsumeBool() /* isCodecForClient */);
+ if (mCodec) {
+ invokekSyncCodecAPIs(isEncoder);
+ AMediaCodec_delete(mCodec);
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ NdkSyncCodecFuzzer ndkSyncCodecFuzzer(data, size);
+ ndkSyncCodecFuzzer.invokeSyncCodeConfigAPI();
+ return 0;
+}
diff --git a/media/ndk/tests/NdkMediaFormat_test.cpp b/media/ndk/tests/NdkMediaFormat_test.cpp
index 668d0a4..18690b8 100644
--- a/media/ndk/tests/NdkMediaFormat_test.cpp
+++ b/media/ndk/tests/NdkMediaFormat_test.cpp
@@ -51,6 +51,13 @@
EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
EXPECT_EQ(i32, 5);
+ // verify detecting some bad parameters.
+ AMediaFormat_setInt32(nullptr, "whatever", 6);
+ AMediaFormat_setInt32(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getInt32(nullptr, "whatever", &i32));
+ EXPECT_FALSE(AMediaFormat_getInt32(fmt1, nullptr, &i32));
+
AMediaFormat_delete(fmt1);
}
@@ -67,6 +74,13 @@
EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
EXPECT_EQ(i64, -1);
+ // verify detecting some bad parameters.
+ AMediaFormat_setInt64(nullptr, "whatever", 6);
+ AMediaFormat_setInt64(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getInt64(nullptr, "whatever", &i64));
+ EXPECT_FALSE(AMediaFormat_getInt64(fmt1, nullptr, &i64));
+
AMediaFormat_delete(fmt1);
}
@@ -80,6 +94,13 @@
EXPECT_TRUE(AMediaFormat_getSize(fmt1, "medium", &size));
EXPECT_EQ(size, 10);
+ // verify detecting some bad parameters.
+ AMediaFormat_setSize(nullptr, "whatever", 6);
+ AMediaFormat_setSize(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getSize(nullptr, "whatever", &size));
+ EXPECT_FALSE(AMediaFormat_getSize(fmt1, nullptr, &size));
+
AMediaFormat_delete(fmt1);
}
@@ -90,6 +111,14 @@
AMediaFormat_setFloat(fmt1, "ship", 0.5);
EXPECT_TRUE(AMediaFormat_getFloat(fmt1, "boat", &f));
EXPECT_EQ(f, 1.5);
+
+ // verify detecting some bad parameters.
+ AMediaFormat_setFloat(nullptr, "whatever", 1.5);
+ AMediaFormat_setFloat(fmt1, nullptr, 1.5);
+
+ EXPECT_FALSE(AMediaFormat_getFloat(nullptr, "whatever", &f));
+ EXPECT_FALSE(AMediaFormat_getFloat(fmt1, nullptr, &f));
+
AMediaFormat_delete(fmt1);
}
@@ -100,6 +129,14 @@
AMediaFormat_setDouble(fmt1, "dip", 0.5);
EXPECT_TRUE(AMediaFormat_getDouble(fmt1, "trouble", &d));
EXPECT_EQ(d, 100.5);
+
+ // verify detecting some bad parameters.
+ AMediaFormat_setDouble(nullptr, "whatever", 1.5);
+ AMediaFormat_setDouble(fmt1, nullptr, 1.5);
+
+ EXPECT_FALSE(AMediaFormat_getDouble(nullptr, "whatever", &d));
+ EXPECT_FALSE(AMediaFormat_getDouble(fmt1, nullptr, &d));
+
AMediaFormat_delete(fmt1);
}
@@ -111,8 +148,16 @@
AMediaFormat_setString(fmt1, "stringtheory", content);
EXPECT_TRUE(AMediaFormat_getString(fmt1, "stringtheory", &out));
EXPECT_NE(out, nullptr);
+ EXPECT_NE(out, content); // should not be the original
EXPECT_EQ(strcmp(out,content), 0);
+ // verify detecting some bad parameters.
+ AMediaFormat_setString(nullptr, "whatever", content);
+ AMediaFormat_setString(fmt1, nullptr, content);
+
+ EXPECT_FALSE(AMediaFormat_getString(nullptr, "whatever", &out));
+ EXPECT_FALSE(AMediaFormat_getString(fmt1, nullptr, &out));
+
AMediaFormat_delete(fmt1);
}
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
index 40a8c9e..ba3e81a 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.h
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -50,7 +50,7 @@
{
lock_guard<mutex> lock(mMutex);
needsNotify = mQueue.empty();
- mQueue.push(move(elem));
+ mQueue.push(std::move(elem));
}
if (needsNotify) mQueueNotEmptyCondition.notify_one();
}
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 04d9ed9..698752f 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -28,19 +28,35 @@
"-Werror",
"-Wextra",
],
+ sanitize: {
+ cfi: true,
+ integer_overflow: true,
+ },
+ target: {
+ host: {
+ sanitize: {
+ cfi: false,
+ },
+ },
+ },
}
filegroup {
name: "libmediautils_core_srcs",
srcs: [
"AImageReaderUtils.cpp",
+ "BatteryNotifier.cpp",
"ISchedulingPolicyService.cpp",
"Library.cpp",
"MediaUtilsDelayed.cpp",
"MethodStatistics.cpp",
"Process.cpp",
+ "ProcessInfo.cpp",
"SchedulingPolicyService.cpp",
+ "ServiceUtilities.cpp",
"ThreadSnapshot.cpp",
+ "TimeCheck.cpp",
+ "TimerThread.cpp",
],
}
@@ -55,47 +71,15 @@
export_include_dirs: ["include"],
}
-cc_library {
- name: "libmediautils_core",
- defaults: ["libmediautils_defaults"],
- host_supported: true,
- srcs: [":libmediautils_core_srcs"],
- shared_libs: [
- "libaudioutils", // for clock.h, Statistics.h
- "libbase",
- "libbinder",
- "libhidlbase",
- "liblog",
- "libpermission",
- "libutils",
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hidl.token@1.0-utils",
- "packagemanager_aidl-cpp",
- ],
-
- export_shared_lib_headers: [
- "libpermission",
- ],
-
- local_include_dirs: ["include"],
- export_include_dirs: ["include"],
-}
cc_library {
name: "libmediautils",
+ host_supported: true,
defaults: ["libmediautils_defaults"],
srcs: [
":libmediautils_core_srcs",
- "BatteryNotifier.cpp",
- "MemoryLeakTrackUtil.cpp",
- "LimitProcessMemory.cpp",
- "ProcessInfo.cpp",
- "ServiceUtilities.cpp",
- "TimeCheck.cpp",
- "TimerThread.cpp",
],
static_libs: [
- "libc_malloc_debug_backtrace",
"libbatterystats_aidl",
"libprocessinfoservice_aidl",
],
@@ -119,11 +103,6 @@
logtags: ["EventLogTags.logtags"],
- header_libs: [
- "bionic_libc_platform_headers",
- "libmedia_headers",
- ],
-
export_shared_lib_headers: [
"libpermission",
],
@@ -132,16 +111,32 @@
"libmediautils_delayed", // lazy loaded
],
- include_dirs: [
- // For DEBUGGER_SIGNAL
- "system/core/debuggerd/include",
- ],
+ target: {
+ android: {
+ srcs: [
+ "LimitProcessMemory.cpp",
+ "MemoryLeakTrackUtil.cpp",
+ ],
+ static_libs: [
+ "libc_malloc_debug_backtrace",
+ ],
+ include_dirs: [
+ // For DEBUGGER_SIGNAL
+ "system/core/debuggerd/include",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
+ },
+ },
+
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
cc_library {
name: "libmediautils_delayed", // match with MEDIAUTILS_DELAYED_LIBRARY_NAME
+ host_supported: true,
defaults: ["libmediautils_defaults"],
srcs: [
"MediaUtilsDelayedLibrary.cpp",
diff --git a/media/utils/MethodStatistics.cpp b/media/utils/MethodStatistics.cpp
index b179b20..086757b 100644
--- a/media/utils/MethodStatistics.cpp
+++ b/media/utils/MethodStatistics.cpp
@@ -22,7 +22,8 @@
std::shared_ptr<std::vector<std::string>>
getStatisticsClassesForModule(std::string_view moduleName) {
- static const std::map<std::string, std::shared_ptr<std::vector<std::string>>> m {
+ static const std::map<std::string, std::shared_ptr<std::vector<std::string>>,
+ std::less<> /* transparent comparator */> m {
{
METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL,
std::shared_ptr<std::vector<std::string>>(
@@ -34,13 +35,14 @@
})
},
};
- auto it = m.find({moduleName.begin(), moduleName.end()});
+ auto it = m.find(moduleName);
if (it == m.end()) return {};
return it->second;
}
static void addClassesToMap(const std::shared_ptr<std::vector<std::string>> &classNames,
- std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> &map) {
+ std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>,
+ std::less<> /* transparent comparator */> &map) {
if (classNames) {
for (const auto& className : *classNames) {
map.emplace(className, std::make_shared<MethodStatistics<std::string>>());
@@ -51,17 +53,18 @@
// singleton statistics for DeviceHalHidl StreamOutHalHidl StreamInHalHidl
std::shared_ptr<MethodStatistics<std::string>>
getStatisticsForClass(std::string_view className) {
- static const std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> m =
+ static const std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>,
+ std::less<> /* transparent comparator */> m =
// copy elided initialization of map m.
[](){
- std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> m;
+ std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>, std::less<>> m;
addClassesToMap(
getStatisticsClassesForModule(METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL),
m);
return m;
}();
- auto it = m.find({className.begin(), className.end()});
+ auto it = m.find(className);
if (it == m.end()) return {};
return it->second;
}
diff --git a/media/utils/ProcessInfo.cpp b/media/utils/ProcessInfo.cpp
index da199c4..3baa4b4 100644
--- a/media/utils/ProcessInfo.cpp
+++ b/media/utils/ProcessInfo.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "ProcessInfo"
#include <utils/Log.h>
-#include <media/stagefright/ProcessInfo.h>
+#include <mediautils/ProcessInfo.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 0848eb3..0cf5bd9 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -14,19 +14,36 @@
* limitations under the License.
*/
+#include <csignal>
+#include "mediautils/TimerThread.h"
#define LOG_TAG "TimeCheck"
#include <optional>
#include <android-base/logging.h>
+#include <android-base/strings.h>
#include <audio_utils/clock.h>
#include <mediautils/EventLog.h>
+#include <mediautils/FixedString.h>
#include <mediautils/MethodStatistics.h>
#include <mediautils/TimeCheck.h>
+#include <mediautils/TidWrapper.h>
#include <utils/Log.h>
+
+#if defined(__ANDROID__)
#include "debuggerd/handler.h"
+#endif
+
namespace android::mediautils {
+// This function appropriately signals a pid to dump a backtrace if we are
+// running on device (and the HAL exists). If we are not running on an Android
+// device, there is no HAL to signal (so we do nothing).
+static inline void signalAudioHAL([[maybe_unused]] pid_t pid) {
+#if defined(__ANDROID__)
+ sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
+#endif
+}
/**
* Returns the std::string "HH:MM:SS.MSc" from a system_clock time_point.
@@ -135,25 +152,27 @@
std::string TimeCheck::toString() {
// note pending and retired are individually locked for maximum concurrency,
// snapshot is not instantaneous at a single time.
- return getTimeCheckThread().toString();
+ return getTimeCheckThread().getSnapshotAnalysis().toString();
}
-TimeCheck::TimeCheck(std::string tag, OnTimerFunc&& onTimer, uint32_t timeoutMs,
- bool crashOnTimeout)
- : mTimeCheckHandler(new TimeCheckHandler{
- std::move(tag), std::move(onTimer), crashOnTimeout,
- std::chrono::system_clock::now(), gettid()})
- , mTimerHandle(timeoutMs == 0
+TimeCheck::TimeCheck(std::string_view tag, OnTimerFunc&& onTimer, Duration requestedTimeoutDuration,
+ Duration secondChanceDuration, bool crashOnTimeout)
+ : mTimeCheckHandler{ std::make_shared<TimeCheckHandler>(
+ tag, std::move(onTimer), crashOnTimeout, requestedTimeoutDuration,
+ secondChanceDuration, std::chrono::system_clock::now(), getThreadIdWrapper()) }
+ , mTimerHandle(requestedTimeoutDuration.count() == 0
+ /* for TimeCheck we don't consider a non-zero secondChanceDuration here */
? getTimeCheckThread().trackTask(mTimeCheckHandler->tag)
: getTimeCheckThread().scheduleTask(
mTimeCheckHandler->tag,
// Pass in all the arguments by value to this task for safety.
// The thread could call the callback before the constructor is finished.
// The destructor is not blocked on callback.
- [ timeCheckHandler = mTimeCheckHandler ] {
- timeCheckHandler->onTimeout();
+ [ timeCheckHandler = mTimeCheckHandler ](TimerThread::Handle timerHandle) {
+ timeCheckHandler->onTimeout(timerHandle);
},
- std::chrono::milliseconds(timeoutMs))) {}
+ requestedTimeoutDuration,
+ secondChanceDuration)) {}
TimeCheck::~TimeCheck() {
if (mTimeCheckHandler) {
@@ -161,30 +180,84 @@
}
}
+/* static */
+std::string TimeCheck::analyzeTimeouts(
+ float requestedTimeoutMs, float elapsedSteadyMs, float elapsedSystemMs) {
+ // Track any OS clock issues with suspend.
+ // It is possible that the elapsedSystemMs is much greater than elapsedSteadyMs if
+ // a suspend occurs; however, we always expect the timeout ms should always be slightly
+ // less than the elapsed steady ms regardless of whether a suspend occurs or not.
+
+ std::string s("Timeout ms ");
+ s.append(std::to_string(requestedTimeoutMs))
+ .append(" elapsed steady ms ").append(std::to_string(elapsedSteadyMs))
+ .append(" elapsed system ms ").append(std::to_string(elapsedSystemMs));
+
+ // Is there something unusual?
+ static constexpr float TOLERANCE_CONTEXT_SWITCH_MS = 200.f;
+
+ if (requestedTimeoutMs > elapsedSteadyMs || requestedTimeoutMs > elapsedSystemMs) {
+ s.append("\nError: early expiration - "
+ "requestedTimeoutMs should be less than elapsed time");
+ }
+
+ if (elapsedSteadyMs > elapsedSystemMs + TOLERANCE_CONTEXT_SWITCH_MS) {
+ s.append("\nWarning: steady time should not advance faster than system time");
+ }
+
+ // This has been found in suspend stress testing.
+ if (elapsedSteadyMs > requestedTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
+ s.append("\nWarning: steady time significantly exceeds timeout "
+ "- possible thread stall or aborted suspend");
+ }
+
+ // This has been found in suspend stress testing.
+ if (elapsedSystemMs > requestedTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
+ s.append("\nInformation: system time significantly exceeds timeout "
+ "- possible suspend");
+ }
+ return s;
+}
+
+// To avoid any potential race conditions, the timer handle
+// (expiration = clock steady start + timeout) is passed into the callback.
void TimeCheck::TimeCheckHandler::onCancel(TimerThread::Handle timerHandle) const
{
if (TimeCheck::getTimeCheckThread().cancelTask(timerHandle) && onTimer) {
- const std::chrono::system_clock::time_point endTime = std::chrono::system_clock::now();
- onTimer(false /* timeout */,
- std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(
- endTime - startTime).count());
+ const std::chrono::steady_clock::time_point endSteadyTime =
+ std::chrono::steady_clock::now();
+ const float elapsedSteadyMs = std::chrono::duration_cast<FloatMs>(
+ endSteadyTime - timerHandle + timeoutDuration).count();
+ // send the elapsed steady time for statistics.
+ onTimer(false /* timeout */, elapsedSteadyMs);
}
}
-void TimeCheck::TimeCheckHandler::onTimeout() const
+// To avoid any potential race conditions, the timer handle
+// (expiration = clock steady start + timeout) is passed into the callback.
+void TimeCheck::TimeCheckHandler::onTimeout(TimerThread::Handle timerHandle) const
{
- const std::chrono::system_clock::time_point endTime = std::chrono::system_clock::now();
+ const std::chrono::steady_clock::time_point endSteadyTime = std::chrono::steady_clock::now();
+ const std::chrono::system_clock::time_point endSystemTime = std::chrono::system_clock::now();
+ // timerHandle incorporates the timeout
+ const float elapsedSteadyMs = std::chrono::duration_cast<FloatMs>(
+ endSteadyTime - (timerHandle - timeoutDuration)).count();
+ const float elapsedSystemMs = std::chrono::duration_cast<FloatMs>(
+ endSystemTime - startSystemTime).count();
+ const float requestedTimeoutMs = std::chrono::duration_cast<FloatMs>(
+ timeoutDuration).count();
+ const float secondChanceMs = std::chrono::duration_cast<FloatMs>(
+ secondChanceDuration).count();
+
if (onTimer) {
- onTimer(true /* timeout */,
- std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(
- endTime - startTime).count());
+ onTimer(true /* timeout */, elapsedSteadyMs);
}
if (!crashOnTimeout) return;
// Generate the TimerThread summary string early before sending signals to the
// HAL processes which can affect thread behavior.
- const std::string summary = getTimeCheckThread().toString(4 /* retiredCount */);
+ const auto snapshotAnalysis = getTimeCheckThread().getSnapshotAnalysis(4 /* retiredCount */);
// Generate audio HAL processes tombstones and allow time to complete
// before forcing restart
@@ -194,7 +267,7 @@
for (const auto& pid : pids) {
ALOGI("requesting tombstone for pid: %d", pid);
halPids.append(std::to_string(pid)).append(" ");
- sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
+ signalAudioHAL(pid);
}
sleep(1);
} else {
@@ -207,10 +280,12 @@
// Create abort message string - caution: this can be very large.
const std::string abortMessage = std::string("TimeCheck timeout for ")
.append(tag)
- .append(" scheduled ").append(formatTime(startTime))
+ .append(" scheduled ").append(formatTime(startSystemTime))
.append(" on thread ").append(std::to_string(tid)).append("\n")
+ .append(analyzeTimeouts(requestedTimeoutMs + secondChanceMs,
+ elapsedSteadyMs, elapsedSystemMs)).append("\n")
.append(halPids).append("\n")
- .append(summary);
+ .append(snapshotAnalysis.toString());
// Note: LOG_ALWAYS_FATAL limits the size of the string - per log/log.h:
// Log message text may be truncated to less than an
@@ -220,7 +295,20 @@
// to avoid the size limitation. LOG(FATAL) does an abort whereas
// LOG(FATAL_WITHOUT_ABORT) does not abort.
- LOG(FATAL) << abortMessage;
+ static constexpr pid_t invalidPid = TimerThread::SnapshotAnalysis::INVALID_PID;
+ pid_t tidToAbort = invalidPid;
+ if (snapshotAnalysis.suspectTid != invalidPid) {
+ tidToAbort = snapshotAnalysis.suspectTid;
+ } else if (snapshotAnalysis.timeoutTid != invalidPid) {
+ tidToAbort = snapshotAnalysis.timeoutTid;
+ }
+
+ LOG(FATAL_WITHOUT_ABORT) << abortMessage;
+ const auto ret = abortTid(tidToAbort);
+ if (ret < 0) {
+ LOG(FATAL) << "TimeCheck thread signal failed, aborting process. "
+ "errno: " << errno << base::ErrnoNumberAsString(errno);
+ }
}
// Automatically create a TimeCheck class for a class and method.
@@ -231,16 +319,16 @@
mediautils::getStatisticsForClass(className);
if (!statistics) return {}; // empty TimeCheck.
return mediautils::TimeCheck(
- std::string(className).append("::").append(methodName),
- [ clazz = std::string(className), method = std::string(methodName),
+ FixedString62(className).append("::").append(methodName),
+ [ safeMethodName = FixedString30(methodName),
stats = std::move(statistics) ]
(bool timeout, float elapsedMs) {
if (timeout) {
; // ignored, there is no timeout value.
} else {
- stats->event(method, elapsedMs);
+ stats->event(safeMethodName.asStringView(), elapsedMs);
}
- }, 0 /* timeoutMs */);
+ }, {} /* timeoutDuration */, {} /* secondChanceDuration */, false /* crashOnTimeout */);
}
} // namespace android::mediautils
diff --git a/media/utils/TimerThread.cpp b/media/utils/TimerThread.cpp
index 6de6b13..b760ee2 100644
--- a/media/utils/TimerThread.cpp
+++ b/media/utils/TimerThread.cpp
@@ -22,68 +22,66 @@
#include <vector>
#include <mediautils/MediaUtilsDelayed.h>
+#include <mediautils/TidWrapper.h>
#include <mediautils/TimerThread.h>
+#include <utils/Log.h>
#include <utils/ThreadDefs.h>
+using namespace std::chrono_literals;
+
namespace android::mediautils {
extern std::string formatTime(std::chrono::system_clock::time_point t);
extern std::string_view timeSuffix(std::string_view time1, std::string_view time2);
TimerThread::Handle TimerThread::scheduleTask(
- std::string tag, std::function<void()>&& func, std::chrono::milliseconds timeout) {
+ std::string_view tag, TimerCallback&& func,
+ Duration timeoutDuration, Duration secondChanceDuration) {
const auto now = std::chrono::system_clock::now();
- std::shared_ptr<const Request> request{
- new Request{ now, now + timeout, gettid(), std::move(tag) }};
- return mMonitorThread.add(std::move(request), std::move(func), timeout);
+ auto request = std::make_shared<const Request>(now, now +
+ std::chrono::duration_cast<std::chrono::system_clock::duration>(timeoutDuration),
+ secondChanceDuration, getThreadIdWrapper(), tag);
+ return mMonitorThread.add(std::move(request), std::move(func), timeoutDuration);
}
-TimerThread::Handle TimerThread::trackTask(std::string tag) {
+TimerThread::Handle TimerThread::trackTask(std::string_view tag) {
const auto now = std::chrono::system_clock::now();
- std::shared_ptr<const Request> request{
- new Request{ now, now, gettid(), std::move(tag) }};
+ auto request = std::make_shared<const Request>(now, now,
+ Duration{} /* secondChanceDuration */, getThreadIdWrapper(), tag);
return mNoTimeoutMap.add(std::move(request));
}
bool TimerThread::cancelTask(Handle handle) {
- std::shared_ptr<const Request> request = mNoTimeoutMap.isValidHandle(handle) ?
+ std::shared_ptr<const Request> request = isNoTimeoutHandle(handle) ?
mNoTimeoutMap.remove(handle) : mMonitorThread.remove(handle);
if (!request) return false;
mRetiredQueue.add(std::move(request));
return true;
}
-std::string TimerThread::toString(size_t retiredCount) const {
+
+std::string TimerThread::SnapshotAnalysis::toString() const {
// Note: These request queues are snapshot very close together but
// not at "identical" times as we don't use a class-wide lock.
-
- std::vector<std::shared_ptr<const Request>> timeoutRequests;
- std::vector<std::shared_ptr<const Request>> retiredRequests;
- mTimeoutQueue.copyRequests(timeoutRequests);
- mRetiredQueue.copyRequests(retiredRequests, retiredCount);
- std::vector<std::shared_ptr<const Request>> pendingRequests =
- getPendingRequests();
-
- struct Analysis analysis = analyzeTimeout(timeoutRequests, pendingRequests);
- std::string analysisSummary;
- if (!analysis.summary.empty()) {
- analysisSummary = std::string("\nanalysis [ ").append(analysis.summary).append(" ]");
- }
+ std::string analysisSummary = std::string("\nanalysis [ ").append(description).append(" ]");
std::string timeoutStack;
- if (analysis.timeoutTid != -1) {
- timeoutStack = std::string("\ntimeout(")
- .append(std::to_string(analysis.timeoutTid)).append(") callstack [\n")
- .append(getCallStackStringForTid(analysis.timeoutTid)).append("]");
- }
std::string blockedStack;
- if (analysis.HALBlockedTid != -1) {
+ if (timeoutTid != -1) {
+ timeoutStack = std::string(suspectTid == timeoutTid ? "\ntimeout/blocked(" : "\ntimeout(")
+ .append(std::to_string(timeoutTid)).append(") callstack [\n")
+ .append(getCallStackStringForTid(timeoutTid)).append("]");
+ }
+
+ if (suspectTid != -1 && suspectTid != timeoutTid) {
blockedStack = std::string("\nblocked(")
- .append(std::to_string(analysis.HALBlockedTid)).append(") callstack [\n")
- .append(getCallStackStringForTid(analysis.HALBlockedTid)).append("]");
+ .append(std::to_string(suspectTid)).append(") callstack [\n")
+ .append(getCallStackStringForTid(suspectTid)).append("]");
}
return std::string("now ")
.append(formatTime(std::chrono::system_clock::now()))
+ .append("\nsecondChanceCount ")
+ .append(std::to_string(secondChanceCount))
.append(analysisSummary)
.append("\ntimeout [ ")
.append(requestsToString(timeoutRequests))
@@ -106,34 +104,41 @@
//
/* static */
bool TimerThread::isRequestFromHal(const std::shared_ptr<const Request>& request) {
- const size_t hidlPos = request->tag.find("Hidl");
+ const size_t hidlPos = request->tag.asStringView().find("Hidl");
if (hidlPos == std::string::npos) return false;
// should be a separator afterwards Hidl which indicates the string was in the class.
- const size_t separatorPos = request->tag.find("::", hidlPos);
+ const size_t separatorPos = request->tag.asStringView().find("::", hidlPos);
return separatorPos != std::string::npos;
}
-/* static */
-struct TimerThread::Analysis TimerThread::analyzeTimeout(
- const std::vector<std::shared_ptr<const Request>>& timeoutRequests,
- const std::vector<std::shared_ptr<const Request>>& pendingRequests) {
-
- if (timeoutRequests.empty() || pendingRequests.empty()) return {}; // nothing to say.
-
+struct TimerThread::SnapshotAnalysis TimerThread::getSnapshotAnalysis(size_t retiredCount) const {
+ struct SnapshotAnalysis analysis{};
+ // The following snapshot of the TimerThread state will be utilized for
+ // analysis. Note, there is no lock around these calls, so there could be
+ // a state update between them.
+ mTimeoutQueue.copyRequests(analysis.timeoutRequests);
+ mRetiredQueue.copyRequests(analysis.retiredRequests, retiredCount);
+ analysis.pendingRequests = getPendingRequests();
+ analysis.secondChanceCount = mMonitorThread.getSecondChanceCount();
+ // No call has timed out, so there is no analysis to be done.
+ if (analysis.timeoutRequests.empty())
+ return analysis;
// for now look at last timeout (in our case, the only timeout)
- const std::shared_ptr<const Request> timeout = timeoutRequests.back();
-
+ const std::shared_ptr<const Request> timeout = analysis.timeoutRequests.back();
+ analysis.timeoutTid = timeout->tid;
+ if (analysis.pendingRequests.empty())
+ return analysis;
// pending Requests that are problematic.
std::vector<std::shared_ptr<const Request>> pendingExact;
std::vector<std::shared_ptr<const Request>> pendingPossible;
- // We look at pending requests that were scheduled no later than kDuration
+ // We look at pending requests that were scheduled no later than kPendingDuration
// after the timeout request. This prevents false matches with calls
// that naturally block for a short period of time
// such as HAL write() and read().
//
- auto constexpr kDuration = std::chrono::milliseconds(1000);
- for (const auto& pending : pendingRequests) {
+ constexpr Duration kPendingDuration = 1000ms;
+ for (const auto& pending : analysis.pendingRequests) {
// If the pending tid is the same as timeout tid, problem identified.
if (pending->tid == timeout->tid) {
pendingExact.emplace_back(pending);
@@ -141,34 +146,32 @@
}
// if the pending tid is scheduled within time limit
- if (pending->scheduled - timeout->scheduled < kDuration) {
+ if (pending->scheduled - timeout->scheduled < kPendingDuration) {
pendingPossible.emplace_back(pending);
}
}
- struct Analysis analysis{};
-
- analysis.timeoutTid = timeout->tid;
- std::string& summary = analysis.summary;
+ std::string& description = analysis.description;
if (!pendingExact.empty()) {
const auto& request = pendingExact.front();
const bool hal = isRequestFromHal(request);
if (hal) {
- summary = std::string("Blocked directly due to HAL call: ")
+ description = std::string("Blocked directly due to HAL call: ")
.append(request->toString());
+ analysis.suspectTid= request->tid;
}
}
- if (summary.empty() && !pendingPossible.empty()) {
+ if (description.empty() && !pendingPossible.empty()) {
for (const auto& request : pendingPossible) {
const bool hal = isRequestFromHal(request);
if (hal) {
// The first blocked call is the most likely one.
// Recent calls might be temporarily blocked
// calls such as write() or read() depending on kDuration.
- summary = std::string("Blocked possibly due to HAL call: ")
+ description = std::string("Blocked possibly due to HAL call: ")
.append(request->toString());
- analysis.HALBlockedTid = request->tid;
+ analysis.suspectTid= request->tid;
}
}
}
@@ -241,15 +244,11 @@
}
}
-bool TimerThread::NoTimeoutMap::isValidHandle(Handle handle) const {
- return handle > getIndexedHandle(mNoTimeoutRequests);
-}
-
TimerThread::Handle TimerThread::NoTimeoutMap::add(std::shared_ptr<const Request> request) {
std::lock_guard lg(mNTMutex);
// A unique handle is obtained by mNoTimeoutRequests.fetch_add(1),
// This need not be under a lock, but we do so anyhow.
- const Handle handle = getIndexedHandle(mNoTimeoutRequests++);
+ const Handle handle = getUniqueHandle_l();
mMap[handle] = request;
return handle;
}
@@ -271,16 +270,6 @@
}
}
-TimerThread::Handle TimerThread::MonitorThread::getUniqueHandle_l(
- std::chrono::milliseconds timeout) {
- // To avoid key collisions, advance by 1 tick until the key is unique.
- auto deadline = std::chrono::steady_clock::now() + timeout;
- for (; mMonitorRequests.find(deadline) != mMonitorRequests.end();
- deadline += std::chrono::steady_clock::duration(1))
- ;
- return deadline;
-}
-
TimerThread::MonitorThread::MonitorThread(RequestQueue& timeoutQueue)
: mTimeoutQueue(timeoutQueue)
, mThread([this] { threadFunc(); }) {
@@ -300,24 +289,78 @@
void TimerThread::MonitorThread::threadFunc() {
std::unique_lock _l(mMutex);
while (!mShouldExit) {
+ Handle nextDeadline = INVALID_HANDLE;
+ Handle now = INVALID_HANDLE;
if (!mMonitorRequests.empty()) {
- Handle nextDeadline = mMonitorRequests.begin()->first;
- if (nextDeadline < std::chrono::steady_clock::now()) {
+ nextDeadline = mMonitorRequests.begin()->first;
+ now = std::chrono::steady_clock::now();
+ if (nextDeadline < now) {
+ auto node = mMonitorRequests.extract(mMonitorRequests.begin());
// Deadline has expired, handle the request.
+ auto secondChanceDuration = node.mapped().first->secondChanceDuration;
+ if (secondChanceDuration.count() != 0) {
+ // We now apply the second chance duration to find the clock
+ // monotonic second deadline. The unique key is then the
+ // pair<second_deadline, first_deadline>.
+ //
+ // The second chance prevents a false timeout should there be
+ // any clock monotonic advancement during suspend.
+ auto newHandle = now + secondChanceDuration;
+ ALOGD("%s: TimeCheck second chance applied for %s",
+ __func__, node.mapped().first->tag.c_str()); // should be rare event.
+ mSecondChanceRequests.emplace_hint(mSecondChanceRequests.end(),
+ std::make_pair(newHandle, nextDeadline),
+ std::move(node.mapped()));
+ // increment second chance counter.
+ mSecondChanceCount.fetch_add(1 /* arg */, std::memory_order_relaxed);
+ } else {
+ {
+ _l.unlock();
+ // We add Request to retired queue early so that it can be dumped out.
+ mTimeoutQueue.add(std::move(node.mapped().first));
+ node.mapped().second(nextDeadline);
+ // Caution: we don't hold lock when we call TimerCallback,
+ // but this is the timeout case! We will crash soon,
+ // maybe before returning.
+ // anything left over is released here outside lock.
+ }
+ // reacquire the lock - if something was added, we loop immediately to check.
+ _l.lock();
+ }
+ // always process expiring monitor requests first.
+ continue;
+ }
+ }
+ // now process any second chance requests.
+ if (!mSecondChanceRequests.empty()) {
+ Handle secondDeadline = mSecondChanceRequests.begin()->first.first;
+ if (now == INVALID_HANDLE) now = std::chrono::steady_clock::now();
+ if (secondDeadline < now) {
+ auto node = mSecondChanceRequests.extract(mSecondChanceRequests.begin());
{
- auto node = mMonitorRequests.extract(mMonitorRequests.begin());
_l.unlock();
// We add Request to retired queue early so that it can be dumped out.
mTimeoutQueue.add(std::move(node.mapped().first));
- node.mapped().second(); // Caution: we don't hold lock here - but do we care?
- // this is the timeout case! We will crash soon,
- // maybe before returning.
- // anything left over is released here outside lock.
+ const Handle originalHandle = node.key().second;
+ node.mapped().second(originalHandle);
+ // Caution: we don't hold lock when we call TimerCallback.
+ // This is benign issue - we permit concurrent operations
+ // while in the callback to the MonitorQueue.
+ //
+ // Anything left over is released here outside lock.
}
// reacquire the lock - if something was added, we loop immediately to check.
_l.lock();
continue;
}
+ // update the deadline.
+ if (nextDeadline == INVALID_HANDLE) {
+ nextDeadline = secondDeadline;
+ } else {
+ nextDeadline = std::min(nextDeadline, secondDeadline);
+ }
+ }
+ if (nextDeadline != INVALID_HANDLE) {
mCond.wait_until(_l, nextDeadline);
} else {
mCond.wait(_l);
@@ -326,26 +369,39 @@
}
TimerThread::Handle TimerThread::MonitorThread::add(
- std::shared_ptr<const Request> request, std::function<void()>&& func,
- std::chrono::milliseconds timeout) {
+ std::shared_ptr<const Request> request, TimerCallback&& func, Duration timeout) {
std::lock_guard _l(mMutex);
const Handle handle = getUniqueHandle_l(timeout);
- mMonitorRequests.emplace(handle, std::make_pair(std::move(request), std::move(func)));
+ mMonitorRequests.emplace_hint(mMonitorRequests.end(),
+ handle, std::make_pair(std::move(request), std::move(func)));
mCond.notify_all();
return handle;
}
std::shared_ptr<const TimerThread::Request> TimerThread::MonitorThread::remove(Handle handle) {
+ std::pair<std::shared_ptr<const Request>, TimerCallback> data;
std::unique_lock ul(mMutex);
- const auto it = mMonitorRequests.find(handle);
- if (it == mMonitorRequests.end()) {
- return {};
+ if (const auto it = mMonitorRequests.find(handle);
+ it != mMonitorRequests.end()) {
+ data = std::move(it->second);
+ mMonitorRequests.erase(it);
+ ul.unlock(); // manually release lock here so func (data.second)
+ // is released outside of lock.
+ return data.first; // request
}
- std::shared_ptr<const TimerThread::Request> request = std::move(it->second.first);
- std::function<void()> func = std::move(it->second.second);
- mMonitorRequests.erase(it);
- ul.unlock(); // manually release lock here so func is released outside of lock.
- return request;
+
+ // this check is O(N), but since the second chance requests are ordered
+ // in terms of earliest expiration time, we would expect better than average results.
+ for (auto it = mSecondChanceRequests.begin(); it != mSecondChanceRequests.end(); ++it) {
+ if (it->first.second == handle) {
+ data = std::move(it->second);
+ mSecondChanceRequests.erase(it);
+ ul.unlock(); // manually release lock here so func (data.second)
+ // is released outside of lock.
+ return data.first; // request
+ }
+ }
+ return {};
}
void TimerThread::MonitorThread::copyRequests(
@@ -354,6 +410,13 @@
for (const auto &[deadline, monitorpair] : mMonitorRequests) {
requests.emplace_back(monitorpair.first);
}
+ // we combine the second map with the first map - this is
+ // everything that is pending on the monitor thread.
+ // The second map will be older than the first map so this
+ // is in order.
+ for (const auto &[deadline, monitorpair] : mSecondChanceRequests) {
+ requests.emplace_back(monitorpair.first);
+ }
}
} // namespace android::mediautils
diff --git a/media/utils/fuzzers/Android.bp b/media/utils/fuzzers/Android.bp
index fc4c2f9..bd9a462 100644
--- a/media/utils/fuzzers/Android.bp
+++ b/media/utils/fuzzers/Android.bp
@@ -14,7 +14,7 @@
"libbinder",
"liblog",
"libcutils",
- "libmediautils_core",
+ "libmediautils",
"libutils",
"framework-permission-aidl-cpp",
"packagemanager_aidl-cpp",
@@ -30,32 +30,24 @@
cc_fuzz {
name: "libmediautils_fuzzer_battery_notifier",
- host_supported: false,
- shared_libs: ["libmediautils"],
defaults: ["libmediautils_fuzzer_defaults"],
srcs: ["BatteryNotifierFuzz.cpp"],
}
cc_fuzz {
name: "libmediautils_fuzzer_scheduling_policy_service",
- host_supported: false,
- shared_libs: ["libmediautils"],
defaults: ["libmediautils_fuzzer_defaults"],
srcs: ["SchedulingPolicyServiceFuzz.cpp"],
}
cc_fuzz {
name: "libmediautils_fuzzer_service_utilities",
- host_supported: false,
- shared_libs: ["libmediautils"],
defaults: ["libmediautils_fuzzer_defaults"],
srcs: ["ServiceUtilitiesFuzz.cpp"],
}
cc_fuzz {
name: "libmediautils_fuzzer_time_check",
- host_supported: false,
- shared_libs: ["libmediautils"],
defaults: ["libmediautils_fuzzer_defaults"],
srcs: ["TimeCheckFuzz.cpp"],
}
diff --git a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
index 32fc3be..d672fb0 100644
--- a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
+++ b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
@@ -19,6 +19,7 @@
#include <utils/String16.h>
#include <android/log.h>
#include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/TidWrapper.h>
#include "fuzzer/FuzzedDataProvider.h"
using android::IBatteryStats;
using android::IBinder;
@@ -55,7 +56,8 @@
int32_t priority = data_provider.ConsumeIntegral<int32_t>();
bool is_for_app = data_provider.ConsumeBool();
bool async = data_provider.ConsumeBool();
- requestPriority(getpid(), gettid(), priority, is_for_app, async);
+ requestPriority(getpid(), android::mediautils::getThreadIdWrapper(), priority, is_for_app,
+ async);
// TODO: Verify and re-enable in AOSP (R).
// bool enable = data_provider.ConsumeBool();
// We are just using batterystats to avoid the need
diff --git a/media/utils/fuzzers/TimeCheckFuzz.cpp b/media/utils/fuzzers/TimeCheckFuzz.cpp
index 7966469..65b2885 100644
--- a/media/utils/fuzzers/TimeCheckFuzz.cpp
+++ b/media/utils/fuzzers/TimeCheckFuzz.cpp
@@ -48,7 +48,9 @@
std::string name = data_provider.ConsumeRandomLengthString(kMaxStringLen);
// 3. The constructor, which is fuzzed here:
- android::mediautils::TimeCheck timeCheck(name.c_str(), {} /* onTimer */, timeoutMs);
+ android::mediautils::TimeCheck timeCheck(name.c_str(), {} /* onTimer */,
+ std::chrono::milliseconds(timeoutMs),
+ {} /* secondChanceDuration */, true /* crashOnTimeout */);
// We will leave some buffer to avoid sleeping too long
uint8_t sleep_amount_ms = data_provider.ConsumeIntegralInRange<uint8_t>(0, timeoutMs / 2);
diff --git a/media/utils/include/mediautils/FixedString.h b/media/utils/include/mediautils/FixedString.h
new file mode 100644
index 0000000..047aa82
--- /dev/null
+++ b/media/utils/include/mediautils/FixedString.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2022 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 <algorithm>
+#include <string>
+#include <string_view>
+
+namespace android::mediautils {
+
+/*
+ * FixedString is a stack allocatable string buffer that supports
+ * simple appending of other strings and string_views.
+ *
+ * It is designed for no-malloc operation when std::string
+ * small buffer optimization is insufficient.
+ *
+ * To keep code small, use asStringView() for operations on this.
+ *
+ * Notes:
+ * 1) Appending beyond the internal buffer size results in truncation.
+ *
+ * Alternatives:
+ * 1) If you want a sharable copy-on-write string implementation,
+ * consider using the legacy android::String8().
+ * 2) Using std::string with a fixed stack allocator may suit your needs,
+ * but exception avoidance is tricky.
+ * 3) Using C++20 ranges https://en.cppreference.com/w/cpp/ranges if you don't
+ * need backing store. Be careful about allocation with ranges.
+ *
+ * Good small sizes are multiples of 16 minus 2, e.g. 14, 30, 46, 62.
+ *
+ * Implementation Notes:
+ * 1) No iterators or [] for FixedString - please convert to std::string_view.
+ * 2) For small N (e.g. less than 62), consider a change to always zero fill and
+ * potentially prevent always zero terminating (if one only does append).
+ *
+ * Possible arguments to create/append:
+ * 1) A FixedString.
+ * 2) A single char.
+ * 3) A char * pointer.
+ * 4) A std::string.
+ * 5) A std::string_view (or something convertible to it).
+ *
+ * Example:
+ *
+ * FixedString s1(std::string("a")); // ctor
+ * s1 << "bc" << 'd' << '\n'; // streaming append
+ * s1 += "hello"; // += append
+ * ASSERT_EQ(s1, "abcd\nhello");
+ */
+template <uint32_t N>
+struct FixedString
+{
+ // Find the best size type.
+ using strsize_t = std::conditional_t<(N > 255), uint32_t, uint8_t>;
+
+ // constructors
+ FixedString() { // override default
+ buffer_[0] = '\0';
+ }
+
+ FixedString(const FixedString& other) { // override default.
+ copyFrom<N>(other);
+ }
+
+ // The following constructor is not explicit to allow
+ // FixedString<8> s = "abcd";
+ template <typename ...Types>
+ FixedString(Types&&... args) {
+ append(std::forward<Types>(args)...);
+ }
+
+ // copy assign (copyFrom checks for equality and returns *this).
+ FixedString& operator=(const FixedString& other) { // override default.
+ return copyFrom<N>(other);
+ }
+
+ template <typename ...Types>
+ FixedString& operator=(Types&&... args) {
+ size_ = 0;
+ return append(std::forward<Types>(args)...);
+ }
+
+ // operator equals
+ bool operator==(const char *s) const {
+ return strncmp(c_str(), s, capacity() + 1) == 0;
+ }
+
+ bool operator==(std::string_view s) const {
+ return size() == s.size() && memcmp(data(), s.data(), size()) == 0;
+ }
+
+ // operator not-equals
+ template <typename T>
+ bool operator!=(const T& other) const {
+ return !operator==(other);
+ }
+
+ // operator +=
+ template <typename ...Types>
+ FixedString& operator+=(Types&&... args) {
+ return append(std::forward<Types>(args)...);
+ }
+
+ // conversion to std::string_view.
+ operator std::string_view() const {
+ return asStringView();
+ }
+
+ // basic observers
+ size_t buffer_offset() const { return offsetof(std::decay_t<decltype(*this)>, buffer_); }
+ static constexpr uint32_t capacity() { return N; }
+ uint32_t size() const { return size_; }
+ uint32_t remaining() const { return size_ >= N ? 0 : N - size_; }
+ bool empty() const { return size_ == 0; }
+ bool full() const { return size_ == N; } // when full, possible truncation risk.
+ char * data() { return buffer_; }
+ const char * data() const { return buffer_; }
+ const char * c_str() const { return buffer_; }
+
+ inline std::string_view asStringView() const {
+ return { buffer_, static_cast<size_t>(size_) };
+ }
+ inline std::string asString() const {
+ return { buffer_, static_cast<size_t>(size_) };
+ }
+
+ void clear() { size_ = 0; buffer_[0] = 0; }
+
+ // Implementation of append - using templates
+ // to guarantee precedence in the presence of ambiguity.
+ //
+ // Consider C++20 template overloading through constraints and concepts.
+ template <typename T>
+ FixedString& append(const T& t) {
+ using decayT = std::decay_t<T>;
+ if constexpr (is_specialization_v<decayT, FixedString>) {
+ // A FixedString<U>
+ if (size_ == 0) {
+ // optimization to erase everything.
+ return copyFrom(t);
+ } else {
+ return appendStringView({t.data(), t.size()});
+ }
+ } else if constexpr(std::is_same_v<decayT, char>) {
+ if (size_ < N) {
+ buffer_[size_++] = t;
+ buffer_[size_] = '\0';
+ }
+ return *this;
+ } else if constexpr(std::is_same_v<decayT, char *>) {
+ // Some char* ptr.
+ return appendString(t);
+ } else if constexpr (std::is_convertible_v<decayT, std::string_view>) {
+ // std::string_view, std::string, or some other convertible type.
+ return appendStringView(t);
+ } else /* constexpr */ {
+ static_assert(dependent_false_v<T>, "non-matching append type");
+ }
+ }
+
+ FixedString& appendStringView(std::string_view s) {
+ uint32_t total = std::min(static_cast<size_t>(N - size_), s.size());
+ memcpy(buffer_ + size_, s.data(), total);
+ size_ += total;
+ buffer_[size_] = '\0';
+ return *this;
+ }
+
+ FixedString& appendString(const char *s) {
+ // strncpy zero pads to the end,
+ // strlcpy returns total expected length,
+ // we don't have strncpy_s in Bionic,
+ // so we write our own here.
+ while (size_ < N && *s != '\0') {
+ buffer_[size_++] = *s++;
+ }
+ buffer_[size_] = '\0';
+ return *this;
+ }
+
+ // Copy initialize the struct.
+ // Note: We are POD but customize the copying for acceleration
+ // of moving small strings embedded in a large buffers.
+ template <uint32_t U>
+ FixedString& copyFrom(const FixedString<U>& other) {
+ if ((void*)this != (void*)&other) { // not a self-assignment
+ if (other.size() == 0) {
+ size_ = 0;
+ buffer_[0] = '\0';
+ return *this;
+ }
+ constexpr size_t kSizeToCopyWhole = 64;
+ if constexpr (N == U &&
+ sizeof(*this) == sizeof(other) &&
+ sizeof(*this) <= kSizeToCopyWhole) {
+ // As we have the same str size type, we can just
+ // memcpy with fixed size, which can be easily optimized.
+ memcpy(static_cast<void*>(this), static_cast<const void*>(&other), sizeof(*this));
+ return *this;
+ }
+ if constexpr (std::is_same_v<strsize_t, typename FixedString<U>::strsize_t>) {
+ constexpr size_t kAlign = 8; // align to a multiple of 8.
+ static_assert((kAlign & (kAlign - 1)) == 0); // power of 2.
+ // we check any alignment issues.
+ if (buffer_offset() == other.buffer_offset() && other.size() <= capacity()) {
+ // improve on standard POD copying by reducing size.
+ const size_t mincpy = buffer_offset() + other.size() + 1 /* nul */;
+ const size_t maxcpy = std::min(sizeof(*this), sizeof(other));
+ const size_t cpysize = std::min(mincpy + kAlign - 1 & ~(kAlign - 1), maxcpy);
+ memcpy(static_cast<void*>(this), static_cast<const void*>(&other), cpysize);
+ return *this;
+ }
+ }
+ size_ = std::min(other.size(), capacity());
+ memcpy(buffer_, other.data(), size_);
+ buffer_[size_] = '\0'; // zero terminate.
+ }
+ return *this;
+ }
+
+private:
+ // Template helper methods
+
+ template <typename Test, template <uint32_t> class Ref>
+ struct is_specialization : std::false_type {};
+
+ template <template <uint32_t> class Ref, uint32_t UU>
+ struct is_specialization<Ref<UU>, Ref>: std::true_type {};
+
+ template <typename Test, template <uint32_t> class Ref>
+ static inline constexpr bool is_specialization_v = is_specialization<Test, Ref>::value;
+
+ // For static assert(false) we need a template version to avoid early failure.
+ template <typename T>
+ static inline constexpr bool dependent_false_v = false;
+
+ // POD variables
+ strsize_t size_ = 0;
+ char buffer_[N + 1 /* allow zero termination */];
+};
+
+// Stream operator syntactic sugar.
+// Example:
+// s << 'b' << "c" << "d" << '\n';
+template <uint32_t N, typename ...Types>
+FixedString<N>& operator<<(FixedString<N>& fs, Types&&... args) {
+ return fs.append(std::forward<Types>(args)...);
+}
+
+// We do not use a default size for fixed string as changing
+// the default size would lead to different behavior - we want the
+// size to be explicitly known.
+
+// FixedString62 of 62 chars fits in one typical cache line.
+using FixedString62 = FixedString<62>;
+
+// Slightly smaller
+using FixedString30 = FixedString<30>;
+
+// Since we have added copy and assignment optimizations,
+// we are no longer trivially assignable and copyable.
+// But we check standard layout here to prevent inclusion of unacceptable members or virtuals.
+static_assert(std::is_standard_layout_v<FixedString62>);
+static_assert(std::is_standard_layout_v<FixedString30>);
+
+} // namespace android::mediautils
diff --git a/media/utils/include/mediautils/InPlaceFunction.h b/media/utils/include/mediautils/InPlaceFunction.h
new file mode 100644
index 0000000..17c6274
--- /dev/null
+++ b/media/utils/include/mediautils/InPlaceFunction.h
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2022 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 <cstdlib>
+#include <functional>
+#include <memory>
+#include <type_traits>
+
+namespace android::mediautils {
+
+namespace detail {
+// Vtable interface for erased types
+template <typename Ret, typename... Args>
+struct ICallableTable {
+ // Destroy the erased type
+ void (*destroy)(void* storage) = nullptr;
+ // Call the erased object
+ Ret (*invoke)(void* storage, Args&&...) = nullptr;
+ // **Note** the next two functions only copy object data, not the vptr
+ // Copy the erased object to a new InPlaceFunction buffer
+ void (*copy_to)(const void* storage, void* other) = nullptr;
+ // Move the erased object to a new InPlaceFunction buffer
+ void (*move_to)(void* storage, void* other) = nullptr;
+};
+} // namespace detail
+
+// This class is an *almost* drop-in replacement for std::function which is guaranteed to never
+// allocate, and always holds the type erased functional object in an in-line small buffer of
+// templated size. If the object is too large to hold, the type will fail to instantiate.
+//
+// Some notable differences are:
+// - operator() is not const (unlike std::function where the call operator is
+// const even if the erased type is not const callable). This retains const
+// correctness by default. A workaround is keeping InPlaceFunction mutable.
+// - Moving from an InPlaceFunction leaves the object in a valid state (operator
+// bool remains true), similar to std::optional/std::variant.
+// Calls to the object are still defined (and are equivalent
+// to calling the underlying type after it has been moved from). To opt-out
+// (and/or ensure safety), clearing the object is recommended:
+// func1 = std::move(func2); // func2 still valid (and moved-from) after this line
+// func2 = nullptr; // calling func2 will now abort
+// - Unsafe implicit conversions of the return value to a reference type are
+// prohibited due to the risk of dangling references (some of this safety was
+// added to std::function in c++23). Only converting a reference to a reference to base class is
+// permitted:
+// std::function<Base&()> = []() -> Derived& {...}
+// - Some (current libc++ implementation) implementations of std::function
+// incorrectly fail to handle returning non-moveable types which is valid given
+// mandatory copy elision.
+//
+// Additionally, the stored functional will use the typical rules of overload
+// resolution to disambiguate the correct call, except, the target class will
+// always be implicitly a non-const lvalue when called. If a different overload
+// is preferred, wrapping the target class in a lambda with explicit casts is
+// recommended (or using inheritance, mixins or CRTP). This avoids the
+// complexity of utilizing abonimable function types as template params.
+template <typename, size_t BufferSize = 32>
+class InPlaceFunction;
+// We partially specialize to match types which are spelled like functions
+template <typename Ret, typename... Args, size_t BufferSize>
+class InPlaceFunction<Ret(Args...), BufferSize> {
+ public:
+ // Storage Type Details
+ static constexpr size_t Size = BufferSize;
+ static constexpr size_t Alignment = alignof(std::max_align_t);
+ using Buffer_t = std::aligned_storage_t<Size, Alignment>;
+ template <typename T, size_t Other>
+ friend class InPlaceFunction;
+
+ private:
+ // Callable which is used for empty InPlaceFunction objects (to match the
+ // std::function interface).
+ struct BadCallable {
+ [[noreturn]] Ret operator()(Args...) { std::abort(); }
+ };
+ static_assert(std::is_trivially_destructible_v<BadCallable>);
+
+ // Implementation of vtable interface for erased types.
+ // Contains only static vtable instantiated once for each erased type and
+ // static helpers.
+ template <typename T>
+ struct TableImpl {
+ // T should be a decayed type
+ static_assert(std::is_same_v<T, std::decay_t<T>>);
+
+ // Helper functions to get an unerased reference to the type held in the
+ // buffer. std::launder is required to avoid strict aliasing rules.
+ // The cast is always defined, as a precondition for these calls is that
+ // (exactly) a T was placement new constructed into the buffer.
+ constexpr static T& getRef(void* storage) {
+ return *std::launder(reinterpret_cast<T*>(storage));
+ }
+
+ constexpr static const T& getRef(const void* storage) {
+ return *std::launder(reinterpret_cast<const T*>(storage));
+ }
+
+ // Constexpr implies inline
+ constexpr static detail::ICallableTable<Ret, Args...> table = {
+ // Stateless lambdas are convertible to function ptrs
+ .destroy = [](void* storage) { getRef(storage).~T(); },
+ .invoke = [](void* storage, Args&&... args) -> Ret {
+ if constexpr (std::is_void_v<Ret>) {
+ std::invoke(getRef(storage), std::forward<Args>(args)...);
+ } else {
+ return std::invoke(getRef(storage), std::forward<Args>(args)...);
+ }
+ },
+ .copy_to = [](const void* storage,
+ void* other) { ::new (other) T(getRef(storage)); },
+ .move_to = [](void* storage,
+ void* other) { ::new (other) T(std::move(getRef(storage))); },
+ };
+ };
+
+ // Check size/align requirements for the T in Buffer_t.
+ template <typename T>
+ static constexpr bool WillFit_v = sizeof(T) <= Size && alignof(T) <= Alignment;
+
+ // Check size/align requirements for a function to function conversion
+ template <typename T>
+ static constexpr bool ConversionWillFit_v = (T::Size < Size) && (T::Alignment <= Alignment);
+
+ template <typename T>
+ struct IsInPlaceFunction : std::false_type {};
+
+ template <size_t BufferSize_>
+ struct IsInPlaceFunction<InPlaceFunction<Ret(Args...), BufferSize_>> : std::true_type {};
+
+ template <typename T>
+ static T BetterDeclval();
+ template <typename T>
+ static void CheckImplicitConversion(T);
+
+ template <class T, class U, class = void>
+ struct CanImplicitConvert : std::false_type {};
+
+ // std::is_convertible/std::invokeable has a bug (in libc++) regarding
+ // mandatory copy elision for non-moveable types. So, we roll our own.
+ // https://github.com/llvm/llvm-project/issues/55346
+ template <class From, class To>
+ struct CanImplicitConvert<From, To,
+ decltype(CheckImplicitConversion<To>(BetterDeclval<From>()))>
+ : std::true_type {};
+
+ // Check if the provided type is a valid functional to be type-erased.
+ // if constexpr utilized for short-circuit behavior
+ template <typename T>
+ static constexpr bool isValidFunctional() {
+ using Target = std::decay_t<T>;
+ if constexpr (IsInPlaceFunction<Target>::value || std::is_same_v<Target, std::nullptr_t>) {
+ // Other overloads handle these cases
+ return false;
+ } else if constexpr (std::is_invocable_v<Target, Args...>) {
+ // The target type is a callable (with some unknown return value)
+ if constexpr (std::is_void_v<Ret>) {
+ // Any return value can be dropped to model a void returning
+ // function.
+ return WillFit_v<Target>;
+ } else {
+ using RawRet = std::invoke_result_t<Target, Args...>;
+ if constexpr (CanImplicitConvert<RawRet, Ret>::value) {
+ if constexpr (std::is_reference_v<Ret>) {
+ // If the return type is a reference, in order to
+ // avoid dangling references, we only permit functionals
+ // which return a reference to the exact type, or a base
+ // type.
+ if constexpr (std::is_reference_v<RawRet> &&
+ (std::is_same_v<std::decay_t<Ret>, std::decay_t<RawRet>> ||
+ std::is_base_of_v<std::decay_t<Ret>,
+ std::decay_t<RawRet>>)) {
+ return WillFit_v<Target>;
+ }
+ return false;
+ }
+ return WillFit_v<Target>;
+ }
+ // If we can't convert the raw return type, the functional is invalid.
+ return false;
+ }
+ }
+ return false;
+ }
+
+ template <typename T>
+ static constexpr bool IsValidFunctional_v = isValidFunctional<T>();
+ // Check if the type is a strictly smaller sized InPlaceFunction
+ template <typename T>
+ static constexpr bool isConvertibleFunc() {
+ using Target = std::decay_t<T>;
+ if constexpr (IsInPlaceFunction<Target>::value) {
+ return ConversionWillFit_v<Target>;
+ }
+ return false;
+ }
+
+ template <typename T>
+ static constexpr bool IsConvertibleFunc_v = isConvertibleFunc<T>();
+
+ // Members below
+ // This must come first for alignment
+ Buffer_t storage_;
+ const detail::ICallableTable<Ret, Args...>* vptr_;
+
+ constexpr void copy_to(InPlaceFunction& other) const {
+ vptr_->copy_to(std::addressof(storage_), std::addressof(other.storage_));
+ other.vptr_ = vptr_;
+ }
+
+ constexpr void move_to(InPlaceFunction& other) {
+ vptr_->move_to(std::addressof(storage_), std::addressof(other.storage_));
+ other.vptr_ = vptr_;
+ }
+
+ constexpr void destroy() { vptr_->destroy(std::addressof(storage_)); }
+
+ template <typename T, typename Target = std::decay_t<T>>
+ constexpr void genericInit(T&& t) {
+ vptr_ = &TableImpl<Target>::table;
+ ::new (std::addressof(storage_)) Target(std::forward<T>(t));
+ }
+
+ template <typename T, typename Target = std::decay_t<T>>
+ constexpr void convertingInit(T&& smallerFunc) {
+ // Redundant, but just in-case
+ static_assert(Target::Size < Size && Target::Alignment <= Alignment);
+ if constexpr (std::is_lvalue_reference_v<T>) {
+ smallerFunc.vptr_->copy_to(std::addressof(smallerFunc.storage_),
+ std::addressof(storage_));
+ } else {
+ smallerFunc.vptr_->move_to(std::addressof(smallerFunc.storage_),
+ std::addressof(storage_));
+ }
+ vptr_ = smallerFunc.vptr_;
+ }
+
+ public:
+ // Public interface
+ template <typename T, std::enable_if_t<IsValidFunctional_v<T>>* = nullptr>
+ constexpr InPlaceFunction(T&& t) {
+ genericInit(std::forward<T>(t));
+ }
+
+ // Conversion from smaller functions.
+ template <typename T, std::enable_if_t<IsConvertibleFunc_v<T>>* = nullptr>
+ constexpr InPlaceFunction(T&& t) {
+ convertingInit(std::forward<T>(t));
+ }
+
+ constexpr InPlaceFunction(const InPlaceFunction& other) { other.copy_to(*this); }
+
+ constexpr InPlaceFunction(InPlaceFunction&& other) { other.move_to(*this); }
+
+ // Making functions default constructible has pros and cons, we will align
+ // with the standard
+ constexpr InPlaceFunction() : InPlaceFunction(BadCallable{}) {}
+
+ constexpr InPlaceFunction(std::nullptr_t) : InPlaceFunction(BadCallable{}) {}
+
+#if __cplusplus >= 202002L
+ constexpr ~InPlaceFunction() {
+#else
+ ~InPlaceFunction() {
+#endif
+ destroy();
+ }
+
+ // The std::function call operator is marked const, but this violates const
+ // correctness. We deviate from the standard and do not mark the operator as
+ // const. Collections of InPlaceFunctions should probably be mutable.
+ constexpr Ret operator()(Args... args) {
+ if constexpr (std::is_void_v<Ret>) {
+ vptr_->invoke(std::addressof(storage_), std::forward<Args>(args)...);
+ } else {
+ return vptr_->invoke(std::addressof(storage_), std::forward<Args>(args)...);
+ }
+ }
+
+ constexpr InPlaceFunction& operator=(const InPlaceFunction& other) {
+ if (std::addressof(other) == this) return *this;
+ destroy();
+ other.copy_to(*this);
+ return *this;
+ }
+
+ constexpr InPlaceFunction& operator=(InPlaceFunction&& other) {
+ if (std::addressof(other) == this) return *this;
+ destroy();
+ other.move_to(*this);
+ return *this;
+ }
+
+ template <typename T, std::enable_if_t<IsValidFunctional_v<T>>* = nullptr>
+ constexpr InPlaceFunction& operator=(T&& t) {
+ // We can't assign to ourselves, since T is a different type
+ destroy();
+ genericInit(std::forward<T>(t));
+ return *this;
+ }
+
+ // Explicitly defining this function saves a move/dtor
+ template <typename T, std::enable_if_t<IsConvertibleFunc_v<T>>* = nullptr>
+ constexpr InPlaceFunction& operator=(T&& t) {
+ // We can't assign to ourselves, since T is different type
+ destroy();
+ convertingInit(std::forward<T>(t));
+ return *this;
+ }
+
+ constexpr InPlaceFunction& operator=(std::nullptr_t) { return operator=(BadCallable{}); }
+
+ // Moved from InPlaceFunctions are still considered valid (similar to
+ // std::optional). If using std::move on a function object explicitly, it is
+ // recommended that the object is reset using nullptr.
+ constexpr explicit operator bool() const { return vptr_ != &TableImpl<BadCallable>::table; }
+
+ constexpr void swap(InPlaceFunction& other) {
+ if (std::addressof(other) == this) return;
+ InPlaceFunction tmp{std::move(other)};
+ other.destroy();
+ move_to(other);
+ destroy();
+ tmp.move_to(*this);
+ }
+
+ friend constexpr void swap(InPlaceFunction& lhs, InPlaceFunction& rhs) { lhs.swap(rhs); }
+};
+
+} // namespace android::mediautils
diff --git a/media/utils/include/mediautils/MethodStatistics.h b/media/utils/include/mediautils/MethodStatistics.h
index 700fbaa..6d7e990 100644
--- a/media/utils/include/mediautils/MethodStatistics.h
+++ b/media/utils/include/mediautils/MethodStatistics.h
@@ -55,15 +55,23 @@
/**
* Adds a method event, typically execution time in ms.
*/
- void event(Code code, FloatType executeMs) {
+ template <typename C>
+ void event(C&& code, FloatType executeMs) {
std::lock_guard lg(mLock);
- mStatisticsMap[code].add(executeMs);
+ auto it = mStatisticsMap.lower_bound(code);
+ if (it != mStatisticsMap.end() && it->first == code) {
+ it->second.add(executeMs);
+ } else {
+ // StatsType ctor takes an optional array of data for initialization.
+ FloatType dataArray[1] = { executeMs };
+ mStatisticsMap.emplace_hint(it, std::forward<C>(code), dataArray);
+ }
}
/**
* Returns the name for the method code.
*/
- std::string getMethodForCode(Code code) const {
+ std::string getMethodForCode(const Code& code) const {
auto it = mMethodMap.find(code);
return it == mMethodMap.end() ? std::to_string((int)code) : it->second;
}
@@ -71,7 +79,7 @@
/**
* Returns the number of times the method was invoked by event().
*/
- size_t getMethodCount(Code code) const {
+ size_t getMethodCount(const Code& code) const {
std::lock_guard lg(mLock);
auto it = mStatisticsMap.find(code);
return it == mStatisticsMap.end() ? 0 : it->second.getN();
@@ -80,7 +88,7 @@
/**
* Returns the statistics object for the method.
*/
- StatsType getStatistics(Code code) const {
+ StatsType getStatistics(const Code& code) const {
std::lock_guard lg(mLock);
auto it = mStatisticsMap.find(code);
return it == mStatisticsMap.end() ? StatsType{} : it->second;
@@ -107,9 +115,10 @@
}
private:
- const std::map<Code, std::string> mMethodMap;
+ // Note: we use a transparent comparator std::less<> for heterogeneous key lookup.
+ const std::map<Code, std::string, std::less<>> mMethodMap;
mutable std::mutex mLock;
- std::map<Code, StatsType> mStatisticsMap GUARDED_BY(mLock);
+ std::map<Code, StatsType, std::less<>> mStatisticsMap GUARDED_BY(mLock);
};
// Managed Statistics support.
diff --git a/media/libstagefright/include/media/stagefright/ProcessInfo.h b/media/utils/include/mediautils/ProcessInfo.h
similarity index 90%
rename from media/libstagefright/include/media/stagefright/ProcessInfo.h
rename to media/utils/include/mediautils/ProcessInfo.h
index 06b9c92..9afa3df 100644
--- a/media/libstagefright/include/media/stagefright/ProcessInfo.h
+++ b/media/utils/include/mediautils/ProcessInfo.h
@@ -18,8 +18,7 @@
#define PROCESS_INFO_H_
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/ProcessInfoInterface.h>
+#include <mediautils/ProcessInfoInterface.h>
#include <map>
#include <mutex>
#include <utils/Condition.h>
@@ -46,7 +45,8 @@
std::mutex mOverrideLock;
std::map<int, ProcessInfoOverride> mOverrideMap GUARDED_BY(mOverrideLock);
- DISALLOW_EVIL_CONSTRUCTORS(ProcessInfo);
+ ProcessInfo(const ProcessInfo&) = delete;
+ ProcessInfo& operator=(const ProcessInfo&) = delete;
};
} // namespace android
diff --git a/media/libstagefright/include/media/stagefright/ProcessInfoInterface.h b/media/utils/include/mediautils/ProcessInfoInterface.h
similarity index 93%
rename from media/libstagefright/include/media/stagefright/ProcessInfoInterface.h
rename to media/utils/include/mediautils/ProcessInfoInterface.h
index b7fc858..b6529fc 100644
--- a/media/libstagefright/include/media/stagefright/ProcessInfoInterface.h
+++ b/media/utils/include/mediautils/ProcessInfoInterface.h
@@ -25,8 +25,8 @@
virtual bool getPriority(int pid, int* priority) = 0;
virtual bool isPidTrusted(int pid) = 0;
virtual bool isPidUidTrusted(int pid, int uid) = 0;
- virtual bool overrideProcessInfo(int pid, int procState, int oomScore);
- virtual void removeProcessInfoOverride(int pid);
+ virtual bool overrideProcessInfo(int pid, int procState, int oomScore) = 0;
+ virtual void removeProcessInfoOverride(int pid) = 0;
protected:
virtual ~ProcessInfoInterface() {}
diff --git a/media/utils/include/mediautils/SharedMemoryAllocator.h b/media/utils/include/mediautils/SharedMemoryAllocator.h
new file mode 100644
index 0000000..cf3a662
--- /dev/null
+++ b/media/utils/include/mediautils/SharedMemoryAllocator.h
@@ -0,0 +1,470 @@
+/*
+** Copyright 2022, 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 <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <iomanip>
+#include <limits>
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <log/log_main.h>
+#include <utils/StrongPointer.h>
+
+namespace std {
+template <typename T>
+struct hash<::android::wp<T>> {
+ size_t operator()(const ::android::wp<T>& x) const {
+ return std::hash<const T*>()(x.unsafe_get());
+ }
+};
+} // namespace std
+
+namespace android::mediautils {
+
+// Allocations represent owning handles to a region of shared memory (and thus
+// should not be copied in order to fulfill RAII).
+// To share ownership between multiple objects, a
+// ref-counting solution such as sp or shared ptr is appropriate, so the dtor
+// is called once for a particular block of memory.
+
+using AllocationType = ::android::sp<IMemory>;
+using WeakAllocationType = ::android::wp<IMemory>;
+
+namespace shared_allocator_impl {
+constexpr inline size_t roundup(size_t size, size_t pageSize) {
+ LOG_ALWAYS_FATAL_IF(pageSize == 0 || (pageSize & (pageSize - 1)) != 0,
+ "Page size not multiple of 2");
+ return ((size + pageSize - 1) & ~(pageSize - 1));
+}
+
+constexpr inline bool isHeapValid(const sp<IMemoryHeap>& heap) {
+ return (heap && heap->getBase() &&
+ heap->getBase() != MAP_FAILED); // TODO if not mapped locally
+}
+
+template <typename, typename = void>
+static constexpr bool has_deallocate_all = false;
+
+template <typename T>
+static constexpr bool has_deallocate_all<
+ T, std::enable_if_t<std::is_same_v<decltype(std::declval<T>().deallocate_all()), void>,
+ void>> = true;
+
+template <typename, typename = void>
+static constexpr bool has_owns = false;
+
+template <typename T>
+static constexpr bool
+ has_owns<T, std::enable_if_t<std::is_same_v<decltype(std::declval<T>().owns(
+ std::declval<const AllocationType>())),
+ bool>,
+ void>> = true;
+
+template <typename, typename = void>
+static constexpr bool has_dump = false;
+
+template <typename T>
+static constexpr bool has_dump<
+ T,
+ std::enable_if_t<std::is_same_v<decltype(std::declval<T>().dump()), std::string>, void>> =
+ true;
+
+} // namespace shared_allocator_impl
+
+struct BasicAllocRequest {
+ size_t size;
+};
+struct NamedAllocRequest : public BasicAllocRequest {
+ std::string_view name;
+};
+
+// We are required to add a layer of indirection to hold a handle to the actual
+// block due to sp<> being unable to be created from an object once its
+// ref-count has dropped to zero. So, we have to hold onto an extra reference
+// here. We effectively want to know when the refCount of the object drops to
+// one, since we need to hold on to a reference to pass the object to interfaces
+// requiring an sp<>.
+// TODO is there some way to avoid paying this cost?
+template <typename Allocator>
+class ScopedAllocator;
+template <typename AllocationT, typename AllocatorHandleType>
+class ScopedAllocation : public BnMemory {
+ public:
+ template <typename T>
+ friend class ScopedAllocator;
+ ScopedAllocation(const AllocationT& allocation, const AllocatorHandleType& handle)
+ : mAllocation(allocation), mHandle(handle) {}
+
+ // Defer the implementation to the underlying mAllocation
+
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset = nullptr,
+ size_t* size = nullptr) const override {
+ return mAllocation->getMemory(offset, size);
+ }
+
+ private:
+ ~ScopedAllocation() override { mHandle->deallocate(mAllocation); }
+
+ const AllocationT mAllocation;
+ const AllocatorHandleType mHandle;
+};
+
+// Allocations are only deallocated when going out of scope.
+// This should almost always be the outermost allocator.
+template <typename Allocator>
+class ScopedAllocator {
+ public:
+ using HandleT = std::shared_ptr<Allocator>;
+ static constexpr size_t alignment() { return Allocator::alignment(); }
+
+ explicit ScopedAllocator(const std::shared_ptr<Allocator>& allocator) : mAllocator(allocator) {}
+
+ ScopedAllocator() : mAllocator(std::make_shared<Allocator>()) {}
+
+ template <typename T>
+ auto allocate(T&& request) {
+ const auto allocation = mAllocator->allocate(std::forward<T>(request));
+ if (!allocation) {
+ return sp<ScopedAllocation<AllocationType, HandleT>>{};
+ }
+ return sp<ScopedAllocation<AllocationType, HandleT>>::make(allocation, mAllocator);
+ }
+
+ // Deallocate and deallocate_all are implicitly unsafe due to double
+ // deallocates upon ScopedAllocation destruction. We can protect against this
+ // efficiently with a gencount (for deallocate_all) or inefficiently (for
+ // deallocate) but we choose not to
+ //
+ // Owns is only safe to pseudo-impl due to static cast reqs
+ template <typename Enable = bool>
+ auto owns(const sp<ScopedAllocation<AllocationType, HandleT>>& allocation) const
+ -> std::enable_if_t<shared_allocator_impl::has_owns<Allocator>, Enable> {
+ return mAllocator->owns(allocation->mAllocation);
+ }
+
+ template <typename Enable = std::string>
+ auto dump() const -> std::enable_if_t<shared_allocator_impl::has_dump<Allocator>, Enable> {
+ return mAllocator->dump();
+ }
+
+ private:
+ // We store a shared pointer in order to ensure that the allocator outlives
+ // allocations (which call back to become dereferenced).
+ const HandleT mAllocator;
+};
+
+// A simple policy for PolicyAllocator which enforces a pool size and an allocation
+// size range.
+template <size_t PoolSize, size_t MinAllocSize = 0,
+ size_t MaxAllocSize = std::numeric_limits<size_t>::max()>
+class SizePolicy {
+ static_assert(PoolSize > 0);
+
+ public:
+ template <typename T>
+ bool isValid(T&& request) const {
+ static_assert(std::is_base_of_v<BasicAllocRequest, std::decay_t<T>>);
+ return !(request.size > kMaxAllocSize || request.size < kMinAllocSize ||
+ mPoolSize + request.size > kPoolSize);
+ }
+
+ void allocated(const AllocationType& alloc) { mPoolSize += alloc->size(); }
+
+ void deallocated(const AllocationType& alloc) { mPoolSize -= alloc->size(); }
+
+ void deallocated_all() { mPoolSize = 0; }
+
+ static constexpr size_t kPoolSize = PoolSize;
+ static constexpr size_t kMinAllocSize = MinAllocSize;
+ static constexpr size_t kMaxAllocSize = MaxAllocSize;
+
+ private:
+ size_t mPoolSize = 0;
+};
+
+// An allocator which accepts or rejects allocation requests by a parametrized
+// policy (which can carry state).
+template <typename Allocator, typename Policy>
+class PolicyAllocator {
+ public:
+ static constexpr size_t alignment() { return Allocator::alignment(); }
+
+ PolicyAllocator(Allocator allocator, Policy policy)
+ : mAllocator(allocator), mPolicy(std::move(policy)) {}
+
+ // Default initialize the allocator and policy
+ PolicyAllocator() = default;
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ static_assert(std::is_base_of_v<android::mediautils::BasicAllocRequest, std::decay_t<T>>);
+ request.size = shared_allocator_impl::roundup(request.size, alignment());
+ if (!mPolicy.isValid(request)) {
+ return {};
+ }
+ AllocationType val = mAllocator.allocate(std::forward<T>(request));
+ if (val == nullptr) return val;
+ mPolicy.allocated(val);
+ return val;
+ }
+
+ void deallocate(const AllocationType& allocation) {
+ if (!allocation) return;
+ mPolicy.deallocated(allocation);
+ mAllocator.deallocate(allocation);
+ }
+
+ template <typename Enable = void>
+ auto deallocate_all()
+ -> std::enable_if_t<shared_allocator_impl::has_deallocate_all<Allocator>, Enable> {
+ mAllocator.deallocate_all();
+ mPolicy.deallocated_all();
+ }
+
+ template <typename Enable = bool>
+ auto owns(const AllocationType& allocation) const
+ -> std::enable_if_t<shared_allocator_impl::has_owns<Allocator>, Enable> {
+ return mAllocator.owns(allocation);
+ }
+
+ template <typename Enable = std::string>
+ auto dump() const -> std::enable_if_t<shared_allocator_impl::has_dump<Allocator>, Enable> {
+ return mAllocator.dump();
+ }
+
+ private:
+ [[no_unique_address]] Allocator mAllocator;
+ [[no_unique_address]] Policy mPolicy;
+};
+
+// An allocator which keeps track of outstanding allocations for logging and
+// querying ownership.
+template <class Allocator>
+class SnoopingAllocator {
+ public:
+ struct AllocationData {
+ std::string name;
+ size_t allocation_number;
+ };
+ static constexpr size_t alignment() { return Allocator::alignment(); }
+
+ SnoopingAllocator(Allocator allocator, std::string_view name)
+ : mName(name), mAllocator(std::move(allocator)) {}
+
+ explicit SnoopingAllocator(std::string_view name) : mName(name), mAllocator(Allocator{}) {}
+
+ explicit SnoopingAllocator(Allocator allocator) : mAllocator(std::move(allocator)) {}
+
+ // Default construct allocator and name
+ SnoopingAllocator() = default;
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ static_assert(std::is_base_of_v<NamedAllocRequest, std::decay_t<T>>);
+ AllocationType allocation = mAllocator.allocate(request);
+ if (allocation)
+ mAllocations.insert({WeakAllocationType{allocation},
+ {std::string{request.name}, mAllocationNumber++}});
+ return allocation;
+ }
+
+ void deallocate(const AllocationType& allocation) {
+ if (!allocation) return;
+ mAllocations.erase(WeakAllocationType{allocation});
+ mAllocator.deallocate(allocation);
+ }
+
+ void deallocate_all() {
+ if constexpr (shared_allocator_impl::has_deallocate_all<Allocator>) {
+ mAllocator.deallocate_all();
+ } else {
+ for (auto& [mem, value] : mAllocations) {
+ mAllocator.deallocate(mem);
+ }
+ }
+ mAllocations.clear();
+ }
+
+ bool owns(const AllocationType& allocation) const {
+ return (mAllocations.count(WeakAllocationType{allocation}) > 0);
+ }
+
+ std::string dump() const {
+ std::ostringstream dump;
+ dump << mName << " Allocator Dump:\n";
+ dump << std::setw(8) << "HeapID" << std::setw(8) << "Size" << std::setw(8) << "Offset"
+ << std::setw(8) << "Order"
+ << " Name\n";
+ for (auto& [mem, value] : mAllocations) {
+ // TODO Imem size and offset
+ const AllocationType handle = mem.promote();
+ if (!handle) {
+ dump << "Invalid memory lifetime!";
+ continue;
+ }
+ const auto heap = handle->getMemory();
+ dump << std::setw(8) << heap->getHeapID() << std::setw(8) << heap->getOffset()
+ << std::setw(8) << heap->getSize() << std::setw(8) << value.allocation_number
+ << " " << value.name << "\n";
+ }
+ return dump.str();
+ }
+
+ const std::unordered_map<WeakAllocationType, AllocationData>& getAllocations() {
+ return mAllocations;
+ }
+
+ private:
+ const std::string mName;
+ [[no_unique_address]] Allocator mAllocator;
+ // We don't take copies of the underlying information in an allocation,
+ // rather, the allocation information is put on the heap and referenced via
+ // a ref-counted solution. So, the address of the allocation information is
+ // appropriate to hash. In order for this block to be freed, the underlying
+ // allocation must be referenced by no one (thus deallocated).
+ std::unordered_map<WeakAllocationType, AllocationData> mAllocations;
+ // For debugging purposes, monotonic
+ size_t mAllocationNumber = 0;
+};
+
+// An allocator which passes a failed allocation request to a backup allocator.
+template <class PrimaryAllocator, class SecondaryAllocator>
+class FallbackAllocator {
+ public:
+ static_assert(PrimaryAllocator::alignment() == SecondaryAllocator::alignment());
+ static_assert(shared_allocator_impl::has_owns<PrimaryAllocator>);
+
+ static constexpr size_t alignment() { return PrimaryAllocator::alignment(); }
+
+ FallbackAllocator(const PrimaryAllocator& primary, const SecondaryAllocator& secondary)
+ : mPrimary(primary), mSecondary(secondary) {}
+
+ // Default construct primary and secondary allocator
+ FallbackAllocator() = default;
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ AllocationType allocation = mPrimary.allocate(std::forward<T>(request));
+ if (!allocation) allocation = mSecondary.allocate(std::forward<T>(request));
+ return allocation;
+ }
+
+ void deallocate(const AllocationType& allocation) {
+ if (!allocation) return;
+ if (mPrimary.owns(allocation)) {
+ mPrimary.deallocate(allocation);
+ } else {
+ mSecondary.deallocate(allocation);
+ }
+ }
+
+ template <typename Enable = void>
+ auto deallocate_all() -> std::enable_if_t<
+ shared_allocator_impl::has_deallocate_all<PrimaryAllocator> &&
+ shared_allocator_impl::has_deallocate_all<SecondaryAllocator>,
+ Enable> {
+ mPrimary.deallocate_all();
+ mSecondary.deallocate_all();
+ }
+
+ template <typename Enable = bool>
+ auto owns(const AllocationType& allocation) const
+ -> std::enable_if_t<shared_allocator_impl::has_owns<SecondaryAllocator>, Enable> {
+ return mPrimary.owns(allocation) || mSecondary.owns(allocation);
+ }
+
+ template <typename Enable = std::string>
+ auto dump() const
+ -> std::enable_if_t<shared_allocator_impl::has_dump<PrimaryAllocator> &&
+ shared_allocator_impl::has_dump<SecondaryAllocator>,
+ Enable> {
+ return std::string("Primary: \n") + mPrimary.dump() + std::string("Secondary: \n") +
+ mSecondary.dump();
+ }
+
+ private:
+ [[no_unique_address]] PrimaryAllocator mPrimary;
+ [[no_unique_address]] SecondaryAllocator mSecondary;
+};
+
+// An allocator which is backed by a shared_ptr to an allocator, so multiple
+// allocators can share the same backing allocator (and thus the same state).
+template <typename Allocator>
+class IndirectAllocator {
+ public:
+ static constexpr size_t alignment() { return Allocator::alignment(); }
+
+ explicit IndirectAllocator(const std::shared_ptr<Allocator>& allocator)
+ : mAllocator(allocator) {}
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ return mAllocator->allocate(std::forward<T>(request));
+ }
+
+ void deallocate(const AllocationType& allocation) {
+ if (!allocation) return;
+ mAllocator->deallocate(allocation);
+ }
+
+ // We can't implement deallocate_all/dump/owns, since we may not be the only allocator with
+ // access to the underlying allocator (making it not well-defined). If these
+ // methods are necesesary, we need to wrap with a snooping allocator.
+ private:
+ const std::shared_ptr<Allocator> mAllocator;
+};
+
+// Stateless. This allocator allocates full page-aligned MemoryHeapBases (backed by
+// a shared memory mapped anonymous file) as allocations.
+class MemoryHeapBaseAllocator {
+ public:
+ static constexpr size_t alignment() { return 4096; /* PAGE_SIZE */ }
+ static constexpr unsigned FLAGS = 0; // default flags
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ static_assert(std::is_base_of_v<BasicAllocRequest, std::decay_t<T>>);
+ auto heap =
+ sp<MemoryHeapBase>::make(shared_allocator_impl::roundup(request.size, alignment()));
+ if (!shared_allocator_impl::isHeapValid(heap)) {
+ return {};
+ }
+ return sp<MemoryBase>::make(heap, 0, heap->getSize());
+ }
+
+ // Passing a block not allocated by a HeapAllocator is undefined.
+ void deallocate(const AllocationType& allocation) {
+ if (!allocation) return;
+ const auto heap = allocation->getMemory();
+ if (!heap) return;
+ // This causes future mapped accesses (even across process boundaries)
+ // to receive SIGBUS.
+ ftruncate(heap->getHeapID(), 0);
+ // This static cast is safe, since as long as the block was originally
+ // allocated by us, the underlying IMemoryHeap was a MemoryHeapBase
+ static_cast<MemoryHeapBase&>(*heap).dispose();
+ }
+};
+} // namespace android::mediautils
diff --git a/media/utils/include/mediautils/StaticStringView.h b/media/utils/include/mediautils/StaticStringView.h
new file mode 100644
index 0000000..14be240
--- /dev/null
+++ b/media/utils/include/mediautils/StaticStringView.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2022 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 <string_view>
+#include <type_traits>
+
+#pragma push_macro("EXPLICIT_CONVERSION_GENERATE_OPERATOR")
+#undef EXPLICIT_CONVERSION_GENERATE_OPERATOR
+#define EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, op) \
+ friend constexpr bool operator op(T lhs, T rhs) { \
+ return operator op(static_cast<U>(lhs), static_cast<U>(rhs)); \
+ } \
+ friend constexpr bool operator op(T lhs, U rhs) { \
+ return operator op(static_cast<U>(lhs), rhs); \
+ } \
+ friend constexpr bool operator op(U lhs, T rhs) { \
+ return operator op(lhs, static_cast<U>(rhs)); \
+ }
+
+#pragma push_macro("EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS")
+#undef EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS
+// Generate comparison operator friend functions for types (appropriately
+// const/ref qualified) where T is **explicitly** convertible to U.
+#define EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS(T, U) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, ==) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, !=) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, <) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, <=) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, >) \
+ EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, >=)
+
+namespace android::mediautils {
+
+// This class a reference to a string with static storage duration
+// which is const (i.e. a string view). We expose an identical API to
+// string_view, however we do not publicly inherit to avoid potential mis-use of
+// non-virtual dtors/methods.
+//
+// We can create APIs which consume only static strings, which
+// avoids allocation/deallocation of the string locally, as well as potential
+// lifetime issues caused by consuming raw pointers (or string_views).
+// Equivalently, a string_view which is always valid, and whose underlying data
+// can never change.
+//
+// In most cases, the string_view should be initialized at compile time (and there are
+// helpers to do so below). In order to initialize a non-constexpr array,
+// the second template param must be false (i.e. opt-in).
+// Construction/usage as follows (constexpr required unless second template param is false):
+//
+// constexpr static std::array<char, 12> debugString = toStdArray("MyMethodName");
+// constexpr auto myStaticStringView = StaticStringView::create<debugString>();
+// const auto size_t length = myStaticStringView.length() // can call any string_view methods
+// globalLog(myStaticStringView, ...); // Pass to APIs consuming StaticStringViews
+//
+struct StaticStringView final : private std::string_view {
+ template <typename T>
+ struct is_const_char_array : std::false_type {};
+
+ // Use templated value helper
+ template <size_t N>
+ struct is_const_char_array<const std::array<char, N>> : std::true_type {};
+
+ template <typename T>
+ static constexpr bool is_const_char_array_v =
+ is_const_char_array<std::remove_reference_t<T>>::value;
+
+ template <auto& val, std::enable_if_t<is_const_char_array_v<decltype(val)>, bool> Check = true>
+ static constexpr StaticStringView create() {
+ if constexpr (Check) {
+ // If this static_assert fails to compile, this method was called
+ // with a non-constexpr
+ static_assert(val[0]);
+ }
+ return StaticStringView{val.data(), val.size()};
+ }
+
+ // We can copy/move assign/construct from other StaticStringViews as their validity is already
+ // ensured
+ constexpr StaticStringView(const StaticStringView& other) = default;
+ constexpr StaticStringView& operator=(const StaticStringView& other) = default;
+ constexpr StaticStringView(StaticStringView&& other) = default;
+ constexpr StaticStringView& operator=(StaticStringView&& other) = default;
+
+ // Explicitly convert to a std::string_view (this is a strict loss of
+ // information so should only be used across APIs which intend to consume
+ // any std::string_view).
+ constexpr std::string_view getStringView() const { return *this; }
+
+ // The following methods expose an identical API to std::string_view
+ using std::string_view::begin;
+ using std::string_view::cbegin;
+ using std::string_view::cend;
+ using std::string_view::crbegin;
+ using std::string_view::crend;
+ using std::string_view::end;
+ using std::string_view::rbegin;
+ using std::string_view::rend;
+ using std::string_view::operator[];
+ using std::string_view::at;
+ using std::string_view::back;
+ using std::string_view::data;
+ using std::string_view::empty;
+ using std::string_view::front;
+ using std::string_view::length;
+ using std::string_view::max_size;
+ using std::string_view::size;
+ // These modifiers are valid because the resulting view is a
+ // substring of the original static string
+ using std::string_view::remove_prefix;
+ using std::string_view::remove_suffix;
+ // Skip swap
+ using std::string_view::compare;
+ using std::string_view::copy;
+ using std::string_view::find;
+ using std::string_view::find_first_not_of;
+ using std::string_view::find_first_of;
+ using std::string_view::find_last_not_of;
+ using std::string_view::find_last_of;
+ using std::string_view::rfind;
+ using std::string_view::substr;
+#if __cplusplus >= 202202L
+ using std::string_view::ends_with;
+ using std::string_view::starts_with;
+#endif
+ using std::string_view::npos;
+
+ // Non-member friend functions to follow. Identical API to std::string_view
+ template <class CharT, class Traits>
+ friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
+ StaticStringView v) {
+ return os << static_cast<std::string_view&>(v);
+ }
+
+ EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS(const StaticStringView&,
+ const std::string_view&)
+
+ private:
+ constexpr StaticStringView(const char* ptr, size_t sz) : std::string_view(ptr, sz){};
+
+ public:
+ // The next two functions are logically consteval (only avail in c++20).
+ // We can't use templates as params, as they would require references to
+ // static which would unnecessarily bloat executable size.
+ template <typename T, size_t N, size_t M>
+ static constexpr std::array<T, N + M> concatArray(const std::array<T, N>& a,
+ const std::array<T, M>& b) {
+ std::array<T, N + M> res{};
+ for (size_t i = 0; i < N; i++) {
+ res[i] = a[i];
+ }
+ for (size_t i = 0; i < M; i++) {
+ res[N + i] = b[i];
+ }
+ return res;
+ }
+
+ static void arrayIsNotNullTerminated();
+
+ // This method should only be called on C-style char arrays which are
+ // null-terminated. Calling this method on a char array with intermediate null
+ // characters (i.e. "hello\0" or "hel\0lo" will result in a std::array with null
+ // characters, which is most likely not intended.
+ // We attempt to detect a non-null terminated char array at link-time, but
+ // this is best effort. A consequence of this approach is that this method
+ // will fail to link for extern args, or when not inlined. Since this method
+ // is intended to be used constexpr, this is not an issue.
+ template <size_t N>
+ static constexpr std::array<char, N - 1> toStdArray(const char (&input)[N]) {
+ std::array<char, N - 1> res{};
+ for (size_t i = 0; i < N - 1; i++) {
+ res[i] = input[i];
+ }
+ // A workaround to generate a link-time error if toStdArray is not called on
+ // a null-terminated char array.
+ if (input[N - 1] != 0) arrayIsNotNullTerminated();
+ return res;
+ }
+};
+} // namespace android::mediautils
+
+// Specialization of std::hash for use with std::unordered_map
+namespace std {
+template <>
+struct hash<android::mediautils::StaticStringView> {
+ constexpr size_t operator()(const android::mediautils::StaticStringView& val) {
+ return std::hash<std::string_view>{}(val.getStringView());
+ }
+};
+} // namespace std
+
+#pragma pop_macro("EXPLICIT_CONVERSION_GENERATE_OPERATOR")
+#pragma pop_macro("EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS")
diff --git a/media/utils/include/mediautils/TidWrapper.h b/media/utils/include/mediautils/TidWrapper.h
new file mode 100644
index 0000000..aeefa01
--- /dev/null
+++ b/media/utils/include/mediautils/TidWrapper.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 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
+
+#if defined(__linux__)
+#include <signal.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+
+namespace android::mediautils {
+
+// The library wrapper for gettid is only available on bionic. If we don't link
+// against it, we syscall directly.
+inline pid_t getThreadIdWrapper() {
+#if defined(__BIONIC__)
+ return ::gettid();
+#else
+ return syscall(SYS_gettid);
+#endif
+}
+
+// Send an abort signal to a (linux) thread id.
+inline int abortTid(int tid) {
+#if defined(__linux__)
+ const pid_t pid = getpid();
+ siginfo_t siginfo = {
+ .si_code = SI_QUEUE,
+ .si_pid = pid,
+ .si_uid = getuid(),
+ };
+ return syscall(SYS_rt_tgsigqueueinfo, pid, tid, SIGABRT, &siginfo);
+#else
+ errno = ENODEV;
+ return -1;
+#endif
+}
+
+}
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index ef03aef..f9ea50c 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -16,6 +16,7 @@
#pragma once
+#include <chrono>
#include <vector>
#include <mediautils/TimerThread.h>
@@ -27,10 +28,33 @@
class TimeCheck {
public:
+
+ // Duration for TimeCheck is based on steady_clock, typically nanoseconds.
+ using Duration = std::chrono::steady_clock::duration;
+
+ // Duration for printing is in milliseconds, using float for additional precision.
+ using FloatMs = std::chrono::duration<float, std::milli>;
+
+ // OnTimerFunc is the callback function with 2 parameters.
+ // bool timeout (which is true when the TimeCheck object
+ // times out, false when the TimeCheck object is
+ // destroyed or leaves scope before the timer expires.)
+ // float elapsedMs (the elapsed time to this event).
using OnTimerFunc = std::function<void(bool /* timeout */, float /* elapsedMs */ )>;
// The default timeout is chosen to be less than system server watchdog timeout
- static constexpr uint32_t kDefaultTimeOutMs = 5000;
+ // Note: kDefaultTimeOutMs should be no less than 2 seconds, otherwise spurious timeouts
+ // may occur with system suspend.
+ static constexpr TimeCheck::Duration kDefaultTimeoutDuration = std::chrono::milliseconds(3000);
+
+ // Due to suspend abort not incrementing the monotonic clock,
+ // we allow another second chance timeout after the first timeout expires.
+ //
+ // The total timeout is therefore kDefaultTimeoutDuration + kDefaultSecondChanceDuration,
+ // and the result is more stable when the monotonic clock increments during suspend.
+ //
+ static constexpr TimeCheck::Duration kDefaultSecondChanceDuration =
+ std::chrono::milliseconds(2000);
/**
* TimeCheck is a RAII object which will notify a callback
@@ -44,24 +68,24 @@
* the deallocation.
*
* \param tag string associated with the TimeCheck object.
- * \param onTimer callback function with 2 parameters
- * bool timeout (which is true when the TimeCheck object
- * times out, false when the TimeCheck object is
- * destroyed or leaves scope before the timer expires.)
- * float elapsedMs (the elapsed time to this event).
+ * \param onTimer callback function with 2 parameters (described above in OnTimerFunc).
* The callback when timeout is true will be called on a different thread.
* This will cancel the callback on the destructor but is not guaranteed
* to block for callback completion if it is already in progress
* (for maximum concurrency and reduced deadlock potential), so use proper
* lifetime analysis (e.g. shared or weak pointers).
- * \param timeoutMs timeout in milliseconds.
+ * \param requestedTimeoutDuration timeout in milliseconds.
* A zero timeout means no timeout is set -
* the callback is called only when
* the TimeCheck object is destroyed or leaves scope.
+ * \param secondChanceDuration additional milliseconds to wait if the first timeout expires.
+ * This is used to prevent false timeouts if the steady (monotonic)
+ * clock advances on aborted suspend.
* \param crashOnTimeout true if the object issues an abort on timeout.
*/
- explicit TimeCheck(std::string tag, OnTimerFunc&& onTimer = {},
- uint32_t timeoutMs = kDefaultTimeOutMs, bool crashOnTimeout = true);
+ explicit TimeCheck(std::string_view tag, OnTimerFunc&& onTimer,
+ Duration requestedTimeoutDuration, Duration secondChanceDuration,
+ bool crashOnTimeout);
TimeCheck() = default;
// Remove copy constructors as there should only be one call to the destructor.
@@ -79,16 +103,35 @@
// The usage here is const safe.
class TimeCheckHandler {
public:
- const std::string tag;
+ template <typename S, typename F>
+ TimeCheckHandler(S&& _tag, F&& _onTimer, bool _crashOnTimeout,
+ Duration _timeoutDuration, Duration _secondChanceDuration,
+ std::chrono::system_clock::time_point _startSystemTime,
+ pid_t _tid)
+ : tag(std::forward<S>(_tag))
+ , onTimer(std::forward<F>(_onTimer))
+ , crashOnTimeout(_crashOnTimeout)
+ , timeoutDuration(_timeoutDuration)
+ , secondChanceDuration(_secondChanceDuration)
+ , startSystemTime(_startSystemTime)
+ , tid(_tid)
+ {}
+ const FixedString62 tag;
const OnTimerFunc onTimer;
const bool crashOnTimeout;
- const std::chrono::system_clock::time_point startTime;
+ const Duration timeoutDuration;
+ const Duration secondChanceDuration;
+ const std::chrono::system_clock::time_point startSystemTime;
const pid_t tid;
-
void onCancel(TimerThread::Handle handle) const;
- void onTimeout() const;
+ void onTimeout(TimerThread::Handle handle) const;
};
+ // Returns a string that represents the timeout vs elapsed time,
+ // and diagnostics if there are any potential issues.
+ static std::string analyzeTimeouts(
+ float timeoutMs, float elapsedSteadyMs, float elapsedSystemMs);
+
static TimerThread& getTimeCheckThread();
static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
diff --git a/media/utils/include/mediautils/TimerThread.h b/media/utils/include/mediautils/TimerThread.h
index ffee602..d5be177 100644
--- a/media/utils/include/mediautils/TimerThread.h
+++ b/media/utils/include/mediautils/TimerThread.h
@@ -21,12 +21,16 @@
#include <deque>
#include <functional>
#include <map>
+#include <memory>
#include <mutex>
#include <string>
#include <thread>
+#include <vector>
#include <android-base/thread_annotations.h>
+#include <mediautils/FixedString.h>
+
namespace android::mediautils {
/**
@@ -34,19 +38,93 @@
*/
class TimerThread {
public:
- // A Handle is a time_point that serves as a unique key. It is ordered.
+ // A Handle is a time_point that serves as a unique key to access a queued
+ // request to the TimerThread.
using Handle = std::chrono::steady_clock::time_point;
+ // Duration is based on steady_clock (typically nanoseconds)
+ // vs the system_clock duration (typically microseconds).
+ using Duration = std::chrono::steady_clock::duration;
+
static inline constexpr Handle INVALID_HANDLE =
std::chrono::steady_clock::time_point::min();
+ // Handle implementation details:
+ // A Handle represents the timer expiration time based on std::chrono::steady_clock
+ // (clock monotonic). This Handle is computed as now() + timeout.
+ //
+ // The lsb of the Handle time_point is adjusted to indicate whether there is
+ // a timeout action (1) or not (0).
+ //
+
+ template <size_t COUNT>
+ static constexpr bool is_power_of_2_v = COUNT > 0 && (COUNT & (COUNT - 1)) == 0;
+
+ template <size_t COUNT>
+ static constexpr size_t mask_from_count_v = COUNT - 1;
+
+ static constexpr size_t HANDLE_TYPES = 2;
+ // HANDLE_TYPES must be a power of 2.
+ static_assert(is_power_of_2_v<HANDLE_TYPES>);
+
+ // The handle types
+ enum class HANDLE_TYPE : size_t {
+ NO_TIMEOUT = 0,
+ TIMEOUT = 1,
+ };
+
+ static constexpr size_t HANDLE_TYPE_MASK = mask_from_count_v<HANDLE_TYPES>;
+
+ template <typename T>
+ static constexpr auto enum_as_value(T x) {
+ return static_cast<std::underlying_type_t<T>>(x);
+ }
+
+ static inline bool isNoTimeoutHandle(Handle handle) {
+ return (handle.time_since_epoch().count() & HANDLE_TYPE_MASK) ==
+ enum_as_value(HANDLE_TYPE::NO_TIMEOUT);
+ }
+
+ static inline bool isTimeoutHandle(Handle handle) {
+ return (handle.time_since_epoch().count() & HANDLE_TYPE_MASK) ==
+ enum_as_value(HANDLE_TYPE::TIMEOUT);
+ }
+
+ // Returns a unique Handle that doesn't exist in the container.
+ template <size_t MAX_TYPED_HANDLES, size_t HANDLE_TYPE_AS_VALUE, typename C, typename T>
+ static Handle getUniqueHandleForHandleType_l(C container, T timeout) {
+ static_assert(MAX_TYPED_HANDLES > 0 && HANDLE_TYPE_AS_VALUE < MAX_TYPED_HANDLES
+ && is_power_of_2_v<MAX_TYPED_HANDLES>,
+ " handles must be power of two");
+
+ // Our initial handle is the deadline as computed from steady_clock.
+ auto deadline = std::chrono::steady_clock::now() + timeout;
+
+ // We adjust the lsbs by the minimum increment to have the correct
+ // HANDLE_TYPE in the least significant bits.
+ auto remainder = deadline.time_since_epoch().count() & HANDLE_TYPE_MASK;
+ size_t offset = HANDLE_TYPE_AS_VALUE > remainder ? HANDLE_TYPE_AS_VALUE - remainder :
+ MAX_TYPED_HANDLES + HANDLE_TYPE_AS_VALUE - remainder;
+ deadline += std::chrono::steady_clock::duration(offset);
+
+ // To avoid key collisions, advance the handle by MAX_TYPED_HANDLES (the modulus factor)
+ // until the key is unique.
+ while (container.find(deadline) != container.end()) {
+ deadline += std::chrono::steady_clock::duration(MAX_TYPED_HANDLES);
+ }
+ return deadline;
+ }
+
+ // TimerCallback invoked on timeout or cancel.
+ using TimerCallback = std::function<void(Handle)>;
+
/**
* Schedules a task to be executed in the future (`timeout` duration from now).
*
* \param tag string associated with the task. This need not be unique,
* as the Handle returned is used for cancelling.
* \param func callback function that is invoked at the timeout.
- * \param timeout timeout duration which is converted to milliseconds with at
+ * \param timeoutDuration timeout duration which is converted to milliseconds with at
* least 45 integer bits.
* A timeout of 0 (or negative) means the timer never expires
* so func() is never called. These tasks are stored internally
@@ -54,7 +132,8 @@
* \returns a handle that can be used for cancellation.
*/
Handle scheduleTask(
- std::string tag, std::function<void()>&& func, std::chrono::milliseconds timeout);
+ std::string_view tag, TimerCallback&& func,
+ Duration timeoutDuration, Duration secondChanceDuration);
/**
* Tracks a task that shows up on toString() until cancelled.
@@ -62,7 +141,7 @@
* \param tag string associated with the task.
* \returns a handle that can be used for cancellation.
*/
- Handle trackTask(std::string tag);
+ Handle trackTask(std::string_view tag);
/**
* Cancels a task previously scheduled with scheduleTask()
@@ -74,7 +153,15 @@
*/
bool cancelTask(Handle handle);
- std::string toString(size_t retiredCount = SIZE_MAX) const;
+ struct SnapshotAnalysis;
+ /**
+ * Take a snapshot of the current state of the TimerThread and determine the
+ * potential cause of a deadlock.
+ * \param retiredCount The number of successfully retired calls to capture
+ * (may be many).
+ * \return See below for a description of a SnapShotAnalysis object
+ */
+ SnapshotAnalysis getSnapshotAnalysis(size_t retiredCount = SIZE_MAX) const;
/**
* Returns a string representation of the TimerThread queue.
@@ -125,20 +212,69 @@
return s;
}
- private:
// To minimize movement of data, we pass around shared_ptrs to Requests.
// These are allocated and deallocated outside of the lock.
+ // TODO(b/243839867) consider options to merge Request with the
+ // TimeCheck::TimeCheckHandler struct.
struct Request {
+ Request(std::chrono::system_clock::time_point _scheduled,
+ std::chrono::system_clock::time_point _deadline,
+ Duration _secondChanceDuration,
+ pid_t _tid,
+ std::string_view _tag)
+ : scheduled(_scheduled)
+ , deadline(_deadline)
+ , secondChanceDuration(_secondChanceDuration)
+ , tid(_tid)
+ , tag(_tag)
+ {}
+
const std::chrono::system_clock::time_point scheduled;
- const std::chrono::system_clock::time_point deadline; // deadline := scheduled + timeout
+ const std::chrono::system_clock::time_point deadline; // deadline := scheduled
+ // + timeoutDuration
+ // + secondChanceDuration
// if deadline == scheduled, no
// timeout, task not executed.
+ Duration secondChanceDuration;
const pid_t tid;
- const std::string tag;
-
+ const FixedString62 tag;
std::string toString() const;
};
+
+ // SnapshotAnalysis contains info deduced by analysisTimeout().
+
+ struct SnapshotAnalysis {
+ // If we were unable to determine any applicable thread ids,
+ // we leave their value as INVALID_PID.
+ // Note, we use the linux thread id (not pthread), so its type is pid_t.
+ static constexpr pid_t INVALID_PID = -1;
+ // Description of likely issue and/or blocked method.
+ // Empty if no actionable info.
+ std::string description;
+ // Tid of the (latest) monitored thread which has timed out.
+ // This is the thread which the suspect is deduced with respect to.
+ // Most often, this is the thread which an abort is being triggered
+ // from.
+ pid_t timeoutTid = INVALID_PID;
+ // Tid of the (HAL) thread which has likely halted progress, selected
+ // from pendingRequests. May be the same as timeoutTid, if the timed-out
+ // thread directly called into the HAL.
+ pid_t suspectTid = INVALID_PID;
+ // Number of second chances given by the timer thread
+ size_t secondChanceCount;
+ // List of pending requests
+ std::vector<std::shared_ptr<const Request>> pendingRequests;
+ // List of timed-out requests
+ std::vector<std::shared_ptr<const Request>> timeoutRequests;
+ // List of retired requests
+ std::vector<std::shared_ptr<const Request>> retiredRequests;
+ // Dumps the information contained above as well as additional call
+ // stacks where applicable.
+ std::string toString() const;
+ };
+
+ private:
// Deque of requests, in order of add().
// This class is thread-safe.
class RequestQueue {
@@ -160,15 +296,17 @@
mRequestQueue GUARDED_BY(mRQMutex);
};
- // A storage map of tasks without timeouts. There is no std::function<void()>
+ // A storage map of tasks without timeouts. There is no TimerCallback
// required, it just tracks the tasks with the tag, scheduled time and the tid.
// These tasks show up on a pendingToString() until manually cancelled.
class NoTimeoutMap {
- // This a counter of the requests that have no timeout (timeout == 0).
- std::atomic<size_t> mNoTimeoutRequests{};
-
mutable std::mutex mNTMutex;
std::map<Handle, std::shared_ptr<const Request>> mMap GUARDED_BY(mNTMutex);
+ Handle getUniqueHandle_l() REQUIRES(mNTMutex) {
+ return getUniqueHandleForHandleType_l<
+ HANDLE_TYPES, enum_as_value(HANDLE_TYPE::NO_TIMEOUT)>(
+ mMap, Duration{} /* timeout */);
+ }
public:
bool isValidHandle(Handle handle) const; // lock free
@@ -182,14 +320,26 @@
// call on timeout.
// This class is thread-safe.
class MonitorThread {
+ std::atomic<size_t> mSecondChanceCount{};
mutable std::mutex mMutex;
- mutable std::condition_variable mCond;
+ mutable std::condition_variable mCond GUARDED_BY(mMutex);
// Ordered map of requests based on time of deadline.
//
- std::map<Handle, std::pair<std::shared_ptr<const Request>, std::function<void()>>>
+ std::map<Handle, std::pair<std::shared_ptr<const Request>, TimerCallback>>
mMonitorRequests GUARDED_BY(mMutex);
+ // Due to monotonic/steady clock inaccuracies during suspend,
+ // we allow an additional second chance waiting time to prevent
+ // false removal.
+
+ // This mSecondChanceRequests queue is almost always empty.
+ // Using a pair with the original handle allows lookup and keeps
+ // the Key unique.
+ std::map<std::pair<Handle /* new */, Handle /* original */>,
+ std::pair<std::shared_ptr<const Request>, TimerCallback>>
+ mSecondChanceRequests GUARDED_BY(mMutex);
+
RequestQueue& mTimeoutQueue; // locked internally, added to when request times out.
// Worker thread variables
@@ -200,60 +350,32 @@
std::thread mThread;
void threadFunc();
- Handle getUniqueHandle_l(std::chrono::milliseconds timeout) REQUIRES(mMutex);
+ Handle getUniqueHandle_l(Duration timeout) REQUIRES(mMutex) {
+ return getUniqueHandleForHandleType_l<
+ HANDLE_TYPES, enum_as_value(HANDLE_TYPE::TIMEOUT)>(
+ mMonitorRequests, timeout);
+ }
public:
MonitorThread(RequestQueue &timeoutQueue);
~MonitorThread();
- Handle add(std::shared_ptr<const Request> request, std::function<void()>&& func,
- std::chrono::milliseconds timeout);
+ Handle add(std::shared_ptr<const Request> request, TimerCallback&& func,
+ Duration timeout);
std::shared_ptr<const Request> remove(Handle handle);
void copyRequests(std::vector<std::shared_ptr<const Request>>& requests) const;
+ size_t getSecondChanceCount() const {
+ return mSecondChanceCount.load(std::memory_order_relaxed);
+ }
};
- // Analysis contains info deduced by analysisTimeout().
- //
- // Summary is the result string from checking timeoutRequests to see if
- // any might be caused by blocked calls in pendingRequests.
- //
- // Summary string is empty if there is no automatic actionable info.
- //
- // timeoutTid is the tid selected from timeoutRequests (if any).
- //
- // HALBlockedTid is the tid that is blocked from pendingRequests believed
- // to cause the timeout.
- // HALBlockedTid may be INVALID_PID if no suspected tid is found,
- // and if HALBlockedTid is valid, it will not be the same as timeoutTid.
- //
- static constexpr pid_t INVALID_PID = -1;
- struct Analysis {
- std::string summary;
- pid_t timeoutTid = INVALID_PID;
- pid_t HALBlockedTid = INVALID_PID;
- };
// A HAL method is where the substring "Hidl" is in the class name.
// The tag should look like: ... Hidl ... :: ...
static bool isRequestFromHal(const std::shared_ptr<const Request>& request);
- // Returns analysis from the requests.
- static Analysis analyzeTimeout(
- const std::vector<std::shared_ptr<const Request>>& timeoutRequests,
- const std::vector<std::shared_ptr<const Request>>& pendingRequests);
-
std::vector<std::shared_ptr<const Request>> getPendingRequests() const;
- // A no-timeout request is represented by a handles at the end of steady_clock time,
- // counting down by the number of no timeout requests previously requested.
- // We manage them on the NoTimeoutMap, but conceptually they could be scheduled
- // on the MonitorThread because those time handles won't expire in
- // the lifetime of the device.
- static inline Handle getIndexedHandle(size_t index) {
- return std::chrono::time_point<std::chrono::steady_clock>::max() -
- std::chrono::time_point<std::chrono::steady_clock>::duration(index);
- }
-
static constexpr size_t kRetiredQueueMax = 16;
RequestQueue mRetiredQueue{kRetiredQueueMax}; // locked internally
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
index f0e3c1e..0689083 100644
--- a/media/utils/tests/Android.bp
+++ b/media/utils/tests/Android.bp
@@ -20,10 +20,34 @@
],
sanitize: {
- address: true,
- cfi: true,
+ undefined: true,
+ misc_undefined: [
+ "float-divide-by-zero",
+ "local-bounds",
+ ],
integer_overflow: true,
+ cfi: true,
memtag_heap: true,
+ diag: {
+ undefined: true,
+ misc_undefined: [
+ "float-divide-by-zero",
+ "local-bounds",
+ ],
+ integer_overflow: true,
+ cfi: true,
+ memtag_heap: true,
+ },
+ },
+ target: {
+ host: {
+ sanitize: {
+ cfi: false,
+ diag: {
+ cfi: false,
+ },
+ },
+ },
},
}
@@ -35,23 +59,7 @@
host_supported: true,
shared_libs: [
- "liblog",
- "libutils",
- ],
-
- static_libs: [
- "libmediautils_core",
- ],
-}
-
-cc_defaults {
- name: "libmediautils_tests_host_unavail",
-
- defaults: ["libmediautils_tests_config"],
-
- host_supported: false,
-
- shared_libs: [
+ "libbinder",
"liblog",
"libmediautils",
"libutils",
@@ -89,22 +97,17 @@
cc_test {
name: "libmediautils_test",
- defaults: ["libmediautils_tests_host_unavail"],
-
- shared_libs: [
- "libmediautils",
- ],
+ defaults: ["libmediautils_tests_defaults"],
srcs: [
"memory-test.cpp",
- "TimerThread-test.cpp",
],
}
cc_test {
name: "media_process_tests",
- defaults: ["libmediautils_tests_host_unavail"],
+ defaults: ["libmediautils_tests_defaults"],
srcs: [
"media_process_tests.cpp",
@@ -114,7 +117,7 @@
cc_test {
name: "media_synchronization_tests",
- defaults: ["libmediautils_tests_host_unavail"],
+ defaults: ["libmediautils_tests_defaults"],
srcs: [
"media_synchronization_tests.cpp",
@@ -124,7 +127,7 @@
cc_test {
name: "media_threadsnapshot_tests",
- defaults: ["libmediautils_tests_host_unavail"],
+ defaults: ["libmediautils_tests_defaults"],
srcs: [
"media_threadsnapshot_tests.cpp",
@@ -132,6 +135,20 @@
}
cc_test {
+ name: "mediautils_fixedstring_tests",
+
+ defaults: ["libmediautils_tests_defaults"],
+
+ shared_libs: [
+ "libaudioutils",
+ ],
+
+ srcs: [
+ "mediautils_fixedstring_tests.cpp",
+ ],
+}
+
+cc_test {
name: "mediautils_scopedstatistics_tests",
defaults: ["libmediautils_tests_defaults"],
@@ -160,9 +177,19 @@
}
cc_test {
+ name: "static_string_tests",
+
+ defaults: ["libmediautils_tests_defaults"],
+
+ srcs: [
+ "static_string_view_tests.cpp",
+ ],
+}
+
+cc_test {
name: "timecheck_tests",
- defaults: ["libmediautils_tests_host_unavail"],
+ defaults: ["libmediautils_tests_defaults"],
srcs: [
"timecheck_tests.cpp",
@@ -170,6 +197,16 @@
}
cc_test {
+ name: "timerthread_tests",
+
+ defaults: ["libmediautils_tests_defaults"],
+
+ srcs: [
+ "TimerThread-test.cpp",
+ ],
+}
+
+cc_test {
name: "extended_accumulator_tests",
defaults: ["libmediautils_tests_defaults"],
@@ -178,3 +215,21 @@
"extended_accumulator_tests.cpp",
],
}
+
+cc_test {
+ name: "inplace_function_tests",
+
+ defaults: ["libmediautils_tests_defaults"],
+
+ srcs: [
+ "inplace_function_tests.cpp",
+ ],
+}
+
+cc_test {
+ name: "shared_memory_allocator_tests",
+ defaults: ["libmediautils_tests_defaults"],
+ srcs: [
+ "shared_memory_allocator_tests.cpp",
+ ],
+}
diff --git a/media/utils/tests/TimerThread-test.cpp b/media/utils/tests/TimerThread-test.cpp
index 1fbe894..468deed 100644
--- a/media/utils/tests/TimerThread-test.cpp
+++ b/media/utils/tests/TimerThread-test.cpp
@@ -33,10 +33,28 @@
return std::count(s.begin(), s.end(), c);
}
-TEST(TimerThread, Basic) {
+
+// Split msec time between timeout and second chance time
+// This tests expiration times weighted between timeout and the second chance time.
+#define DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(msec, frac) \
+ std::chrono::milliseconds(int((msec) * (frac)) + 1), \
+ std::chrono::milliseconds(int((msec) * (1.f - (frac))))
+
+// The TimerThreadTest is parameterized on a fraction between 0.f and 1.f which
+// is how the total timeout time is split between the first timeout and the second chance time.
+//
+class TimerThreadTest : public ::testing::TestWithParam<float> {
+protected:
+
+static void testBasic() {
+ const auto frac = GetParam();
+
std::atomic<bool> taskRan = false;
TimerThread thread;
- thread.scheduleTask("Basic", [&taskRan] { taskRan = true; }, 100ms);
+ TimerThread::Handle handle =
+ thread.scheduleTask("Basic", [&taskRan](TimerThread::Handle) {
+ taskRan = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
+ ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
std::this_thread::sleep_for(100ms - kJitter);
ASSERT_FALSE(taskRan);
std::this_thread::sleep_for(2 * kJitter);
@@ -46,11 +64,15 @@
ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
}
-TEST(TimerThread, Cancel) {
+static void testCancel() {
+ const auto frac = GetParam();
+
std::atomic<bool> taskRan = false;
TimerThread thread;
TimerThread::Handle handle =
- thread.scheduleTask("Cancel", [&taskRan] { taskRan = true; }, 100ms);
+ thread.scheduleTask("Cancel", [&taskRan](TimerThread::Handle) {
+ taskRan = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
+ ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
std::this_thread::sleep_for(100ms - kJitter);
ASSERT_FALSE(taskRan);
ASSERT_TRUE(thread.cancelTask(handle));
@@ -61,11 +83,17 @@
ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
}
-TEST(TimerThread, CancelAfterRun) {
+static void testCancelAfterRun() {
+ const auto frac = GetParam();
+
std::atomic<bool> taskRan = false;
TimerThread thread;
TimerThread::Handle handle =
- thread.scheduleTask("CancelAfterRun", [&taskRan] { taskRan = true; }, 100ms);
+ thread.scheduleTask("CancelAfterRun",
+ [&taskRan](TimerThread::Handle) {
+ taskRan = true; },
+ DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
+ ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
std::this_thread::sleep_for(100ms + kJitter);
ASSERT_TRUE(taskRan); // timed-out called.
ASSERT_FALSE(thread.cancelTask(handle));
@@ -74,77 +102,70 @@
ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
}
-TEST(TimerThread, MultipleTasks) {
+static void testMultipleTasks() {
+ const auto frac = GetParam();
+
std::array<std::atomic<bool>, 6> taskRan{};
TimerThread thread;
auto startTime = std::chrono::steady_clock::now();
- thread.scheduleTask("0", [&taskRan] { taskRan[0] = true; }, 300ms);
- thread.scheduleTask("1", [&taskRan] { taskRan[1] = true; }, 100ms);
- thread.scheduleTask("2", [&taskRan] { taskRan[2] = true; }, 200ms);
- thread.scheduleTask("3", [&taskRan] { taskRan[3] = true; }, 400ms);
- auto handle4 = thread.scheduleTask("4", [&taskRan] { taskRan[4] = true; }, 200ms);
- thread.scheduleTask("5", [&taskRan] { taskRan[5] = true; }, 200ms);
+ thread.scheduleTask("0", [&taskRan](TimerThread::Handle) {
+ taskRan[0] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(300, frac));
+ thread.scheduleTask("1", [&taskRan](TimerThread::Handle) {
+ taskRan[1] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
+ thread.scheduleTask("2", [&taskRan](TimerThread::Handle) {
+ taskRan[2] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
+ thread.scheduleTask("3", [&taskRan](TimerThread::Handle) {
+ taskRan[3] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(400, frac));
+ auto handle4 = thread.scheduleTask("4", [&taskRan](TimerThread::Handle) {
+ taskRan[4] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
+ thread.scheduleTask("5", [&taskRan](TimerThread::Handle) {
+ taskRan[5] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
// 6 tasks pending
ASSERT_EQ(6ul, countChars(thread.pendingToString(), REQUEST_START));
// 0 tasks completed
ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
+ // None of the tasks are expected to have finished at the start.
+ std::array<std::atomic<bool>, 6> expected{};
+
// Task 1 should trigger around 100ms.
std::this_thread::sleep_until(startTime + 100ms - kJitter);
- ASSERT_FALSE(taskRan[0]);
- ASSERT_FALSE(taskRan[1]);
- ASSERT_FALSE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_FALSE(taskRan[5]);
+
+ ASSERT_EQ(expected, taskRan);
+
std::this_thread::sleep_until(startTime + 100ms + kJitter);
- ASSERT_FALSE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_FALSE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_FALSE(taskRan[5]);
+
+ expected[1] = true;
+ ASSERT_EQ(expected, taskRan);
// Cancel task 4 before it gets a chance to run.
thread.cancelTask(handle4);
// Tasks 2 and 5 should trigger around 200ms.
std::this_thread::sleep_until(startTime + 200ms - kJitter);
- ASSERT_FALSE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_FALSE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_FALSE(taskRan[5]);
+
+ ASSERT_EQ(expected, taskRan);
+
std::this_thread::sleep_until(startTime + 200ms + kJitter);
- ASSERT_FALSE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_TRUE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_TRUE(taskRan[5]);
+
+ expected[2] = true;
+ expected[5] = true;
+ ASSERT_EQ(expected, taskRan);
// Task 0 should trigger around 300ms.
std::this_thread::sleep_until(startTime + 300ms - kJitter);
- ASSERT_FALSE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_TRUE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_TRUE(taskRan[5]);
+
+ ASSERT_EQ(expected, taskRan);
std::this_thread::sleep_until(startTime + 300ms + kJitter);
- ASSERT_TRUE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_TRUE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_TRUE(taskRan[5]);
+
+ expected[0] = true;
+ ASSERT_EQ(expected, taskRan);
// 1 task pending
ASSERT_EQ(1ul, countChars(thread.pendingToString(), REQUEST_START));
@@ -154,24 +175,17 @@
// Task 3 should trigger around 400ms.
std::this_thread::sleep_until(startTime + 400ms - kJitter);
- ASSERT_TRUE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_TRUE(taskRan[2]);
- ASSERT_FALSE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_TRUE(taskRan[5]);
+
+ ASSERT_EQ(expected, taskRan);
// 4 tasks called on timeout and 1 cancelled
ASSERT_EQ(4ul, countChars(thread.timeoutToString(), REQUEST_START));
ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
std::this_thread::sleep_until(startTime + 400ms + kJitter);
- ASSERT_TRUE(taskRan[0]);
- ASSERT_TRUE(taskRan[1]);
- ASSERT_TRUE(taskRan[2]);
- ASSERT_TRUE(taskRan[3]);
- ASSERT_FALSE(taskRan[4]);
- ASSERT_TRUE(taskRan[5]);
+
+ expected[3] = true;
+ ASSERT_EQ(expected, taskRan);
// 0 tasks pending
ASSERT_EQ(0ul, countChars(thread.pendingToString(), REQUEST_START));
@@ -180,6 +194,30 @@
ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
}
+}; // class TimerThreadTest
+
+TEST_P(TimerThreadTest, Basic) {
+ testBasic();
+}
+
+TEST_P(TimerThreadTest, Cancel) {
+ testCancel();
+}
+
+TEST_P(TimerThreadTest, CancelAfterRun) {
+ testCancelAfterRun();
+}
+
+TEST_P(TimerThreadTest, MultipleTasks) {
+ testMultipleTasks();
+}
+
+INSTANTIATE_TEST_CASE_P(
+ TimerThread,
+ TimerThreadTest,
+ ::testing::Values(0.f, 0.5f, 1.f)
+ );
+
TEST(TimerThread, TrackedTasks) {
TimerThread thread;
@@ -187,6 +225,10 @@
auto handle1 = thread.trackTask("1");
auto handle2 = thread.trackTask("2");
+ ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle0));
+ ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle1));
+ ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle2));
+
// 3 tasks pending
ASSERT_EQ(3ul, countChars(thread.pendingToString(), REQUEST_START));
// 0 tasks retired
@@ -210,6 +252,7 @@
// Add another tracked task.
auto handle3 = thread.trackTask("3");
+ ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle3));
// 2 tasks pending
ASSERT_EQ(2ul, countChars(thread.pendingToString(), REQUEST_START));
diff --git a/media/utils/tests/inplace_function_tests.cpp b/media/utils/tests/inplace_function_tests.cpp
new file mode 100644
index 0000000..6172aa4
--- /dev/null
+++ b/media/utils/tests/inplace_function_tests.cpp
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2022 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_TAG "inplace_function_tests"
+
+#include <mediautils/InPlaceFunction.h>
+
+#include <type_traits>
+
+#include <gtest/gtest.h>
+#include <log/log.h>
+
+using namespace android;
+using namespace android::mediautils;
+
+struct BigCallable {
+ BigCallable(size_t* x, size_t val1, size_t val2) : ptr(x), a(val1), b(val2) {}
+ size_t* ptr;
+ size_t a;
+ size_t b;
+ size_t operator()(size_t input) const {
+ *ptr += a * 100 + b * 10 + input;
+ return 8;
+ }
+};
+
+TEST(InPlaceFunctionTests, Basic) {
+ size_t x = 5;
+ InPlaceFunction<size_t(size_t)> func;
+ {
+ BigCallable test{&x, 2, 3};
+ func = test;
+ }
+ EXPECT_EQ(func(2), 8ull);
+ EXPECT_EQ(x, 232ull + 5);
+}
+
+TEST(InPlaceFunctionTests, Invalid) {
+ InPlaceFunction<size_t(size_t)> func;
+ EXPECT_TRUE(!func);
+ InPlaceFunction<size_t(size_t)> func2{nullptr};
+ EXPECT_TRUE(!func2);
+ InPlaceFunction<size_t(size_t)> func3 = [](size_t x) { return x; };
+ EXPECT_TRUE(!(!func3));
+ func3 = nullptr;
+ EXPECT_TRUE(!func3);
+}
+
+TEST(InPlaceFunctionTests, MultiArg) {
+ InPlaceFunction<size_t(size_t, size_t, size_t)> func = [](size_t a, size_t b, size_t c) {
+ return a + b + c;
+ };
+ EXPECT_EQ(func(2, 3, 5), 2ull + 3 + 5);
+}
+struct Record {
+ Record(size_t m, size_t c, size_t d) : move_called(m), copy_called(c), dtor_called(d) {}
+ Record() {}
+ size_t move_called = 0;
+ size_t copy_called = 0;
+ size_t dtor_called = 0;
+ friend std::ostream& operator<<(std::ostream& os, const Record& record) {
+ return os << "Record, moves: " << record.move_called << ", copies: " << record.copy_called
+ << ", dtor: " << record.dtor_called << '\n';
+ }
+};
+
+bool operator==(const Record& lhs, const Record& rhs) {
+ return lhs.move_called == rhs.move_called && lhs.copy_called == rhs.copy_called &&
+ lhs.dtor_called == rhs.dtor_called;
+}
+
+struct Noisy {
+ Record& ref;
+ size_t state;
+ Noisy(Record& record, size_t val) : ref(record), state(val) {}
+ Noisy(const Noisy& other) : ref(other.ref), state(other.state) { ref.copy_called++; }
+
+ Noisy(Noisy&& other) : ref(other.ref), state(other.state) { ref.move_called++; }
+ ~Noisy() { ref.dtor_called++; }
+
+ size_t operator()() { return state; }
+};
+
+TEST(InPlaceFunctionTests, CtorForwarding) {
+ Record record;
+ Noisy noisy{record, 17};
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func(), 17ull);
+ Record record2;
+ Noisy noisy2{record2, 13};
+ InPlaceFunction<size_t()> func2{std::move(noisy2)};
+ EXPECT_EQ(record2, Record(1, 0, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), 13ull);
+}
+
+TEST(InPlaceFunctionTests, FunctionCtorForwarding) {
+ {
+ Record record;
+ Noisy noisy{record, 17};
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func(), 17ull);
+ InPlaceFunction<size_t()> func2{func};
+ EXPECT_EQ(record, Record(0, 2, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), 17ull);
+ }
+ Record record;
+ Noisy noisy{record, 13};
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func(), 13ull);
+ InPlaceFunction<size_t()> func2{std::move(func)};
+ EXPECT_EQ(record, Record(1, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), 13ull);
+ // We expect moved from functions to still be valid
+ EXPECT_TRUE(!(!func));
+ EXPECT_EQ(static_cast<bool>(func), static_cast<bool>(func2));
+ EXPECT_EQ(func(), 13ull);
+}
+
+TEST(InPlaceFunctionTests, Dtor) {
+ Record record;
+ {
+ InPlaceFunction<size_t()> func;
+ {
+ Noisy noisy{record, 17};
+ func = noisy;
+ }
+ EXPECT_EQ(func(), 17ull);
+ EXPECT_EQ(record.dtor_called, 1ull);
+ }
+ EXPECT_EQ(record.dtor_called, 2ull);
+}
+
+TEST(InPlaceFunctionTests, Assignment) {
+ {
+ Record record;
+ Record record2;
+ Noisy noisy{record, 17};
+ Noisy noisy2{record2, 5};
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(func(), 17ull);
+ EXPECT_EQ(record.dtor_called, 0ull);
+ func = noisy2;
+ EXPECT_EQ(record.dtor_called, 1ull);
+ EXPECT_EQ(record2, Record(0, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func(), 5ull);
+ }
+ {
+ Record record;
+ Record record2;
+ Noisy noisy{record, 17};
+ Noisy noisy2{record2, 5};
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(func(), 17ull);
+ EXPECT_EQ(record.dtor_called, 0ull);
+ func = std::move(noisy2);
+ EXPECT_EQ(record.dtor_called, 1ull);
+ EXPECT_EQ(record2, Record(1, 0, 0)); // move, copy, dtor
+ EXPECT_EQ(func(), 5ull);
+ }
+
+ {
+ Record record;
+ Record record2;
+ Noisy noisy{record, 17};
+ Noisy noisy2{record2, 13};
+ {
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(func(), 17ull);
+ InPlaceFunction<size_t()> func2{noisy2};
+ EXPECT_EQ(record2, Record(0, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(record.dtor_called, 0ull);
+ func = func2;
+ EXPECT_EQ(record.dtor_called, 1ull);
+ EXPECT_EQ(func(), 13ull);
+ EXPECT_EQ(record2, Record(0, 2, 0)); // move, copy, dtor
+ EXPECT_TRUE(static_cast<bool>(func2));
+ EXPECT_EQ(func2(), 13ull);
+ }
+ EXPECT_EQ(record2, Record(0, 2, 2)); // move, copy, dtor
+ }
+
+ {
+ Record record;
+ Record record2;
+ Noisy noisy{record, 17};
+ Noisy noisy2{record2, 13};
+ {
+ InPlaceFunction<size_t()> func{noisy};
+ EXPECT_EQ(func(), 17ull);
+ InPlaceFunction<size_t()> func2{noisy2};
+ EXPECT_EQ(record.dtor_called, 0ull);
+ EXPECT_EQ(record2, Record(0, 1, 0)); // move, copy, dtor
+ func = std::move(func2);
+ EXPECT_EQ(record.dtor_called, 1ull);
+ EXPECT_EQ(func(), 13ull);
+ EXPECT_EQ(record2, Record(1, 1, 0)); // move, copy, dtor
+ // Moved from function is still valid
+ EXPECT_TRUE(static_cast<bool>(func2));
+ EXPECT_EQ(func2(), 13ull);
+ }
+ EXPECT_EQ(record2, Record(1, 1, 2)); // move, copy, dtor
+ }
+}
+
+TEST(InPlaceFunctionTests, Swap) {
+ Record record1;
+ Record record2;
+ InPlaceFunction<size_t()> func1 = Noisy{record1, 5};
+ InPlaceFunction<size_t()> func2 = Noisy{record2, 7};
+ EXPECT_EQ(record1, Record(1, 0, 1)); // move, copy, dtor
+ EXPECT_EQ(record2, Record(1, 0, 1)); // move, copy, dtor
+ EXPECT_EQ(func1(), 5ull);
+ EXPECT_EQ(func2(), 7ull);
+ func1.swap(func2);
+ EXPECT_EQ(record1, Record(2, 0, 2)); // move, copy, dtor
+ // An additional move and destroy into the temporary object
+ EXPECT_EQ(record2, Record(3, 0, 3)); // move, copy, dtor
+ EXPECT_EQ(func1(), 7ull);
+ EXPECT_EQ(func2(), 5ull);
+}
+
+TEST(InPlaceFunctionTests, Conversion) {
+ Record record;
+ Noisy noisy{record, 15};
+ {
+ InPlaceFunction<size_t(), 16> func2 = noisy;
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ {
+ InPlaceFunction<size_t(), 32> func{func2};
+ EXPECT_EQ(record, Record(0, 2, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), func());
+ }
+ EXPECT_EQ(record, Record(0, 2, 1)); // move, copy, dtor
+ }
+ EXPECT_EQ(record, Record(0, 2, 2)); // move, copy, dtor
+}
+
+TEST(InPlaceFunctionTests, ConversionMove) {
+ Record record;
+ Noisy noisy{record, 15};
+ {
+ InPlaceFunction<size_t(), 16> func2 = noisy;
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ {
+ InPlaceFunction<size_t(), 32> func{std::move(func2)};
+ EXPECT_EQ(record, Record(1, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), func());
+ }
+ EXPECT_EQ(record, Record(1, 1, 1)); // move, copy, dtor
+ }
+ EXPECT_EQ(record, Record(1, 1, 2)); // move, copy, dtor
+}
+
+TEST(InPlaceFunctionTests, ConversionAssign) {
+ Record record;
+ Noisy noisy{record, 15};
+ {
+ InPlaceFunction<size_t(), 32> func;
+ {
+ InPlaceFunction<size_t(), 16> func2 = noisy;
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ func = func2;
+ EXPECT_EQ(record, Record(0, 2, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), func());
+ }
+ EXPECT_EQ(record, Record(0, 2, 1)); // move, copy, dtor
+ }
+ EXPECT_EQ(record, Record(0, 2, 2)); // move, copy, dtor
+}
+
+TEST(InPlaceFunctionTests, ConversionAssignMove) {
+ Record record;
+ Noisy noisy{record, 15};
+ {
+ InPlaceFunction<size_t(), 32> func;
+ {
+ InPlaceFunction<size_t(), 16> func2 = noisy;
+ EXPECT_EQ(record, Record(0, 1, 0)); // move, copy, dtor
+ func = std::move(func2);
+ EXPECT_EQ(record, Record(1, 1, 0)); // move, copy, dtor
+ EXPECT_EQ(func2(), func());
+ }
+ EXPECT_EQ(record, Record(1, 1, 1)); // move, copy, dtor
+ }
+ EXPECT_EQ(record, Record(1, 1, 2)); // move, copy, dtor
+}
+
+struct NoMoveCopy {
+ NoMoveCopy() = default;
+ NoMoveCopy(const NoMoveCopy&) = delete;
+ NoMoveCopy(NoMoveCopy&&) = delete;
+};
+struct TestCallable {
+ NoMoveCopy& operator()(NoMoveCopy& x) { return x; }
+};
+
+TEST(InPlaceFunctionTests, ArgumentForwarding) {
+ const auto lambd = [](NoMoveCopy& x) -> NoMoveCopy& { return x; };
+ InPlaceFunction<NoMoveCopy&(NoMoveCopy&)> func = lambd;
+ const auto lambd2 = [](NoMoveCopy&& x) -> NoMoveCopy&& { return std::move(x); };
+ InPlaceFunction<NoMoveCopy && (NoMoveCopy &&)> func2 = lambd2;
+ auto lvalue = NoMoveCopy{};
+ func(lvalue);
+ func2(NoMoveCopy{});
+ InPlaceFunction<void(NoMoveCopy&)> func3 = [](const NoMoveCopy&) {};
+ func3(lvalue);
+ InPlaceFunction<void(NoMoveCopy &&)> func4 = [](const NoMoveCopy&) {};
+ func4(std::move(lvalue));
+ InPlaceFunction<void(const NoMoveCopy&)> func5 = [](const NoMoveCopy&) {};
+ func5(lvalue);
+ InPlaceFunction<void(const NoMoveCopy&&)> func6 = [](const NoMoveCopy&) {};
+ func6(std::move(lvalue));
+ InPlaceFunction<void(const NoMoveCopy&&)> func7 = [](const NoMoveCopy&&) {};
+ func7(std::move(lvalue));
+ InPlaceFunction<void(NoMoveCopy &&)> func8 = [](const NoMoveCopy&&) {};
+ func8(std::move(lvalue));
+
+ {
+ Record record;
+ Noisy noisy{record, 5};
+ const auto lambd3 = [](Noisy) {};
+ InPlaceFunction<void(Noisy)> func3{lambd3};
+ EXPECT_EQ(record, Record(0, 0, 0)); // move, copy, dtor
+ func3(std::move(noisy));
+ EXPECT_EQ(record, Record(2, 0, 2)); // move, copy, dtor
+ }
+
+ {
+ Record record;
+ Noisy noisy{record, 5};
+ const auto lambd3 = [](Noisy) {};
+ InPlaceFunction<void(Noisy)> func3{lambd3};
+ EXPECT_EQ(record, Record(0, 0, 0)); // move, copy, dtor
+ func3(noisy);
+ EXPECT_EQ(record, Record(1, 1, 2)); // move, copy, dtor
+ }
+}
+
+TEST(InPlaceFunctionTests, VoidFunction) {
+ InPlaceFunction<void(size_t)> func = [](size_t x) -> size_t { return x; };
+ func(5);
+ InPlaceFunction<void(void)> func2 = []() -> size_t { return 5; };
+ func2();
+}
+NoMoveCopy foo() {
+ return NoMoveCopy();
+}
+struct Test {
+ NoMoveCopy operator()() { return NoMoveCopy{}; }
+};
+
+TEST(InPlaceFunctionTests, FullElision) {
+ InPlaceFunction<NoMoveCopy()> func = foo;
+}
+
+TEST(InPlaceFunctionTests, ReturnConversion) {
+ const auto lambd = [](int&& x) -> int&& { return std::move(x); };
+ InPlaceFunction<int && (int&& x)> func = lambd;
+ func(5);
+ InPlaceFunction<void(int)> func3 = [](double) {};
+ func3(5);
+ InPlaceFunction<double()> func4 = []() -> int { return 5; };
+ func4();
+}
+
+struct Overloaded {
+ int operator()() & { return 2; }
+ int operator()() const& { return 3; }
+ int operator()() && { return 4; }
+ int operator()() const&& { return 5; }
+};
+
+TEST(InPlaceFunctionTests, OverloadResolution) {
+ InPlaceFunction<int()> func = Overloaded{};
+ EXPECT_EQ(func(), 2);
+ EXPECT_EQ(std::move(func()), 2);
+}
+
+template <class T, class U, class = void>
+struct can_assign : std::false_type {};
+
+template <class T, class U>
+struct can_assign<T, U, typename std::void_t<decltype(T().operator=(U()))>> : std::true_type {};
+
+template <class From, class To, bool Expected>
+static constexpr bool Convertible =
+ (can_assign<To, From>::value ==
+ std::is_constructible_v<To, From>)&&(std::is_constructible_v<To, From> == Expected);
+
+struct TooBig {
+ std::array<uint64_t, 5> big = {1, 2, 3, 4, 5};
+ size_t operator()() { return static_cast<size_t>(big[0] + big[1] + big[2] + big[3] + big[4]); }
+};
+static_assert(sizeof(TooBig) == 40);
+struct NotCallable {};
+struct WrongArg {
+ void operator()(NotCallable) {}
+};
+struct WrongRet {
+ NotCallable operator()(size_t) { return NotCallable{}; }
+};
+
+static_assert(Convertible<InPlaceFunction<size_t(), 32>, InPlaceFunction<size_t(), 32>, true>);
+static_assert(
+ Convertible<InPlaceFunction<size_t(size_t), 32>, InPlaceFunction<size_t(), 32>, false>);
+static_assert(Convertible<InPlaceFunction<void(), 32>, InPlaceFunction<size_t(), 32>, false>);
+static_assert(Convertible<TooBig, InPlaceFunction<size_t(), 32>, false>);
+static_assert(Convertible<TooBig, InPlaceFunction<size_t(), 40>, true>);
+static_assert(Convertible<NotCallable, InPlaceFunction<size_t(), 40>, false>);
+static_assert(Convertible<WrongArg, InPlaceFunction<void(size_t), 40>, false>);
+static_assert(Convertible<WrongRet, InPlaceFunction<size_t(size_t), 40>, false>);
+// Void returning functions are modelled by any return type
+static_assert(Convertible<WrongRet, InPlaceFunction<void(size_t), 40>, true>);
+
+// Check constructibility/assignability from smaller function types
+static_assert(Convertible<InPlaceFunction<size_t(), 32>, InPlaceFunction<size_t(), 24>, false>);
+static_assert(Convertible<InPlaceFunction<size_t(), 32>, InPlaceFunction<size_t(), 40>, true>);
+static_assert(
+ Convertible<InPlaceFunction<size_t(), 32>, InPlaceFunction<size_t(size_t), 40>, false>);
+static_assert(
+ Convertible<InPlaceFunction<size_t(), 32>, InPlaceFunction<NotCallable(), 40>, false>);
+
+struct BadLambd {
+ int operator()(int&& x) { return std::move(x); }
+};
+
+static_assert(Convertible<BadLambd, InPlaceFunction<int(int&&), 32>, true>);
+static_assert(Convertible<BadLambd, InPlaceFunction<int&(int&&), 32>, false>);
+static_assert(Convertible<BadLambd, InPlaceFunction<const int&(int&&), 32>, false>);
+static_assert(Convertible<BadLambd, InPlaceFunction<int && (int&&), 32>, false>);
+static_assert(Convertible<BadLambd, InPlaceFunction<const int && (int&&), 32>, false>);
+
+struct Base {};
+struct Derived : Base {};
+struct Converted {
+ Converted(const Derived&) {}
+};
+
+struct ConvertCallable {
+ Derived operator()() { return Derived{}; }
+ Derived& operator()(Derived& x) { return x; }
+ Derived&& operator()(Derived&& x) { return std::move(x); }
+ const Derived& operator()(const Derived& x) { return x; }
+ const Derived&& operator()(const Derived&& x) { return std::move(x); }
+};
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Derived&()>, false>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Base&()>, false>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Derived()>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Base()>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Converted()>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Converted&()>, false>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Converted && ()>, false>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Converted&()>, false>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Converted && ()>, false>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Derived&(Derived&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Base&(Derived&)>, true>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Derived && (Derived &&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<Base && (Derived &&)>, true>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Derived&(const Derived&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Base&(const Derived&)>, true>);
+
+static_assert(
+ Convertible<ConvertCallable, InPlaceFunction<const Derived && (const Derived&&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Base && (const Derived&&)>, true>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Derived&(Derived&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Base&(Derived&)>, true>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Derived && (Derived &&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Base && (Derived &&)>, true>);
+
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Derived&(Derived&&)>, true>);
+static_assert(Convertible<ConvertCallable, InPlaceFunction<const Base&(Derived&&)>, true>);
diff --git a/media/utils/tests/library_tests.cpp b/media/utils/tests/library_tests.cpp
index c5c500c..f15f7f9 100644
--- a/media/utils/tests/library_tests.cpp
+++ b/media/utils/tests/library_tests.cpp
@@ -26,8 +26,9 @@
namespace {
-static int32_t here = 0; // accessed on same thread.
+[[maybe_unused]] static int32_t here = 0; // accessed on same thread.
+#if __android__
TEST(library_tests, basic) {
std::string path = android::base::GetExecutableDirectory() + "/libsharedtest.so";
// The flags to loadLibrary should not include RTLD_GLOBAL or RTLD_NODELETE
@@ -64,6 +65,7 @@
// will prevent unloading libraries.
ASSERT_EQ(1, here);
}
+#endif
TEST(library_tests, sad_library) {
std::string path = android::base::GetExecutableDirectory()
diff --git a/media/utils/tests/media_process_tests.cpp b/media/utils/tests/media_process_tests.cpp
index 6e738b1..391c6a7 100644
--- a/media/utils/tests/media_process_tests.cpp
+++ b/media/utils/tests/media_process_tests.cpp
@@ -15,6 +15,7 @@
*/
#include <mediautils/Process.h>
+#include <mediautils/TidWrapper.h>
#define LOG_TAG "media_process_tests"
@@ -33,7 +34,7 @@
}
TEST(media_process_tests, basic) {
- const std::string schedString = getThreadSchedAsString(gettid());
+ const std::string schedString = getThreadSchedAsString(getThreadIdWrapper());
(void)schedString;
// We don't test schedString, only that we haven't crashed.
diff --git a/media/utils/tests/media_threadsnapshot_tests.cpp b/media/utils/tests/media_threadsnapshot_tests.cpp
index fc9aeab..57cf698 100644
--- a/media/utils/tests/media_threadsnapshot_tests.cpp
+++ b/media/utils/tests/media_threadsnapshot_tests.cpp
@@ -15,6 +15,7 @@
*/
#include <mediautils/ThreadSnapshot.h>
+#include <mediautils/TidWrapper.h>
#define LOG_TAG "media_threadsnapshot_tests"
@@ -38,7 +39,7 @@
TEST(media_threadsnapshot_tests, basic) {
using namespace std::chrono_literals;
- ThreadSnapshot threadSnapshot(gettid());
+ ThreadSnapshot threadSnapshot(getThreadIdWrapper());
threadSnapshot.onBegin();
diff --git a/media/utils/tests/mediautils_fixedstring_tests.cpp b/media/utils/tests/mediautils_fixedstring_tests.cpp
new file mode 100644
index 0000000..7ab9a9f
--- /dev/null
+++ b/media/utils/tests/mediautils_fixedstring_tests.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 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_TAG "mediautils_fixedstring_tests"
+
+#include <mediautils/FixedString.h>
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+using namespace android::mediautils;
+
+TEST(mediautils_fixedstring_tests, ctor) {
+ FixedString<8> s0("abcde");
+
+ ASSERT_FALSE(s0.empty());
+ ASSERT_EQ(8U, s0.capacity());
+
+ ASSERT_EQ(5U, s0.size());
+ ASSERT_EQ(3U, s0.remaining());
+ ASSERT_EQ(0, strcmp(s0.c_str(), "abcde"));
+
+ ASSERT_EQ(0, strcmp(s0.data(), "abcde"));
+
+ // overflow
+ FixedString<8> s1("abcdefghijk");
+ ASSERT_EQ(8U, s1.size());
+ ASSERT_TRUE(s1.full());
+ ASSERT_EQ(0U, s1.remaining());
+ ASSERT_EQ(0, strcmp(s1.c_str(), "abcdefgh"));
+
+ // overflow
+ FixedString<8> s2(std::string("abcdefghijk"));
+ ASSERT_TRUE(s2.full());
+
+ ASSERT_EQ(8U, s2.size());
+ ASSERT_EQ(0, strcmp(s2.c_str(), "abcdefgh"));
+
+ // complex
+ ASSERT_EQ(s1, s2);
+ ASSERT_EQ(FixedString<12>().append(s1), s2);
+ ASSERT_NE(s1, "bcd");
+
+ // string and stringview
+ ASSERT_EQ(s1.asString(), s1.asStringView());
+
+ FixedString30 s3;
+ s3 = std::string("abcd");
+ ASSERT_EQ(s3, "abcd");
+
+ s3.clear();
+ ASSERT_EQ(s3, "");
+ ASSERT_NE(s3, "abcd");
+ ASSERT_EQ(0U, s3.size());
+}
+
+TEST(mediautils_fixedstring_tests, append) {
+ FixedString<8> s0;
+ ASSERT_EQ(0U, s0.size());
+ ASSERT_EQ(0, strcmp(s0.c_str(), ""));
+ ASSERT_TRUE(s0.empty());
+ ASSERT_FALSE(s0.full());
+
+ s0.append("abc");
+ ASSERT_EQ(3U, s0.size());
+ ASSERT_EQ(0, strcmp(s0.c_str(), "abc"));
+
+ s0.append(std::string("d"));
+ ASSERT_EQ(4U, s0.size());
+ ASSERT_EQ(0, strcmp(s0.c_str(), "abcd"));
+
+ // overflow
+ s0.append("efghijk");
+ ASSERT_EQ(8U, s0.size());
+ ASSERT_EQ(0, strcmp(s0.c_str(), "abcdefgh"));
+ ASSERT_TRUE(s0.full());
+
+ // concatenated
+ ASSERT_EQ(FixedString62("abcd"),
+ FixedString<8>("ab").append("c").append(FixedString<8>("d")));
+ ASSERT_EQ(FixedString<12>("a").append(FixedString<12>("b")), "ab");
+}
+
+TEST(mediautils_fixedstring_tests, plus_equals) {
+ FixedString<8> s0;
+ ASSERT_EQ(0U, s0.size());
+ ASSERT_EQ(0, strcmp(s0.c_str(), ""));
+
+ s0 += "abc";
+ s0 += "def";
+ ASSERT_EQ(s0, "abcdef");
+}
+
+TEST(mediautils_fixedstring_tests, stream_operator) {
+ FixedString<8> s0('a');
+
+ s0 << 'b' << "c" << "d" << '\n';
+ ASSERT_EQ(s0, "abcd\n");
+}
+
+TEST(mediautils_fixedstring_tests, examples) {
+ FixedString30 s1(std::string("a"));
+ s1 << "bc" << 'd' << '\n';
+ s1 += "hello";
+
+ ASSERT_EQ(s1, "abcd\nhello");
+
+ FixedString30 s2;
+ for (const auto &c : s1.asStringView()) {
+ s2.append(c);
+ };
+ ASSERT_EQ(s1, s2);
+
+ FixedString30 s3(std::move(s1));
+}
+
+// Ensure type alias works fine as well.
+using FixedString1024 = FixedString<1024>;
+
+TEST(mediautils_fixedstring_tests, copy) {
+ FixedString1024 s0("abc");
+ FixedString62 s1(s0);
+
+ ASSERT_EQ(3U, s1.size());
+ ASSERT_EQ(0, strcmp(s1.c_str(), "abc"));
+ ASSERT_EQ(s0, s1);
+
+ FixedString<1024> s2(s1);
+ ASSERT_EQ(3U, s2.size());
+ ASSERT_EQ(0, strcmp(s2.c_str(), "abc"));
+ ASSERT_EQ(s2, "abc");
+ ASSERT_NE(s2, "def");
+ ASSERT_EQ(s2, std::string("abc"));
+ ASSERT_NE(s2, std::string("def"));
+ ASSERT_EQ(s1, s2);
+ ASSERT_EQ(s0, s2);
+ ASSERT_EQ(s2, FixedString62(FixedString1024("abc")));
+}
diff --git a/media/utils/tests/shared_memory_allocator_tests.cpp b/media/utils/tests/shared_memory_allocator_tests.cpp
new file mode 100644
index 0000000..11bc72a
--- /dev/null
+++ b/media/utils/tests/shared_memory_allocator_tests.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2022 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_TAG "shared_memory_allocator_tests"
+
+#include <gtest/gtest.h>
+#include <mediautils/SharedMemoryAllocator.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+
+using namespace android;
+using namespace android::mediautils;
+
+namespace {
+void validate_block(const AllocationType& block) {
+ ASSERT_TRUE(block != nullptr);
+ memset(block->unsecurePointer(), 10, 4096);
+ EXPECT_EQ(*(static_cast<char*>(block->unsecurePointer()) + 100), static_cast<char>(10));
+}
+
+template <size_t N = 0, bool FatalOwn = true>
+struct ValidateForwarding {
+ static constexpr size_t alignment() { return 1337; }
+
+ bool owns(const AllocationType& allocation) const {
+ if (allocation == owned) return true;
+ if constexpr (FatalOwn) {
+ LOG_ALWAYS_FATAL_IF(allocation != not_owned, "Invalid allocation passed to allocator");
+ }
+ return false;
+ }
+
+ void deallocate_all() { deallocate_all_count++; }
+ std::string dump() const { return dump_string; }
+
+ static inline size_t deallocate_all_count = 0;
+ static inline const AllocationType owned =
+ MemoryHeapBaseAllocator().allocate(BasicAllocRequest{4096});
+ static inline const AllocationType not_owned =
+ MemoryHeapBaseAllocator().allocate(BasicAllocRequest{4096});
+ static inline const std::string dump_string = std::to_string(N) + "Test Dump Forwarding";
+};
+
+}; // namespace
+static_assert(shared_allocator_impl::has_owns<MemoryHeapBaseAllocator> == false);
+static_assert(shared_allocator_impl::has_dump<MemoryHeapBaseAllocator> == false);
+static_assert(shared_allocator_impl::has_deallocate_all<MemoryHeapBaseAllocator> == false);
+static_assert(shared_allocator_impl::has_owns<SnoopingAllocator<MemoryHeapBaseAllocator>> == true);
+static_assert(shared_allocator_impl::has_dump<SnoopingAllocator<MemoryHeapBaseAllocator>> == true);
+static_assert(
+ shared_allocator_impl::has_deallocate_all<SnoopingAllocator<MemoryHeapBaseAllocator>> ==
+ true);
+static_assert(
+ shared_allocator_impl::has_owns<
+ PolicyAllocator<SnoopingAllocator<MemoryHeapBaseAllocator>, SizePolicy<4096>>> ==
+ true);
+static_assert(
+ shared_allocator_impl::has_dump<
+ PolicyAllocator<SnoopingAllocator<MemoryHeapBaseAllocator>, SizePolicy<4096>>> ==
+ true);
+static_assert(
+ shared_allocator_impl::has_deallocate_all<
+ PolicyAllocator<SnoopingAllocator<MemoryHeapBaseAllocator>, SizePolicy<4096>>> ==
+ true);
+static_assert(shared_allocator_impl::has_owns<
+ FallbackAllocator<SnoopingAllocator<MemoryHeapBaseAllocator>,
+ SnoopingAllocator<MemoryHeapBaseAllocator>>> == true);
+
+TEST(shared_memory_allocator_tests, roundup) {
+ using namespace shared_allocator_impl;
+ EXPECT_EQ(roundup(1023, 1024), 1024ul);
+ EXPECT_EQ(roundup(1024, 1024), 1024ul);
+ EXPECT_EQ(roundup(1025, 1024), 2048ul);
+ EXPECT_DEATH(roundup(1023, 1023), "");
+ EXPECT_DEATH(roundup(1023, 0), "");
+}
+
+TEST(shared_memory_allocator_tests, mheapbase_allocator) {
+ MemoryHeapBaseAllocator allocator;
+ const auto memory = allocator.allocate(BasicAllocRequest{500});
+ ASSERT_TRUE(memory != nullptr);
+ const auto fd = dup(memory->getMemory()->getHeapID());
+ EXPECT_EQ(memory->size(), static_cast<unsigned>(4096));
+ EXPECT_EQ(memory->size(), memory->getMemory()->getSize());
+ validate_block(memory);
+ allocator.deallocate(memory);
+ // Ensures we have closed the fd
+ EXPECT_EQ(memory->unsecurePointer(), nullptr);
+ EXPECT_EQ(memory->getMemory()->getBase(), nullptr);
+ struct stat st;
+ const auto err = fstat(fd, &st);
+ EXPECT_EQ(err, 0);
+ // Ensure we reclaim pages (overly-zealous)
+ EXPECT_EQ(st.st_size, 0);
+}
+
+TEST(shared_memory_allocator_tests, mheapbase_allocator_independence) {
+ static_assert(MemoryHeapBaseAllocator::alignment() == 4096);
+ MemoryHeapBaseAllocator allocator;
+ const auto first_memory = allocator.allocate(BasicAllocRequest{500});
+ const auto second_memory = allocator.allocate(BasicAllocRequest{500});
+ ASSERT_TRUE(first_memory != nullptr && second_memory != nullptr);
+ EXPECT_NE(first_memory->getMemory()->getHeapID(), second_memory->getMemory()->getHeapID());
+ allocator.deallocate(first_memory);
+ validate_block(second_memory);
+ allocator.deallocate(second_memory);
+}
+
+TEST(shared_memory_allocator_tests, snooping_allocator) {
+ static_assert(SnoopingAllocator<ValidateForwarding<0>>::alignment() ==
+ ValidateForwarding<0>::alignment());
+
+ SnoopingAllocator<MemoryHeapBaseAllocator> allocator{"allocator"};
+ const auto first_memory = allocator.allocate(NamedAllocRequest{{500}, "allocate_1"});
+ auto second_memory = first_memory;
+ {
+ const auto tmp = allocator.allocate(NamedAllocRequest{{5000}, "allocate_2"});
+ // Test copying handle around
+ second_memory = tmp;
+ }
+ ASSERT_TRUE(first_memory && second_memory);
+ EXPECT_TRUE(allocator.owns(first_memory) && allocator.owns(second_memory));
+ const auto first_allocations = allocator.getAllocations();
+ EXPECT_EQ(first_allocations.size(), 2ull);
+ for (const auto& [key, val] : allocator.getAllocations()) {
+ if (val.allocation_number == 0) {
+ EXPECT_EQ(val.name, "allocate_1");
+ EXPECT_TRUE(first_memory == key);
+ }
+ if (val.allocation_number == 1) {
+ EXPECT_EQ(val.name, "allocate_2");
+ EXPECT_TRUE(second_memory == key);
+ }
+ }
+ // TODO test dump and deallocate forwarding
+ // EXPECT_EQ(allocator.dump(), std::string{});
+ validate_block(second_memory);
+ allocator.deallocate(second_memory);
+ EXPECT_EQ(second_memory->unsecurePointer(), nullptr);
+ EXPECT_FALSE(allocator.owns(second_memory));
+ EXPECT_TRUE(allocator.owns(first_memory));
+ const auto second_allocations = allocator.getAllocations();
+ EXPECT_EQ(second_allocations.size(), 1ul);
+ for (const auto& [key, val] : second_allocations) {
+ EXPECT_EQ(val.name, "allocate_1");
+ EXPECT_TRUE(first_memory == key);
+ }
+ // EXPECT_EQ(allocator.dump(), std::string{});
+ // TODO test deallocate_all O(1)
+}
+
+// TODO generic policy test
+TEST(shared_memory_allocator_tests, size_policy_allocator_enforcement) {
+ PolicyAllocator allocator{MemoryHeapBaseAllocator{},
+ SizePolicy<4096 * 7, 4096 * 2, 4096 * 4>{}};
+ // Violate max size
+ EXPECT_TRUE(allocator.allocate(BasicAllocRequest{4096 * 5}) == nullptr);
+ // Violate min alloc size
+ EXPECT_TRUE(allocator.allocate(BasicAllocRequest{4096}) == nullptr);
+ const auto first_memory = allocator.allocate(BasicAllocRequest{4096 * 4});
+ validate_block(first_memory);
+ // Violate pool size
+ EXPECT_TRUE(allocator.allocate(BasicAllocRequest{4096 * 4}) == nullptr);
+ const auto second_memory = allocator.allocate(BasicAllocRequest{4096 * 3});
+ validate_block(second_memory);
+ allocator.deallocate(second_memory);
+ // Check pool size update after deallocation
+ const auto new_second_memory = allocator.allocate(BasicAllocRequest{4096 * 2});
+ validate_block(new_second_memory);
+}
+
+TEST(shared_memory_allocator_tests, indirect_allocator) {
+ static_assert(IndirectAllocator<ValidateForwarding<0>>::alignment() ==
+ ValidateForwarding<0>::alignment());
+ const auto allocator_handle = std::make_shared<SnoopingAllocator<MemoryHeapBaseAllocator>>();
+ IndirectAllocator allocator{allocator_handle};
+ const auto memory = allocator.allocate(NamedAllocRequest{{4096}, "allocation"});
+ EXPECT_TRUE(allocator_handle->owns(memory));
+ EXPECT_TRUE(allocator_handle->getAllocations().size() == 1);
+ allocator.deallocate(memory);
+ EXPECT_FALSE(allocator_handle->owns(memory));
+ EXPECT_TRUE(allocator_handle->getAllocations().size() == 0);
+}
+
+TEST(shared_memory_allocator_tests, policy_allocator_forwarding) {
+ // Test appropriate forwarding of allocator, deallocate
+ const auto primary_allocator =
+ std::make_shared<SnoopingAllocator<MemoryHeapBaseAllocator>>("allocator");
+ PolicyAllocator allocator{IndirectAllocator(primary_allocator), SizePolicy<4096>{}};
+ const auto memory = allocator.allocate(NamedAllocRequest{{4096}, "allocation"});
+ EXPECT_TRUE(primary_allocator->owns(memory));
+ const auto& allocations = primary_allocator->getAllocations();
+ EXPECT_TRUE(allocations.size() == 1);
+ allocator.deallocate(memory);
+ EXPECT_TRUE(allocations.size() == 0);
+ const auto memory2 = allocator.allocate(NamedAllocRequest{{4096}, "allocation_2"});
+ EXPECT_TRUE(allocations.size() == 1);
+ EXPECT_TRUE(primary_allocator->owns(memory2));
+ allocator.deallocate(memory2);
+ EXPECT_FALSE(primary_allocator->owns(memory2));
+ EXPECT_TRUE(allocations.size() == 0);
+ // Test appropriate forwarding of own, dump, alignment, deallocate_all
+ PolicyAllocator allocator2{ValidateForwarding<0>{}, SizePolicy<4096>{}};
+ EXPECT_TRUE(allocator2.owns(ValidateForwarding<0>::owned));
+ EXPECT_FALSE(allocator2.owns(ValidateForwarding<0>::not_owned));
+ EXPECT_TRUE(allocator2.dump().find(ValidateForwarding<0>::dump_string) != std::string::npos);
+ static_assert(decltype(allocator2)::alignment() == ValidateForwarding<0>::alignment());
+ size_t prev = ValidateForwarding<0>::deallocate_all_count;
+ allocator2.deallocate_all();
+ EXPECT_EQ(ValidateForwarding<0>::deallocate_all_count, prev + 1);
+}
+
+TEST(shared_memory_allocator_tests, snooping_allocator_nullptr) {
+ SnoopingAllocator allocator{PolicyAllocator{MemoryHeapBaseAllocator{}, SizePolicy<4096 * 2>{}}};
+ const auto memory = allocator.allocate(NamedAllocRequest{{3000}, "allocation_1"});
+ validate_block(memory);
+ ASSERT_TRUE(allocator.allocate(NamedAllocRequest{{5000}, "allocation_2"}) == nullptr);
+ const auto& allocations = allocator.getAllocations();
+ EXPECT_EQ(allocations.size(), 1ul);
+ for (const auto& [key, val] : allocations) {
+ EXPECT_EQ(val.name, "allocation_1");
+ EXPECT_EQ(val.allocation_number, 0ul);
+ EXPECT_TRUE(key == memory);
+ }
+}
+
+TEST(shared_memory_allocator_tests, fallback_allocator) {
+ // Construct Fallback Allocator
+ const auto primary_allocator = std::make_shared<
+ SnoopingAllocator<PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<4096>>>>(
+ PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<4096>>{}, "primary_allocator");
+ const auto secondary_allocator =
+ std::make_shared<SnoopingAllocator<MemoryHeapBaseAllocator>>("secondary_allocator");
+
+ FallbackAllocator fallback_allocator{SnoopingAllocator{IndirectAllocator{primary_allocator}},
+ SnoopingAllocator{IndirectAllocator{secondary_allocator}}};
+ static_assert(decltype(fallback_allocator)::alignment() == 4096);
+ // Basic Allocation Test
+ const auto memory = fallback_allocator.allocate(NamedAllocRequest{{3000}, "allocation_1"});
+ validate_block(memory);
+ // Correct allocator selected
+ EXPECT_TRUE(fallback_allocator.owns(memory));
+ EXPECT_TRUE(primary_allocator->owns(memory));
+ EXPECT_FALSE(secondary_allocator->owns(memory));
+ // Test fallback allocation
+ const auto memory2 = fallback_allocator.allocate(NamedAllocRequest{{3000}, "allocation_2"});
+ validate_block(memory2);
+ // Correct allocator selected
+ EXPECT_TRUE(fallback_allocator.owns(memory2));
+ EXPECT_FALSE(primary_allocator->owns(memory2));
+ EXPECT_TRUE(secondary_allocator->owns(memory2));
+ // Allocations ended up in the correct allocators
+ const auto& primary_allocations = primary_allocator->getAllocations();
+ EXPECT_TRUE(primary_allocations.size() == 1ul);
+ ASSERT_TRUE(primary_allocations.find(memory) != primary_allocations.end());
+ EXPECT_EQ(primary_allocations.find(memory)->second.name, std::string{"allocation_1"});
+ const auto& secondary_allocations = secondary_allocator->getAllocations();
+ EXPECT_TRUE(secondary_allocations.size() == 1ul);
+ ASSERT_TRUE(secondary_allocations.find(memory2) != secondary_allocations.end());
+ EXPECT_EQ(secondary_allocations.find(memory2)->second.name, std::string{"allocation_2"});
+ // Test deallocate appropriate forwarding
+ fallback_allocator.deallocate(memory);
+ EXPECT_TRUE(primary_allocator->getAllocations().size() == 0ul);
+ EXPECT_TRUE(secondary_allocator->getAllocations().size() == 1ul);
+ // Appropriate fallback after deallocation
+ const auto memory3 = fallback_allocator.allocate(NamedAllocRequest{{3000}, "allocation_3"});
+ EXPECT_TRUE(fallback_allocator.owns(memory3));
+ EXPECT_TRUE(primary_allocator->owns(memory3));
+ EXPECT_FALSE(secondary_allocator->owns(memory3));
+ EXPECT_TRUE(primary_allocator->getAllocations().size() == 1ul);
+ // Test deallocate appropriate forwarding
+ EXPECT_TRUE(secondary_allocator->getAllocations().size() == 1ul);
+ fallback_allocator.deallocate(memory2);
+ EXPECT_TRUE(secondary_allocator->getAllocations().size() == 0ul);
+ const auto memory4 = fallback_allocator.allocate(NamedAllocRequest{{3000}, "allocation_4"});
+ EXPECT_TRUE(fallback_allocator.owns(memory4));
+ EXPECT_FALSE(primary_allocator->owns(memory4));
+ EXPECT_TRUE(secondary_allocator->owns(memory4));
+ // Allocations ended up in the correct allocators
+ EXPECT_TRUE(primary_allocator->getAllocations().size() == 1ul);
+ EXPECT_TRUE(secondary_allocator->getAllocations().size() == 1ul);
+ ASSERT_TRUE(primary_allocations.find(memory3) != primary_allocations.end());
+ EXPECT_EQ(primary_allocations.find(memory3)->second.name, std::string{"allocation_3"});
+ ASSERT_TRUE(secondary_allocations.find(memory4) != secondary_allocations.end());
+ EXPECT_EQ(secondary_allocations.find(memory4)->second.name, std::string{"allocation_4"});
+}
+
+TEST(shared_memory_allocator_tests, fallback_allocator_forwarding) {
+ // Test forwarding
+ using Alloc1 = ValidateForwarding<0, false>;
+ using Alloc2 = ValidateForwarding<1, false>;
+ FallbackAllocator forward_test{Alloc1{}, Alloc2{}};
+ EXPECT_TRUE(forward_test.dump().find(Alloc1::dump_string) != std::string::npos);
+ EXPECT_TRUE(forward_test.dump().find(Alloc2::dump_string) != std::string::npos);
+ // Test owned forwarding
+ EXPECT_TRUE(forward_test.owns(Alloc1::owned));
+ EXPECT_TRUE(forward_test.owns(Alloc2::owned));
+ EXPECT_FALSE(forward_test.owns(Alloc1::not_owned));
+ EXPECT_FALSE(forward_test.owns(Alloc2::not_owned));
+ // Test alignment forwarding
+ static_assert(FallbackAllocator<Alloc1, Alloc2>::alignment() == Alloc1::alignment());
+ // Test deallocate_all forwarding
+ size_t prev1 = Alloc1::deallocate_all_count;
+ size_t prev2 = Alloc2::deallocate_all_count;
+ forward_test.deallocate_all();
+ EXPECT_EQ(prev1 + 1, Alloc1::deallocate_all_count);
+ EXPECT_EQ(prev2 + 1, Alloc2::deallocate_all_count);
+}
+
+TEST(shared_memory_allocator_tests, scoped_allocator) {
+ const auto underlying_allocator =
+ std::make_shared<SnoopingAllocator<MemoryHeapBaseAllocator>>("Allocator");
+ ScopedAllocator allocator{underlying_allocator};
+ const auto& allocations = underlying_allocator->getAllocations();
+ {
+ decltype(allocator.allocate(NamedAllocRequest{})) copy;
+ {
+ EXPECT_EQ(allocations.size(), 0ul);
+ const auto memory = allocator.allocate(NamedAllocRequest{{3000}, "allocation_1"});
+ copy = memory;
+ EXPECT_EQ(allocations.size(), 1ul);
+ EXPECT_TRUE(allocator.owns(copy));
+ EXPECT_TRUE(allocator.owns(memory));
+ }
+ EXPECT_TRUE(allocator.owns(copy));
+ EXPECT_EQ(allocations.size(), 1ul);
+ for (const auto& [key, value] : allocations) {
+ EXPECT_EQ(value.name, std::string{"allocation_1"});
+ }
+ }
+ EXPECT_EQ(allocations.size(), 0ul);
+ // Test forwarding
+ static_assert(ScopedAllocator<ValidateForwarding<0>>::alignment() ==
+ ValidateForwarding<0>::alignment());
+ ScopedAllocator<ValidateForwarding<0>> forwarding{};
+ EXPECT_EQ(forwarding.dump(), ValidateForwarding<0>::dump_string);
+}
diff --git a/media/utils/tests/static_string_view_tests.cpp b/media/utils/tests/static_string_view_tests.cpp
new file mode 100644
index 0000000..c00de68
--- /dev/null
+++ b/media/utils/tests/static_string_view_tests.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 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_TAG "StaticStringViewTests"
+
+#include <mediautils/StaticStringView.h>
+
+#include <gtest/gtest.h>
+#include <log/log.h>
+
+using namespace android::mediautils;
+
+template <auto& T, class = void>
+struct CanCreate : std::false_type {};
+
+template <auto& T>
+struct CanCreate<T, typename std::void_t<decltype(StaticStringView::create<T>)>> : std::true_type {
+};
+
+static constexpr std::array<char, 2> global = {'a', 'b'};
+
+TEST(StaticStringViewTests, CreateTicket) {
+ // This will always fail due to template param binding rules
+ // const std::array<char,2> nonstatic = {'a', 'b'};
+ // static_assert(can_assign<nonstatic>::value == false);
+ static std::array<char, 2> nonconst = {'a', 'b'};
+ static const std::array<char, 2> nonconstexpr = {'a', 'b'};
+ static constexpr std::array<int, 2> nonchar = {1, 2};
+ static constexpr size_t nonarray = 2;
+
+ static_assert(CanCreate<nonconst>::value == false);
+ static_assert(CanCreate<nonarray>::value == false);
+ static_assert(CanCreate<nonchar>::value == false);
+ static_assert(CanCreate<nonconstexpr>::value == false);
+
+ static constexpr std::array<char, 2> scoped = {'a', 'b'};
+ constexpr StaticStringView Ticket1 = StaticStringView::create<global>();
+ constexpr StaticStringView Ticket2 = StaticStringView::create<scoped>();
+ const StaticStringView Ticket3 = StaticStringView::create<scoped>();
+ EXPECT_EQ(Ticket3, Ticket2);
+ EXPECT_EQ(Ticket1.getStringView(), Ticket2.getStringView());
+ EXPECT_EQ(std::string_view{"ab"}, Ticket1.getStringView());
+}
+TEST(StaticStringViewTests, CompileTimeConvert) {
+ static constexpr std::array<char, 4> converted = StaticStringView::toStdArray("test");
+ constexpr StaticStringView ticket = StaticStringView::create<converted>();
+ EXPECT_EQ(ticket, std::string_view{"test"});
+ // Unchecked constexpr construction
+ static const std::array<char, 5> converted2 = StaticStringView::toStdArray("test2");
+ constexpr auto ticket2 = StaticStringView::create<converted2, false>();
+ EXPECT_EQ(ticket2, std::string_view{"test2"});
+ constexpr char stack_array[4] = {'a', 'b', 'c', '\0'};
+ static constexpr auto converted3 = StaticStringView::toStdArray(stack_array);
+ constexpr auto ticket3 = StaticStringView::create<converted3>();
+ EXPECT_EQ(ticket3, std::string_view{"abc"});
+}
+
+TEST(StaticStringViewTests, CompileTimeConcat) {
+ // temporaries should not be static to prevent odr use
+ constexpr std::array<char, 3> arr1 = {'a', 'b', 'c'};
+ constexpr std::array<char, 4> arr2 = {'d', 'e', 'f', 'g'};
+ static constexpr std::array<char, 7> res = StaticStringView::concatArray(arr1, arr2);
+ static constexpr std::array<char, 7> expected = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
+ EXPECT_EQ(res, expected);
+}
+
+TEST(StaticStringViewTests, StringViewForwarding) {
+ static constexpr auto converted = StaticStringView::toStdArray("test");
+ constexpr auto ticket = StaticStringView::create<converted>();
+ EXPECT_EQ(ticket.length(), ticket.getStringView().length());
+ EXPECT_TRUE(ticket == ticket.getStringView());
+ EXPECT_TRUE(ticket == ticket);
+ EXPECT_TRUE(ticket.getStringView() == ticket);
+ EXPECT_TRUE(ticket > "abc");
+ EXPECT_TRUE("abc" < ticket);
+}
diff --git a/media/utils/tests/timecheck_tests.cpp b/media/utils/tests/timecheck_tests.cpp
index 6ebf44d..bd91efa 100644
--- a/media/utils/tests/timecheck_tests.cpp
+++ b/media/utils/tests/timecheck_tests.cpp
@@ -26,7 +26,6 @@
using namespace std::chrono_literals;
namespace {
-
TEST(timecheck_tests, success) {
bool timeoutRegistered = false;
float elapsedMsRegistered = 0.f;
@@ -39,7 +38,7 @@
timeoutRegistered = timeout;
elapsedMsRegistered = elapsedMs;
event = true;
- }, 1000 /* msec */, false /* crash */);
+ }, 1000ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */);
}
ASSERT_TRUE(event);
ASSERT_FALSE(timeoutRegistered);
@@ -58,7 +57,7 @@
timeoutRegistered = timeout;
elapsedMsRegistered = elapsedMs;
event = true; // store-release, must be last.
- }, 1 /* msec */, false /* crash */);
+ }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */);
std::this_thread::sleep_for(100ms);
}
ASSERT_TRUE(event); // load-acquire, must be first.
@@ -69,4 +68,33 @@
// Note: We do not test TimeCheck crash because TimeCheck is multithreaded and the
// EXPECT_EXIT() signal catching is imperfect due to the gtest fork.
-} // namespace
\ No newline at end of file
+// Note, the following test is to manually verify the correct thread is aborted.
+// Due to difficulties with gtest and EXPECT_EXIT, this is difficult to verify
+// automatically. TODO(b/246446561) Attempt to use EXPECT_EXIT
+
+#if 0
+void threadFunction() {
+ bool timeoutRegistered = false;
+ float elapsedMsRegistered = 0.f;
+ std::atomic_bool event = false; // seq-cst implies acquire-release
+ {
+ TimeCheck timeCheck("timeout",
+ [&event, &timeoutRegistered, &elapsedMsRegistered]
+ (bool timeout, float elapsedMs) {
+ timeoutRegistered = timeout;
+ elapsedMsRegistered = elapsedMs;
+ event = true; // store-release, must be last.
+ }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, true /* crash */);
+ std::this_thread::sleep_for(100ms);
+ ADD_FAILURE();
+ }
+}
+
+TEST(timecheck_tests, death) {
+ std::thread mthread{threadFunction};
+ mthread.join();
+}
+#endif
+
+} // namespace
+
diff --git a/services/OWNERS b/services/OWNERS
deleted file mode 100644
index 17e605d..0000000
--- a/services/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-elaurent@google.com
-essick@google.com
-etalvala@google.com
-hunga@google.com
-nchalko@google.com
-quxiangfang@google.com
diff --git a/services/audioflinger/AllocatorFactory.h b/services/audioflinger/AllocatorFactory.h
new file mode 100644
index 0000000..7534607
--- /dev/null
+++ b/services/audioflinger/AllocatorFactory.h
@@ -0,0 +1,95 @@
+/*
+**
+** Copyright 2022, 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 <mediautils/SharedMemoryAllocator.h>
+
+#pragma once
+
+// TODO how do we appropriately restrict visibility of this header?
+// It should only be included in AudioFlinger.h
+// We will make everything internal linkage for now.
+namespace android {
+namespace AllocatorFactory {
+namespace {
+// TODO make sure these are appropriate
+constexpr inline size_t MAX_MEMORY_SIZE = 1024 * 1024 * 100; // 100 MiB
+constexpr inline size_t DED_SIZE = (MAX_MEMORY_SIZE * 4) / 10; // 40 MiB
+constexpr inline size_t SHARED_SIZE = MAX_MEMORY_SIZE - DED_SIZE; // 60 MiB
+constexpr inline size_t SHARED_SIZE_LARGE = (SHARED_SIZE * 4) / 6; // 40 MiB
+constexpr inline size_t SHARED_SIZE_SMALL = SHARED_SIZE - SHARED_SIZE_LARGE; // 20 MiB
+constexpr inline size_t SMALL_THRESHOLD = 1024 * 40; // 40 KiB
+
+inline auto getDedicated() {
+ using namespace mediautils;
+ static const auto allocator =
+ std::make_shared<PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<DED_SIZE>>>();
+ return allocator;
+}
+
+inline auto getSharedLarge() {
+ using namespace mediautils;
+ static const auto allocator = std::make_shared<
+ PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<SHARED_SIZE_LARGE>>>();
+ return allocator;
+}
+
+inline auto getSharedSmall() {
+ using namespace mediautils;
+ static const auto allocator =
+ std::make_shared<PolicyAllocator<MemoryHeapBaseAllocator,
+ SizePolicy<SHARED_SIZE_SMALL, 0, SMALL_THRESHOLD>>>();
+ return allocator;
+}
+
+template <typename Policy, typename Allocator>
+inline auto wrapWithPolicySnooping(Allocator allocator, std::string_view name) {
+ using namespace mediautils;
+ return SnoopingAllocator{PolicyAllocator{IndirectAllocator{allocator}, Policy{}}, name};
+}
+
+// A reasonable upper bound on how many clients we expect, and how many pieces to slice
+// the dedicate pool.
+constexpr inline size_t CLIENT_BOUND = 32;
+// Maximum amount of shared pools a single client can take (50%).
+constexpr inline size_t ADV_THRESHOLD_INV = 2;
+
+inline auto getClientAllocator() {
+ using namespace mediautils;
+ const auto makeDedPool = []() {
+ return wrapWithPolicySnooping<SizePolicy<DED_SIZE / CLIENT_BOUND>>(getDedicated(),
+ "Dedicated Pool");
+ };
+ const auto makeLargeShared = []() {
+ return wrapWithPolicySnooping<SizePolicy<SHARED_SIZE_LARGE / ADV_THRESHOLD_INV>>(
+ getSharedLarge(), "Large Shared");
+ };
+ const auto makeSmallShared = []() {
+ return wrapWithPolicySnooping<
+ SizePolicy<SHARED_SIZE_SMALL / ADV_THRESHOLD_INV>>(
+ getSharedSmall(), "Small Shared");
+ };
+
+ return ScopedAllocator{std::make_shared<
+ FallbackAllocator<decltype(makeDedPool()),
+ decltype(FallbackAllocator(makeLargeShared(), makeSmallShared()))>>(
+ makeDedPool(), FallbackAllocator{makeLargeShared(), makeSmallShared()})};
+}
+
+using ClientAllocator = decltype(getClientAllocator());
+} // namespace
+} // namespace AllocatorFactory
+} // namespace android
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index a08879e..87c67bd 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -22,6 +22,10 @@
cc_library_shared {
name: "libaudioflinger",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioFlinger.cpp",
"AudioHwDevice.cpp",
@@ -55,7 +59,6 @@
],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioflinger-aidl-cpp",
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
@@ -71,6 +74,7 @@
"liblog",
"libbinder",
"libaudioclient",
+ "libaudiomanager",
"libmedialogservice",
"libmediametrics",
"libmediautils",
@@ -113,3 +117,8 @@
},
}
+
+cc_library_headers {
+ name: "libaudioflinger_headers",
+ export_include_dirs: ["."],
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 7a9027c..3e9400b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -54,7 +54,7 @@
#include <cutils/properties.h>
#include <system/audio.h>
-#include <audiomanager/AudioManager.h>
+#include <audiomanager/IAudioManager.h>
#include "AudioFlinger.h"
#include "NBAIO_Tee.h"
@@ -114,11 +114,12 @@
using media::audio::common::AudioMMapPolicyType;
using android::content::AttributionSourceState;
-static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
-static const char kHardwareLockedString[] = "Hardware lock is taken\n";
-static const char kClientLockedString[] = "Client lock is taken\n";
-static const char kNoEffectsFactory[] = "Effects Factory is absent\n";
+static constexpr char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
+static constexpr char kHardwareLockedString[] = "Hardware lock is taken\n";
+static constexpr char kClientLockedString[] = "Client lock is taken\n";
+static constexpr char kNoEffectsFactory[] = "Effects Factory is absent\n";
+static constexpr char kAudioServiceName[] = "audio";
nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
@@ -596,6 +597,11 @@
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
AUDIO_OUTPUT_FLAG_DIRECT),
deviceId, &portId, &secondaryOutputs, &isSpatialized);
+ if (ret != NO_ERROR) {
+ config->sample_rate = fullConfig.sample_rate;
+ config->channel_mask = fullConfig.channel_mask;
+ config->format = fullConfig.format;
+ }
ALOGW_IF(!secondaryOutputs.empty(),
"%s does not support secondary outputs, ignoring them", __func__);
} else {
@@ -730,10 +736,10 @@
for (size_t i = 0; i < mClients.size(); ++i) {
sp<Client> client = mClients.valueAt(i).promote();
if (client != 0) {
- result.appendFormat("%6d %12zu\n", client->pid(),
- client->heap()->getMemoryHeap()->getSize());
+ result.append("Client: %d\n", client->pid());
+ result.append(client->allocator().dump().c_str());
}
- }
+ }
result.append("Notification Clients:\n");
result.append(" pid uid name\n");
@@ -2180,12 +2186,8 @@
AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
: RefBase(),
mAudioFlinger(audioFlinger),
- mPid(pid)
-{
- mMemoryDealer = new MemoryDealer(
- audioFlinger->getClientSharedHeapSize(),
- (std::string("AudioFlinger::Client(") + std::to_string(pid) + ")").c_str());
-}
+ mPid(pid),
+ mClientAllocator(AllocatorFactory::getClientAllocator()) {}
// Client destructor must be called with AudioFlinger::mClientLock held
AudioFlinger::Client::~Client()
@@ -2193,9 +2195,9 @@
mAudioFlinger->removeClient_l(mPid);
}
-sp<MemoryDealer> AudioFlinger::Client::heap() const
+AllocatorFactory::ClientAllocator& AudioFlinger::Client::allocator()
{
- return mMemoryDealer;
+ return mClientAllocator;
}
// ----------------------------------------------------------------------------
@@ -2722,9 +2724,28 @@
ThreadBase *thread = (ThreadBase *)mMmapThreads.valueAt(i).get();
thread->systemReady();
}
+
+ // Java services are ready, so we can create a reference to AudioService
+ getOrCreateAudioManager();
+
return NO_ERROR;
}
+sp<IAudioManager> AudioFlinger::getOrCreateAudioManager()
+{
+ if (mAudioManager.load() == nullptr) {
+ // use checkService() to avoid blocking
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16(kAudioServiceName));
+ if (binder != nullptr) {
+ mAudioManager = interface_cast<IAudioManager>(binder);
+ } else {
+ ALOGE("%s(): binding to audio service failed.", __func__);
+ }
+ }
+ return mAudioManager.load();
+}
+
status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
{
AutoMutex lock(mHardwareLock);
@@ -3710,6 +3731,12 @@
using namespace std::chrono_literals;
auto inChannelMask = audio_channel_mask_out_to_in(track->channelMask());
+ if (inChannelMask == AUDIO_CHANNEL_INVALID) {
+ // The downstream PatchTrack has the proper output channel mask,
+ // so if there is no input channel mask equivalent, we can just
+ // use an index mask here to create the PatchRecord.
+ inChannelMask = audio_channel_mask_out_to_in_index_mask(track->channelMask());
+ }
sp patchRecord = new RecordThread::PatchRecord(nullptr /* thread */,
track->sampleRate(),
inChannelMask,
@@ -4608,7 +4635,9 @@
} else {
getIAudioFlingerStatistics().event(code, elapsedMs);
}
- });
+ }, mediautils::TimeCheck::kDefaultTimeoutDuration,
+ mediautils::TimeCheck::kDefaultSecondChanceDuration,
+ true /* crashOnTimeout */);
// Make sure we connect to Audio Policy Service before calling into AudioFlinger:
// - AudioFlinger can call into Audio Policy Service with its global mutex held
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index fc4c807..7c5afce 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -75,6 +75,7 @@
#include <media/ExtendedAudioBufferProvider.h>
#include <media/VolumeShaper.h>
#include <mediautils/ServiceUtilities.h>
+#include <mediautils/SharedMemoryAllocator.h>
#include <mediautils/Synchronization.h>
#include <mediautils/ThreadSnapshot.h>
@@ -94,7 +95,7 @@
#include "NBAIO_Tee.h"
#include "ThreadMetrics.h"
#include "TrackMetrics.h"
-
+#include "AllocatorFactory.h"
#include <android/os/IPowerManager.h>
#include <media/nblog/NBLog.h>
@@ -117,6 +118,7 @@
class DevicesFactoryHalInterface;
class EffectsFactoryHalInterface;
class FastMixer;
+class IAudioManager;
class PassthruBufferProvider;
class RecordBufferConverter;
class ServerProxy;
@@ -498,19 +500,19 @@
// --- Client ---
class Client : public RefBase {
- public:
- Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+ public:
+ Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
virtual ~Client();
- sp<MemoryDealer> heap() const;
+ AllocatorFactory::ClientAllocator& allocator();
pid_t pid() const { return mPid; }
sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
private:
DISALLOW_COPY_AND_ASSIGN(Client);
- const sp<AudioFlinger> mAudioFlinger;
- sp<MemoryDealer> mMemoryDealer;
+ const sp<AudioFlinger> mAudioFlinger;
const pid_t mPid;
+ AllocatorFactory::ClientAllocator mClientAllocator;
};
// --- Notification Client ---
@@ -988,6 +990,8 @@
size_t rejectedKVPSize, const String8& rejectedKVPs,
uid_t callingUid);
+ sp<IAudioManager> getOrCreateAudioManager();
+
public:
// These methods read variables atomically without mLock,
// though the variables are updated with mLock.
@@ -1029,6 +1033,9 @@
std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
int32_t mAAudioBurstsPerBuffer = 0;
int32_t mAAudioHwBurstMinMicros = 0;
+
+ /** Interface for interacting with the AudioService. */
+ mediautils::atomic_sp<IAudioManager> mAudioManager;
};
#undef INCLUDING_FROM_AUDIOFLINGER_H
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 53ac5cb..4f3ed0a 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -106,8 +106,13 @@
if (lStatus == NO_ERROR) {
lStatus = effect->addHandle(handle.get());
if (lStatus == NO_ERROR) {
- effect->init(patches);
- mDeviceEffects.emplace(device, effect);
+ lStatus = effect->init(patches);
+ if (lStatus == NAME_NOT_FOUND) {
+ lStatus = NO_ERROR;
+ }
+ if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
+ mDeviceEffects.emplace(device, effect);
+ }
}
}
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 72c378d..7b4ae24 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -278,8 +278,8 @@
if (!doRegister && !(registered && doEnable)) {
return NO_ERROR;
}
- mPolicyLock.lock();
}
+ mPolicyLock.lock();
ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
__func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
if (doRegister) {
@@ -1058,6 +1058,13 @@
&size,
&cmdStatus);
}
+
+ if (isVolumeControl()) {
+ // Force initializing the volume as 0 for volume control effect for safer ramping
+ uint32_t left = 0;
+ uint32_t right = 0;
+ setVolumeInternal(&left, &right, true /*controller*/);
+ }
}
// mConfig.outputCfg.buffer.frameCount cannot be zero.
@@ -1431,23 +1438,24 @@
((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
- uint32_t volume[2];
- uint32_t *pVolume = NULL;
- uint32_t size = sizeof(volume);
- volume[0] = *left;
- volume[1] = *right;
- if (controller) {
- pVolume = volume;
- }
- status = mEffectInterface->command(EFFECT_CMD_SET_VOLUME,
- size,
- volume,
- &size,
- pVolume);
- if (controller && status == NO_ERROR && size == sizeof(volume)) {
- *left = volume[0];
- *right = volume[1];
- }
+ status = setVolumeInternal(left, right, controller);
+ }
+ return status;
+}
+
+status_t AudioFlinger::EffectModule::setVolumeInternal(
+ uint32_t *left, uint32_t *right, bool controller) {
+ uint32_t volume[2] = {*left, *right};
+ uint32_t *pVolume = controller ? volume : nullptr;
+ uint32_t size = sizeof(volume);
+ status_t status = mEffectInterface->command(EFFECT_CMD_SET_VOLUME,
+ size,
+ volume,
+ &size,
+ pVolume);
+ if (controller && status == NO_ERROR && size == sizeof(volume)) {
+ *left = volume[0];
+ *right = volume[1];
}
return status;
}
@@ -1753,7 +1761,14 @@
return;
}
int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
- mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
+ mCblkMemory = client->allocator().allocate(mediautils::NamedAllocRequest{
+ {static_cast<size_t>(EFFECT_PARAM_BUFFER_SIZE + bufOffset)},
+ std::string("Effect ID: ")
+ .append(std::to_string(effect->id()))
+ .append(" Session ID: ")
+ .append(std::to_string(static_cast<int>(effect->sessionId())))
+ .append(" \n")
+ });
if (mCblkMemory == 0 ||
(mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->unsecurePointer())) == NULL) {
ALOGE("not enough memory for Effect size=%zu", EFFECT_PARAM_BUFFER_SIZE +
@@ -1809,7 +1824,7 @@
} else {
getIEffectStatistics().event(code, elapsedMs);
}
- }, 0 /* timeoutMs */);
+ }, {} /* timeoutDuration */, {} /* secondChanceDuration */, false /* crashOnTimeout */);
return BnEffect::onTransact(code, data, reply, flags);
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index a89a814..78788df 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -306,6 +306,8 @@
? EFFECT_BUFFER_ACCESS_WRITE : EFFECT_BUFFER_ACCESS_ACCUMULATE;
}
+ status_t setVolumeInternal(uint32_t *left, uint32_t *right, bool controller);
+
effect_config_t mConfig; // input and output audio configuration
sp<EffectHalInterface> mEffectInterface; // Effect module HAL
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index eb640bb..cb46c52 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -54,6 +54,14 @@
bool getAndSetSilencedNotified_l() { bool silencedNotified = mSilencedNotified;
mSilencedNotified = true;
return silencedNotified; }
+
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ void processMuteEvent_l(const sp<IAudioManager>& audioManager,
+ mute_state_t muteState)
+ REQUIRES(AudioFlinger::MmapPlaybackThread::mLock);
private:
friend class MmapThread;
@@ -71,5 +79,12 @@
pid_t mPid;
bool mSilenced; // protected by MMapThread::mLock
bool mSilencedNotified; // protected by MMapThread::mLock
+
+ // TODO: replace PersistableBundle with own struct
+ // access these two variables only when holding player thread lock.
+ std::unique_ptr<os::PersistableBundle> mMuteEventExtras
+ GUARDED_BY(AudioFlinger::MmapPlaybackThread::mLock);
+ mute_state_t mMuteState
+ GUARDED_BY(AudioFlinger::MmapPlaybackThread::mLock);
}; // end of Track
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 93593a3..68a3800 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -31,7 +31,6 @@
mPlaybackThreadHandle(playbackThreadHandle),
mRecordThreadHandle(recordThreadHandle) {}
SoftwarePatch(const SoftwarePatch&) = default;
- SoftwarePatch& operator=(const SoftwarePatch&) = default;
// Must be called under AudioFlinger::mLock
status_t getLatencyMs_l(double *latencyMs) const;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 6a138bb..e52d1ee 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -204,6 +204,12 @@
float getSpeed() const { return mSpeed; }
bool isSpatialized() const override { return mIsSpatialized; }
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState);
+
protected:
// for numerous
friend class PlaybackThread;
@@ -354,6 +360,11 @@
TeePatches mTeePatches;
const float mSpeed;
const bool mIsSpatialized;
+
+ // TODO: replace PersistableBundle with own struct
+ // access these two variables only when holding player thread lock.
+ std::unique_ptr<os::PersistableBundle> mMuteEventExtras;
+ mute_state_t mMuteState;
}; // end of Track
diff --git a/services/audioflinger/TEST_MAPPING b/services/audioflinger/TEST_MAPPING
index 3de5a9f..9aff137 100644
--- a/services/audioflinger/TEST_MAPPING
+++ b/services/audioflinger/TEST_MAPPING
@@ -1,10 +1,19 @@
{
- "presubmit": [
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e127431..71c24f3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -31,6 +31,7 @@
#include <sys/syscall.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
+#include <binder/PersistableBundle.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioParameter.h>
@@ -178,6 +179,11 @@
// Direct output thread minimum sleep time in idle or active(underrun) state
static const nsecs_t kDirectMinSleepTimeUs = 10000;
+// Minimum amount of time between checking to see if the timestamp is advancing
+// for underrun detection. If we check too frequently, we may not detect a
+// timestamp update and will falsely detect underrun.
+static const nsecs_t kMinimumTimeBetweenTimestampChecksNs = 150 /* ms */ * 1000;
+
// The universal constant for ubiquitous 20ms value. The value of 20ms seems to provide a good
// balance between power consumption and latency, and allows threads to be scheduled reliably
// by the CFS scheduler.
@@ -2040,7 +2046,8 @@
mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
mLeftVolFloat(-1.0), mRightVolFloat(-1.0),
- mDownStreamPatch{}
+ mDownStreamPatch{},
+ mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
{
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -5378,8 +5385,19 @@
volume *= vh;
track->mCachedVolume = volume;
gain_minifloat_packed_t vlr = proxy->getVolumeLR();
- float vlf = volume * float_from_gain(gain_minifloat_unpack_left(vlr));
- float vrf = volume * float_from_gain(gain_minifloat_unpack_right(vlr));
+ float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
+ float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
+
+ track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ /*muteState=*/{masterVolume == 0.f,
+ mStreamTypes[track->streamType()].volume == 0.f,
+ mStreamTypes[track->streamType()].mute,
+ track->isPlaybackRestricted(),
+ vlf == 0.f && vrf == 0.f,
+ vh == 0.f});
+
+ vlf *= volume;
+ vrf *= volume;
track->setFinalVolume((vlf + vrf) / 2.f);
++fastTracks;
@@ -5552,6 +5570,15 @@
ALOGV("Track right volume out of range: %.3g", vrf);
vrf = GAIN_FLOAT_UNITY;
}
+
+ track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ /*muteState=*/{masterVolume == 0.f,
+ mStreamTypes[track->streamType()].volume == 0.f,
+ mStreamTypes[track->streamType()].mute,
+ track->isPlaybackRestricted(),
+ vlf == 0.f && vrf == 0.f,
+ vh == 0.f});
+
// now apply the master volume and stream type volume and shaper volume
vlf *= v * vh;
vrf *= v * vh;
@@ -5910,18 +5937,35 @@
return trackCount;
}
-bool AudioFlinger::PlaybackThread::checkRunningTimestamp()
+bool AudioFlinger::PlaybackThread::IsTimestampAdvancing::check(AudioStreamOut * output)
{
+ // Check the timestamp to see if it's advancing once every 150ms. If we check too frequently, we
+ // could falsely detect that the frame position has stalled due to underrun because we haven't
+ // given the Audio HAL enough time to update.
+ const nsecs_t nowNs = systemTime();
+ if (nowNs - mPreviousNs < mMinimumTimeBetweenChecksNs) {
+ return mLatchedValue;
+ }
+ mPreviousNs = nowNs;
+ mLatchedValue = false;
+ // Determine if the presentation position is still advancing.
uint64_t position = 0;
struct timespec unused;
- const status_t ret = mOutput->getPresentationPosition(&position, &unused);
+ const status_t ret = output->getPresentationPosition(&position, &unused);
if (ret == NO_ERROR) {
- if (position != mLastCheckedTimestampPosition) {
- mLastCheckedTimestampPosition = position;
- return true;
+ if (position != mPreviousPosition) {
+ mPreviousPosition = position;
+ mLatchedValue = true;
}
}
- return false;
+ return mLatchedValue;
+}
+
+void AudioFlinger::PlaybackThread::IsTimestampAdvancing::clear()
+{
+ mLatchedValue = true;
+ mPreviousPosition = 0;
+ mPreviousNs = 0;
}
// isTrackAllowed_l() must be called with ThreadBase::mLock held
@@ -6121,31 +6165,44 @@
{
float left, right;
+
// Ensure volumeshaper state always advances even when muted.
const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
const auto [shaperVolume, shaperActive] = track->getVolumeHandler()->getVolume(
proxy->framesReleased());
mVolumeShaperActive = shaperActive;
+ gain_minifloat_packed_t vlr = proxy->getVolumeLR();
+ left = float_from_gain(gain_minifloat_unpack_left(vlr));
+ right = float_from_gain(gain_minifloat_unpack_right(vlr));
+
+ const bool clientVolumeMute = (left == 0.f && right == 0.f);
+
if (mMasterMute || mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
left = right = 0;
} else {
float typeVolume = mStreamTypes[track->streamType()].volume;
const float v = mMasterVolume * typeVolume * shaperVolume;
- gain_minifloat_packed_t vlr = proxy->getVolumeLR();
- left = float_from_gain(gain_minifloat_unpack_left(vlr));
if (left > GAIN_FLOAT_UNITY) {
left = GAIN_FLOAT_UNITY;
}
- left *= v * mMasterBalanceLeft; // DirectOutputThread balance applied as track volume
- right = float_from_gain(gain_minifloat_unpack_right(vlr));
if (right > GAIN_FLOAT_UNITY) {
right = GAIN_FLOAT_UNITY;
}
+
+ left *= v * mMasterBalanceLeft; // DirectOutputThread balance applied as track volume
right *= v * mMasterBalanceRight;
}
+ track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ /*muteState=*/{mMasterMute,
+ mStreamTypes[track->streamType()].volume == 0.f,
+ mStreamTypes[track->streamType()].mute,
+ track->isPlaybackRestricted(),
+ clientVolumeMute,
+ shaperVolume == 0.f});
+
if (lastTrack) {
track->setFinalVolume((left + right) / 2.f);
if (left != mLeftVolFloat || right != mRightVolFloat) {
@@ -6356,9 +6413,9 @@
// No buffers for this track. Give it a few chances to
// fill a buffer, then remove it from active list.
// Only consider last track started for mixer state control
+ bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (--(track->mRetryCount) <= 0) {
- const bool running = checkRunningTimestamp();
- if (running) { // still running, give us more time.
+ if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
track->mRetryCount = kMaxTrackRetriesOffload;
} else {
ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId);
@@ -6939,9 +6996,9 @@
} else {
// No buffers for this track. Give it a few chances to
// fill a buffer, then remove it from active list.
+ bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (--(track->mRetryCount) <= 0) {
- const bool running = checkRunningTimestamp();
- if (running) { // still running, give us more time.
+ if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
track->mRetryCount = kMaxTrackRetriesOffload;
} else {
ALOGV("OffloadThread: BUFFER TIMEOUT: remove track(%d) from active list",
@@ -10408,6 +10465,14 @@
}
for (const sp<MmapTrack> &track : mActiveTracks) {
track->setMetadataHasChanged();
+ track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ /*muteState=*/{mMasterMute,
+ mStreamVolume == 0.f,
+ mStreamMute,
+ // TODO(b/241533526): adjust logic to include mute from AppOps
+ false /*muteFromPlaybackRestricted*/,
+ false /*muteFromClientVolume*/,
+ false /*muteFromVolumeShaper*/});
}
}
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index fc37bd2..b477d65 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -624,7 +624,7 @@
virtual void dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
- friend class AudioFlinger; // for mEffectChains
+ friend class AudioFlinger; // for mEffectChains and mAudioManager
const type_t mType;
@@ -1177,7 +1177,7 @@
volatile int32_t mSuspended;
int64_t mBytesWritten;
- int64_t mFramesWritten; // not reset on standby
+ std::atomic<int64_t> mFramesWritten; // not reset on standby
int64_t mLastFramesWritten = -1; // track changes in timestamp
// server frames written.
int64_t mSuspendedFrames; // not reset on standby
@@ -1391,6 +1391,7 @@
virtual bool hasFastMixer() const = 0;
virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex __unused) const
{ FastTrackUnderruns dummy; return dummy; }
+ const std::atomic<int64_t>& framesWritten() const { return mFramesWritten; }
protected:
// accessed by both binder threads and within threadLoop(), lock on mutex needed
@@ -1408,13 +1409,38 @@
std::atomic_bool mCheckOutputStageEffects{};
- // A differential check on the timestamps to see if there is a change in the
- // timestamp frame position between the last call to checkRunningTimestamp.
- uint64_t mLastCheckedTimestampPosition = ~0LL;
- bool checkRunningTimestamp();
+ // Provides periodic checking for timestamp advancement for underrun detection.
+ class IsTimestampAdvancing {
+ public:
+ // The timestamp will not be checked any faster than the specified time.
+ IsTimestampAdvancing(nsecs_t minimumTimeBetweenChecksNs)
+ : mMinimumTimeBetweenChecksNs(minimumTimeBetweenChecksNs)
+ {
+ clear();
+ }
+ // Check if the presentation position has advanced in the last periodic time.
+ bool check(AudioStreamOut * output);
+ // Clear the internal state when the playback state changes for the output
+ // stream.
+ void clear();
+ private:
+ // The minimum time between timestamp checks.
+ const nsecs_t mMinimumTimeBetweenChecksNs;
+ // Add differential check on the timestamps to see if there is a change in the
+ // timestamp frame position between the last call to check.
+ uint64_t mPreviousPosition;
+ // The time at which the last check occurred, to ensure we don't check too
+ // frequently, giving the Audio HAL enough time to update its timestamps.
+ nsecs_t mPreviousNs;
+ // The valued is latched so we don't check timestamps too frequently.
+ bool mLatchedValue;
+ };
+ IsTimestampAdvancing mIsTimestampAdvancing;
- virtual void flushHw_l() { mLastCheckedTimestampPosition = ~0LL; }
+ virtual void flushHw_l() {
+ mIsTimestampAdvancing.clear();
+ }
};
class MixerThread : public PlaybackThread {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2dfa1b2..cfb296c 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -162,11 +162,12 @@
}
if (client != 0) {
- mCblkMemory = client->heap()->allocate(size);
+ mCblkMemory = client->allocator().allocate(mediautils::NamedAllocRequest{{size},
+ std::string("Track ID: ").append(std::to_string(mId))});
if (mCblkMemory == 0 ||
(mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->unsecurePointer())) == NULL) {
ALOGE("%s(%d): not enough memory for AudioTrack size=%zu", __func__, mId, size);
- client->heap()->dump("AudioTrack");
+ ALOGE("%s", client->allocator().dump().c_str());
mCblkMemory.clear();
return;
}
@@ -1094,12 +1095,22 @@
__func__, mId, (int)mThreadIoHandle);
}
- // states to reset position info for non-offloaded/direct tracks
- if (!isOffloaded() && !isDirect()
+ PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+
+ // states to reset position info for pcm tracks
+ if (audio_is_linear_pcm(mFormat)
&& (state == IDLE || state == STOPPED || state == FLUSHED)) {
mFrameMap.reset();
+
+ if (!isFastTrack() && (isDirect() || isOffloaded())) {
+ // Start point of track -> sink frame map. If the HAL returns a
+ // frame position smaller than the first written frame in
+ // updateTrackFrameInfo, the timestamp can be interpolated
+ // instead of using a larger value.
+ mFrameMap.push(mAudioTrackServerProxy->framesReleased(),
+ playbackThread->framesWritten());
+ }
}
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
if (isFastTrack()) {
// refresh fast track underruns on start because that field is never cleared
// by the fast mixer; furthermore, the same track can be recycled, i.e. start
@@ -1484,6 +1495,39 @@
}
}
+// must be called with player thread lock held
+void AudioFlinger::PlaybackThread::Track::processMuteEvent_l(const sp<
+ IAudioManager>& audioManager, mute_state_t muteState)
+{
+ if (mMuteState == muteState) {
+ // mute state did not change, do nothing
+ return;
+ }
+
+ status_t result = UNKNOWN_ERROR;
+ if (audioManager && mPortId != AUDIO_PORT_HANDLE_NONE) {
+ if (mMuteEventExtras == nullptr) {
+ mMuteEventExtras = std::make_unique<os::PersistableBundle>();
+ }
+ mMuteEventExtras->putInt(String16(kExtraPlayerEventMuteKey),
+ static_cast<int>(muteState));
+
+ result = audioManager->portEvent(mPortId,
+ PLAYER_UPDATE_MUTED,
+ mMuteEventExtras);
+ }
+
+ if (result == OK) {
+ mMuteState = muteState;
+ } else {
+ ALOGW("%s(%d): cannot process mute state for port ID %d, status error %d",
+ __func__,
+ id(),
+ mPortId,
+ result);
+ }
+}
+
status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
{
if (!isOffloaded() && !isDirect()) {
@@ -3097,6 +3141,38 @@
{
}
+void AudioFlinger::MmapThread::MmapTrack::processMuteEvent_l(const sp<
+ IAudioManager>& audioManager, mute_state_t muteState)
+{
+ if (mMuteState == muteState) {
+ // mute state did not change, do nothing
+ return;
+ }
+
+ status_t result = UNKNOWN_ERROR;
+ if (audioManager && mPortId != AUDIO_PORT_HANDLE_NONE) {
+ if (mMuteEventExtras == nullptr) {
+ mMuteEventExtras = std::make_unique<os::PersistableBundle>();
+ }
+ mMuteEventExtras->putInt(String16(kExtraPlayerEventMuteKey),
+ static_cast<int>(muteState));
+
+ result = audioManager->portEvent(mPortId,
+ PLAYER_UPDATE_MUTED,
+ mMuteEventExtras);
+ }
+
+ if (result == OK) {
+ mMuteState = muteState;
+ } else {
+ ALOGW("%s(%d): cannot process mute state for port ID %d, status error %d",
+ __func__,
+ id(),
+ mPortId,
+ result);
+ }
+}
+
void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
{
result.appendFormat("Client Session Port Id Format Chn mask SRate Flags %s\n",
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 496591a..c4c27e8 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -134,17 +134,17 @@
// request an output appropriate for playback of the supplied stream type and parameters
virtual audio_io_handle_t getOutput(audio_stream_type_t stream) = 0;
virtual status_t getOutputForAttr(const audio_attributes_t *attr,
- audio_io_handle_t *output,
- audio_session_t session,
- audio_stream_type_t *stream,
- const AttributionSourceState& attributionSouce,
- const audio_config_t *config,
- audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
- audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs,
- output_type_t *outputType,
- bool *isSpatialized) = 0;
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ const AttributionSourceState& attributionSouce,
+ audio_config_t *config,
+ audio_output_flags_t *flags,
+ audio_port_handle_t *selectedDeviceId,
+ audio_port_handle_t *portId,
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType,
+ bool *isSpatialized) = 0;
// indicates to the audio policy manager that the output starts being used by corresponding
// stream.
virtual status_t startOutput(audio_port_handle_t portId) = 0;
@@ -160,7 +160,7 @@
audio_unique_id_t riid,
audio_session_t session,
const AttributionSourceState& attributionSouce,
- const audio_config_base_t *config,
+ audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t *selectedDeviceId,
input_type_t *inputType,
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
index f130f7c..4d43eb0 100644
--- a/services/audiopolicy/TEST_MAPPING
+++ b/services/audiopolicy/TEST_MAPPING
@@ -11,12 +11,23 @@
"include-filter": "com.google.android.gts.audio.AudioHostTest#testTwoChannelCapturing"
}
]
- },
+ }
+ ],
+ "postsubmit": [
{
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
- "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_DEFAULT__OUTPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__INPUT"
+ },
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index bb1699e..afffcd5 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -55,7 +55,7 @@
status_t getAudioPolicyMix(audio_devices_t deviceType,
const String8& address, sp<AudioPolicyMix> &policyMix) const;
- status_t registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc);
+ status_t registerMix(const AudioMix& mix, const sp<SwAudioOutputDescriptor>& desc);
status_t unregisterMix(const AudioMix& mix);
@@ -124,7 +124,7 @@
void dump(String8 *dst) const;
private:
- enum class MixMatchStatus { MATCH, NO_MATCH, INVALID_MIX };
+ enum class MixMatchStatus { MATCH, NO_MATCH };
MixMatchStatus mixMatch(const AudioMix* mix, size_t mixIndex,
const audio_attributes_t& attributes,
const audio_config_base_t& config,
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 0431619..7119b85 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -239,12 +239,13 @@
}
void setUseSwBridge() { mUseSwBridge = true; }
bool useSwBridge() const { return mUseSwBridge; }
+ bool canCloseOutput() const { return mCloseOutput; }
bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
sp<DeviceDescriptor> sinkDevice() const { return mSinkDevice; }
wp<SwAudioOutputDescriptor> swOutput() const { return mSwOutput; }
- void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput);
+ void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput, bool closeOutput = false);
wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
@@ -258,6 +259,15 @@
wp<SwAudioOutputDescriptor> mSwOutput;
wp<HwAudioOutputDescriptor> mHwOutput;
bool mUseSwBridge = false;
+ /**
+ * For either HW bridge associated to a SwOutput for activity / volume or SwBridge for also
+ * sample rendering / activity & volume, an existing playback thread may be reused (e.g.
+ * not already opened at APM startup or Direct Output).
+ * If reusing an already opened output, when this output is not used anymore, the AudioFlinger
+ * patch must be updated to refine the output device(s) information and ensure the right
+ * behavior of AudioDeviceCallback.
+ */
+ bool mCloseOutput = false;
};
/**
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 90b812d..37443ab 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -97,6 +97,25 @@
uint32_t flags,
bool exactMatchRequiredForInputFlags = false) const;
+ /**
+ * @brief areAllDevicesSupported: Checks if the given devices are supported by the IO profile.
+ *
+ * @param devices vector of devices to be checked for compatibility
+ * @return true if all devices are supported, false otherwise.
+ */
+ bool areAllDevicesSupported(const DeviceVector &devices) const;
+
+ /**
+ * @brief isCompatibleProfileForFlags: Checks if the IO profile is compatible with
+ * specified flags.
+ *
+ * @param flags to be checked for compatibility
+ * @param exactMatchRequiredForInputFlags true if exact match is required on flags
+ * @return true if the profile is compatible, false otherwise.
+ */
+ bool isCompatibleProfileForFlags(uint32_t flags,
+ bool exactMatchRequiredForInputFlags = false) const;
+
void dump(String8 *dst, int spaces) const;
void log();
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 551eab6..65fab43 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "APM_AudioPolicyMix"
//#define LOG_NDEBUG 0
+#include <algorithm>
#include "AudioPolicyMix.h"
#include "TypeConverter.h"
#include "HwModule.h"
@@ -25,6 +26,34 @@
#include <AudioOutputDescriptor.h>
namespace android {
+namespace {
+
+// Consistency checks: for each "dimension" of rules (usage, uid...), we can
+// only have MATCH rules, or EXCLUDE rules in each dimension, not a combination.
+bool areMixCriteriaConsistent(const std::vector<AudioMixMatchCriterion>& criteria) {
+ std::set<uint32_t> positiveCriteria;
+ for (const AudioMixMatchCriterion& c : criteria) {
+ if (c.isExcludeCriterion()) {
+ continue;
+ }
+ positiveCriteria.insert(c.mRule);
+ }
+
+ auto isConflictingCriterion = [&positiveCriteria](const AudioMixMatchCriterion& c) {
+ uint32_t ruleWithoutExclusion = c.mRule & ~RULE_EXCLUSION_MASK;
+ return c.isExcludeCriterion() &&
+ (positiveCriteria.find(ruleWithoutExclusion) != positiveCriteria.end());
+ };
+ return std::none_of(criteria.begin(), criteria.end(), isConflictingCriterion);
+}
+
+template <typename Predicate>
+void EraseCriteriaIf(std::vector<AudioMixMatchCriterion>& v,
+ const Predicate& predicate) {
+ v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());
+}
+
+} // namespace
void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
{
@@ -78,7 +107,8 @@
}
}
-status_t AudioPolicyMixCollection::registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc)
+status_t AudioPolicyMixCollection::registerMix(const AudioMix& mix,
+ const sp<SwAudioOutputDescriptor>& desc)
{
for (size_t i = 0; i < size(); i++) {
const sp<AudioPolicyMix>& registeredMix = itemAt(i);
@@ -89,12 +119,17 @@
return BAD_VALUE;
}
}
- sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
+ if (!areMixCriteriaConsistent(mix.mCriteria)) {
+ ALOGE("registerMix(): Mix contains inconsistent criteria "
+ "(MATCH & EXCLUDE criteria of the same type)");
+ return BAD_VALUE;
+ }
+ sp<AudioPolicyMix> policyMix = sp<AudioPolicyMix>::make(mix);
add(policyMix);
ALOGD("registerMix(): adding mix for dev=0x%x addr=%s",
policyMix->mDeviceType, policyMix->mDeviceAddress.string());
- if (desc != 0) {
+ if (desc != nullptr) {
desc->mPolicyMix = policyMix;
policyMix->setOutput(desc);
}
@@ -177,15 +212,9 @@
continue; // Primary output already found
}
- switch (mixMatch(policyMix.get(), i, attributes, config, uid)) {
- case MixMatchStatus::INVALID_MIX:
- // The mix has contradictory rules, ignore it
- // TODO: reject invalid mix at registration
- continue;
- case MixMatchStatus::NO_MATCH:
- ALOGV("%s: Mix %zu: does not match", __func__, i);
- continue; // skip the mix
- case MixMatchStatus::MATCH:;
+ if(mixMatch(policyMix.get(), i, attributes, config, uid) == MixMatchStatus::NO_MATCH) {
+ ALOGV("%s: Mix %zu: does not match", __func__, i);
+ continue; // skip the mix
}
if (primaryOutputMix) {
@@ -232,7 +261,8 @@
// Permit match only if requested format and mix format are PCM and can be format
// adapted by the mixer, or are the same (compressed) format.
- if (!((audio_is_linear_pcm(config.format) && audio_is_linear_pcm(mix->mFormat.format)) ||
+ if (!is_mix_loopback(mix->mRouteFlags) &&
+ !((audio_is_linear_pcm(config.format) && audio_is_linear_pcm(mix->mFormat.format)) ||
(config.format == mix->mFormat.format)) &&
config.format != AUDIO_CONFIG_BASE_INITIALIZER.format) {
return MixMatchStatus::NO_MATCH;
@@ -331,23 +361,6 @@
break;
}
- // consistency checks: for each "dimension" of rules (usage, uid...), we can
- // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination
- if (hasUsageMatchRules && hasUsageExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE"
- " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUidMatchRules && hasUidExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID"
- " and RULE_EXCLUDE_UID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUserIdMatchRules && hasUserIdExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_USERID"
- " and RULE_EXCLUDE_USERID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
if ((hasUsageExcludeRules && usageExclusionFound)
|| (hasUidExcludeRules && uidExclusionFound)
@@ -500,7 +513,7 @@
// AND it doesn't have a "match uid" rule
// THEN add a rule to exclude the uid
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -530,27 +543,16 @@
status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
// for each player mix: remove existing rules that match or exclude this uid
for (size_t i = 0; i < size(); i++) {
- bool foundUidRule = false;
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
- std::vector<size_t> criteriaToRemove;
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- const uint32_t rule = mix->mCriteria[j].mRule;
- // is this rule excluding the uid? (not considering uid match rules
- // as those are not used for uid-device affinity)
- if (rule == RULE_EXCLUDE_UID
- && uid == mix->mCriteria[j].mValue.mUid) {
- foundUidRule = true;
- criteriaToRemove.insert(criteriaToRemove.begin(), j);
- }
- }
- if (foundUidRule) {
- for (size_t j = 0; j < criteriaToRemove.size(); j++) {
- mix->mCriteria.removeAt(criteriaToRemove[j]);
- }
- }
+
+ // is this rule excluding the uid? (not considering uid match rules
+ // as those are not used for uid-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [uid](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_UID && c.mValue.mUid == uid;
+ });
}
return NO_ERROR;
}
@@ -585,7 +587,7 @@
// "match userId" rule for this userId, return an error
// (adding a userId-device affinity would result in contradictory rules)
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix* mix = itemAt(i).get();
+ AudioPolicyMix* mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -602,7 +604,7 @@
// AND it doesn't have a "match userId" rule
// THEN add a rule to exclude the userId
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -632,27 +634,16 @@
status_t AudioPolicyMixCollection::removeUserIdDeviceAffinities(int userId) {
// for each player mix: remove existing rules that match or exclude this userId
for (size_t i = 0; i < size(); i++) {
- bool foundUserIdRule = false;
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
- std::vector<size_t> criteriaToRemove;
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- const uint32_t rule = mix->mCriteria[j].mRule;
- // is this rule excluding the userId? (not considering userId match rules
- // as those are not used for userId-device affinity)
- if (rule == RULE_EXCLUDE_USERID
- && userId == mix->mCriteria[j].mValue.mUserId) {
- foundUserIdRule = true;
- criteriaToRemove.insert(criteriaToRemove.begin(), j);
- }
- }
- if (foundUserIdRule) {
- for (size_t j = 0; j < criteriaToRemove.size(); j++) {
- mix->mCriteria.removeAt(criteriaToRemove[j]);
- }
- }
+
+ // is this rule excluding the userId? (not considering userId match rules
+ // as those are not used for userId-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [userId](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_USERID && c.mValue.mUserId == userId;
+ });
}
return NO_ERROR;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 713b0ac..8b6866e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -105,9 +105,11 @@
{
}
-void SourceClientDescriptor::setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput)
+void SourceClientDescriptor::setSwOutput(
+ const sp<SwAudioOutputDescriptor>& swOutput, bool closeOutput)
{
mSwOutput = swOutput;
+ mCloseOutput = closeOutput;
}
void SourceClientDescriptor::setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput)
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index 21f2018..7b4cecf 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -40,11 +40,9 @@
const bool isRecordThread =
getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK;
ALOG_ASSERT(isPlaybackThread != isRecordThread);
-
- if (!devices.isEmpty()) {
- if (!mSupportedDevices.containsAllDevices(devices)) {
- return false;
- }
+ if (!areAllDevicesSupported(devices) ||
+ !isCompatibleProfileForFlags(flags, exactMatchRequiredForInputFlags)) {
+ return false;
}
if (!audio_is_valid_format(format) ||
@@ -78,6 +76,33 @@
}
}
+ if (updatedSamplingRate != NULL) {
+ *updatedSamplingRate = myUpdatedSamplingRate;
+ }
+ if (updatedFormat != NULL) {
+ *updatedFormat = myUpdatedFormat;
+ }
+ if (updatedChannelMask != NULL) {
+ *updatedChannelMask = myUpdatedChannelMask;
+ }
+ return true;
+}
+
+bool IOProfile::areAllDevicesSupported(const DeviceVector &devices) const {
+ if (devices.empty()) {
+ return true;
+ }
+ return mSupportedDevices.containsAllDevices(devices);
+}
+
+bool IOProfile::isCompatibleProfileForFlags(uint32_t flags,
+ bool exactMatchRequiredForInputFlags) const {
+ const bool isPlaybackThread =
+ getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SOURCE;
+ const bool isRecordThread =
+ getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK;
+ ALOG_ASSERT(isPlaybackThread != isRecordThread);
+
const uint32_t mustMatchOutputFlags =
AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
if (isPlaybackThread && (((getFlags() ^ flags) & mustMatchOutputFlags)
@@ -93,15 +118,6 @@
return false;
}
- if (updatedSamplingRate != NULL) {
- *updatedSamplingRate = myUpdatedSamplingRate;
- }
- if (updatedFormat != NULL) {
- *updatedFormat = myUpdatedFormat;
- }
- if (updatedChannelMask != NULL) {
- *updatedChannelMask = myUpdatedChannelMask;
- }
return true;
}
diff --git a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
index c3b19c2..c453dea 100644
--- a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
+++ b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
@@ -12,6 +12,7 @@
</mixPort>
<!-- Le Audio Audio Ports -->
<mixPort name="le audio output" role="source" />
+ <mixPort name="le audio broadcast output" role="source" />
<mixPort name="le audio input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 16000 24000 32000 44100 48000"
@@ -65,6 +66,6 @@
<route type="mix" sink="BLE Speaker Out"
sources="le audio output"/>
<route type="mix" sink="BLE Broadcast Out"
- sources="le audio output"/>
+ sources="le audio broadcast output"/>
</routes>
</module>
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index b036e12..60b16ac 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -25,11 +25,11 @@
const engineConfig::ProductStrategies gOrderedStrategies = {
{"STRATEGY_PHONE",
{
- {"phone", AUDIO_STREAM_VOICE_CALL, "AUDIO_STREAM_VOICE_CALL",
+ {AUDIO_STREAM_VOICE_CALL, "AUDIO_STREAM_VOICE_CALL",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}},
},
- {"sco", AUDIO_STREAM_BLUETOOTH_SCO, "AUDIO_STREAM_BLUETOOTH_SCO",
+ {AUDIO_STREAM_BLUETOOTH_SCO, "AUDIO_STREAM_BLUETOOTH_SCO",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_SCO,
""}},
}
@@ -37,11 +37,11 @@
},
{"STRATEGY_SONIFICATION",
{
- {"ring", AUDIO_STREAM_RING, "AUDIO_STREAM_RING",
+ {AUDIO_STREAM_RING, "AUDIO_STREAM_RING",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}}
},
- {"alarm", AUDIO_STREAM_ALARM, "AUDIO_STREAM_ALARM",
+ {AUDIO_STREAM_ALARM, "AUDIO_STREAM_ALARM",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}},
}
@@ -49,7 +49,7 @@
},
{"STRATEGY_ENFORCED_AUDIBLE",
{
- {"", AUDIO_STREAM_ENFORCED_AUDIBLE, "AUDIO_STREAM_ENFORCED_AUDIBLE",
+ {AUDIO_STREAM_ENFORCED_AUDIBLE, "AUDIO_STREAM_ENFORCED_AUDIBLE",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_AUDIBILITY_ENFORCED, ""}}
}
@@ -57,7 +57,7 @@
},
{"STRATEGY_ACCESSIBILITY",
{
- {"", AUDIO_STREAM_ACCESSIBILITY, "AUDIO_STREAM_ACCESSIBILITY",
+ {AUDIO_STREAM_ACCESSIBILITY, "AUDIO_STREAM_ACCESSIBILITY",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}}
}
@@ -65,7 +65,7 @@
},
{"STRATEGY_SONIFICATION_RESPECTFUL",
{
- {"", AUDIO_STREAM_NOTIFICATION, "AUDIO_STREAM_NOTIFICATION",
+ {AUDIO_STREAM_NOTIFICATION, "AUDIO_STREAM_NOTIFICATION",
{
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""},
@@ -77,11 +77,11 @@
},
{"STRATEGY_MEDIA",
{
- {"assistant", AUDIO_STREAM_ASSISTANT, "AUDIO_STREAM_ASSISTANT",
+ {AUDIO_STREAM_ASSISTANT, "AUDIO_STREAM_ASSISTANT",
{{AUDIO_CONTENT_TYPE_SPEECH, AUDIO_USAGE_ASSISTANT,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}}
},
- {"music", AUDIO_STREAM_MUSIC, "AUDIO_STREAM_MUSIC",
+ {AUDIO_STREAM_MUSIC, "AUDIO_STREAM_MUSIC",
{
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""},
@@ -95,7 +95,7 @@
AUDIO_FLAG_NONE, ""}
},
},
- {"system", AUDIO_STREAM_SYSTEM, "AUDIO_STREAM_SYSTEM",
+ {AUDIO_STREAM_SYSTEM, "AUDIO_STREAM_SYSTEM",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_SONIFICATION,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}}
}
@@ -103,7 +103,7 @@
},
{"STRATEGY_DTMF",
{
- {"", AUDIO_STREAM_DTMF, "AUDIO_STREAM_DTMF",
+ {AUDIO_STREAM_DTMF, "AUDIO_STREAM_DTMF",
{
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}
@@ -113,7 +113,7 @@
},
{"STRATEGY_CALL_ASSISTANT",
{
- {"", AUDIO_STREAM_CALL_ASSISTANT, "AUDIO_STREAM_CALL_ASSISTANT",
+ {AUDIO_STREAM_CALL_ASSISTANT, "AUDIO_STREAM_CALL_ASSISTANT",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_CALL_ASSISTANT, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}}
}
@@ -121,7 +121,7 @@
},
{"STRATEGY_TRANSMITTED_THROUGH_SPEAKER",
{
- {"", AUDIO_STREAM_TTS, "AUDIO_STREAM_TTS",
+ {AUDIO_STREAM_TTS, "AUDIO_STREAM_TTS",
{
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_BEACON, ""},
@@ -140,7 +140,7 @@
const engineConfig::ProductStrategies gOrderedSystemStrategies = {
{"rerouting",
{
- {"", AUDIO_STREAM_REROUTING, "AUDIO_STREAM_REROUTING",
+ {AUDIO_STREAM_REROUTING, "AUDIO_STREAM_REROUTING",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VIRTUAL_SOURCE, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}}
}
@@ -148,7 +148,7 @@
},
{"patch",
{
- {"", AUDIO_STREAM_PATCH, "AUDIO_STREAM_PATCH",
+ {AUDIO_STREAM_PATCH, "AUDIO_STREAM_PATCH",
{{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}}
}
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 2ebb7df..8036eea 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -35,7 +35,6 @@
using StreamVector = std::vector<audio_stream_type_t>;
struct AttributesGroup {
- std::string name;
audio_stream_type_t stream;
std::string volumeGroup;
AttributesVector attributesVect;
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 6f560d5..ac117f0 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -57,7 +57,6 @@
static constexpr const char *collectionTag = "AttributesGroups";
struct Attributes {
- static constexpr const char *name = "name";
static constexpr const char *streamType = "streamType";
static constexpr const char *volumeGroup = "volumeGroup";
};
@@ -313,12 +312,6 @@
status_t AttributesGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
Collection &attributesGroup)
{
- std::string name = getXmlAttribute(child, Attributes::name);
- if (name.empty()) {
- ALOGV("AttributesGroupTraits No attribute %s found", Attributes::name);
- }
- ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
-
std::string volumeGroup = getXmlAttribute(child, Attributes::volumeGroup);
if (volumeGroup.empty()) {
ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::volumeGroup);
@@ -339,7 +332,7 @@
AttributesVector attributesVect;
deserializeAttributesCollection(doc, child, attributesVect);
- attributesGroup.push_back({name, streamType, volumeGroup, attributesVect});
+ attributesGroup.push_back({streamType, volumeGroup, attributesVect});
return NO_ERROR;
}
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
index 40efb3d..77ea507 100644
--- a/services/audiopolicy/engineconfigurable/tools/Android.bp
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -37,7 +37,7 @@
// Tools for audio policy engine criterion type configuration file
//
python_binary_host {
- name: "buildPolicyCriterionTypes.py",
+ name: "buildPolicyCriterionTypes",
main: "buildPolicyCriterionTypes.py",
srcs: [
"buildPolicyCriterionTypes.py",
@@ -47,10 +47,10 @@
genrule_defaults {
name: "buildpolicycriteriontypesrule",
- tools: ["buildPolicyCriterionTypes.py"],
+ tools: ["buildPolicyCriterionTypes"],
cmd: "cp $(locations :audio_policy_configuration_files) $(genDir)/. && " +
"cp $(location :audio_policy_configuration_top_file) $(genDir)/audio_policy_configuration.xml && " +
- "$(location buildPolicyCriterionTypes.py) " +
+ "$(location buildPolicyCriterionTypes) " +
" --androidaudiobaseheader $(location :libaudio_system_audio_base) " +
" --androidaudiocommonbaseheader $(location :libaudio_system_audio_common_base) " +
"--audiopolicyconfigurationfile $(genDir)/audio_policy_configuration.xml " +
@@ -72,7 +72,7 @@
// Tools for audio policy engine parameter framework configurable domains
//
python_binary_host {
- name: "domainGeneratorPolicy.py",
+ name: "domainGeneratorPolicy",
main: "domainGeneratorPolicy.py",
srcs: [
"domainGeneratorPolicy.py",
@@ -91,13 +91,13 @@
genrule_defaults {
name: "domaingeneratorpolicyrule",
tools: [
- "domainGeneratorPolicy.py",
+ "domainGeneratorPolicy",
"domainGeneratorConnector",
],
cmd: "mkdir -p $(genDir)/Structure/Policy && " +
"cp $(locations :audio_policy_pfw_structure_files) $(genDir)/Structure/Policy && " +
"cp $(location :audio_policy_pfw_toplevel) $(genDir)/top_level && " +
- "$(location domainGeneratorPolicy.py) " +
+ "$(location domainGeneratorPolicy) " +
"--validate " +
"--domain-generator-tool $(location domainGeneratorConnector) " +
"--toplevel-config $(genDir)/top_level " +
@@ -121,7 +121,7 @@
// Tools for policy parameter-framework product strategies structure file generation
//
python_binary_host {
- name: "buildStrategiesStructureFile.py",
+ name: "buildStrategiesStructureFile",
main: "buildStrategiesStructureFile.py",
srcs: [
"buildStrategiesStructureFile.py",
@@ -131,9 +131,9 @@
genrule_defaults {
name: "buildstrategiesstructurerule",
- tools: ["buildStrategiesStructureFile.py"],
+ tools: ["buildStrategiesStructureFile"],
cmd: "cp $(locations :audio_policy_engine_configuration_files) $(genDir) && ls -l $(genDir) &&"+
- "$(location buildStrategiesStructureFile.py) " +
+ "$(location buildStrategiesStructureFile) " +
"--audiopolicyengineconfigurationfile $(genDir)/audio_policy_engine_configuration.xml "+
"--productstrategiesstructurefile $(location :product_strategies_structure_template) " +
"--outputfile $(out)",
@@ -149,7 +149,7 @@
// Tools for policy parameter-framework common type structure file generation
//
python_binary_host {
- name: "buildCommonTypesStructureFile.py",
+ name: "buildCommonTypesStructureFile",
main: "buildCommonTypesStructureFile.py",
srcs: [
"buildCommonTypesStructureFile.py",
@@ -159,8 +159,8 @@
genrule_defaults {
name: "buildcommontypesstructurerule",
- tools: ["buildCommonTypesStructureFile.py"],
- cmd: "$(location buildCommonTypesStructureFile.py) " +
+ tools: ["buildCommonTypesStructureFile"],
+ cmd: "$(location buildCommonTypesStructureFile) " +
"--androidaudiobaseheader $(location :libaudio_system_audio_base) " +
"--commontypesstructure $(location :common_types_structure_template) " +
"--outputfile $(out)",
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 08d6453..7534984 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -78,7 +78,7 @@
case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
config != AUDIO_POLICY_FORCE_NONE) {
- ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
+ ALOGW("setForceUse() invalid config %d for COMMUNICATION", config);
return BAD_VALUE;
}
break;
@@ -88,14 +88,14 @@
config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
- ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
+ ALOGW("setForceUse() invalid config %d for MEDIA", config);
return BAD_VALUE;
}
break;
case AUDIO_POLICY_FORCE_FOR_RECORD:
if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
config != AUDIO_POLICY_FORCE_NONE) {
- ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
+ ALOGW("setForceUse() invalid config %d for RECORD", config);
return BAD_VALUE;
}
break;
@@ -105,19 +105,22 @@
config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
- ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
+ ALOGW("setForceUse() invalid config %d for DOCK", config);
+ return BAD_VALUE;
}
break;
case AUDIO_POLICY_FORCE_FOR_SYSTEM:
if (config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
- ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
+ ALOGW("setForceUse() invalid config %d for SYSTEM", config);
+ return BAD_VALUE;
}
break;
case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
if (config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
+ return BAD_VALUE;
}
break;
case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
@@ -131,13 +134,13 @@
break;
case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
- ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
+ ALOGW("setForceUse() invalid config %d for VIBRATE_RINGING", config);
return BAD_VALUE;
}
break;
default:
ALOGW("setForceUse() invalid usage %d", usage);
- break; // TODO return BAD_VALUE?
+ return BAD_VALUE;
}
return EngineBase::setForceUse(usage, config);
}
@@ -273,10 +276,15 @@
break;
case STRATEGY_PHONE: {
- devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
- if (!devices.isEmpty()) break;
+ // TODO(b/243670205): remove this logic that gives preference to last removable devices
+ // once a UX decision has been made
devices = availableOutputDevices.getFirstDevicesFromTypes(
- getLastRemovableMediaDevices(GROUP_NONE, {AUDIO_DEVICE_OUT_BLE_HEADSET}));
+ getLastRemovableMediaDevices(GROUP_NONE, {
+ // excluding HEARING_AID and BLE_HEADSET because Dialer uses
+ // setCommunicationDevice to select them explicitly
+ AUDIO_DEVICE_OUT_HEARING_AID,
+ AUDIO_DEVICE_OUT_BLE_HEADSET
+ }));
if (!devices.isEmpty()) break;
devices = availableOutputDevices.getFirstDevicesFromTypes({
AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_EARPIECE});
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 48f7410..28268c9 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -544,10 +544,11 @@
status_t AudioPolicyManagerFuzzerDynamicPolicy::addPolicyMix(
int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
const audio_config_t &audioConfig, const std::vector<PolicyMixTuple> &rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ std::vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ myMixMatchCriteria.reserve(rules.size());
for (const auto &rule : rules) {
- myMixMatchCriteria.add(
+ myMixMatchCriteria.push_back(
AudioMixMatchCriterion(std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
}
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
index 4b4817e..6e34eb0 100644
--- a/services/audiopolicy/managerdefault/Android.bp
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -10,6 +10,10 @@
cc_library_shared {
name: "libaudiopolicymanagerdefault",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioPolicyManager.cpp",
"EngineLibrary.cpp",
@@ -36,7 +40,6 @@
"libaudiopolicyenginedefault",
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index dea329a..8a3cd63 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1132,7 +1132,7 @@
const audio_attributes_t *attr,
audio_stream_type_t *stream,
uid_t uid,
- const audio_config_t *config,
+ audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
bool *isRequestedDeviceForExclusiveUse,
@@ -1273,6 +1273,15 @@
flags, isSpatialized, resultAttr->flags & AUDIO_FLAG_MUTE_HAPTIC);
}
if (*output == AUDIO_IO_HANDLE_NONE) {
+ AudioProfileVector profiles;
+ status_t ret = getProfilesForDevices(outputDevices, profiles, *flags, false /*isInput*/);
+ if (ret == NO_ERROR && !profiles.empty()) {
+ config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
+ : *profiles[0]->getChannels().begin();
+ config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
+ : *profiles[0]->getSampleRates().begin();
+ config->format = profiles[0]->getFormat();
+ }
return INVALID_OPERATION;
}
@@ -1300,7 +1309,7 @@
audio_session_t session,
audio_stream_type_t *stream,
const AttributionSourceState& attributionSource,
- const audio_config_t *config,
+ audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
@@ -2412,7 +2421,7 @@
audio_unique_id_t riid,
audio_session_t session,
const AttributionSourceState& attributionSource,
- const audio_config_base_t *config,
+ audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t *selectedDeviceId,
input_type_t *inputType,
@@ -2553,6 +2562,16 @@
*input = getInputForDevice(device, session, attributes, config, flags, policyMix);
if (*input == AUDIO_IO_HANDLE_NONE) {
status = INVALID_OPERATION;
+ AudioProfileVector profiles;
+ status_t ret = getProfilesForDevices(
+ DeviceVector(device), profiles, flags, true /*isInput*/);
+ if (ret == NO_ERROR && !profiles.empty()) {
+ config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
+ : *profiles[0]->getChannels().begin();
+ config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
+ : *profiles[0]->getSampleRates().begin();
+ config->format = profiles[0]->getFormat();
+ }
goto error;
}
@@ -2584,7 +2603,7 @@
audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescriptor> &device,
audio_session_t session,
const audio_attributes_t &attributes,
- const audio_config_base_t *config,
+ audio_config_base_t *config,
audio_input_flags_t flags,
const sp<AudioPolicyMix> &policyMix)
{
@@ -4085,8 +4104,8 @@
status_t AudioPolicyManager::getDirectProfilesForAttributes(const audio_attributes_t* attr,
AudioProfileVector& audioProfilesVector) {
- AudioDeviceTypeAddrVector devices;
- status_t status = getDevicesForAttributes(*attr, &devices, false /* forVolume */);
+ DeviceVector devices;
+ status_t status = getDevicesForAttributes(*attr, devices, false /* forVolume */);
if (status != OK) {
return status;
}
@@ -4094,44 +4113,8 @@
if (devices.empty()) {
return OK; // no output devices for the attributes
}
-
- for (const auto& hwModule : mHwModules) {
- // the MSD module checks for different conditions
- if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
- continue;
- }
- for (const auto& outputProfile : hwModule->getOutputProfiles()) {
- if (!outputProfile->asAudioPort()->isDirectOutput()) {
- continue;
- }
- // allow only profiles that support all the available and routed devices
- if (outputProfile->getSupportedDevices().getDevicesFromDeviceTypeAddrVec(devices).size()
- != devices.size()) {
- continue;
- }
- audioProfilesVector.addAllValidProfiles(
- outputProfile->asAudioPort()->getAudioProfiles());
- }
- }
-
- // add the direct profiles from MSD if present and has audio patches to all the output(s)
- const auto& msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
- if (msdModule != nullptr) {
- if (msdHasPatchesToAllDevices(devices)) {
- ALOGV("%s: MSD audio patches set to all output devices.", __func__);
- for (const auto& outputProfile : msdModule->getOutputProfiles()) {
- if (!outputProfile->asAudioPort()->isDirectOutput()) {
- continue;
- }
- audioProfilesVector.addAllValidProfiles(
- outputProfile->asAudioPort()->getAudioProfiles());
- }
- } else {
- ALOGV("%s: MSD audio patches NOT set to all output devices.", __func__);
- }
- }
-
- return NO_ERROR;
+ return getProfilesForDevices(devices, audioProfilesVector,
+ AUDIO_OUTPUT_FLAG_DIRECT /*flags*/, false /*isInput*/);
}
status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
@@ -4556,7 +4539,8 @@
ALOGE("%s output is duplicated", __func__);
return INVALID_OPERATION;
}
- sourceDesc->setSwOutput(outputDesc);
+ bool closeOutput = outputDesc->mDirectOpenCount != 0;
+ sourceDesc->setSwOutput(outputDesc, closeOutput);
} else {
// Same for "raw patches" aka created from createAudioPatch API
SortedVector<audio_io_handle_t> outputs =
@@ -4575,7 +4559,7 @@
__func__, sinkDevice->toString().c_str());
return INVALID_OPERATION;
}
- sourceDesc->setSwOutput(outputDesc);
+ sourceDesc->setSwOutput(outputDesc, /* closeOutput= */ false);
}
// create a software bridge in PatchPanel if:
// - source and sink devices are on different HW modules OR
@@ -4704,17 +4688,29 @@
// releaseOutput has already called closeOutput in case of direct output
return NO_ERROR;
}
- if (!outputDesc->isActive() && !sourceDesc->useSwBridge()) {
- resetOutputDevice(outputDesc);
- } else {
- // Reuse patch handle if still valid / do not force rerouting if still routed
- patchHandle = outputDesc->getPatchHandle();
- setOutputDevices(outputDesc,
- getNewOutputDevices(outputDesc, true /*fromCache*/),
- patchHandle == AUDIO_PATCH_HANDLE_NONE, /*force*/
- 0,
- patchHandle == AUDIO_PATCH_HANDLE_NONE ? nullptr : &patchHandle);
- }
+ patchHandle = outputDesc->getPatchHandle();
+ // When a Sw bridge is released, the mixer used by this bridge will release its
+ // patch at AudioFlinger side. Hence, the mixer audio patch must be recreated
+ // Reuse patch handle to force audio flinger removing initial mixer patch removal
+ // updating hal patch handle (prevent leaks).
+ // While using a HwBridge, force reconsidering device only if not reusing an existing
+ // output and no more activity on output (will force to close).
+ bool force = sourceDesc->useSwBridge() ||
+ (sourceDesc->canCloseOutput() && !outputDesc->isActive());
+ // APM pattern is to have always outputs opened / patch realized for reachable devices.
+ // Update device may result to NONE (empty), coupled with force, it releases the patch.
+ // Reconsider device only for cases:
+ // 1 / Active Output
+ // 2 / Inactive Output previously hosting HwBridge
+ // 3 / Inactive Output previously hosting SwBridge that can be closed.
+ bool updateDevice = outputDesc->isActive() || !sourceDesc->useSwBridge() ||
+ sourceDesc->canCloseOutput();
+ setOutputDevices(outputDesc,
+ updateDevice ? getNewOutputDevices(outputDesc, true /*fromCache*/) :
+ outputDesc->devices(),
+ force,
+ 0,
+ patchHandle == AUDIO_PATCH_HANDLE_NONE ? nullptr : &patchHandle);
} else {
return BAD_VALUE;
}
@@ -6680,70 +6676,15 @@
return (stream1 == stream2);
}
-// TODO - consider MSD routes b/214971780
status_t AudioPolicyManager::getDevicesForAttributes(
const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices, bool forVolume) {
if (devices == nullptr) {
return BAD_VALUE;
}
- // Devices are determined in the following precedence:
- //
- // 1) Devices associated with a dynamic policy matching the attributes. This is often
- // a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
- //
- // If no such dynamic policy then
- // 2) Devices containing an active client using setPreferredDevice
- // with same strategy as the attributes.
- // (from the default Engine::getOutputDevicesForAttributes() implementation).
- //
- // If no corresponding active client with setPreferredDevice then
- // 3) Devices associated with the strategy determined by the attributes
- // (from the default Engine::getOutputDevicesForAttributes() implementation).
- //
- // See related getOutputForAttrInt().
-
- // check dynamic policies but only for primary descriptors (secondary not used for audible
- // audio routing, only used for duplication for playback capture)
- sp<AudioPolicyMix> policyMix;
- status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
- 0 /*uid unknown here*/, AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr);
- if (status != OK) {
- return status;
- }
-
DeviceVector curDevices;
- if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
- // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
- // as they are unaffected by device/stream volume
- // (per SwAudioOutputDescriptor::isFixedVolume()).
- (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
- ) {
- sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
- policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
- curDevices.add(deviceDesc);
- } else {
- // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
- // which selects setPreferredDevice if active. This means forVolume call
- // will take an active setPreferredDevice, if such exists.
-
- curDevices = mEngine->getOutputDevicesForAttributes(
- attr, nullptr /* preferredDevice */, false /* fromCache */);
- }
-
- if (forVolume) {
- // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
- // for single volume control in AudioService (such relationship should exist if
- // SPEAKER_SAFE is present).
- //
- // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
- DeviceVector speakerSafeDevices =
- curDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
- if (!speakerSafeDevices.isEmpty()) {
- curDevices.merge(
- mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
- curDevices.remove(speakerSafeDevices);
- }
+ if (status_t status = getDevicesForAttributes(attr, curDevices, forVolume); status != OK) {
+ return status;
}
for (const auto& device : curDevices) {
devices->push_back(device->getDeviceTypeAddr());
@@ -7850,6 +7791,9 @@
addOutput(output, desc);
+ sp<DeviceDescriptor> speaker = mAvailableOutputDevices.getDevice(
+ AUDIO_DEVICE_OUT_SPEAKER, String8(""), AUDIO_FORMAT_DEFAULT);
+
if (audio_is_remote_submix_device(deviceType) && address != "0") {
sp<AudioPolicyMix> policyMix;
if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix) == NO_ERROR) {
@@ -7860,13 +7804,13 @@
address.string());
}
- } else if (hasPrimaryOutput() && profile->getModule()
- != mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)
+ } else if (hasPrimaryOutput() && speaker != nullptr
+ && mPrimaryOutput->supportsDevice(speaker) && !desc->supportsDevice(speaker)
&& ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
// no duplicated output for:
// - direct outputs
// - outputs used by dynamic policy mixes
- // - outputs opened on the primary HW module
+ // - outputs that supports SPEAKER while the primary output does not.
audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
//TODO: configure audio effect output stage here
@@ -7894,4 +7838,109 @@
return desc;
}
+status_t AudioPolicyManager::getDevicesForAttributes(
+ const audio_attributes_t &attr, DeviceVector &devices, bool forVolume) {
+ // Devices are determined in the following precedence:
+ //
+ // 1) Devices associated with a dynamic policy matching the attributes. This is often
+ // a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
+ //
+ // If no such dynamic policy then
+ // 2) Devices containing an active client using setPreferredDevice
+ // with same strategy as the attributes.
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // If no corresponding active client with setPreferredDevice then
+ // 3) Devices associated with the strategy determined by the attributes
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // See related getOutputForAttrInt().
+
+ // check dynamic policies but only for primary descriptors (secondary not used for audible
+ // audio routing, only used for duplication for playback capture)
+ sp<AudioPolicyMix> policyMix;
+ status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
+ 0 /*uid unknown here*/, AUDIO_OUTPUT_FLAG_NONE, policyMix,
+ nullptr /* secondaryMixes */);
+ if (status != OK) {
+ return status;
+ }
+
+ if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
+ // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+ // as they are unaffected by device/stream volume
+ // (per SwAudioOutputDescriptor::isFixedVolume()).
+ (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
+ ) {
+ sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
+ policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+ devices.add(deviceDesc);
+ } else {
+ // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
+ // which selects setPreferredDevice if active. This means forVolume call
+ // will take an active setPreferredDevice, if such exists.
+
+ devices = mEngine->getOutputDevicesForAttributes(
+ attr, nullptr /* preferredDevice */, false /* fromCache */);
+ }
+
+ if (forVolume) {
+ // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
+ // for single volume control in AudioService (such relationship should exist if
+ // SPEAKER_SAFE is present).
+ //
+ // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
+ DeviceVector speakerSafeDevices =
+ devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
+ if (!speakerSafeDevices.isEmpty()) {
+ devices.merge(mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
+ devices.remove(speakerSafeDevices);
+ }
+ }
+
+ return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getProfilesForDevices(const DeviceVector& devices,
+ AudioProfileVector& audioProfiles,
+ uint32_t flags,
+ bool isInput) {
+ for (const auto& hwModule : mHwModules) {
+ // the MSD module checks for different conditions
+ if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
+ continue;
+ }
+ IOProfileCollection ioProfiles = isInput ? hwModule->getInputProfiles()
+ : hwModule->getOutputProfiles();
+ for (const auto& profile : ioProfiles) {
+ if (!profile->areAllDevicesSupported(devices) ||
+ !profile->isCompatibleProfileForFlags(
+ flags, false /*exactMatchRequiredForInputFlags*/)) {
+ continue;
+ }
+ audioProfiles.addAllValidProfiles(profile->asAudioPort()->getAudioProfiles());
+ }
+ }
+
+ if (!isInput) {
+ // add the direct profiles from MSD if present and has audio patches to all the output(s)
+ const auto &msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
+ if (msdModule != nullptr) {
+ if (msdHasPatchesToAllDevices(devices.toTypeAddrVector())) {
+ ALOGV("%s: MSD audio patches set to all output devices.", __func__);
+ for (const auto &profile: msdModule->getOutputProfiles()) {
+ if (!profile->asAudioPort()->isDirectOutput()) {
+ continue;
+ }
+ audioProfiles.addAllValidProfiles(profile->asAudioPort()->getAudioProfiles());
+ }
+ } else {
+ ALOGV("%s: MSD audio patches NOT set to all output devices.", __func__);
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 87e6974..74460c7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -117,7 +117,7 @@
audio_session_t session,
audio_stream_type_t *stream,
const AttributionSourceState& attributionSource,
- const audio_config_t *config,
+ audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
@@ -132,7 +132,7 @@
audio_unique_id_t riid,
audio_session_t session,
const AttributionSourceState& attributionSource,
- const audio_config_base_t *config,
+ audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t *selectedDeviceId,
input_type_t *inputType,
@@ -1052,7 +1052,7 @@
const audio_attributes_t *attr,
audio_stream_type_t *stream,
uid_t uid,
- const audio_config_t *config,
+ audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
bool *isRequestedDeviceForExclusiveUse,
@@ -1133,7 +1133,9 @@
* @param session requester session id
* @param uid requester uid
* @param attributes requester audio attributes (e.g. input source and tags matter)
- * @param config requester audio configuration (e.g. sample rate, format, channel mask).
+ * @param config requested audio configuration (e.g. sample rate, format, channel mask),
+ * will be updated if current configuration doesn't support but another
+ * one does
* @param flags requester input flags
* @param policyMix may be null, policy rules to be followed by the requester
* @return input io handle aka unique input identifier selected for this device.
@@ -1141,7 +1143,7 @@
audio_io_handle_t getInputForDevice(const sp<DeviceDescriptor> &device,
audio_session_t session,
const audio_attributes_t &attributes,
- const audio_config_base_t *config,
+ audio_config_base_t *config,
audio_input_flags_t flags,
const sp<AudioPolicyMix> &policyMix);
@@ -1260,6 +1262,15 @@
// Filters only the relevant flags for getProfileForOutput
audio_output_flags_t getRelevantFlags (audio_output_flags_t flags, bool directOnly);
+
+ status_t getDevicesForAttributes(const audio_attributes_t &attr,
+ DeviceVector &devices,
+ bool forVolume);
+
+ status_t getProfilesForDevices(const DeviceVector& devices,
+ AudioProfileVector& audioProfiles,
+ uint32_t flags,
+ bool isInput);
};
};
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index cdad9a6..4c19d40 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -10,6 +10,10 @@
cc_library_shared {
name: "libaudiopolicyservice",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioPolicyClientImpl.cpp",
"AudioPolicyEffects.cpp",
@@ -49,7 +53,6 @@
"libshmemcompat",
"libutils",
"libstagefright_foundation",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index df49bba..b15b61d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -443,6 +443,13 @@
convertContainer<std::vector<int32_t>>(secondaryOutputs,
legacy2aidl_audio_io_handle_t_int32_t));
_aidl_return->isSpatialized = isSpatialized;
+ } else {
+ _aidl_return->configBase.format = VALUE_OR_RETURN_BINDER_STATUS(
+ legacy2aidl_audio_format_t_AudioFormatDescription(config.format));
+ _aidl_return->configBase.channelMask = VALUE_OR_RETURN_BINDER_STATUS(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ config.channel_mask, false /*isInput*/));
+ _aidl_return->configBase.sampleRate = config.sample_rate;
}
return binderStatusFromStatusT(result);
}
@@ -755,6 +762,9 @@
if (status == PERMISSION_DENIED) {
AutoCallerClear acc;
mAudioPolicyManager->releaseInput(portId);
+ } else {
+ _aidl_return->config = VALUE_OR_RETURN_BINDER_STATUS(
+ legacy2aidl_audio_config_base_t_AudioConfigBase(config, true /*isInput*/));
}
return binderStatusFromStatusT(status);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 691f13c..92e1b6b 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -272,6 +272,11 @@
if (hasSpatializer) {
mSpatializer = Spatializer::create(this);
}
+ if (mSpatializer == nullptr) {
+ // No spatializer created, signal the reason: NO_INIT a failure, OK means intended.
+ const status_t createStatus = hasSpatializer ? NO_INIT : OK;
+ Spatializer::sendEmptyCreateSpatializerMetricWithStatus(createStatus);
+ }
}
AudioSystem::audioPolicyReady();
}
@@ -516,7 +521,8 @@
void AudioPolicyService::doOnCheckSpatializer()
{
- ALOGI("%s mSpatializer %p level %d", __func__, mSpatializer.get(), (int)mSpatializer->getLevel());
+ ALOGV("%s mSpatializer %p level %d",
+ __func__, mSpatializer.get(), (int)mSpatializer->getLevel());
if (mSpatializer != nullptr) {
// Note: mSpatializer != nullptr => mAudioPolicyManager != nullptr
@@ -1210,6 +1216,14 @@
dumpReleaseLock(mLock, locked);
+ if (mSpatializer != nullptr) {
+ std::string dumpString = mSpatializer->toString(1 /* level */);
+ write(fd, dumpString.c_str(), dumpString.size());
+ } else {
+ String8 spatializerPtr = String8::format("Spatializer no supportted on this device\n");
+ write(fd, spatializerPtr.c_str(), spatializerPtr.size());
+ }
+
{
std::string timeCheckStats = getIAudioPolicyServiceStatistics().dump();
dprintf(fd, "\nIAudioPolicyService binder call profile\n");
@@ -1333,7 +1347,9 @@
} else {
getIAudioPolicyServiceStatistics().event(code, elapsedMs);
}
- });
+ }, mediautils::TimeCheck::kDefaultTimeoutDuration,
+ mediautils::TimeCheck::kDefaultSecondChanceDuration,
+ true /* crashOnTimeout */);
switch (code) {
case SHELL_COMMAND_TRANSACTION: {
@@ -1716,6 +1732,7 @@
}
bool AudioPolicyService::UidPolicy::isA11yOnTop() {
+ Mutex::Autolock _l(mLock);
for (const auto &uid : mCachedUids) {
if (!isA11yUid(uid.first)) {
continue;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index a87d871..5c37f99 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -475,8 +475,8 @@
Mutex mLock;
ActivityManager mAm;
bool mObserverRegistered = false;
- std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
- std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
+ std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids GUARDED_BY(mLock);
+ std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids GUARDED_BY(mLock);
std::vector<uid_t> mAssistantUids;
std::vector<uid_t> mActiveAssistantUids;
std::vector<uid_t> mA11yUids;
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index b24ab14..af40d1f 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -15,11 +15,12 @@
** limitations under the License.
*/
-
+#include <string>
#define LOG_TAG "Spatializer"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
@@ -58,11 +59,13 @@
if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
std::move(_tmp.value()); })
-audio_channel_mask_t getMaxChannelMask(std::vector<audio_channel_mask_t> masks) {
+static audio_channel_mask_t getMaxChannelMask(
+ const std::vector<audio_channel_mask_t>& masks, size_t channelLimit = SIZE_MAX) {
uint32_t maxCount = 0;
audio_channel_mask_t maxMask = AUDIO_CHANNEL_NONE;
for (auto mask : masks) {
const size_t count = audio_channel_count_from_out_mask(mask);
+ if (count > channelLimit) continue; // ignore masks greater than channelLimit
if (count > maxCount) {
maxMask = mask;
maxCount = count;
@@ -84,6 +87,7 @@
kWhatOnFramesProcessed, // AudioEffect::EVENT_FRAMES_PROCESSED
kWhatOnHeadToStagePose, // SpatializerPoseController::Listener::onHeadToStagePose
kWhatOnActualModeChange, // SpatializerPoseController::Listener::onActualModeChange
+ kWhatOnLatencyModesChanged, // Spatializer::onSupportedLatencyModesChanged
};
static constexpr const char *kNumFramesKey = "numFrames";
static constexpr const char *kModeKey = "mode";
@@ -93,15 +97,27 @@
static constexpr const char *kRotation0Key = "rotation0";
static constexpr const char *kRotation1Key = "rotation1";
static constexpr const char *kRotation2Key = "rotation2";
+ static constexpr const char *kLatencyModesKey = "latencyModes";
+
+ class LatencyModes : public RefBase {
+ public:
+ LatencyModes(audio_io_handle_t output,
+ const std::vector<audio_latency_mode_t>& latencyModes)
+ : mOutput(output), mLatencyModes(latencyModes) {}
+ ~LatencyModes() = default;
+
+ audio_io_handle_t mOutput;
+ std::vector<audio_latency_mode_t> mLatencyModes;
+ };
void onMessageReceived(const sp<AMessage> &msg) override {
+ sp<Spatializer> spatializer = mSpatializer.promote();
+ if (spatializer == nullptr) {
+ ALOGW("%s: Cannot promote spatializer", __func__);
+ return;
+ }
switch (msg->what()) {
case kWhatOnFramesProcessed: {
- sp<Spatializer> spatializer = mSpatializer.promote();
- if (spatializer == nullptr) {
- ALOGW("%s: Cannot promote spatializer", __func__);
- return;
- }
int numFrames;
if (!msg->findInt32(kNumFramesKey, &numFrames)) {
ALOGE("%s: Cannot find num frames!", __func__);
@@ -112,11 +128,6 @@
}
} break;
case kWhatOnHeadToStagePose: {
- sp<Spatializer> spatializer = mSpatializer.promote();
- if (spatializer == nullptr) {
- ALOGW("%s: Cannot promote spatializer", __func__);
- return;
- }
std::vector<float> headToStage(sHeadPoseKeys.size());
for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) {
@@ -127,18 +138,25 @@
spatializer->onHeadToStagePoseMsg(headToStage);
} break;
case kWhatOnActualModeChange: {
- sp<Spatializer> spatializer = mSpatializer.promote();
- if (spatializer == nullptr) {
- ALOGW("%s: Cannot promote spatializer", __func__);
- return;
- }
int mode;
- if (!msg->findInt32(EngineCallbackHandler::kModeKey, &mode)) {
+ if (!msg->findInt32(kModeKey, &mode)) {
ALOGE("%s: Cannot find actualMode!", __func__);
return;
}
spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode));
} break;
+
+ case kWhatOnLatencyModesChanged: {
+ sp<RefBase> object;
+ if (!msg->findObject(kLatencyModesKey, &object)) {
+ ALOGE("%s: Cannot find latency modes!", __func__);
+ return;
+ }
+ sp<LatencyModes> latencyModes = static_cast<LatencyModes*>(object.get());
+ spatializer->onSupportedLatencyModesChangedMsg(
+ latencyModes->mOutput, std::move(latencyModes->mLatencyModes));
+ } break;
+
default:
LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what());
}
@@ -157,6 +175,41 @@
};
// ---------------------------------------------------------------------------
+
+// Convert recorded sensor data to string with level indentation.
+std::string Spatializer::HeadToStagePoseRecorder::toString(unsigned level) const {
+ std::string prefixSpace(level, ' ');
+ return mPoseRecordLog.dumpToString((prefixSpace + " ").c_str(), Spatializer::mMaxLocalLogLine);
+}
+
+// Compute sensor data, record into local log when it is time.
+void Spatializer::HeadToStagePoseRecorder::record(const std::vector<float>& headToStage) {
+ if (headToStage.size() != mPoseVectorSize) return;
+
+ if (mNumOfSampleSinceLastRecord++ == 0) {
+ mFirstSampleTimestamp = std::chrono::steady_clock::now();
+ }
+ // if it's time, do record and reset.
+ if (shouldRecordLog()) {
+ poseSumToAverage();
+ mPoseRecordLog.log(
+ "mean: %s, min: %s, max %s, calculated %d samples in %0.4f second(s)",
+ Spatializer::toString<double>(mPoseRadianSum, true /* radianToDegree */).c_str(),
+ Spatializer::toString<float>(mMinPoseAngle, true /* radianToDegree */).c_str(),
+ Spatializer::toString<float>(mMaxPoseAngle, true /* radianToDegree */).c_str(),
+ mNumOfSampleSinceLastRecord, mNumOfSecondsSinceLastRecord.count());
+ resetRecord();
+ }
+ // update stream average.
+ for (int i = 0; i < mPoseVectorSize; i++) {
+ mPoseRadianSum[i] += headToStage[i];
+ mMaxPoseAngle[i] = std::max(mMaxPoseAngle[i], headToStage[i]);
+ mMinPoseAngle[i] = std::min(mMinPoseAngle[i], headToStage[i]);
+ }
+ return;
+}
+
+// ---------------------------------------------------------------------------
sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) {
sp<Spatializer> spatializer;
@@ -176,17 +229,22 @@
ALOG_ASSERT(!descriptors.empty(),
"%s getDescriptors() returned no error but empty list", __func__);
- //TODO: get supported spatialization modes from FX engine or descriptor
-
+ // TODO: get supported spatialization modes from FX engine or descriptor
sp<EffectHalInterface> effect;
status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE,
AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect);
- ALOGI("%s FX create status %d effect %p", __func__, status, effect.get());
+ ALOGI("%s FX create status %d effect ID %" PRId64, __func__, status,
+ effect ? effect->effectId() : 0);
if (status == NO_ERROR && effect != nullptr) {
spatializer = new Spatializer(descriptors[0], callback);
if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) {
spatializer.clear();
+ ALOGW("%s loadEngine error: %d effect Id %" PRId64,
+ __func__, status, effect ? effect->effectId() : 0);
+ } else {
+ spatializer->mLocalLog.log("%s with effect Id %" PRId64, __func__,
+ effect ? effect->effectId() : 0);
}
}
@@ -221,6 +279,16 @@
mHandler.clear();
}
+static std::string channelMaskVectorToString(
+ const std::vector<audio_channel_mask_t>& masks) {
+ std::stringstream ss;
+ for (const auto &mask : masks) {
+ if (ss.tellp() != 0) ss << "|";
+ ss << mask;
+ }
+ return ss.str();
+}
+
status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
ALOGV("%s", __func__);
@@ -268,6 +336,7 @@
ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES", __func__);
return status;
}
+
for (const auto spatializationMode : spatializationModes) {
if (!aidl_utils::isValidEnum(spatializationMode)) {
ALOGW("%s: ignoring spatializationMode:%d", __func__, (int)spatializationMode);
@@ -309,7 +378,7 @@
}
mediametrics::LogItem(mMetricsId)
.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
- .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)getMaxChannelMask(mChannelMasks))
+ .set(AMEDIAMETRICS_PROP_CHANNELMASKS, channelMaskVectorToString(mChannelMasks))
.set(AMEDIAMETRICS_PROP_LEVELS, aidl_utils::enumsToString(mLevels))
.set(AMEDIAMETRICS_PROP_MODES, aidl_utils::enumsToString(mSpatializationModes))
.set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, aidl_utils::enumsToString(mHeadTrackingModes))
@@ -318,12 +387,24 @@
return NO_ERROR;
}
+/* static */
+void Spatializer::sendEmptyCreateSpatializerMetricWithStatus(status_t status) {
+ mediametrics::LogItem(kDefaultMetricsId)
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
+ .set(AMEDIAMETRICS_PROP_CHANNELMASKS, "")
+ .set(AMEDIAMETRICS_PROP_LEVELS, "")
+ .set(AMEDIAMETRICS_PROP_MODES, "")
+ .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, "")
+ .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
+ .record();
+}
+
/** Gets the channel mask, sampling rate and format set for the spatializer input. */
audio_config_base_t Spatializer::getAudioInConfig() const {
std::lock_guard lock(mLock);
audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
// For now use highest supported channel count
- config.channel_mask = getMaxChannelMask(mChannelMasks);
+ config.channel_mask = getMaxChannelMask(mChannelMasks, FCC_LIMIT);
return config;
}
@@ -334,6 +415,17 @@
return BAD_VALUE;
}
+ if (mSpatializerCallback != nullptr) {
+ if (IInterface::asBinder(callback) == IInterface::asBinder(mSpatializerCallback)) {
+ ALOGW("%s: Registering callback %p again",
+ __func__, mSpatializerCallback.get());
+ return NO_ERROR;
+ }
+ ALOGE("%s: Already one client registered with callback %p",
+ __func__, mSpatializerCallback.get());
+ return INVALID_OPERATION;
+ }
+
sp<IBinder> binder = IInterface::asBinder(callback);
status_t status = binder->linkToDeath(this);
if (status == NO_ERROR) {
@@ -366,7 +458,8 @@
}
Status Spatializer::setLevel(SpatializationLevel level) {
- ALOGV("%s level %d", __func__, (int)level);
+ ALOGV("%s level %s", __func__, media::toString(level).c_str());
+ mLocalLog.log("%s with %s", __func__, media::toString(level).c_str());
if (level != SpatializationLevel::NONE
&& std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) {
return binderStatusFromStatusT(BAD_VALUE);
@@ -426,11 +519,12 @@
}
Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) {
- ALOGV("%s mode %d", __func__, (int)mode);
+ ALOGV("%s mode %s", __func__, media::toString(mode).c_str());
if (!mSupportsHeadTracking) {
return binderStatusFromStatusT(INVALID_OPERATION);
}
+ mLocalLog.log("%s with %s", __func__, media::toString(mode).c_str());
std::lock_guard lock(mLock);
switch (mode) {
case SpatializerHeadTrackingMode::OTHER:
@@ -485,6 +579,7 @@
}
std::lock_guard lock(mLock);
if (mPoseController != nullptr) {
+ mLocalLog.log("%s with screenToStage %s", __func__, toString<float>(screenToStage).c_str());
mPoseController->setScreenToStagePose(maybePose.value());
}
return Status::ok();
@@ -520,6 +615,7 @@
}
std::lock_guard lock(mLock);
if (mHeadSensor != sensorHandle) {
+ mLocalLog.log("%s with 0x%08x", __func__, sensorHandle);
mHeadSensor = sensorHandle;
checkPoseController_l();
checkSensorsState_l();
@@ -534,6 +630,7 @@
}
std::lock_guard lock(mLock);
if (mScreenSensor != sensorHandle) {
+ mLocalLog.log("%s with 0x%08x", __func__, sensorHandle);
mScreenSensor = sensorHandle;
// TODO: consider a new method setHeadAndScreenSensor()
// because we generally set both at the same time.
@@ -550,6 +647,7 @@
}
std::lock_guard lock(mLock);
mDisplayOrientation = physicalToLogicalAngle;
+ mLocalLog.log("%s with %f", __func__, physicalToLogicalAngle);
if (mPoseController != nullptr) {
mPoseController->setDisplayOrientation(mDisplayOrientation);
}
@@ -564,6 +662,7 @@
std::lock_guard lock(mLock);
ALOGV("%s hingeAngle %f", __func__, hingeAngle);
if (mEngine != nullptr) {
+ mLocalLog.log("%s with %f", __func__, hingeAngle);
setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{hingeAngle});
}
return Status::ok();
@@ -650,6 +749,8 @@
callback = mHeadTrackingCallback;
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
+ mPoseRecorder.record(headToStage);
+ mPoseDurableRecorder.record(headToStage);
}
}
@@ -659,9 +760,9 @@
}
void Spatializer::onActualModeChange(HeadTrackingMode mode) {
- ALOGV("%s(%d)", __func__, (int)mode);
- sp<AMessage> msg =
- new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
+ std::string modeStr = media::toString(mode);
+ ALOGV("%s(%s)", __func__, modeStr.c_str());
+ sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
msg->post();
}
@@ -695,6 +796,8 @@
std::vector<SpatializerHeadTrackingMode>{spatializerMode});
}
callback = mHeadTrackingCallback;
+ mLocalLog.log("%s: %s, spatializerMode %s", __func__, media::toString(mode).c_str(),
+ media::toString(spatializerMode).c_str());
}
if (callback != nullptr) {
callback->onHeadTrackingModeChanged(spatializerMode);
@@ -708,6 +811,8 @@
{
std::lock_guard lock(mLock);
ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput);
+ mLocalLog.log("%s with output %d tracks %zu (mOutput %d)", __func__, (int)output,
+ numActiveTracks, (int)mOutput);
if (mOutput != AUDIO_IO_HANDLE_NONE) {
LOG_ALWAYS_FATAL_IF(mEngine == nullptr, "%s output set without FX engine", __func__);
// remove FX instance
@@ -762,6 +867,7 @@
{
std::lock_guard lock(mLock);
+ mLocalLog.log("%s with output %d tracks %zu", __func__, (int)mOutput, mNumActiveTracks);
ALOGV("%s mOutput %d", __func__, (int)mOutput);
if (mOutput == AUDIO_IO_HANDLE_NONE) {
return output;
@@ -784,9 +890,21 @@
void Spatializer::onSupportedLatencyModesChanged(
audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) {
+ ALOGV("%s output %d num modes %zu", __func__, (int)output, modes.size());
+ sp<AMessage> msg =
+ new AMessage(EngineCallbackHandler::kWhatOnLatencyModesChanged, mHandler);
+ msg->setObject(EngineCallbackHandler::kLatencyModesKey,
+ sp<EngineCallbackHandler::LatencyModes>::make(output, modes));
+ msg->post();
+}
+
+void Spatializer::onSupportedLatencyModesChangedMsg(
+ audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes) {
std::lock_guard lock(mLock);
+ ALOGV("%s output %d mOutput %d num modes %zu",
+ __func__, (int)output, (int)mOutput, modes.size());
if (output == mOutput) {
- mSupportedLatencyModes = modes;
+ mSupportedLatencyModes = std::move(modes);
checkSensorsState_l();
}
}
@@ -794,6 +912,7 @@
void Spatializer::updateActiveTracks(size_t numActiveTracks) {
std::lock_guard lock(mLock);
if (mNumActiveTracks != numActiveTracks) {
+ mLocalLog.log("%s from %zu to %zu", __func__, mNumActiveTracks, numActiveTracks);
mNumActiveTracks = numActiveTracks;
checkEngineState_l();
checkSensorsState_l();
@@ -872,4 +991,80 @@
msg->post();
}
+std::string Spatializer::toString(unsigned level) const {
+ std::string prefixSpace;
+ prefixSpace.append(level, ' ');
+ std::string ss = prefixSpace + "Spatializer:\n";
+ bool needUnlock = false;
+
+ prefixSpace += ' ';
+ if (!mLock.try_lock()) {
+ // dumpsys even try_lock failed, information dump can be useful although may not accurate
+ ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
+ } else {
+ needUnlock = true;
+ }
+
+ // Spatializer class information.
+ // 1. Capabilities (mLevels, mHeadTrackingModes, mSpatializationModes, mChannelMasks, etc)
+ ss.append(prefixSpace).append("Supported levels: [");
+ for (auto& level : mLevels) {
+ base::StringAppendF(&ss, " %s", media::toString(level).c_str());
+ }
+ base::StringAppendF(&ss, "], mLevel: %s", media::toString(mLevel).c_str());
+
+ base::StringAppendF(&ss, "\n%smHeadTrackingModes: [", prefixSpace.c_str());
+ for (auto& mode : mHeadTrackingModes) {
+ base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+ }
+ base::StringAppendF(&ss, "], Desired: %s, Actual %s\n",
+ media::toString(mDesiredHeadTrackingMode).c_str(),
+ media::toString(mActualHeadTrackingMode).c_str());
+
+ base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str());
+ for (auto& mode : mSpatializationModes) {
+ base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+ }
+ ss += "]\n";
+
+ base::StringAppendF(&ss, "%smChannelMasks: ", prefixSpace.c_str());
+ for (auto& mask : mChannelMasks) {
+ base::StringAppendF(&ss, "%s", audio_channel_out_mask_to_string(mask));
+ }
+ base::StringAppendF(&ss, "\n%smSupportsHeadTracking: %s\n", prefixSpace.c_str(),
+ mSupportsHeadTracking ? "true" : "false");
+ // 2. Settings (Output, tracks)
+ base::StringAppendF(&ss, "%smNumActiveTracks: %zu\n", prefixSpace.c_str(), mNumActiveTracks);
+ base::StringAppendF(&ss, "%sOutputStreamHandle: %d\n", prefixSpace.c_str(), (int)mOutput);
+
+ // 3. Sensors, Effect information.
+ base::StringAppendF(&ss, "%sHeadSensorHandle: 0x%08x\n", prefixSpace.c_str(), mHeadSensor);
+ base::StringAppendF(&ss, "%sScreenSensorHandle: 0x%08x\n", prefixSpace.c_str(), mScreenSensor);
+ base::StringAppendF(&ss, "%sEffectHandle: %p\n", prefixSpace.c_str(), mEngine.get());
+ base::StringAppendF(&ss, "%sDisplayOrientation: %f\n", prefixSpace.c_str(),
+ mDisplayOrientation);
+
+ ss.append(prefixSpace + "CommandLog:\n");
+ ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
+
+ // PostController dump.
+ if (mPoseController != nullptr) {
+ ss += mPoseController->toString(level + 1);
+ ss.append(prefixSpace +
+ "Sensor data format - [rx, ry, rz, vx, vy, vz] (units-degree, "
+ "r-transform, v-angular velocity, x-pitch, y-roll, z-yaw):\n");
+ ss.append(prefixSpace + " PerMinuteHistory:\n");
+ ss += mPoseDurableRecorder.toString(level + 1);
+ ss.append(prefixSpace + " PerSecondHistory:\n");
+ ss += mPoseRecorder.toString(level + 1);
+ } else {
+ ss.append(prefixSpace).append("SpatializerPoseController not exist\n");
+ }
+
+ if (needUnlock) {
+ mLock.unlock();
+ }
+ return ss;
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 4aebcea..9eb8c48 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -17,15 +17,19 @@
#ifndef ANDROID_MEDIA_SPATIALIZER_H
#define ANDROID_MEDIA_SPATIALIZER_H
+#include <android-base/stringprintf.h>
#include <android/media/BnEffect.h>
#include <android/media/BnSpatializer.h>
#include <android/media/SpatializationLevel.h>
#include <android/media/SpatializationMode.h>
#include <android/media/SpatializerHeadTrackingMode.h>
+#include <audio_utils/SimpleLog.h>
+#include <math.h>
+#include <media/AudioEffect.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/stagefright/foundation/ALooper.h>
-#include <media/AudioEffect.h>
#include <system/audio_effects/effect_spatializer.h>
+#include <string>
#include "SpatializerPoseController.h"
@@ -156,6 +160,50 @@
void calculateHeadPose();
+ /** Convert fields in Spatializer and sub-modules to a string. Disable thread-safety-analysis
+ * here because we want to dump mutex guarded members even try_lock failed to provide as much
+ * information as possible for debugging purpose. */
+ std::string toString(unsigned level) const NO_THREAD_SAFETY_ANALYSIS;
+
+ static std::string toString(audio_latency_mode_t mode) {
+ switch (mode) {
+ case AUDIO_LATENCY_MODE_FREE:
+ return "LATENCY_MODE_FREE";
+ case AUDIO_LATENCY_MODE_LOW:
+ return "LATENCY_MODE_LOW";
+ }
+ return "EnumNotImplemented";
+ };
+
+ /**
+ * Format head to stage vector to a string, [0.00, 0.00, 0.00, -1.29, -0.50, 15.27].
+ */
+ template <typename T>
+ static std::string toString(const std::vector<T>& vec, bool radianToDegree = false) {
+ if (vec.size() == 0) {
+ return "[]";
+ }
+
+ std::string ss = "[";
+ for (auto f = vec.begin(); f != vec.end(); ++f) {
+ if (f != vec.begin()) {
+ ss .append(", ");
+ }
+ if (radianToDegree) {
+ base::StringAppendF(&ss, "%0.2f", HeadToStagePoseRecorder::getDegreeWithRadian(*f));
+ } else {
+ base::StringAppendF(&ss, "%f", *f);
+ }
+ }
+ ss.append("]");
+ return ss;
+ };
+
+ // If the Spatializer is not created, we send the status for metrics purposes.
+ // OK: Spatializer not expected to be created.
+ // NO_INIT: Spatializer creation failed.
+ static void sendEmptyCreateSpatializerMetricWithStatus(status_t status);
+
private:
Spatializer(effect_descriptor_t engineDescriptor,
SpatializerPolicyCallback *callback);
@@ -168,6 +216,8 @@
void onHeadToStagePoseMsg(const std::vector<float>& headToStage);
void onActualModeChangeMsg(media::HeadTrackingMode mode);
+ void onSupportedLatencyModesChangedMsg(
+ audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes);
static constexpr int kMaxEffectParamValues = 10;
/**
@@ -307,7 +357,9 @@
SpatializerPolicyCallback* const mPolicyCallback;
/** Currently there is only one version of the spatializer running */
- const std::string mMetricsId = AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "0";
+ static constexpr const char* kDefaultMetricsId =
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "0";
+ const std::string mMetricsId = kDefaultMetricsId;
/** Mutex protecting internal state */
mutable std::mutex mLock;
@@ -362,9 +414,103 @@
size_t mNumActiveTracks GUARDED_BY(mLock) = 0;
std::vector<audio_latency_mode_t> mSupportedLatencyModes GUARDED_BY(mLock);
- static const std::vector<const char *> sHeadPoseKeys;
-};
+ static const std::vector<const char*> sHeadPoseKeys;
+ // Local log for command messages.
+ static constexpr int mMaxLocalLogLine = 10;
+ SimpleLog mLocalLog{mMaxLocalLogLine};
+
+ /**
+ * @brief Calculate and record sensor data.
+ * Dump to local log with max/average pose angle every mPoseRecordThreshold.
+ */
+ class HeadToStagePoseRecorder {
+ public:
+ HeadToStagePoseRecorder(std::chrono::duration<double> threshold, int maxLogLine)
+ : mPoseRecordThreshold(threshold), mPoseRecordLog(maxLogLine) {
+ resetRecord();
+ }
+
+ /** Convert recorded sensor data to string with level indentation */
+ std::string toString(unsigned level) const;
+
+ /**
+ * @brief Calculate sensor data, record into local log when it is time.
+ *
+ * @param headToStage The vector from Pose3f::toVector().
+ */
+ void record(const std::vector<float>& headToStage);
+
+ static constexpr float getDegreeWithRadian(const float radian) {
+ float radianToDegreeRatio = (180 / PI);
+ return (radian * radianToDegreeRatio);
+ }
+
+ private:
+ static constexpr float PI = M_PI;
+ /**
+ * Pose recorder time threshold to record sensor data in local log.
+ * Sensor data will be recorded into log at least every mPoseRecordThreshold.
+ */
+ std::chrono::duration<double> mPoseRecordThreshold;
+ // Number of seconds pass since last record.
+ std::chrono::duration<double> mNumOfSecondsSinceLastRecord;
+ /**
+ * According to frameworks/av/media/libheadtracking/include/media/Pose.h
+ * "The vector will have exactly 6 elements, where the first three are a translation vector
+ * and the last three are a rotation vector."
+ */
+ static constexpr size_t mPoseVectorSize = 6;
+ /**
+ * Timestamp of last sensor data record in local log.
+ */
+ std::chrono::time_point<std::chrono::steady_clock> mFirstSampleTimestamp;
+ /**
+ * Number of sensor samples received since last record, sample rate is ~100Hz which produce
+ * ~6k samples/minute.
+ */
+ uint32_t mNumOfSampleSinceLastRecord = 0;
+ /* The sum of pose angle represented by radian since last dump, div
+ * mNumOfSampleSinceLastRecord to get arithmetic mean. Largest possible value: 2PI * 100Hz *
+ * mPoseRecordThreshold.
+ */
+ std::vector<double> mPoseRadianSum;
+ std::vector<float> mMaxPoseAngle;
+ std::vector<float> mMinPoseAngle;
+ // Local log for history sensor data.
+ SimpleLog mPoseRecordLog{mMaxLocalLogLine};
+
+ bool shouldRecordLog() {
+ mNumOfSecondsSinceLastRecord = std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::steady_clock::now() - mFirstSampleTimestamp);
+ return mNumOfSecondsSinceLastRecord >= mPoseRecordThreshold;
+ }
+
+ void resetRecord() {
+ mPoseRadianSum.assign(mPoseVectorSize, 0);
+ mMaxPoseAngle.assign(mPoseVectorSize, -PI);
+ mMinPoseAngle.assign(mPoseVectorSize, PI);
+ mNumOfSampleSinceLastRecord = 0;
+ mNumOfSecondsSinceLastRecord = std::chrono::seconds(0);
+ }
+
+ // Add each sample to sum and only calculate when record.
+ void poseSumToAverage() {
+ if (mNumOfSampleSinceLastRecord == 0) return;
+ for (auto& p : mPoseRadianSum) {
+ const float reciprocal = 1.f / mNumOfSampleSinceLastRecord;
+ p *= reciprocal;
+ }
+ }
+ }; // HeadToStagePoseRecorder
+
+ // Record one log line per second (up to mMaxLocalLogLine) to capture most recent sensor data.
+ HeadToStagePoseRecorder mPoseRecorder GUARDED_BY(mLock) =
+ HeadToStagePoseRecorder(std::chrono::seconds(1), mMaxLocalLogLine);
+ // Record one log line per minute (up to mMaxLocalLogLine) to capture durable sensor data.
+ HeadToStagePoseRecorder mPoseDurableRecorder GUARDED_BY(mLock) =
+ HeadToStagePoseRecorder(std::chrono::minutes(1), mMaxLocalLogLine);
+}; // Spatializer
}; // namespace android
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 23bcd77..9735479 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
#include "SpatializerPoseController.h"
+#include <android-base/stringprintf.h>
+#include <chrono>
+#include <cstdint>
+#include <string>
#define LOG_TAG "SpatializerPoseController"
//#define LOG_NDEBUG 0
@@ -48,7 +52,9 @@
constexpr auto kPredictionDuration = 50ms;
// After not getting a pose sample for this long, we would treat the measurement as stale.
-constexpr auto kFreshnessTimeout = 50ms;
+// The max connection interval is 50ms, and HT sensor event interval can differ depending on the
+// sampling rate, scheduling, sensor eventQ FIFO etc. 120 (2 * 50 + 20) ms seems reasonable for now.
+constexpr auto kFreshnessTimeout = 120ms;
// Auto-recenter kicks in after the head has been still for this long.
constexpr auto kAutoRecenterWindowDuration = 6s;
@@ -61,13 +67,13 @@
// Screen is considered to be unstable (not still) if it has moved significantly within the last
// time window of this duration.
-constexpr auto kScreenStillnessWindowDuration = 3s;
+constexpr auto kScreenStillnessWindowDuration = 750ms;
// Screen is considered to have moved significantly if translated by this much (in meter, approx).
constexpr float kScreenStillnessTranslationThreshold = 0.1f;
// Screen is considered to have moved significantly if rotated by this much (in radians, approx).
-constexpr float kScreenStillnessRotationThreshold = 7.0f / 180 * M_PI;
+constexpr float kScreenStillnessRotationThreshold = 15.0f / 180 * M_PI;
// Time units for system clock ticks. This is what the Sensor Framework timestamps represent and
// what we use for pose filtering.
@@ -291,4 +297,58 @@
}
}
+std::string SpatializerPoseController::toString(unsigned level) const {
+ std::string prefixSpace;
+ prefixSpace.append(level, ' ');
+ std::string ss = prefixSpace + "SpatializerPoseController:\n";
+ bool needUnlock = false;
+
+ prefixSpace += ' ';
+ auto now = std::chrono::steady_clock::now();
+ if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
+ ss.append(prefixSpace).append("try_lock failed, dumpsys maybe INACCURATE!\n");
+ } else {
+ needUnlock = true;
+ }
+
+ ss += prefixSpace;
+ if (mHeadSensor == INVALID_SENSOR) {
+ ss += "HeadSensor: INVALID\n";
+ } else {
+ base::StringAppendF(&ss, "HeadSensor: 0x%08x\n", mHeadSensor);
+ }
+
+ ss += prefixSpace;
+ if (mScreenSensor == INVALID_SENSOR) {
+ ss += "ScreenSensor: INVALID\n";
+ } else {
+ base::StringAppendF(&ss, "ScreenSensor: 0x%08x\n", mScreenSensor);
+ }
+
+ ss += prefixSpace;
+ if (mActualMode.has_value()) {
+ base::StringAppendF(&ss, "ActualMode: %s\n", media::toString(mActualMode.value()).c_str());
+ } else {
+ ss += "ActualMode NOTEXIST\n";
+ }
+
+ if (mProcessor) {
+ ss += mProcessor->toString_l(level + 1);
+ } else {
+ ss.append(prefixSpace.c_str()).append("HeadTrackingProcessor not exist\n");
+ }
+
+ if (mPoseProvider) {
+ ss += mPoseProvider->toString(level + 1);
+ } else {
+ ss.append(prefixSpace.c_str()).append("SensorPoseProvider not exist\n");
+ }
+
+ if (needUnlock) {
+ mMutex.unlock();
+ }
+ // TODO: 233092747 add history sensor info with SimpleLog.
+ return ss;
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index f199ecb..233f94c 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -113,8 +113,11 @@
*/
void waitUntilCalculated();
+ // convert fields to a printable string
+ std::string toString(unsigned level) const;
+
private:
- mutable std::mutex mMutex;
+ mutable std::timed_mutex mMutex;
Listener* const mListener;
const std::chrono::microseconds mSensorPeriod;
// Order matters for the following two members to ensure correct destruction.
@@ -123,7 +126,7 @@
int32_t mHeadSensor = media::SensorPoseProvider::INVALID_HANDLE;
int32_t mScreenSensor = media::SensorPoseProvider::INVALID_HANDLE;
std::optional<media::HeadTrackingMode> mActualMode;
- std::condition_variable mCondVar;
+ std::condition_variable_any mCondVar;
bool mShouldCalculate = true;
bool mShouldExit = false;
bool mCalculated = false;
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index e887798..6813587 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -10,6 +10,10 @@
cc_test {
name: "audiopolicy_tests",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
+
include_dirs: [
"frameworks/av/services/audiopolicy",
],
@@ -30,7 +34,6 @@
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudiopolicycomponents",
"libgmock",
@@ -58,6 +61,11 @@
cc_test {
name: "audio_health_tests",
+
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
require_root: true,
shared_libs: [
@@ -67,7 +75,6 @@
"liblog",
"libmedia_helper",
"libutils",
- "android.media.audio.common.types-V1-cpp",
"libaudioclient_aidl_conversion",
"libstagefright_foundation",
"libshmemcompat",
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index bb00c48..d51c57c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -42,6 +42,32 @@
using testing::UnorderedElementsAre;
using android::content::AttributionSourceState;
+namespace {
+
+AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUid = uid;
+ criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
+ return criterion;
+}
+
+AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUsage = usage;
+ criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
+ return criterion;
+}
+
+AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mSource = source;
+ criterion.mRule = exclude ?
+ RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
+ return criterion;
+}
+
+} // namespace
+
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
AudioPolicyTestManager manager(&client);
@@ -943,15 +969,13 @@
}
}
-using PolicyMixTuple = std::tuple<audio_usage_t, audio_source_t, uint32_t>;
-
class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
protected:
void TearDown() override;
status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules);
+ const std::vector<AudioMixMatchCriterion>& matchCriteria);
void clearPolicyMix();
Vector<AudioMix> mAudioMixes;
@@ -965,15 +989,8 @@
status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
-
- for(const auto &rule: rules) {
- myMixMatchCriteria.add(AudioMixMatchCriterion(
- std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
- }
-
- AudioMix myAudioMix(myMixMatchCriteria, mixType, audioConfig, mixFlag,
+ const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
+ AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
String8(mixAddress.c_str()), 0);
myAudioMix.mDeviceType = deviceType;
// Clear mAudioMix before add new one to make sure we don't add already exist mixes.
@@ -1007,13 +1024,13 @@
// Only capture of playback is allowed in LOOP_BACK &RENDER mode
ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Fail due to the device is already connected.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register policy mixes with valid parameter should succeed.
@@ -1022,8 +1039,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1034,19 +1050,19 @@
// This will need to be updated if earpiece is added in the test configuration file.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Registration should fail due to output not found.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register valid policy mixes should succeed.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1061,8 +1077,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// After successfully registering policy mixes, it should be able to unregister.
@@ -1075,6 +1090,37 @@
ASSERT_EQ(INVALID_OPERATION, ret);
}
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUidCriterion(/*uid=*/1235, /*exclude=*/true),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(INVALID_OPERATION, ret);
+}
+
class AudioPolicyManagerTestForHdmi
: public AudioPolicyManagerTestWithConfigurationFile,
public testing::WithParamInterface<audio_format_t> {
@@ -1299,7 +1345,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
ret = mManager->unregisterPolicyMixes(mAudioMixes);
@@ -1314,9 +1360,9 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mUsageRules = {
- {AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE},
- {AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}
+ std::vector<AudioMixMatchCriterion> mUsageRules = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA),
+ createUsageCriterion(AUDIO_USAGE_ALARM)
};
struct audio_port_v7 mInjectionPort;
@@ -1376,9 +1422,10 @@
getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
attr);
- if (std::find_if(begin(mUsageRules), end(mUsageRules), [&usage](const auto &usageRule) {
- return (std::get<0>(usageRule) == usage) &&
- (std::get<2>(usageRule) == RULE_MATCH_ATTRIBUTE_USAGE);}) != end(mUsageRules) ||
+ if (std::find_if(begin(mUsageRules), end(mUsageRules),
+ [&usage](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_USAGE &&
+ c.mValue.mUsage == usage;}) != end(mUsageRules) ||
(strncmp(attr.tags, "addr=", strlen("addr=")) == 0 &&
strncmp(attr.tags + strlen("addr="), mMixAddress.c_str(),
AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0)) {
@@ -1499,10 +1546,10 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mSourceRules = {
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_CAMCORDER, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_MIC, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_VOICE_COMMUNICATION, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}
+ std::vector<AudioMixMatchCriterion> mSourceRules = {
+ createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
+ createCapturePresetCriterion(AUDIO_SOURCE_MIC),
+ createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
};
struct audio_port_v7 mExtractionPort;
@@ -1562,9 +1609,10 @@
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
getInputForAttr(attr, mTracker->getRiid(), &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
- if (std::find_if(begin(mSourceRules), end(mSourceRules), [&source](const auto &sourceRule) {
- return (std::get<1>(sourceRule) == source) &&
- (std::get<2>(sourceRule) == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET);})
+ if (std::find_if(begin(mSourceRules), end(mSourceRules),
+ [&source](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET &&
+ c.mValue.mSource == source;})
!= end(mSourceRules)) {
EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
} else {
@@ -1801,7 +1849,7 @@
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
const std::string kTestBusMediaOutput = "bus0_media_out";
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a2e7f7e..bc8981e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1712,7 +1712,13 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
}
- if (mCameraServiceProxyWrapper->isCameraDisabled()) {
+ userid_t clientUserId = multiuser_get_user_id(clientUid);
+ int callingUid = CameraThreadState::getCallingUid();
+ if (clientUid == USE_CALLING_UID) {
+ clientUserId = multiuser_get_user_id(callingUid);
+ }
+
+ if (mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
String8 msg =
String8::format("Camera disabled by device policy");
ALOGE("%s: %s", __FUNCTION__, msg.string());
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.cpp b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
index e101dd3..74497d1 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.cpp
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
@@ -41,7 +41,8 @@
tidToCycleCounterMap[currentThreadId]++;
if (tidToCycleCounterMap[currentThreadId] >= mMaxCycles) {
- ALOGW("CameraServiceWatchdog triggering abort for pid: %d", getpid());
+ ALOGW("CameraServiceWatchdog triggering abort for pid: %d tid: %d", getpid(),
+ currentThreadId);
// We use abort here so we can get a tombstone for better
// debugging.
abort();
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6f43270..f926b88 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -105,11 +105,6 @@
TClientBase::mCameraIdStr.string());
status_t res;
- // Verify ops permissions
- res = TClientBase::startCameraOps();
- if (res != OK) {
- return res;
- }
IPCTransport providerTransport = IPCTransport::INVALID;
res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr.string(),
&providerTransport);
@@ -145,6 +140,14 @@
return res;
}
+ // Verify ops permissions
+ res = TClientBase::startCameraOps();
+ if (res != OK) {
+ TClientBase::finishCameraOps();
+ mDevice.clear();
+ return res;
+ }
+
wp<NotificationListener> weakThis(this);
res = mDevice->setNotifyCallback(weakThis);
if (res != OK) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index acee2ab..644f682 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1512,6 +1512,7 @@
maxExpectedDuration);
status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
if (res != OK) {
+ mStatusTracker->dumpActiveComponents();
SET_ERR_L("Can't idle device in %f seconds!",
maxExpectedDuration/1e9);
}
@@ -2231,7 +2232,6 @@
if (mStatus == STATUS_ACTIVE) {
markClientActive = true;
mPauseStateNotify = true;
- mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
rc = internalPauseAndWaitLocked(maxExpectedDuration);
}
@@ -3448,6 +3448,10 @@
if (res == OK) {
sp<Camera3Device> parent = mParent.promote();
if (parent != nullptr) {
+ sp<StatusTracker> statusTracker = mStatusTracker.promote();
+ if (statusTracker != nullptr) {
+ statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
+ }
mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
}
setPaused(false);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index e12d8be..5a1ee9b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -331,7 +331,7 @@
status_t res =
gbLocker.lockAsync(
GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_RARELY,
- &mapped, fenceFd.get());
+ &mapped, fenceFd.release());
if (res != OK) {
ALOGE("%s: Failed to lock the buffer: %s (%d)", __FUNCTION__, strerror(-res), res);
return res;
@@ -507,10 +507,6 @@
mStreamUnpreparable = true;
}
- if (res != OK) {
- close(anwReleaseFence);
- }
-
*releaseFenceOut = releaseFence;
return res;
@@ -1309,7 +1305,7 @@
void* mapped = nullptr;
base::unique_fd fenceFd(dup(fence));
status_t res = graphicBuffer->lockAsync(GraphicBuffer::USAGE_SW_READ_OFTEN, &mapped,
- fenceFd.get());
+ fenceFd.release());
if (res != OK) {
ALOGE("%s: Failed to lock the buffer: %s (%d)", __FUNCTION__, strerror(-res), res);
return;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f4e3fad..5d3da45 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -128,12 +128,41 @@
return res;
}
+void correctMeteringRegions(camera_metadata_t *meta) {
+ if (meta == nullptr) return;
+
+ uint32_t meteringRegionKeys[] = {
+ ANDROID_CONTROL_AE_REGIONS,
+ ANDROID_CONTROL_AWB_REGIONS,
+ ANDROID_CONTROL_AF_REGIONS };
+
+ for (uint32_t key : meteringRegionKeys) {
+ camera_metadata_entry_t entry;
+ int res = find_camera_metadata_entry(meta, key, &entry);
+ if (res != OK) continue;
+
+ for (size_t i = 0; i < entry.count; i += 5) {
+ if (entry.data.i32[0] > entry.data.i32[2]) {
+ ALOGW("%s: Invalid metering region (%d): left: %d, right: %d",
+ __FUNCTION__, key, entry.data.i32[0], entry.data.i32[2]);
+ entry.data.i32[2] = entry.data.i32[0];
+ }
+ if (entry.data.i32[1] > entry.data.i32[3]) {
+ ALOGW("%s: Invalid metering region (%d): top: %d, bottom: %d",
+ __FUNCTION__, key, entry.data.i32[1], entry.data.i32[3]);
+ entry.data.i32[3] = entry.data.i32[1];
+ }
+ }
+ }
+}
+
void insertResultLocked(CaptureOutputStates& states, CaptureResult *result, uint32_t frameNumber) {
if (result == nullptr) return;
camera_metadata_t *meta = const_cast<camera_metadata_t *>(
result->mMetadata.getAndLock());
set_camera_metadata_vendor_id(meta, states.vendorTagId);
+ correctMeteringRegions(meta);
result->mMetadata.unlock(meta);
if (result->mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
@@ -152,6 +181,7 @@
camera_metadata_t *pmeta = const_cast<camera_metadata_t *>(
physicalMetadata.mPhysicalCameraMetadata.getAndLock());
set_camera_metadata_vendor_id(pmeta, states.vendorTagId);
+ correctMeteringRegions(pmeta);
physicalMetadata.mPhysicalCameraMetadata.unlock(pmeta);
}
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
index 27b00c9..515259e 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
@@ -354,17 +354,8 @@
if (weight == 0) {
continue;
}
- // Top left (inclusive)
- scaleCoordinates(entry.data.i32 + j, 1, zoomRatio, true /*clamp*/, arrayWidth,
+ scaleRegion(entry.data.i32 + j, zoomRatio, arrayWidth,
arrayHeight);
- // Bottom right (exclusive): Use adjacent inclusive pixel to
- // calculate.
- entry.data.i32[j+2] -= 1;
- entry.data.i32[j+3] -= 1;
- scaleCoordinates(entry.data.i32 + j + 2, 1, zoomRatio, true /*clamp*/, arrayWidth,
- arrayHeight);
- entry.data.i32[j+2] += 1;
- entry.data.i32[j+3] += 1;
}
}
@@ -401,17 +392,8 @@
if (weight == 0) {
continue;
}
- // Top-left (inclusive)
- scaleCoordinates(entry.data.i32 + j, 1, 1.0 / zoomRatio, true /*clamp*/, arrayWidth,
+ scaleRegion(entry.data.i32 + j, 1.0 / zoomRatio, arrayWidth,
arrayHeight);
- // Bottom-right (exclusive): Use adjacent inclusive pixel to
- // calculate.
- entry.data.i32[j+2] -= 1;
- entry.data.i32[j+3] -= 1;
- scaleCoordinates(entry.data.i32 + j + 2, 1, 1.0 / zoomRatio, true /*clamp*/, arrayWidth,
- arrayHeight);
- entry.data.i32[j+2] += 1;
- entry.data.i32[j+3] += 1;
}
}
for (auto rect : kRectsToCorrect) {
@@ -470,6 +452,24 @@
}
}
+void ZoomRatioMapper::scaleRegion(int32_t* region, float scaleRatio,
+ int32_t arrayWidth, int32_t arrayHeight) {
+ // Top-left (inclusive)
+ scaleCoordinates(region, 1, scaleRatio, true /*clamp*/, arrayWidth,
+ arrayHeight);
+ // Bottom-right (exclusive): Use adjacent inclusive pixel to
+ // calculate.
+ region[2] -= 1;
+ region[3] -= 1;
+ scaleCoordinates(region + 2, 1, scaleRatio, true /*clamp*/, arrayWidth,
+ arrayHeight);
+ region[2] += 1;
+ region[3] += 1;
+ // Make sure bottom-right >= top-left
+ region[2] = std::max(region[0], region[2]);
+ region[3] = std::max(region[1], region[3]);
+}
+
void ZoomRatioMapper::scaleRects(int32_t* rects, int rectCount,
float scaleRatio, int32_t arrayWidth, int32_t arrayHeight) {
for (int i = 0; i < rectCount * 4; i += 4) {
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.h b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
index b7a9e41..1aa8e78 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.h
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
@@ -69,6 +69,8 @@
public: // Visible for testing. Do not use concurently.
void scaleCoordinates(int32_t* coordPairs, int coordCount,
float scaleRatio, bool clamp, int32_t arrayWidth, int32_t arrayHeight);
+ void scaleRegion(int32_t* region, float scaleRatio,
+ int32_t arrayWidth, int32_t arrayHeight);
bool isValid() { return mIsValid; }
private:
diff --git a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
index 4359f9b..42d99e8 100644
--- a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
@@ -138,12 +138,12 @@
return mCameraServiceProxy->notifyCameraState(cameraSessionStats);
}
- virtual binder::Status isCameraDisabled(bool *ret) override {
+ virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
if (mOverrideCameraDisabled) {
*ret = mCameraDisabled;
return binder::Status::ok();
}
- return mCameraServiceProxy->isCameraDisabled(ret);
+ return mCameraServiceProxy->isCameraDisabled(userId, ret);
}
void setCameraDisabled(bool cameraDisabled) {
@@ -167,7 +167,7 @@
{ }
~AutoDisconnectDevice() {
- if (mDevice != nullptr) {
+ if (mDevice != nullptr) {
mDevice->disconnect();
}
}
diff --git a/services/camera/libcameraservice/tests/ZoomRatioTest.cpp b/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
index ff7aafd..badd47a 100644
--- a/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
+++ b/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
@@ -160,11 +160,9 @@
false/*hasZoomRatioRange*/, zoomRatioRange,
usePreCorrectArray));
- size_t index = 0;
int32_t width = testActiveArraySize[2];
int32_t height = testActiveArraySize[3];
if (usePreCorrectArray) {
- index = 1;
width = testPreCorrActiveArraySize[2];
height = testPreCorrActiveArraySize[3];
}
@@ -254,6 +252,19 @@
for (size_t i = 0; i < coords.size(); i++) {
EXPECT_LE(std::abs(coords[i] - expectedZoomOutCoords[i]), kMaxAllowedPixelError);
}
+
+ // Verify region zoom scaling doesn't generate invalid metering region
+ // (width < 0, or height < 0)
+ std::array<float, 3> scaleRatios = {10.0f, 1.0f, 0.1f};
+ for (float scaleRatio : scaleRatios) {
+ for (size_t i = 0; i < originalCoords.size(); i+= 2) {
+ int32_t coordinates[] = {originalCoords[i], originalCoords[i+1],
+ originalCoords[i], originalCoords[i+1]};
+ mapper.scaleRegion(coordinates, scaleRatio, width, height);
+ EXPECT_LE(coordinates[0], coordinates[2]);
+ EXPECT_LE(coordinates[1], coordinates[3]);
+ }
+ }
}
TEST(ZoomRatioTest, scaleCoordinatesTest) {
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index 733ecd9..885c6aa 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -269,11 +269,11 @@
sessionStats->onClose(proxyBinder, latencyMs);
}
-bool CameraServiceProxyWrapper::isCameraDisabled() {
+bool CameraServiceProxyWrapper::isCameraDisabled(int userId) {
sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
if (proxyBinder == nullptr) return true;
bool ret = false;
- auto status = proxyBinder->isCameraDisabled(&ret);
+ auto status = proxyBinder->isCameraDisabled(userId, &ret);
if (!status.isOk()) {
ALOGE("%s: Failed during camera disabled query: %s", __FUNCTION__,
status.exceptionMessage().c_str());
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index 6af56c3..c00c691 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -105,7 +105,7 @@
int getRotateAndCropOverride(String16 packageName, int lensFacing, int userId);
// Detect if the camera is disabled by device policy.
- bool isCameraDisabled();
+ bool isCameraDisabled(int userId);
};
} // android
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 99e3691..12593ff 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -240,6 +240,35 @@
"sharing_requested",
};
+static constexpr const char * HeadTrackerDeviceEnabledFields[] {
+ "mediametrics_headtrackerdeviceenabled_reported",
+ "type",
+ "event",
+ "enabled",
+};
+
+static constexpr const char * HeadTrackerDeviceSupportedFields[] {
+ "mediametrics_headtrackerdevicesupported_reported",
+ "type",
+ "event",
+ "supported",
+};
+
+static constexpr const char * SpatializerCapabilitiesFields[] {
+ "mediametrics_spatializer_reported",
+ "head_tracking_modes",
+ "spatializer_levels",
+ "spatializer_modes",
+ "channel_masks",
+};
+
+static constexpr const char * SpatializerDeviceEnabledFields[] {
+ "mediametrics_spatializerdeviceenabled_reported",
+ "type",
+ "event",
+ "enabled",
+};
+
/**
* printFields is a helper method that prints the fields and corresponding values
* in a human readable style.
@@ -459,6 +488,15 @@
[this](const std::shared_ptr<const android::mediametrics::Item> &item){
mAudioPowerUsage.checkCreatePatch(item);
}));
+
+ // Handle Spatializer - these keys are prefixed by "audio.spatializer."
+ mActions.addAction(
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "*." AMEDIAMETRICS_PROP_EVENT,
+ std::monostate{}, /* match any event */
+ std::make_shared<AnalyticsActions::Function>(
+ [this](const std::shared_ptr<const android::mediametrics::Item> &item){
+ mSpatializer.onEvent(item);
+ }));
}
AudioAnalytics::~AudioAnalytics()
@@ -1525,5 +1563,173 @@
return { s, n };
}
+// Classifies the setting event for statsd (use generated statsd enums.proto constants).
+static int32_t classifySettingEvent(bool isSetAlready, bool withinBoot) {
+ if (isSetAlready) {
+ return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_NORMAL;
+ }
+ if (withinBoot) {
+ return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_BOOT;
+ }
+ return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_FIRST;
+}
+
+void AudioAnalytics::Spatializer::onEvent(
+ const std::shared_ptr<const android::mediametrics::Item> &item)
+{
+ const auto key = item->getKey();
+
+ if (!startsWith(key, AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER)) return;
+
+ const std::string suffix =
+ key.substr(std::size(AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER) - 1);
+
+ std::string eventStr; // optional - find the actual event string.
+ (void)item->get(AMEDIAMETRICS_PROP_EVENT, &eventStr);
+
+ const size_t delim = suffix.find('.'); // note could use split.
+ if (delim == suffix.npos) {
+ // on create with suffix == "0" for the first spatializer effect.
+
+ std::string headTrackingModes;
+ (void)item->get(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, &headTrackingModes);
+
+ std::string levels;
+ (void)item->get(AMEDIAMETRICS_PROP_LEVELS, &levels);
+
+ std::string modes;
+ (void)item->get(AMEDIAMETRICS_PROP_MODES, &modes);
+
+ std::string channelMasks;
+ (void)item->get(AMEDIAMETRICS_PROP_CHANNELMASKS, &channelMasks);
+
+ LOG(LOG_LEVEL) << "key:" << key
+ << " headTrackingModes:" << headTrackingModes
+ << " levels:" << levels
+ << " modes:" << modes
+ << " channelMasks:" << channelMasks
+ ;
+
+ const std::vector<int32_t> headTrackingModesVector =
+ types::vectorFromMap(headTrackingModes, types::getHeadTrackingModeMap());
+ const std::vector<int32_t> levelsVector =
+ types::vectorFromMap(levels, types::getSpatializerLevelMap());
+ const std::vector<int32_t> modesVector =
+ types::vectorFromMap(modes, types::getSpatializerModeMap());
+ const std::vector<int64_t> channelMasksVector =
+ types::channelMaskVectorFromString(channelMasks);
+
+ const auto [ result, str ] = sendToStatsd(SpatializerCapabilitiesFields,
+ CONDITION(android::util::MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED)
+ , headTrackingModesVector
+ , levelsVector
+ , modesVector
+ , channelMasksVector
+ );
+
+ mAudioAnalytics.mStatsdLog->log(
+ android::util::MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED, str);
+
+ std::lock_guard lg(mLock);
+ if (mFirstCreateTimeNs == 0) {
+ // Only update the create time once to prevent audioserver restart
+ // from looking like a boot.
+ mFirstCreateTimeNs = item->getTimestamp();
+ }
+ mSimpleLog.log("%s suffix: %s item: %s",
+ __func__, suffix.c_str(), item->toString().c_str());
+ } else {
+ std::string subtype = suffix.substr(0, delim);
+ if (subtype != "device") return; // not a device.
+
+ const std::string deviceType = suffix.substr(std::size("device.") - 1);
+
+ const int32_t deviceTypeStatsd =
+ types::lookup<types::AUDIO_DEVICE_INFO_TYPE, int32_t>(deviceType);
+
+ std::string address;
+ (void)item->get(AMEDIAMETRICS_PROP_ADDRESS, &address);
+ std::string enabled;
+ (void)item->get(AMEDIAMETRICS_PROP_ENABLED, &enabled);
+ std::string hasHeadTracker;
+ (void)item->get(AMEDIAMETRICS_PROP_HASHEADTRACKER, &hasHeadTracker);
+ std::string headTrackerEnabled;
+ (void)item->get(AMEDIAMETRICS_PROP_HEADTRACKERENABLED, &headTrackerEnabled);
+
+ std::lock_guard lg(mLock);
+
+ // Validate from our cached state
+
+ // Our deviceKey takes the device type and appends the address if any.
+ // This distinguishes different wireless devices for the purposes of tracking.
+ std::string deviceKey(deviceType);
+ deviceKey.append("_").append(address);
+ DeviceState& deviceState = mDeviceStateMap[deviceKey];
+
+ // check whether the settings event is within a certain time of spatializer creation.
+ const bool withinBoot =
+ item->getTimestamp() - mFirstCreateTimeNs < kBootDurationThreshold;
+
+ if (!enabled.empty()) {
+ if (enabled != deviceState.enabled) {
+ const int32_t settingEventStatsd =
+ classifySettingEvent(!deviceState.enabled.empty(), withinBoot);
+ deviceState.enabled = enabled;
+ const bool enabledStatsd = enabled == "true";
+ const auto [ result, str ] = sendToStatsd(SpatializerDeviceEnabledFields,
+ CONDITION(android::util::MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED)
+ , deviceTypeStatsd
+ , settingEventStatsd
+ , enabledStatsd
+ );
+ mAudioAnalytics.mStatsdLog->log(
+ android::util::MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED, str);
+ }
+ }
+ if (!hasHeadTracker.empty()) {
+ if (hasHeadTracker != deviceState.hasHeadTracker) {
+ const int32_t settingEventStatsd =
+ classifySettingEvent(!deviceState.hasHeadTracker.empty(), withinBoot);
+ deviceState.hasHeadTracker = hasHeadTracker;
+ const bool supportedStatsd = hasHeadTracker == "true";
+ const auto [ result, str ] = sendToStatsd(HeadTrackerDeviceSupportedFields,
+ CONDITION(android::util::MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED)
+ , deviceTypeStatsd
+ , settingEventStatsd
+ , supportedStatsd
+ );
+ mAudioAnalytics.mStatsdLog->log(
+ android::util::MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED, str);
+ }
+ }
+ if (!headTrackerEnabled.empty()) {
+ if (headTrackerEnabled != deviceState.headTrackerEnabled) {
+ const int32_t settingEventStatsd =
+ classifySettingEvent(!deviceState.headTrackerEnabled.empty(), withinBoot);
+ deviceState.headTrackerEnabled = headTrackerEnabled;
+ const bool enabledStatsd = headTrackerEnabled == "true";
+ const auto [ result, str ] = sendToStatsd(HeadTrackerDeviceEnabledFields,
+ CONDITION(android::util::MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED)
+ , deviceTypeStatsd
+ , settingEventStatsd
+ , enabledStatsd
+ );
+ mAudioAnalytics.mStatsdLog->log(
+ android::util::MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED, str);
+ }
+ }
+ mSimpleLog.log("%s deviceKey: %s item: %s",
+ __func__, deviceKey.c_str(), item->toString().c_str());
+ }
+}
+
+std::pair<std::string, int32_t> AudioAnalytics::Spatializer::dump(
+ int32_t lines, const char *prefix) const
+{
+ std::lock_guard lg(mLock);
+ std::string s = mSimpleLog.dumpToString(prefix == nullptr ? "" : prefix, lines);
+ size_t n = std::count(s.begin(), s.end(), '\n');
+ return { s, n };
+}
} // namespace android::mediametrics
diff --git a/services/mediametrics/AudioTypes.cpp b/services/mediametrics/AudioTypes.cpp
index 6e24a58..d2b4aab 100644
--- a/services/mediametrics/AudioTypes.cpp
+++ b/services/mediametrics/AudioTypes.cpp
@@ -135,6 +135,94 @@
return map;
}
+// A map for the Java AudioDeviceInfo types to internal (native) output devices.
+const std::unordered_map<std::string, int32_t>& getAudioDeviceOutCompactMap() {
+ // DO NOT MODIFY VALUES (OK to add new ones).
+ static std::unordered_map<std::string, int32_t> map{
+ // should "unknown" go to AUDIO_DEVICE_NONE?
+ {"earpiece", AUDIO_DEVICE_OUT_EARPIECE},
+ {"speaker", AUDIO_DEVICE_OUT_SPEAKER},
+ {"headset", AUDIO_DEVICE_OUT_WIRED_HEADSET},
+ {"headphone", AUDIO_DEVICE_OUT_WIRED_HEADPHONE},
+ {"bt_sco", AUDIO_DEVICE_OUT_BLUETOOTH_SCO},
+ {"bt_sco_hs", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET},
+ {"bt_sco_carkit", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT},
+ {"bt_a2dp", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP},
+ {"bt_a2dp_hp", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES},
+ {"bt_a2dp_spk", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER},
+ {"aux_digital", AUDIO_DEVICE_OUT_AUX_DIGITAL},
+ {"hdmi", AUDIO_DEVICE_OUT_HDMI},
+ {"analog_dock", AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET},
+ {"digital_dock", AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET},
+ {"usb_accessory", AUDIO_DEVICE_OUT_USB_ACCESSORY},
+ {"usb_device", AUDIO_DEVICE_OUT_USB_DEVICE},
+ {"remote_submix", AUDIO_DEVICE_OUT_REMOTE_SUBMIX},
+ {"telephony_tx", AUDIO_DEVICE_OUT_TELEPHONY_TX},
+ {"line", AUDIO_DEVICE_OUT_LINE},
+ {"hdmi_arc", AUDIO_DEVICE_OUT_HDMI_ARC},
+ {"hdmi_earc", AUDIO_DEVICE_OUT_HDMI_EARC},
+ {"spdif", AUDIO_DEVICE_OUT_SPDIF},
+ {"fm_transmitter", AUDIO_DEVICE_OUT_FM},
+ {"aux_line", AUDIO_DEVICE_OUT_AUX_LINE},
+ {"speaker_safe", AUDIO_DEVICE_OUT_SPEAKER_SAFE},
+ {"ip", AUDIO_DEVICE_OUT_IP},
+ {"bus", AUDIO_DEVICE_OUT_BUS},
+ {"proxy", AUDIO_DEVICE_OUT_PROXY},
+ {"usb_headset", AUDIO_DEVICE_OUT_USB_HEADSET},
+ {"hearing_aid_out", AUDIO_DEVICE_OUT_HEARING_AID},
+ {"echo_canceller", AUDIO_DEVICE_OUT_ECHO_CANCELLER},
+ // default does not exist
+ {"ble_headset", AUDIO_DEVICE_OUT_BLE_HEADSET},
+ {"ble_speaker", AUDIO_DEVICE_OUT_BLE_SPEAKER},
+ {"ble_broadcast", AUDIO_DEVICE_OUT_BLE_BROADCAST},
+ };
+ return map;
+}
+
+// A map for the Java AudioDeviceInfo types.
+// This uses generated statsd enums.proto constants.
+const std::unordered_map<std::string, int32_t>& getAudioDeviceInfoTypeMap() {
+ // DO NOT MODIFY VALUES (OK to add new ones).
+ static std::unordered_map<std::string, int32_t> map{
+ {"unknown", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_UNKNOWN},
+ {"earpiece", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_EARPIECE},
+ {"speaker", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_SPEAKER},
+ {"headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_WIRED_HEADSET},
+ {"headphone", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_WIRED_HEADPHONES}, // sic
+ {"bt_sco", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
+ {"bt_sco_hs", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
+ {"bt_sco_carkit", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
+ {"bt_a2dp", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
+ {"bt_a2dp_hp", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
+ {"bt_a2dp_spk", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
+ {"aux_digital", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI},
+ {"hdmi", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI},
+ {"analog_dock", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_DOCK},
+ {"digital_dock", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_DOCK},
+ {"usb_accessory", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_ACCESSORY},
+ {"usb_device", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_DEVICE},
+ {"usb_headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_HEADSET},
+ {"remote_submix", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_REMOTE_SUBMIX},
+ {"telephony_tx", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_TELEPHONY},
+ {"line", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_LINE_ANALOG},
+ {"hdmi_arc", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI_ARC},
+ {"hdmi_earc", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI_EARC},
+ {"spdif", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_LINE_DIGITAL},
+ {"fm_transmitter", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_FM},
+ {"aux_line", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_AUX_LINE},
+ {"speaker_safe", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_SPEAKER_SAFE},
+ {"ip", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_IP},
+ {"bus", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUS},
+ {"proxy", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_UNKNOWN /* AUDIO_DEVICE_INFO_TYPE_PROXY */},
+ {"hearing_aid_out", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HEARING_AID},
+ {"echo_canceller", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_ECHO_REFERENCE}, // sic
+ {"ble_headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_HEADSET},
+ {"ble_speaker", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_SPEAKER},
+ {"ble_broadcast", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_BROADCAST},
+ };
+ return map;
+}
+
const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap() {
// DO NOT MODIFY VALUES (OK to add new ones).
// This may be found in frameworks/av/services/audioflinger/Threads.h
@@ -197,6 +285,41 @@
return map;
}
+const std::unordered_map<std::string, int32_t>& getHeadTrackingModeMap() {
+ // DO NOT MODIFY VALUES(OK to add new ones).
+ // frameworks/base/media/java/android/media/Spatializer.java
+ // frameworks/av/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
+ static std::unordered_map<std::string, int32_t> map {
+ {"OTHER", 0},
+ {"DISABLED", -1},
+ {"RELATIVE_WORLD", 1},
+ {"RELATIVE_SCREEN", 2},
+ };
+ return map;
+}
+
+const std::unordered_map<std::string, int32_t>& getSpatializerLevelMap() {
+ // DO NOT MODIFY VALUES(OK to add new ones).
+ // frameworks/base/media/java/android/media/Spatializer.java
+ // frameworks/av/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
+ static std::unordered_map<std::string, int32_t> map {
+ {"NONE", 0},
+ {"SPATIALIZER_MULTICHANNEL", 1},
+ {"SPATIALIZER_MCHAN_BED_PLUS_OBJECTS", 2},
+ };
+ return map;
+}
+
+const std::unordered_map<std::string, int32_t>& getSpatializerModeMap() {
+ // DO NOT MODIFY VALUES(OK to add new ones).
+ // frameworks/av/media/libaudioclient/aidl/android/media/SpatializationMode.aidl
+ static std::unordered_map<std::string, int32_t> map {
+ {"SPATIALIZER_BINAURAL", 0},
+ {"SPATIALIZER_TRANSAURAL", 1},
+ };
+ return map;
+}
+
const std::unordered_map<std::string, int32_t>& getStatusMap() {
// DO NOT MODIFY VALUES(OK to add new ones).
static std::unordered_map<std::string, int32_t> map {
@@ -286,6 +409,35 @@
return value;
}
+std::vector<int32_t> vectorFromMap(
+ const std::string &str, const std::unordered_map<std::string, int32_t>& map)
+{
+ std::vector<int32_t> v;
+
+ if (str.empty()) return v;
+
+ const auto result = stringutils::split(str, "|");
+ for (const auto &s : result) {
+ auto it = map.find(s);
+ if (it == map.end()) continue;
+ v.push_back(it->second);
+ }
+ return v;
+}
+
+std::vector<int64_t> channelMaskVectorFromString(const std::string &s)
+{
+ std::vector<int64_t> v;
+
+ const auto result = stringutils::split(s, "|");
+ for (const auto &mask : result) {
+ // 0 if undetected or if actually 0.
+ int64_t int64Mask = strtoll(mask.c_str(), nullptr, 0);
+ v.push_back(int64Mask);
+ }
+ return v;
+}
+
template <>
int32_t lookup<CONTENT_TYPE>(const std::string &contentType)
{
@@ -441,6 +593,17 @@
}
template <>
+int32_t lookup<AUDIO_DEVICE_INFO_TYPE>(const std::string& audioDeviceInfoType)
+{
+ auto& map = getAudioDeviceInfoTypeMap();
+ auto it = map.find(audioDeviceInfoType);
+ if (it == map.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+template <>
int32_t lookup<CALLER_NAME>(const std::string &callerName)
{
auto& map = getAudioCallerNameMap();
@@ -463,6 +626,39 @@
}
template <>
+int32_t lookup<HEAD_TRACKING_MODE>(const std::string& headTrackingMode)
+{
+ auto& map = getHeadTrackingModeMap();
+ auto it = map.find(headTrackingMode);
+ if (it == map.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+template <>
+int32_t lookup<SPATIALIZER_LEVEL>(const std::string& spatializerLevel)
+{
+ auto& map = getSpatializerLevelMap();
+ auto it = map.find(spatializerLevel);
+ if (it == map.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+template <>
+int32_t lookup<SPATIALIZER_MODE>(const std::string& spatializerMode)
+{
+ auto& map = getSpatializerModeMap();
+ auto it = map.find(spatializerMode);
+ if (it == map.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+template <>
int32_t lookup<STATUS>(const std::string &status)
{
auto& map = getStatusMap();
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 9e2f896..ceb3e6a 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -338,6 +338,15 @@
result << "-- some lines may be truncated --\n";
}
+ const int32_t spatializerLinesToDump = all ? INT32_MAX : 15;
+ result << "\nSpatializer Message Log:";
+ const auto [ spatializerDumpString, spatializerLines ] =
+ mAudioAnalytics.dumpSpatializer(spatializerLinesToDump);
+ result << "\n" << spatializerDumpString;
+ if (spatializerLines == spatializerLinesToDump) {
+ result << "-- some lines may be truncated --\n";
+ }
+
result << "\nLogSessionId:\n"
<< mediametrics::ValidateId::get()->dump();
diff --git a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
index 5ee8c30..7000ba8 100644
--- a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
+++ b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
@@ -92,6 +92,15 @@
return mHealth.dump(lines);
}
+ /**
+ * Returns a pair consisting of the dump string and the number of lines in the string.
+ *
+ * Spatializer dump.
+ */
+ std::pair<std::string, int32_t> dumpSpatializer(int32_t lines = INT32_MAX) const {
+ return mSpatializer.dump(lines);
+ }
+
void clear() {
// underlying state is locked.
mPreviousAnalyticsState->clear();
@@ -317,6 +326,36 @@
SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
} mHealth{*this};
+ // Spatializer is a nested class that tracks related messages.
+ class Spatializer {
+ public:
+ explicit Spatializer(AudioAnalytics &audioAnalytics)
+ : mAudioAnalytics(audioAnalytics) {}
+
+ // an item that starts with "audio.spatializer"
+ void onEvent(const std::shared_ptr<const android::mediametrics::Item> &item);
+
+ std::pair<std::string, int32_t> dump(
+ int32_t lines = INT32_MAX, const char *prefix = nullptr) const;
+
+ private:
+
+ // Current device state as strings:
+ // "" means unknown, "true" or "false".
+ struct DeviceState {
+ std::string enabled;
+ std::string hasHeadTracker;
+ std::string headTrackerEnabled;
+ };
+
+ AudioAnalytics& mAudioAnalytics;
+ static constexpr int64_t kBootDurationThreshold = 120 /* seconds */ * 1e9;
+ mutable std::mutex mLock;
+ int64_t mFirstCreateTimeNs GUARDED_BY(mLock) = 0;
+ std::map<std::string, DeviceState> mDeviceStateMap GUARDED_BY(mLock);
+ SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
+ } mSpatializer{*this};
+
AudioPowerUsage mAudioPowerUsage;
};
diff --git a/services/mediametrics/include/mediametricsservice/AudioTypes.h b/services/mediametrics/include/mediametricsservice/AudioTypes.h
index 5dbff9b..b5fe28b 100644
--- a/services/mediametrics/include/mediametricsservice/AudioTypes.h
+++ b/services/mediametrics/include/mediametricsservice/AudioTypes.h
@@ -29,6 +29,14 @@
const std::unordered_map<std::string, int64_t>& getAudioDeviceOutMap();
const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap();
const std::unordered_map<std::string, int32_t>& getAudioTrackTraitsMap();
+const std::unordered_map<std::string, int32_t>& getHeadTrackingModeMap();
+const std::unordered_map<std::string, int32_t>& getSpatializerLevelMap();
+const std::unordered_map<std::string, int32_t>& getSpatializerModeMap();
+
+std::vector<int32_t> vectorFromMap(
+ const std::string &str, const std::unordered_map<std::string, int32_t>& map);
+
+std::vector<int64_t> channelMaskVectorFromString(const std::string &s);
// Enumeration for the device connection results.
enum DeviceConnectionResult : int32_t {
@@ -47,14 +55,18 @@
AAUDIO_DIRECTION,
AAUDIO_PERFORMANCE_MODE,
AAUDIO_SHARING_MODE,
+ AUDIO_DEVICE_INFO_TYPE,
CALLER_NAME,
CONTENT_TYPE,
ENCODING,
+ HEAD_TRACKING_MODE,
INPUT_DEVICE, // int64_t
INPUT_FLAG,
OUTPUT_DEVICE, // int64_t
OUTPUT_FLAG,
SOURCE_TYPE,
+ SPATIALIZER_LEVEL,
+ SPATIALIZER_MODE,
STATUS,
STREAM_TYPE,
THREAD_TYPE,
diff --git a/services/mediametrics/include/mediametricsservice/MediaMetricsService.h b/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
index 8d0b1cf..3ec5ac7 100644
--- a/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
+++ b/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
@@ -125,7 +125,7 @@
std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.
// mStatsdLog is locked internally (thread-safe) and shows the last atoms logged
- static constexpr size_t STATSD_LOG_LINES_MAX = 30; // recent log lines to keep
+ static constexpr size_t STATSD_LOG_LINES_MAX = 48; // recent log lines to keep
static constexpr size_t STATSD_LOG_LINES_DUMP = 4; // normal amount of lines to dump
const std::shared_ptr<mediametrics::StatsdLog> mStatsdLog{
std::make_shared<mediametrics::StatsdLog>(STATSD_LOG_LINES_MAX)};
diff --git a/services/mediametrics/include/mediametricsservice/StringUtils.h b/services/mediametrics/include/mediametricsservice/StringUtils.h
index a56f5b8..a91d37b 100644
--- a/services/mediametrics/include/mediametricsservice/StringUtils.h
+++ b/services/mediametrics/include/mediametricsservice/StringUtils.h
@@ -23,6 +23,19 @@
namespace android::mediametrics::stringutils {
+// Define a way of printing a vector - this
+// is used for proto repeated arguments.
+template <typename T>
+inline std::ostream & operator<< (std::ostream& s,
+ std::vector<T> const& v) {
+ s << "{ ";
+ for (const auto& e : v) {
+ s << e << " ";
+ }
+ s << "}";
+ return s;
+}
+
/**
* fieldPrint is a helper method that logs to a stringstream a sequence of
* field names (in a fixed size array) together with a variable number of arg parameters.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index b4610bc..adf0a5e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -26,8 +26,9 @@
#include <cutils/sched_policy.h>
#include <dirent.h>
#include <media/MediaResourcePolicy.h>
-#include <media/stagefright/ProcessInfo.h>
+#include <media/stagefright/foundation/ABase.h>
#include <mediautils/BatteryNotifier.h>
+#include <mediautils/ProcessInfo.h>
#include <mediautils/SchedulingPolicyService.h>
#include <string.h>
#include <sys/types.h>
@@ -271,10 +272,9 @@
snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
result.append(buffer);
- std::string clientName;
- Status status = infos[j].client->getName(&clientName);
- if (!status.isOk()) {
- clientName = "<unknown client>";
+ std::string clientName = "<unknown client>";
+ if (infos[j].client != nullptr) {
+ Status status = infos[j].client->getName(&clientName);
}
snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
result.append(buffer);
diff --git a/services/mediaresourcemanager/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index 81c85e5..08ac90e 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -40,6 +40,7 @@
"libbinder",
"libbinder_ndk",
"libmedia",
+ "libmediautils",
"libutils",
],
fuzz_config: {
diff --git a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
index e4aaea0..7003dcb 100644
--- a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
+++ b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
@@ -22,8 +22,8 @@
#include <aidl/android/media/BnResourceManagerClient.h>
#include <media/MediaResource.h>
#include <media/MediaResourcePolicy.h>
-#include <media/stagefright/ProcessInfoInterface.h>
#include <media/stagefright/foundation/ADebug.h>
+#include <mediautils/ProcessInfoInterface.h>
#include "ResourceManagerService.h"
#include "fuzzer/FuzzedDataProvider.h"
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index 618626f..0366d9b 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -18,6 +18,7 @@
"libbinder_ndk",
"liblog",
"libmedia",
+ "libmediautils",
"libutils",
],
include_dirs: [
@@ -63,6 +64,7 @@
"libbinder_ndk",
"liblog",
"libmedia",
+ "libmediautils",
"libutils",
],
include_dirs: [
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 5bf44ce..7bd9484 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -21,7 +21,7 @@
#include <media/MediaResource.h>
#include <media/MediaResourcePolicy.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/ProcessInfoInterface.h>
+#include <mediautils/ProcessInfoInterface.h>
namespace android {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index bbfa0b7..290e9ff 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -22,6 +22,7 @@
#include <assert.h>
#include <map>
#include <mutex>
+#include <set>
#include <sstream>
#include <thread>
#include <utils/Singleton.h>
@@ -68,9 +69,29 @@
return result.str();
}
+namespace {
+
+const static std::map<audio_format_t, audio_format_t> NEXT_FORMAT_TO_TRY = {
+ {AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_32_BIT},
+ {AUDIO_FORMAT_PCM_32_BIT, AUDIO_FORMAT_PCM_24_BIT_PACKED},
+ {AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_16_BIT}
+};
+
+audio_format_t getNextFormatToTry(audio_format_t curFormat, audio_format_t returnedFromAPM) {
+ if (returnedFromAPM != AUDIO_FORMAT_DEFAULT) {
+ return returnedFromAPM;
+ }
+ const auto it = NEXT_FORMAT_TO_TRY.find(curFormat);
+ return it != NEXT_FORMAT_TO_TRY.end() ? it->second : AUDIO_FORMAT_DEFAULT;
+}
+
+}
+
aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
aaudio_result_t result = AAUDIO_OK;
copyFrom(request.getConstantConfiguration());
+ mRequestedDeviceId = getDeviceId();
+
mMmapClient.attributionSource = request.getAttributionSource();
// TODO b/182392769: use attribution source util
mMmapClient.attributionSource.uid = VALUE_OR_FATAL(
@@ -79,43 +100,45 @@
legacy2aidl_pid_t_int32_t(IPCThreadState::self()->getCallingPid()));
audio_format_t audioFormat = getFormat();
+ std::set<audio_format_t> formatsTried;
+ while (true) {
+ if (formatsTried.find(audioFormat) != formatsTried.end()) {
+ // APM returning something that has already tried.
+ ALOGW("Have already tried to open #x, but failed before");
+ break;
+ }
+ formatsTried.insert(audioFormat);
- result = openWithFormat(audioFormat);
- if (result == AAUDIO_OK) return result;
+ audio_format_t nextFormatToTry = AUDIO_FORMAT_DEFAULT;
+ result = openWithFormat(audioFormat, &nextFormatToTry);
+ if (result == AAUDIO_OK || result != AAUDIO_ERROR_UNAVAILABLE) {
+ // Return if it is successful or there is an error that is not
+ // AAUDIO_ERROR_UNAVAILABLE happens.
+ ALOGI("Opened format=%#x with result=%d", audioFormat, result);
+ break;
+ }
- if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
- ALOGD("%s() FLOAT failed, perhaps due to format. Try again with 32_BIT", __func__);
- audioFormat = AUDIO_FORMAT_PCM_32_BIT;
- result = openWithFormat(audioFormat);
- }
- if (result == AAUDIO_OK) return result;
-
- if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_32_BIT) {
- ALOGD("%s() 32_BIT failed, perhaps due to format. Try again with 24_BIT_PACKED", __func__);
- audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- result = openWithFormat(audioFormat);
- }
- if (result == AAUDIO_OK) return result;
-
- // TODO The HAL and AudioFlinger should be recommending a format if the open fails.
- // But that recommendation is not propagating back from the HAL.
- // So for now just try something very likely to work.
- if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
- ALOGD("%s() 24_BIT failed, perhaps due to format. Try again with 16_BIT", __func__);
- audioFormat = AUDIO_FORMAT_PCM_16_BIT;
- result = openWithFormat(audioFormat);
+ nextFormatToTry = getNextFormatToTry(audioFormat, nextFormatToTry);
+ ALOGD("%s() %#x failed, perhaps due to format. Try again with %#x",
+ __func__, audioFormat, nextFormatToTry);
+ audioFormat = nextFormatToTry;
+ if (audioFormat == AUDIO_FORMAT_DEFAULT) {
+ // Nothing else to try
+ break;
+ }
}
return result;
}
-aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(audio_format_t audioFormat) {
+aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(
+ audio_format_t audioFormat, audio_format_t* nextFormatToTry) {
aaudio_result_t result = AAUDIO_OK;
audio_config_base_t config;
audio_port_handle_t deviceId;
const audio_attributes_t attributes = getAudioAttributesFrom(this);
- mRequestedDeviceId = deviceId = getDeviceId();
+ deviceId = mRequestedDeviceId;
// Fill in config
config.format = audioFormat;
@@ -151,6 +174,10 @@
audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
// Open HAL stream. Set mMmapStream
+ ALOGD("%s trying to open MMAP stream with format=%#x, "
+ "sample_rate=%u, channel_mask=%#x, device=%d",
+ __func__, config.format, config.sample_rate,
+ config.channel_mask, deviceId);
status_t status = MmapStreamInterface::openMmapStream(streamDirection,
&attributes,
&config,
@@ -165,7 +192,11 @@
if (status != OK) {
// This can happen if the resource is busy or the config does
// not match the hardware.
- ALOGD("%s() - openMmapStream() returned status %d", __func__, status);
+ ALOGD("%s() - openMmapStream() returned status=%d, suggested format=%#x, sample_rate=%u, "
+ "channel_mask=%#x",
+ __func__, status, config.format, config.sample_rate, config.format);
+ *nextFormatToTry = config.format != audioFormat ? config.format
+ : *nextFormatToTry;
return AAUDIO_ERROR_UNAVAILABLE;
}
@@ -221,6 +252,9 @@
error:
close();
+ // restore original requests
+ setDeviceId(mRequestedDeviceId);
+ setSessionId(requestedSessionId);
return result;
}
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 3658c58..73e0f61 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -92,7 +92,7 @@
private:
- aaudio_result_t openWithFormat(audio_format_t audioFormat);
+ aaudio_result_t openWithFormat(audio_format_t audioFormat, audio_format_t* nextFormatToTry);
aaudio_result_t createMmapBuffer(android::base::unique_fd* fileDescriptor);
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 9f48f80..d395c25 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -278,7 +278,7 @@
if (result != AAUDIO_OK) goto error;
// This should happen at the end of the start.
- sendServiceEvent(AAUDIO_SERVICE_EVENT_STARTED);
+ sendServiceEvent(AAUDIO_SERVICE_EVENT_STARTED, static_cast<int64_t>(mClientHandle));
setState(AAUDIO_STREAM_STATE_STARTED);
return result;
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 80e4296..5076239 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -25,6 +25,10 @@
name: "libaaudioservice",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AAudioClientTracker.cpp",
"AAudioCommandQueue.cpp",
@@ -70,7 +74,6 @@
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
"packagemanager_aidl-cpp",
- "android.media.audio.common.types-V1-cpp",
],
export_shared_lib_headers: [
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 5c1dda1..9c4f9a5 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -17,7 +17,6 @@
"android.hardware.common.fmq-V1",
"android.hardware.tv.tuner-V1",
],
-
backend: {
java: {
enabled: false,
diff --git a/services/tuner/TunerDemux.cpp b/services/tuner/TunerDemux.cpp
index a6f3a2c..7e07da1 100644
--- a/services/tuner/TunerDemux.cpp
+++ b/services/tuner/TunerDemux.cpp
@@ -26,6 +26,7 @@
#include <aidl/android/hardware/tv/tuner/Result.h>
#include "TunerDvr.h"
+#include "TunerService.h"
#include "TunerTimeFilter.h"
using ::aidl::android::hardware::tv::tuner::IDvr;
@@ -41,23 +42,20 @@
namespace tv {
namespace tuner {
-TunerDemux::TunerDemux(shared_ptr<IDemux> demux, int id) {
+TunerDemux::TunerDemux(const shared_ptr<IDemux> demux, const int id,
+ const shared_ptr<TunerService> tuner) {
mDemux = demux;
mDemuxId = id;
+ mTunerService = tuner;
}
TunerDemux::~TunerDemux() {
mDemux = nullptr;
+ mTunerService = nullptr;
}
::ndk::ScopedAStatus TunerDemux::setFrontendDataSource(
const shared_ptr<ITunerFrontend>& in_frontend) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
int frontendId;
in_frontend->getFrontendId(&frontendId);
@@ -65,43 +63,26 @@
}
::ndk::ScopedAStatus TunerDemux::setFrontendDataSourceById(int frontendId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDemux->setFrontendDataSource(frontendId);
}
::ndk::ScopedAStatus TunerDemux::openFilter(const DemuxFilterType& in_type, int32_t in_bufferSize,
const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IFilter> filter;
shared_ptr<TunerFilter::FilterCallback> filterCb =
::ndk::SharedRefBase::make<TunerFilter::FilterCallback>(in_cb);
shared_ptr<IFilterCallback> cb = filterCb;
auto status = mDemux->openFilter(in_type, in_bufferSize, cb, &filter);
if (status.isOk()) {
- *_aidl_return = ::ndk::SharedRefBase::make<TunerFilter>(filter, filterCb, in_type);
+ *_aidl_return =
+ ::ndk::SharedRefBase::make<TunerFilter>(filter, filterCb, in_type, mTunerService);
}
return status;
}
::ndk::ScopedAStatus TunerDemux::openTimeFilter(shared_ptr<ITunerTimeFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<ITimeFilter> filter;
auto status = mDemux->openTimeFilter(&filter);
if (status.isOk()) {
@@ -113,35 +94,17 @@
::ndk::ScopedAStatus TunerDemux::getAvSyncHwId(const shared_ptr<ITunerFilter>& tunerFilter,
int32_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IFilter> halFilter = (static_cast<TunerFilter*>(tunerFilter.get()))->getHalFilter();
return mDemux->getAvSyncHwId(halFilter, _aidl_return);
}
::ndk::ScopedAStatus TunerDemux::getAvSyncTime(int32_t avSyncHwId, int64_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDemux->getAvSyncTime(avSyncHwId, _aidl_return);
}
::ndk::ScopedAStatus TunerDemux::openDvr(DvrType in_dvbType, int32_t in_bufferSize,
const shared_ptr<ITunerDvrCallback>& in_cb,
shared_ptr<ITunerDvr>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IDvrCallback> callback = ::ndk::SharedRefBase::make<TunerDvr::DvrCallback>(in_cb);
shared_ptr<IDvr> halDvr;
auto res = mDemux->openDvr(in_dvbType, in_bufferSize, callback, &halDvr);
@@ -153,36 +116,15 @@
}
::ndk::ScopedAStatus TunerDemux::connectCiCam(int32_t ciCamId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDemux->connectCiCam(ciCamId);
}
::ndk::ScopedAStatus TunerDemux::disconnectCiCam() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDemux->disconnectCiCam();
}
::ndk::ScopedAStatus TunerDemux::close() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto res = mDemux->close();
- mDemux = nullptr;
-
- return res;
+ return mDemux->close();
}
} // namespace tuner
diff --git a/services/tuner/TunerDemux.h b/services/tuner/TunerDemux.h
index cdb3aa0..0c71987 100644
--- a/services/tuner/TunerDemux.h
+++ b/services/tuner/TunerDemux.h
@@ -32,10 +32,13 @@
namespace tv {
namespace tuner {
+class TunerService;
+
class TunerDemux : public BnTunerDemux {
public:
- TunerDemux(shared_ptr<IDemux> demux, int demuxId);
+ TunerDemux(const shared_ptr<IDemux> demux, const int demuxId,
+ const shared_ptr<TunerService> tuner);
virtual ~TunerDemux();
::ndk::ScopedAStatus setFrontendDataSource(
@@ -60,6 +63,7 @@
private:
shared_ptr<IDemux> mDemux;
int mDemuxId;
+ shared_ptr<TunerService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/TunerDescrambler.cpp b/services/tuner/TunerDescrambler.cpp
index 70aee20..8cc5fe0 100644
--- a/services/tuner/TunerDescrambler.cpp
+++ b/services/tuner/TunerDescrambler.cpp
@@ -46,33 +46,15 @@
::ndk::ScopedAStatus TunerDescrambler::setDemuxSource(
const shared_ptr<ITunerDemux>& in_tunerDemux) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDescrambler->setDemuxSource((static_cast<TunerDemux*>(in_tunerDemux.get()))->getId());
}
::ndk::ScopedAStatus TunerDescrambler::setKeyToken(const vector<uint8_t>& in_keyToken) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDescrambler->setKeyToken(in_keyToken);
}
::ndk::ScopedAStatus TunerDescrambler::addPid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -83,12 +65,6 @@
::ndk::ScopedAStatus TunerDescrambler::removePid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -98,16 +74,7 @@
}
::ndk::ScopedAStatus TunerDescrambler::close() {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto res = mDescrambler->close();
- mDescrambler = nullptr;
-
- return res;
+ return mDescrambler->close();
}
} // namespace tuner
diff --git a/services/tuner/TunerDvr.cpp b/services/tuner/TunerDvr.cpp
index 8776f7e..9a35db8 100644
--- a/services/tuner/TunerDvr.cpp
+++ b/services/tuner/TunerDvr.cpp
@@ -41,32 +41,14 @@
}
::ndk::ScopedAStatus TunerDvr::getQueueDesc(AidlMQDesc* _aidl_return) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDvr->getQueueDesc(_aidl_return);
}
::ndk::ScopedAStatus TunerDvr::configure(const DvrSettings& in_settings) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDvr->configure(in_settings);
}
::ndk::ScopedAStatus TunerDvr::attachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -82,12 +64,6 @@
}
::ndk::ScopedAStatus TunerDvr::detachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -103,46 +79,19 @@
}
::ndk::ScopedAStatus TunerDvr::start() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDvr->start();
}
::ndk::ScopedAStatus TunerDvr::stop() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDvr->stop();
}
::ndk::ScopedAStatus TunerDvr::flush() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mDvr->flush();
}
::ndk::ScopedAStatus TunerDvr::close() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto status = mDvr->close();
- mDvr = nullptr;
-
- return status;
+ return mDvr->close();
}
/////////////// IDvrCallback ///////////////////////
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index e8c7767..fd1f886 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -36,28 +36,28 @@
using namespace std;
-TunerFilter::TunerFilter(shared_ptr<IFilter> filter, shared_ptr<FilterCallback> cb,
- DemuxFilterType type)
+TunerFilter::TunerFilter(const shared_ptr<IFilter> filter, const shared_ptr<FilterCallback> cb,
+ const DemuxFilterType type, const shared_ptr<TunerService> tuner)
: mFilter(filter),
mType(type),
mStarted(false),
mShared(false),
mClientPid(-1),
- mFilterCallback(cb) {}
+ mFilterCallback(cb),
+ mTunerService(tuner) {}
TunerFilter::~TunerFilter() {
- Mutex::Autolock _l(mLock);
- mFilter = nullptr;
+ freeSharedFilterToken("");
+
+ {
+ Mutex::Autolock _l(mLock);
+ mFilter = nullptr;
+ mTunerService = nullptr;
+ }
}
::ndk::ScopedAStatus TunerFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -73,12 +73,6 @@
::ndk::ScopedAStatus TunerFilter::getId(int32_t* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -94,12 +88,6 @@
::ndk::ScopedAStatus TunerFilter::getId64Bit(int64_t* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -115,12 +103,6 @@
::ndk::ScopedAStatus TunerFilter::configure(const DemuxFilterSettings& in_settings) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -132,12 +114,6 @@
::ndk::ScopedAStatus TunerFilter::configureMonitorEvent(int32_t monitorEventType) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -149,12 +125,6 @@
::ndk::ScopedAStatus TunerFilter::configureIpFilterContextId(int32_t cid) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -166,12 +136,6 @@
::ndk::ScopedAStatus TunerFilter::configureAvStreamType(const AvStreamType& in_avStreamType) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -183,12 +147,6 @@
::ndk::ScopedAStatus TunerFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -207,12 +165,6 @@
::ndk::ScopedAStatus TunerFilter::getAvSharedHandle(NativeHandle* out_avMemory,
int64_t* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -225,12 +177,6 @@
::ndk::ScopedAStatus TunerFilter::releaseAvHandle(const NativeHandle& in_handle,
int64_t in_avDataId) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -242,12 +188,6 @@
::ndk::ScopedAStatus TunerFilter::start() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -267,12 +207,6 @@
::ndk::ScopedAStatus TunerFilter::stop() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -291,12 +225,6 @@
::ndk::ScopedAStatus TunerFilter::flush() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -312,12 +240,6 @@
::ndk::ScopedAStatus TunerFilter::close() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -326,7 +248,7 @@
mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
mFilterCallback->detachSharedFilterCallback();
}
- TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerFilter>());
} else {
// Calling from shared process, do not really close this filter.
if (mFilterCallback != nullptr) {
@@ -341,7 +263,6 @@
mFilterCallback->detachCallbacks();
}
auto res = mFilter->close();
- mFilter = nullptr;
mStarted = false;
mShared = false;
mClientPid = -1;
@@ -351,12 +272,6 @@
::ndk::ScopedAStatus TunerFilter::acquireSharedFilterToken(string* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared || mStarted) {
ALOGD("create SharedFilter in wrong state");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -365,7 +280,7 @@
IPCThreadState* ipc = IPCThreadState::self();
mClientPid = ipc->getCallingPid();
- string token = TunerService::getTunerService()->addFilterToShared(this->ref<TunerFilter>());
+ string token = mTunerService->addFilterToShared(this->ref<TunerFilter>());
_aidl_return->assign(token);
mShared = true;
@@ -374,12 +289,6 @@
::ndk::ScopedAStatus TunerFilter::freeSharedFilterToken(const string& /* in_filterToken */) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (!mShared) {
// The filter is not shared or the shared filter has been closed.
return ::ndk::ScopedAStatus::ok();
@@ -390,7 +299,7 @@
mFilterCallback->detachSharedFilterCallback();
}
- TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerFilter>());
mShared = false;
return ::ndk::ScopedAStatus::ok();
@@ -398,24 +307,12 @@
::ndk::ScopedAStatus TunerFilter::getFilterType(DemuxFilterType* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
*_aidl_return = mType;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerFilter::setDelayHint(const FilterDelayHint& in_hint) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFilter->setDelayHint(in_hint);
}
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index 93d8898..f6178c4 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -53,8 +53,9 @@
using AidlMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
-class TunerFilter : public BnTunerFilter {
+class TunerService;
+class TunerFilter : public BnTunerFilter {
public:
class FilterCallback : public BnFilterCallback {
public:
@@ -75,7 +76,8 @@
Mutex mCallbackLock;
};
- TunerFilter(shared_ptr<IFilter> filter, shared_ptr<FilterCallback> cb, DemuxFilterType type);
+ TunerFilter(const shared_ptr<IFilter> filter, const shared_ptr<FilterCallback> cb,
+ const DemuxFilterType type, const shared_ptr<TunerService> tuner);
virtual ~TunerFilter();
::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
@@ -113,6 +115,7 @@
int32_t mClientPid;
shared_ptr<FilterCallback> mFilterCallback;
Mutex mLock;
+ shared_ptr<TunerService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index 5116305..b52a740 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -43,12 +43,6 @@
::ndk::ScopedAStatus TunerFrontend::setCallback(
const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (tunerFrontendCallback == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -60,53 +54,23 @@
}
::ndk::ScopedAStatus TunerFrontend::tune(const FrontendSettings& settings) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->tune(settings);
}
::ndk::ScopedAStatus TunerFrontend::stopTune() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->stopTune();
}
::ndk::ScopedAStatus TunerFrontend::scan(const FrontendSettings& settings,
FrontendScanType frontendScanType) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->scan(settings, frontendScanType);
}
::ndk::ScopedAStatus TunerFrontend::stopScan() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->stopScan();
}
::ndk::ScopedAStatus TunerFrontend::setLnb(const shared_ptr<ITunerLnb>& lnb) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (lnb == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -116,46 +80,19 @@
}
::ndk::ScopedAStatus TunerFrontend::linkCiCamToFrontend(int32_t ciCamId, int32_t* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->linkCiCam(ciCamId, _aidl_return);
}
::ndk::ScopedAStatus TunerFrontend::unlinkCiCamToFrontend(int32_t ciCamId) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->unlinkCiCam(ciCamId);
}
::ndk::ScopedAStatus TunerFrontend::close() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto res = mFrontend->close();
- mFrontend = nullptr;
-
- return res;
+ return mFrontend->close();
}
::ndk::ScopedAStatus TunerFrontend::getStatus(const vector<FrontendStatusType>& in_statusTypes,
vector<FrontendStatus>* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->getStatus(in_statusTypes, _aidl_return);
}
@@ -165,34 +102,16 @@
}
::ndk::ScopedAStatus TunerFrontend::getHardwareInfo(std::string* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->getHardwareInfo(_aidl_return);
}
::ndk::ScopedAStatus TunerFrontend::removeOutputPid(int32_t in_pid) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->removeOutputPid(in_pid);
}
::ndk::ScopedAStatus TunerFrontend::getFrontendStatusReadiness(
const std::vector<FrontendStatusType>& in_statusTypes,
std::vector<FrontendStatusReadiness>* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mFrontend->getFrontendStatusReadiness(in_statusTypes, _aidl_return);
}
diff --git a/services/tuner/TunerLnb.cpp b/services/tuner/TunerLnb.cpp
index 1e143c3..22306e1 100644
--- a/services/tuner/TunerLnb.cpp
+++ b/services/tuner/TunerLnb.cpp
@@ -42,12 +42,6 @@
::ndk::ScopedAStatus TunerLnb::setCallback(
const shared_ptr<ITunerLnbCallback>& in_tunerLnbCallback) {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_tunerLnbCallback == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -59,56 +53,23 @@
}
::ndk::ScopedAStatus TunerLnb::setVoltage(LnbVoltage in_voltage) {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mLnb->setVoltage(in_voltage);
}
::ndk::ScopedAStatus TunerLnb::setTone(LnbTone in_tone) {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mLnb->setTone(in_tone);
}
::ndk::ScopedAStatus TunerLnb::setSatellitePosition(LnbPosition in_position) {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mLnb->setSatellitePosition(in_position);
}
::ndk::ScopedAStatus TunerLnb::sendDiseqcMessage(const vector<uint8_t>& in_diseqcMessage) {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mLnb->sendDiseqcMessage(in_diseqcMessage);
}
::ndk::ScopedAStatus TunerLnb::close() {
- if (mLnb == nullptr) {
- ALOGE("ILnb is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto res = mLnb->close();
- mLnb = nullptr;
-
- return res;
+ return mLnb->close();
}
/////////////// ILnbCallback ///////////////////////
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 4833aaf..514a636 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -27,6 +27,7 @@
#include <android/binder_manager.h>
#include <binder/IPCThreadState.h>
#include <binder/PermissionCache.h>
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <string>
@@ -51,65 +52,45 @@
namespace tv {
namespace tuner {
-shared_ptr<TunerService> TunerService::sTunerService = nullptr;
-
TunerService::TunerService() {
- if (!TunerHelper::checkTunerFeature()) {
- ALOGD("Device doesn't have tuner hardware.");
- return;
+ const string statsServiceName = string() + ITuner::descriptor + "/default";
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(statsServiceName.c_str()));
+ mTuner = ITuner::fromBinder(binder);
+ ALOGE_IF(mTuner == nullptr, "Failed to get Tuner HAL Service");
+
+ mTunerVersion = TUNER_HAL_VERSION_2_0;
+ if (mTuner->getInterfaceVersion(&mTunerVersion).isOk()) {
+ // Tuner AIDL HAL version 1 will be Tuner HAL 2.0
+ mTunerVersion = (mTunerVersion + 1) << 16;
}
+ // Register the tuner resources to TRM.
updateTunerResources();
}
-TunerService::~TunerService() {}
+TunerService::~TunerService() {
+ mTuner = nullptr;
+}
binder_status_t TunerService::instantiate() {
- sTunerService = ::ndk::SharedRefBase::make<TunerService>();
- return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
-}
-
-shared_ptr<TunerService> TunerService::getTunerService() {
- return sTunerService;
-}
-
-bool TunerService::hasITuner() {
- ALOGV("hasITuner");
- if (mTuner != nullptr) {
- return true;
+ shared_ptr<TunerService> tunerService = ::ndk::SharedRefBase::make<TunerService>();
+ bool lazyHal = property_get_bool("ro.tuner.lazyhal", false);
+ if (lazyHal) {
+ return AServiceManager_registerLazyService(tunerService->asBinder().get(),
+ getServiceName());
}
- const string statsServiceName = string() + ITuner::descriptor + "/default";
- if (AServiceManager_isDeclared(statsServiceName.c_str())) {
- ::ndk::SpAIBinder binder(AServiceManager_waitForService(statsServiceName.c_str()));
- mTuner = ITuner::fromBinder(binder);
- } else {
- mTuner = nullptr;
- ALOGE("Failed to get Tuner HAL Service");
- return false;
- }
-
- mTunerVersion = TUNER_HAL_VERSION_2_0;
- // TODO: Enable this after Tuner HAL is frozen.
- // if (mTuner->getInterfaceVersion(&mTunerVersion).isOk()) {
- // // Tuner AIDL HAL version 1 will be Tuner HAL 2.0
- // mTunerVersion = (mTunerVersion + 1) << 16;
- //}
-
- return true;
+ return AServiceManager_addService(tunerService->asBinder().get(), getServiceName());
}
::ndk::ScopedAStatus TunerService::openDemux(int32_t /* in_demuxHandle */,
shared_ptr<ITunerDemux>* _aidl_return) {
ALOGV("openDemux");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
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]);
+ *_aidl_return =
+ ::ndk::SharedRefBase::make<TunerDemux>(demux, id[0], this->ref<TunerService>());
}
return status;
@@ -117,41 +98,19 @@
::ndk::ScopedAStatus TunerService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
ALOGV("getDemuxCaps");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->getDemuxCaps(_aidl_return);
}
::ndk::ScopedAStatus TunerService::getFrontendIds(vector<int32_t>* ids) {
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->getFrontendIds(ids);
}
::ndk::ScopedAStatus TunerService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->getFrontendInfo(id, _aidl_return);
}
::ndk::ScopedAStatus TunerService::openFrontend(int32_t frontendHandle,
shared_ptr<ITunerFrontend>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
shared_ptr<IFrontend> frontend;
auto status = mTuner->openFrontendById(id, &frontend);
@@ -163,12 +122,6 @@
}
::ndk::ScopedAStatus TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<ILnb> lnb;
int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
auto status = mTuner->openLnbById(id, &lnb);
@@ -181,12 +134,6 @@
::ndk::ScopedAStatus TunerService::openLnbByName(const string& lnbName,
shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
vector<int32_t> id;
shared_ptr<ILnb> lnb;
auto status = mTuner->openLnbByName(lnbName, &id, &lnb);
@@ -199,12 +146,6 @@
::ndk::ScopedAStatus TunerService::openDescrambler(int32_t /*descramblerHandle*/,
shared_ptr<ITunerDescrambler>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
shared_ptr<IDescrambler> descrambler;
// int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
auto status = mTuner->openDescrambler(&descrambler);
@@ -216,7 +157,6 @@
}
::ndk::ScopedAStatus TunerService::getTunerHalVersion(int* _aidl_return) {
- hasITuner();
*_aidl_return = mTunerVersion;
return ::ndk::ScopedAStatus::ok();
}
@@ -224,12 +164,6 @@
::ndk::ScopedAStatus TunerService::openSharedFilter(const string& in_filterToken,
const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -261,34 +195,16 @@
}
::ndk::ScopedAStatus TunerService::setLna(bool bEnable) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->setLna(bEnable);
}
::ndk::ScopedAStatus TunerService::setMaxNumberOfFrontends(FrontendType in_frontendType,
int32_t in_maxNumber) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->setMaxNumberOfFrontends(in_frontendType, in_maxNumber);
}
::ndk::ScopedAStatus TunerService::getMaxNumberOfFrontends(FrontendType in_frontendType,
int32_t* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTuner->getMaxNumberOfFrontends(in_frontendType, _aidl_return);
}
@@ -309,11 +225,6 @@
}
void TunerService::updateTunerResources() {
- if (!hasITuner()) {
- ALOGE("Failed to updateTunerResources");
- return;
- }
-
TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
}
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 7fc2aa4..6435e17 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -86,10 +86,7 @@
string addFilterToShared(const shared_ptr<TunerFilter>& sharedFilter);
void removeSharedFilter(const shared_ptr<TunerFilter>& sharedFilter);
- static shared_ptr<TunerService> getTunerService();
-
private:
- bool hasITuner();
void updateTunerResources();
vector<TunerFrontendInfo> getTRMFrontendInfos();
vector<int32_t> getTRMLnbHandles();
@@ -98,8 +95,6 @@
int mTunerVersion = TUNER_HAL_VERSION_UNKNOWN;
Mutex mSharedFiltersLock;
map<string, shared_ptr<TunerFilter>> mSharedFilters;
-
- static shared_ptr<TunerService> sTunerService;
};
} // namespace tuner
diff --git a/services/tuner/TunerTimeFilter.cpp b/services/tuner/TunerTimeFilter.cpp
index 73cd6b4..f5094b9 100644
--- a/services/tuner/TunerTimeFilter.cpp
+++ b/services/tuner/TunerTimeFilter.cpp
@@ -39,33 +39,14 @@
}
::ndk::ScopedAStatus TunerTimeFilter::setTimeStamp(int64_t timeStamp) {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTimeFilter->setTimeStamp(timeStamp);
}
::ndk::ScopedAStatus TunerTimeFilter::clearTimeStamp() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
return mTimeFilter->clearTimeStamp();
}
::ndk::ScopedAStatus TunerTimeFilter::getSourceTime(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
auto status = mTimeFilter->getSourceTime(_aidl_return);
if (!status.isOk()) {
*_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
@@ -74,13 +55,6 @@
}
::ndk::ScopedAStatus TunerTimeFilter::getTimeStamp(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
auto status = mTimeFilter->getTimeStamp(_aidl_return);
if (!status.isOk()) {
*_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
@@ -89,16 +63,7 @@
}
::ndk::ScopedAStatus TunerTimeFilter::close() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- auto status = mTimeFilter->close();
- mTimeFilter = nullptr;
-
- return status;
+ return mTimeFilter->close();
}
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlDemux.cpp b/services/tuner/hidl/TunerHidlDemux.cpp
index a8151d2..bbb7782 100644
--- a/services/tuner/hidl/TunerHidlDemux.cpp
+++ b/services/tuner/hidl/TunerHidlDemux.cpp
@@ -20,6 +20,7 @@
#include "TunerHidlDvr.h"
#include "TunerHidlFilter.h"
+#include "TunerHidlService.h"
#include "TunerHidlTimeFilter.h"
using ::aidl::android::hardware::tv::tuner::DemuxFilterSubType;
@@ -42,23 +43,20 @@
namespace tv {
namespace tuner {
-TunerHidlDemux::TunerHidlDemux(sp<IDemux> demux, int id) {
+TunerHidlDemux::TunerHidlDemux(const sp<IDemux> demux, const int id,
+ const shared_ptr<TunerHidlService> tuner) {
mDemux = demux;
mDemuxId = id;
+ mTunerService = tuner;
}
TunerHidlDemux::~TunerHidlDemux() {
mDemux = nullptr;
+ mTunerService = nullptr;
}
::ndk::ScopedAStatus TunerHidlDemux::setFrontendDataSource(
const shared_ptr<ITunerFrontend>& in_frontend) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
int frontendId;
in_frontend->getFrontendId(&frontendId);
HidlResult res = mDemux->setFrontendDataSource(frontendId);
@@ -69,12 +67,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::setFrontendDataSourceById(int frontendId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->setFrontendDataSource(frontendId);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -86,12 +78,6 @@
int32_t in_bufferSize,
const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlDemuxFilterMainType mainType = static_cast<HidlDemuxFilterMainType>(in_type.mainType);
HidlDemuxFilterType filterType{
.mainType = mainType,
@@ -132,17 +118,12 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
- *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, filterCb, in_type);
+ *_aidl_return =
+ ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, filterCb, in_type, mTunerService);
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlDemux::openTimeFilter(shared_ptr<ITunerTimeFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlITimeFilter> filterSp;
mDemux->openTimeFilter([&](HidlResult r, const sp<HidlITimeFilter>& filter) {
@@ -159,12 +140,6 @@
::ndk::ScopedAStatus TunerHidlDemux::getAvSyncHwId(const shared_ptr<ITunerFilter>& tunerFilter,
int32_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
uint32_t avSyncHwId;
HidlResult res;
sp<HidlIFilter> halFilter = static_cast<TunerHidlFilter*>(tunerFilter.get())->getHalFilter();
@@ -181,12 +156,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::getAvSyncTime(int32_t avSyncHwId, int64_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
uint64_t time;
HidlResult res;
mDemux->getAvSyncTime(static_cast<uint32_t>(avSyncHwId), [&](HidlResult r, uint64_t ts) {
@@ -204,12 +173,6 @@
::ndk::ScopedAStatus TunerHidlDemux::openDvr(DvrType in_dvbType, int32_t in_bufferSize,
const shared_ptr<ITunerDvrCallback>& in_cb,
shared_ptr<ITunerDvr>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res;
sp<HidlIDvrCallback> callback = new TunerHidlDvr::DvrCallback(in_cb);
sp<HidlIDvr> hidlDvr;
@@ -228,12 +191,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::connectCiCam(int32_t ciCamId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->connectCiCam(static_cast<uint32_t>(ciCamId));
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -242,12 +199,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::disconnectCiCam() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->disconnectCiCam();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -256,15 +207,7 @@
}
::ndk::ScopedAStatus TunerHidlDemux::close() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->close();
- mDemux = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlDemux.h b/services/tuner/hidl/TunerHidlDemux.h
index d535da6..94a715e 100644
--- a/services/tuner/hidl/TunerHidlDemux.h
+++ b/services/tuner/hidl/TunerHidlDemux.h
@@ -37,9 +37,12 @@
namespace tv {
namespace tuner {
+class TunerHidlService;
+
class TunerHidlDemux : public BnTunerDemux {
public:
- TunerHidlDemux(sp<HidlIDemux> demux, int demuxId);
+ TunerHidlDemux(const sp<HidlIDemux> demux, const int demuxId,
+ const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlDemux();
::ndk::ScopedAStatus setFrontendDataSource(
@@ -64,6 +67,7 @@
private:
sp<HidlIDemux> mDemux;
int mDemuxId;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlDescrambler.cpp b/services/tuner/hidl/TunerHidlDescrambler.cpp
index dd8cd9c..51b7ede 100644
--- a/services/tuner/hidl/TunerHidlDescrambler.cpp
+++ b/services/tuner/hidl/TunerHidlDescrambler.cpp
@@ -45,12 +45,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::setDemuxSource(
const shared_ptr<ITunerDemux>& in_tunerDemux) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->setDemuxSource(
static_cast<TunerHidlDemux*>(in_tunerDemux.get())->getId());
if (res != HidlResult::SUCCESS) {
@@ -60,12 +54,6 @@
}
::ndk::ScopedAStatus TunerHidlDescrambler::setKeyToken(const vector<uint8_t>& in_keyToken) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->setKeyToken(in_keyToken);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -75,12 +63,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::addPid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
sp<HidlIFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -94,12 +76,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::removePid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
sp<HidlIFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -112,15 +88,7 @@
}
::ndk::ScopedAStatus TunerHidlDescrambler::close() {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->close();
- mDescrambler = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlDvr.cpp b/services/tuner/hidl/TunerHidlDvr.cpp
index 1a619d5..50d92de 100644
--- a/services/tuner/hidl/TunerHidlDvr.cpp
+++ b/services/tuner/hidl/TunerHidlDvr.cpp
@@ -54,12 +54,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::getQueueDesc(AidlMQDesc* _aidl_return) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
MQDesc dvrMQDesc;
HidlResult res;
mDvr->getQueueDesc([&](HidlResult r, const MQDesc& desc) {
@@ -77,12 +71,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::configure(const DvrSettings& in_settings) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->configure(getHidlDvrSettings(in_settings));
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -91,12 +79,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::attachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -116,12 +98,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::detachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -141,12 +117,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::start() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->start();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -155,12 +125,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::stop() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->stop();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -169,12 +133,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::flush() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->flush();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -183,15 +141,7 @@
}
::ndk::ScopedAStatus TunerHidlDvr::close() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->close();
- mDvr = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index fe74a5c..d4a3db5 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -92,31 +92,32 @@
namespace tv {
namespace tuner {
-TunerHidlFilter::TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb,
- DemuxFilterType type)
+TunerHidlFilter::TunerHidlFilter(const sp<HidlIFilter> filter, const sp<FilterCallback> cb,
+ const DemuxFilterType type,
+ const shared_ptr<TunerHidlService> tuner)
: mFilter(filter),
mType(type),
mStarted(false),
mShared(false),
mClientPid(-1),
- mFilterCallback(cb) {
+ mFilterCallback(cb),
+ mTunerService(tuner) {
mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
}
TunerHidlFilter::~TunerHidlFilter() {
- Mutex::Autolock _l(mLock);
- mFilter = nullptr;
- mFilter_1_1 = nullptr;
+ freeSharedFilterToken("");
+
+ {
+ Mutex::Autolock _l(mLock);
+ mFilter = nullptr;
+ mFilter_1_1 = nullptr;
+ mTunerService = nullptr;
+ }
}
::ndk::ScopedAStatus TunerHidlFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -146,12 +147,6 @@
::ndk::ScopedAStatus TunerHidlFilter::getId(int32_t* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -200,12 +195,6 @@
::ndk::ScopedAStatus TunerHidlFilter::configure(const DemuxFilterSettings& in_settings) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -318,12 +307,6 @@
::ndk::ScopedAStatus TunerHidlFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -378,12 +361,6 @@
::ndk::ScopedAStatus TunerHidlFilter::releaseAvHandle(const NativeHandle& in_handle,
int64_t in_avDataId) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -407,12 +384,6 @@
::ndk::ScopedAStatus TunerHidlFilter::start() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -434,12 +405,6 @@
::ndk::ScopedAStatus TunerHidlFilter::stop() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -461,12 +426,6 @@
::ndk::ScopedAStatus TunerHidlFilter::flush() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -487,12 +446,6 @@
::ndk::ScopedAStatus TunerHidlFilter::close() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -501,7 +454,7 @@
mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
mFilterCallback->detachSharedFilterCallback();
}
- TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerHidlFilter>());
} else {
// Calling from shared process, do not really close this filter.
if (mFilterCallback != nullptr) {
@@ -516,8 +469,6 @@
mFilterCallback->detachCallbacks();
}
HidlResult res = mFilter->close();
- mFilter = nullptr;
- mFilter_1_1 = nullptr;
mStarted = false;
mShared = false;
mClientPid = -1;
@@ -531,12 +482,6 @@
::ndk::ScopedAStatus TunerHidlFilter::acquireSharedFilterToken(string* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared || mStarted) {
ALOGD("create SharedFilter in wrong state");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -545,8 +490,7 @@
IPCThreadState* ipc = IPCThreadState::self();
mClientPid = ipc->getCallingPid();
- string token =
- TunerHidlService::getTunerService()->addFilterToShared(this->ref<TunerHidlFilter>());
+ string token = mTunerService->addFilterToShared(this->ref<TunerHidlFilter>());
_aidl_return->assign(token);
mShared = true;
@@ -555,12 +499,6 @@
::ndk::ScopedAStatus TunerHidlFilter::freeSharedFilterToken(const string& /* in_filterToken */) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (!mShared) {
// The filter is not shared or the shared filter has been closed.
return ::ndk::ScopedAStatus::ok();
@@ -571,19 +509,13 @@
mFilterCallback->detachSharedFilterCallback();
}
- TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerHidlFilter>());
mShared = false;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlFilter::getFilterType(DemuxFilterType* _aidl_return) {
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
*_aidl_return = mType;
return ::ndk::ScopedAStatus::ok();
}
diff --git a/services/tuner/hidl/TunerHidlFilter.h b/services/tuner/hidl/TunerHidlFilter.h
index 63c7a1b..a58eeca 100644
--- a/services/tuner/hidl/TunerHidlFilter.h
+++ b/services/tuner/hidl/TunerHidlFilter.h
@@ -114,6 +114,8 @@
const static int IP_V4_LENGTH = 4;
const static int IP_V6_LENGTH = 16;
+class TunerHidlService;
+
class TunerHidlFilter : public BnTunerFilter {
public:
class FilterCallback : public HidlIFilterCallback {
@@ -165,7 +167,8 @@
Mutex mCallbackLock;
};
- TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb, DemuxFilterType type);
+ TunerHidlFilter(const sp<HidlIFilter> filter, const sp<FilterCallback> cb,
+ const DemuxFilterType type, const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlFilter();
::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
@@ -230,6 +233,7 @@
int32_t mClientPid;
sp<FilterCallback> mFilterCallback;
Mutex mLock;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlFrontend.cpp b/services/tuner/hidl/TunerHidlFrontend.cpp
index 03957f3..7ffb2a4 100644
--- a/services/tuner/hidl/TunerHidlFrontend.cpp
+++ b/services/tuner/hidl/TunerHidlFrontend.cpp
@@ -176,26 +176,23 @@
namespace tv {
namespace tuner {
-TunerHidlFrontend::TunerHidlFrontend(sp<HidlIFrontend> frontend, int id) {
+TunerHidlFrontend::TunerHidlFrontend(const sp<HidlIFrontend> frontend, const int id,
+ const shared_ptr<TunerHidlService> tuner) {
mFrontend = frontend;
mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
mId = id;
+ mTunerService = tuner;
}
TunerHidlFrontend::~TunerHidlFrontend() {
mFrontend = nullptr;
mFrontend_1_1 = nullptr;
mId = -1;
+ mTunerService = nullptr;
}
::ndk::ScopedAStatus TunerHidlFrontend::setCallback(
const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (tunerFrontendCallback == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -211,12 +208,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::tune(const FrontendSettings& settings) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
HidlFrontendSettings frontendSettings;
HidlFrontendSettingsExt1_1 frontendSettingsExt;
@@ -234,12 +225,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::stopTune() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mFrontend->stopTune();
if (status == HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::ok();
@@ -250,12 +235,6 @@
::ndk::ScopedAStatus TunerHidlFrontend::scan(const FrontendSettings& settings,
FrontendScanType frontendScanType) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
HidlFrontendSettings frontendSettings;
HidlFrontendSettingsExt1_1 frontendSettingsExt;
@@ -276,12 +255,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::stopScan() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mFrontend->stopScan();
if (status == HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::ok();
@@ -291,12 +264,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::setLnb(const shared_ptr<ITunerLnb>& lnb) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (lnb == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -349,18 +316,8 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::close() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- TunerHidlService::getTunerService()->removeFrontend(this->ref<TunerHidlFrontend>());
-
+ mTunerService->removeFrontend(this->ref<TunerHidlFrontend>());
HidlResult status = mFrontend->close();
- mFrontend = nullptr;
- mFrontend_1_1 = nullptr;
-
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
@@ -370,12 +327,6 @@
::ndk::ScopedAStatus TunerHidlFrontend::getStatus(const vector<FrontendStatusType>& in_statusTypes,
vector<FrontendStatus>* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
vector<HidlFrontendStatus> status;
vector<HidlFrontendStatusExt1_1> statusExt;
@@ -442,11 +393,6 @@
}
void TunerHidlFrontend::setLna(bool bEnable) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return;
- }
-
mFrontend->setLna(bEnable);
}
diff --git a/services/tuner/hidl/TunerHidlFrontend.h b/services/tuner/hidl/TunerHidlFrontend.h
index f698655..f54127b 100644
--- a/services/tuner/hidl/TunerHidlFrontend.h
+++ b/services/tuner/hidl/TunerHidlFrontend.h
@@ -64,9 +64,12 @@
namespace tv {
namespace tuner {
+class TunerHidlService;
+
class TunerHidlFrontend : public BnTunerFrontend {
public:
- TunerHidlFrontend(sp<HidlIFrontend> frontend, int id);
+ TunerHidlFrontend(const sp<HidlIFrontend> frontend, const int id,
+ const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlFrontend();
::ndk::ScopedAStatus setCallback(
@@ -118,6 +121,7 @@
int mId;
sp<HidlIFrontend> mFrontend;
sp<::android::hardware::tv::tuner::V1_1::IFrontend> mFrontend_1_1;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index 6f55f1e..aa03316 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -24,6 +24,7 @@
#include <android/binder_manager.h>
#include <binder/IPCThreadState.h>
#include <binder/PermissionCache.h>
+#include <cutils/properties.h>
#include <utils/Log.h>
#include "TunerHelper.h"
@@ -46,7 +47,6 @@
using ::aidl::android::hardware::tv::tuner::FrontendIsdbtTimeInterleaveMode;
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::Result;
-using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
using ::android::IPCThreadState;
using ::android::PermissionCache;
using ::android::hardware::hidl_vec;
@@ -63,47 +63,9 @@
namespace tv {
namespace tuner {
-shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
-
TunerHidlService::TunerHidlService() {
- if (!TunerHelper::checkTunerFeature()) {
- ALOGD("Device doesn't have tuner hardware.");
- return;
- }
-
- updateTunerResources();
-}
-
-TunerHidlService::~TunerHidlService() {
- mOpenedFrontends.clear();
- mLnaStatus = -1;
-}
-
-binder_status_t TunerHidlService::instantiate() {
- if (HidlITuner::getService() == nullptr) {
- ALOGD("Failed to get ITuner HIDL HAL");
- return STATUS_NAME_NOT_FOUND;
- }
-
- sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
- return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
-}
-
-shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
- return sTunerService;
-}
-
-bool TunerHidlService::hasITuner() {
- ALOGV("hasITuner");
- if (mTuner != nullptr) {
- return true;
- }
-
mTuner = HidlITuner::getService();
- if (mTuner == nullptr) {
- ALOGE("Failed to get ITuner service");
- return false;
- }
+ ALOGE_IF(mTuner == nullptr, "Failed to get ITuner service");
mTunerVersion = TUNER_HAL_VERSION_1_0;
mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
@@ -113,23 +75,35 @@
ALOGD("Failed to get ITuner_1_1 service");
}
- return true;
+ // Register tuner resources to TRM.
+ updateTunerResources();
}
-bool TunerHidlService::hasITuner_1_1() {
- ALOGV("hasITuner_1_1");
- hasITuner();
- return (mTunerVersion == TUNER_HAL_VERSION_1_1);
+TunerHidlService::~TunerHidlService() {
+ mOpenedFrontends.clear();
+ mLnaStatus = -1;
+ mTuner = nullptr;
+ mTuner_1_1 = nullptr;
+}
+
+binder_status_t TunerHidlService::instantiate() {
+ if (HidlITuner::getService() == nullptr) {
+ ALOGD("Failed to get ITuner HIDL HAL");
+ return STATUS_NAME_NOT_FOUND;
+ }
+
+ shared_ptr<TunerHidlService> tunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
+ bool lazyHal = property_get_bool("ro.tuner.lazyhal", false);
+ if (lazyHal) {
+ return AServiceManager_registerLazyService(tunerService->asBinder().get(),
+ getServiceName());
+ }
+ return AServiceManager_addService(tunerService->asBinder().get(), getServiceName());
}
::ndk::ScopedAStatus TunerHidlService::openDemux(int32_t /* in_demuxHandle */,
shared_ptr<ITunerDemux>* _aidl_return) {
ALOGV("openDemux");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
uint32_t id;
sp<IDemux> demuxSp = nullptr;
@@ -140,7 +114,8 @@
ALOGD("open demux, id = %d", demuxId);
});
if (res == HidlResult::SUCCESS) {
- *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id);
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id,
+ this->ref<TunerHidlService>());
return ::ndk::ScopedAStatus::ok();
}
@@ -150,11 +125,6 @@
::ndk::ScopedAStatus TunerHidlService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
ALOGV("getDemuxCaps");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
HidlDemuxCapabilities caps;
mTuner->getDemuxCaps([&](HidlResult r, const HidlDemuxCapabilities& demuxCaps) {
@@ -171,11 +141,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getFrontendIds(vector<int32_t>* ids) {
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
hidl_vec<HidlFrontendId> feIds;
HidlResult res = getHidlFrontendIds(feIds);
if (res != HidlResult::SUCCESS) {
@@ -188,12 +153,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlFrontendInfo info;
HidlResult res = getHidlFrontendInfo(id, info);
if (res != HidlResult::SUCCESS) {
@@ -202,7 +161,7 @@
HidlFrontendDtmbCapabilities dtmbCaps;
if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
- if (!hasITuner_1_1()) {
+ if (mTuner_1_1 == nullptr) {
ALOGE("ITuner_1_1 service is not init.");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -224,12 +183,6 @@
::ndk::ScopedAStatus TunerHidlService::openFrontend(int32_t frontendHandle,
shared_ptr<ITunerFrontend>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlIFrontend> frontend;
int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
@@ -241,8 +194,8 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
- shared_ptr<TunerHidlFrontend> tunerFrontend =
- ::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
+ shared_ptr<TunerHidlFrontend> tunerFrontend = ::ndk::SharedRefBase::make<TunerHidlFrontend>(
+ frontend, id, this->ref<TunerHidlService>());
if (mLnaStatus != -1) {
tunerFrontend->setLna(mLnaStatus == 1);
}
@@ -255,12 +208,6 @@
}
::ndk::ScopedAStatus TunerHidlService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlILnb> lnb;
int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
@@ -278,12 +225,6 @@
::ndk::ScopedAStatus TunerHidlService::openLnbByName(const string& lnbName,
shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
int lnbId;
HidlResult status;
sp<HidlILnb> lnb;
@@ -302,12 +243,6 @@
::ndk::ScopedAStatus TunerHidlService::openDescrambler(
int32_t /*descramblerHandle*/, shared_ptr<ITunerDescrambler>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlIDescrambler> descrambler;
//int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
@@ -324,7 +259,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getTunerHalVersion(int* _aidl_return) {
- hasITuner();
*_aidl_return = mTunerVersion;
return ::ndk::ScopedAStatus::ok();
}
@@ -332,7 +266,7 @@
::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (!hasITuner()) {
+ if (mTuner == nullptr) {
ALOGE("get ITuner failed");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -369,7 +303,7 @@
}
::ndk::ScopedAStatus TunerHidlService::setLna(bool bEnable) {
- if (!hasITuner()) {
+ if (mTuner == nullptr) {
ALOGE("get ITuner failed");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -428,11 +362,6 @@
}
void TunerHidlService::updateTunerResources() {
- if (!hasITuner()) {
- ALOGE("Failed to updateTunerResources");
- return;
- }
-
TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
}
diff --git a/services/tuner/hidl/TunerHidlService.h b/services/tuner/hidl/TunerHidlService.h
index 2252d35..6f43d43 100644
--- a/services/tuner/hidl/TunerHidlService.h
+++ b/services/tuner/hidl/TunerHidlService.h
@@ -99,11 +99,7 @@
void removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter);
void removeFrontend(const shared_ptr<TunerHidlFrontend>& frontend);
- static shared_ptr<TunerHidlService> getTunerService();
-
private:
- bool hasITuner();
- bool hasITuner_1_1();
void updateTunerResources();
vector<TunerFrontendInfo> getTRMFrontendInfos();
vector<int32_t> getTRMLnbHandles();
@@ -121,8 +117,6 @@
Mutex mOpenedFrontendsLock;
unordered_set<shared_ptr<TunerHidlFrontend>> mOpenedFrontends;
int mLnaStatus = -1;
-
- static shared_ptr<TunerHidlService> sTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlTimeFilter.cpp b/services/tuner/hidl/TunerHidlTimeFilter.cpp
index d0606d6..06a71d0 100644
--- a/services/tuner/hidl/TunerHidlTimeFilter.cpp
+++ b/services/tuner/hidl/TunerHidlTimeFilter.cpp
@@ -43,12 +43,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::setTimeStamp(int64_t timeStamp) {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mTimeFilter->setTimeStamp(static_cast<uint64_t>(timeStamp));
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
@@ -57,12 +51,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::clearTimeStamp() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mTimeFilter->clearTimeStamp();
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
@@ -71,13 +59,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::getSourceTime(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
mTimeFilter->getSourceTime([&](HidlResult r, uint64_t t) {
status = r;
@@ -91,13 +72,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::getTimeStamp(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
mTimeFilter->getTimeStamp([&](HidlResult r, uint64_t t) {
status = r;
@@ -111,15 +85,7 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::close() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mTimeFilter->close();
- mTimeFilter = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/main_tunerservice.cpp b/services/tuner/main_tunerservice.cpp
index 43ff95c..f8311ff 100644
--- a/services/tuner/main_tunerservice.cpp
+++ b/services/tuner/main_tunerservice.cpp
@@ -32,6 +32,7 @@
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
+ ProcessState::self()->setThreadPoolMaxThreadCount(8);
// Check legacy HIDL HAL first. If it's not existed, use AIDL HAL.
binder_status_t status = TunerHidlService::instantiate();
@@ -40,7 +41,6 @@
CHECK(status == STATUS_OK);
}
- ProcessState::self()->setThreadPoolMaxThreadCount(8);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return EXIT_FAILURE; // should not reached
diff --git a/services/tuner/mediatuner.rc b/services/tuner/mediatuner.rc
index 6a3e199..90a0090 100644
--- a/services/tuner/mediatuner.rc
+++ b/services/tuner/mediatuner.rc
@@ -1,8 +1,14 @@
+# media.tuner service is not started by default unless tuner.server.enable is set
+# as "true" by TRM (Tuner Resource Manager). TRM checks ro.tuner.lazyhal, if it
+# isn't true , TRM sets tuner.server.enable as "true".
service media.tuner /system/bin/mediatuner
class main
group media
ioprio rt 4
- onrestart restart vendor.tuner-hal-1-0
- onrestart restart vendor.tuner-hal-1-1
- onrestart restart vendor.tuner-default
task_profiles ProcessCapacityHigh HighPerformance
+ interface aidl media.tuner
+ oneshot
+ disabled
+
+on property:tuner.server.enable=true
+ enable media.tuner