Merge "Fix makefile include hierarchy"
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index e9dcbdb..47580f8 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -83,4 +83,12 @@
* can retry after receiving this callback.
*/
oneway void onCameraAccessPrioritiesChanged();
+
+ /**
+ * Notify registered clients about cameras being opened/closed.
+ * Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission
+ * will receive such callbacks.
+ */
+ oneway void onCameraOpened(String cameraId, String clientPackageId);
+ oneway void onCameraClosed(String cameraId);
}
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index e945ba0..cba6c73 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -92,6 +92,12 @@
}
virtual binder::Status onCameraAccessPrioritiesChanged();
+ virtual binder::Status onCameraOpened(const String16&, const String16&) {
+ return binder::Status::ok();
+ }
+ virtual binder::Status onCameraClosed(const String16&) {
+ return binder::Status::ok();
+ }
private:
const wp<CameraManagerGlobal> mCameraManager;
diff --git a/camera/ndk/include/camera/NdkCameraMetadata.h b/camera/ndk/include/camera/NdkCameraMetadata.h
index 9bbfb83..4a99391 100644
--- a/camera/ndk/include/camera/NdkCameraMetadata.h
+++ b/camera/ndk/include/camera/NdkCameraMetadata.h
@@ -36,6 +36,7 @@
#ifndef _NDK_CAMERA_METADATA_H
#define _NDK_CAMERA_METADATA_H
+#include <stdbool.h>
#include <stdint.h>
#include <sys/cdefs.h>
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 8fe029a..dc5afc5 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -95,6 +95,17 @@
return binder::Status::ok();
}
+ virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
+ const String16& /*clientPackageName*/) {
+ // No op
+ return binder::Status::ok();
+ }
+
+ virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+ // No op
+ return binder::Status::ok();
+ }
+
bool waitForNumCameras(size_t num) const {
Mutex::Autolock l(mLock);
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 51274d1..c2cc429 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -1071,6 +1071,7 @@
Vector<uint8_t> keySetId;
readVector(data, keySetId);
DrmPlugin::OfflineLicenseState state;
+ state = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
status_t result = getOfflineLicenseState(keySetId, &state);
reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
reply->writeInt32(result);
diff --git a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
index caff393..121a4e2 100644
--- a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
@@ -76,10 +76,21 @@
android::status_t InitDataParser::parsePssh(const Vector<uint8_t>& initData,
Vector<const uint8_t*>* keyIds) {
+ // Description of PSSH format:
+ // https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
size_t readPosition = 0;
- // Validate size field
uint32_t expectedSize = initData.size();
+ const char psshIdentifier[4] = {'p', 's', 's', 'h'};
+ const uint8_t psshVersion1[4] = {1, 0, 0, 0};
+ uint32_t keyIdCount = 0;
+ size_t headerSize = sizeof(expectedSize) + sizeof(psshIdentifier) +
+ sizeof(psshVersion1) + kSystemIdSize + sizeof(keyIdCount);
+ if (initData.size() < headerSize) {
+ return android::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ // Validate size field
expectedSize = htonl(expectedSize);
if (memcmp(&initData[readPosition], &expectedSize,
sizeof(expectedSize)) != 0) {
@@ -88,7 +99,6 @@
readPosition += sizeof(expectedSize);
// Validate PSSH box identifier
- const char psshIdentifier[4] = {'p', 's', 's', 'h'};
if (memcmp(&initData[readPosition], psshIdentifier,
sizeof(psshIdentifier)) != 0) {
return android::ERROR_DRM_CANNOT_HANDLE;
@@ -96,7 +106,6 @@
readPosition += sizeof(psshIdentifier);
// Validate EME version number
- const uint8_t psshVersion1[4] = {1, 0, 0, 0};
if (memcmp(&initData[readPosition], psshVersion1,
sizeof(psshVersion1)) != 0) {
return android::ERROR_DRM_CANNOT_HANDLE;
@@ -110,12 +119,14 @@
readPosition += kSystemIdSize;
// Read key ID count
- uint32_t keyIdCount;
memcpy(&keyIdCount, &initData[readPosition], sizeof(keyIdCount));
keyIdCount = ntohl(keyIdCount);
readPosition += sizeof(keyIdCount);
- if (readPosition + ((uint64_t)keyIdCount * kKeyIdSize) !=
- initData.size() - sizeof(uint32_t)) {
+
+ uint64_t psshSize = 0;
+ if (__builtin_mul_overflow(keyIdCount, kKeyIdSize, &psshSize) ||
+ __builtin_add_overflow(readPosition, psshSize, &psshSize) ||
+ psshSize != initData.size() - sizeof(uint32_t) /* DataSize(0) */) {
return android::ERROR_DRM_CANNOT_HANDLE;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index 3ecf6d5..f164f28 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -136,8 +136,6 @@
return Void();
}
- base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
-
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 7cb5a38..d74bc53 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -809,11 +809,6 @@
// count - number of secure stops
// list of fixed length secure stops
size_t countBufferSize = sizeof(uint32_t);
- if (input.size() < countBufferSize) {
- // SafetyNet logging
- android_errorWriteLog(0x534e4554, "144766455");
- return Status::BAD_VALUE;
- }
uint32_t count = 0;
sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index 97f114a..7472b6d 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -30,6 +30,7 @@
name: "libstagefright_bufferpool@2.0.1",
defaults: ["libstagefright_bufferpool@2.0-default"],
vendor_available: true,
+ min_sdk_version: "29",
cflags: [
"-DBUFFERPOOL_CLONE_HANDLES",
],
diff --git a/media/codec2/components/flac/Android.bp b/media/codec2/components/flac/Android.bp
index e5eb51d..48cc51b 100644
--- a/media/codec2/components/flac/Android.bp
+++ b/media/codec2/components/flac/Android.bp
@@ -23,8 +23,11 @@
srcs: ["C2SoftFlacEnc.cpp"],
- static_libs: [
+ shared_libs: [
"libaudioutils",
+ ],
+
+ static_libs: [
"libFLAC",
],
}
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
index 95eb909..7b6f21a 100644
--- a/media/codec2/components/raw/C2SoftRawDec.cpp
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -58,7 +58,7 @@
addParameter(
DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
.withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).inRange(8000, 384000)})
+ .withFields({C2F(mSampleRate, value).greaterThan(0)})
.withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
.build());
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index ebc7a8f..a23db16 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -455,8 +455,8 @@
const C2ConstGraphicBlock inBuffer =
inputBuffer->data().graphicBlocks().front();
- if (inBuffer.width() != mSize->width ||
- inBuffer.height() != mSize->height) {
+ if (inBuffer.width() < mSize->width ||
+ inBuffer.height() < mSize->height) {
ALOGE("unexpected Input buffer attributes %d(%d) x %d(%d)",
inBuffer.width(), mSize->width, inBuffer.height(),
mSize->height);
@@ -467,8 +467,8 @@
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
vpx_image_t raw_frame;
const C2PlanarLayout &layout = rView->layout();
- uint32_t width = rView->width();
- uint32_t height = rView->height();
+ uint32_t width = mSize->width;
+ uint32_t height = mSize->height;
if (width > 0x8000 || height > 0x8000) {
ALOGE("Image too big: %u x %u", width, height);
work->result = C2_BAD_VALUE;
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
index e3bbfd6..b0eabb9 100644
--- a/media/codec2/core/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -1,12 +1,14 @@
cc_library_headers {
name: "libcodec2_headers",
vendor_available: true,
+ min_sdk_version: "29",
export_include_dirs: ["include"],
}
cc_library_shared {
name: "libcodec2",
vendor_available: true,
+ min_sdk_version: "29",
vndk: {
enabled: true,
},
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index 19a7666..072f78a 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -49,6 +49,7 @@
cc_library {
name: "libcodec2_hidl@1.0",
vendor_available: true,
+ min_sdk_version: "29",
defaults: ["hidl_defaults"],
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index 78d221e..c7588e9 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -62,7 +62,7 @@
android::base::unique_fd &&fd0,
android::base::unique_fd &&fd1) {
Mutexed<Jobs>::Locked jobs(mJobs);
- auto it = jobs->queues.try_emplace(comp, comp, systemTime()).first;
+ auto it = jobs->queues.try_emplace(comp, comp).first;
it->second.workList.emplace_back(
std::move(work), fenceFd, std::move(fd0), std::move(fd1));
jobs->cond.broadcast();
@@ -79,7 +79,8 @@
for (auto it = jobs->queues.begin(); it != jobs->queues.end(); ) {
Queue &queue = it->second;
if (queue.workList.empty()
- || nowNs - queue.lastQueuedTimestampNs < kIntervalNs) {
+ || (queue.lastQueuedTimestampNs != 0 &&
+ nowNs - queue.lastQueuedTimestampNs < kIntervalNs)) {
++it;
continue;
}
@@ -104,6 +105,7 @@
sp<Fence> fence(new Fence(fenceFd));
fence->waitForever(LOG_TAG);
}
+ queue.lastQueuedTimestampNs = nowNs;
comp->queue(&items);
for (android::base::unique_fd &ufd : uniqueFds) {
(void)ufd.release();
@@ -143,8 +145,8 @@
android::base::unique_fd fd1;
};
struct Queue {
- Queue(const std::shared_ptr<Codec2Client::Component> &comp, nsecs_t timestamp)
- : component(comp), lastQueuedTimestampNs(timestamp) {}
+ Queue(const std::shared_ptr<Codec2Client::Component> &comp)
+ : component(comp), lastQueuedTimestampNs(0) {}
Queue(const Queue &) = delete;
Queue &operator =(const Queue &) = delete;
diff --git a/media/codec2/sfplugin/utils/Android.bp b/media/codec2/sfplugin/utils/Android.bp
index 8c8f025..d971135 100644
--- a/media/codec2/sfplugin/utils/Android.bp
+++ b/media/codec2/sfplugin/utils/Android.bp
@@ -1,6 +1,7 @@
cc_library_shared {
name: "libsfplugin_ccodec_utils",
vendor_available: true,
+ min_sdk_version: "29",
srcs: [
"Codec2BufferUtils.cpp",
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index d4eb8d9..e33a81f 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -7,6 +7,8 @@
// TODO: Remove this when this module is moved back to frameworks/av.
vendor_available: true,
+
+ min_sdk_version: "29",
}
// !!!DO NOT DEPEND ON THIS SHARED LIBRARY DIRECTLY!!!
@@ -14,6 +16,7 @@
cc_library_shared {
name: "libcodec2_vndk",
vendor_available: true,
+ min_sdk_version: "29",
srcs: [
"C2AllocatorIon.cpp",
@@ -87,6 +90,8 @@
"libcodec2_vndk",
"libutils",
],
+
+ min_sdk_version: "29",
}
// public dependency for implementing Codec 2 framework utilities
diff --git a/media/codecs/g711/decoder/Android.bp b/media/codecs/g711/decoder/Android.bp
index 377833f..efff60b 100644
--- a/media/codecs/g711/decoder/Android.bp
+++ b/media/codecs/g711/decoder/Android.bp
@@ -36,6 +36,7 @@
cfi: true,
},
apex_available: ["com.android.media.swcodec"],
+ min_sdk_version: "29",
target: {
darwin: {
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
index 4ed57eb..96b1e84 100644
--- a/media/extractors/Android.bp
+++ b/media/extractors/Android.bp
@@ -21,7 +21,6 @@
shared_libs: [
"liblog",
- "libmediandk#29",
],
// extractors are supposed to work on Q(29)
@@ -39,6 +38,21 @@
version_script: "exports.lds",
+ target: {
+ android: {
+ shared_libs: [
+ "libmediandk#29",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libutils",
+ "libmediandk_format",
+ "libmedia_ndkformatpriv",
+ ],
+ },
+ },
+
sanitize: {
cfi: true,
misc_undefined: [
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 9d183d4..5d00d94 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -132,6 +132,7 @@
AACExtractor::AACExtractor(
DataSourceHelper *source, off64_t offset)
: mDataSource(source),
+ mMeta(nullptr),
mInitCheck(NO_INIT),
mFrameDurationUs(0) {
@@ -180,7 +181,9 @@
}
AACExtractor::~AACExtractor() {
- AMediaFormat_delete(mMeta);
+ if (mMeta != nullptr) {
+ AMediaFormat_delete(mMeta);
+ }
}
media_status_t AACExtractor::getMetaData(AMediaFormat *meta) {
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index 49c9567..440065f 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -8,4 +8,10 @@
"libstagefright_foundation",
],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ }
}
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
index 818e466..502743e 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/extractors/fuzzers/Android.bp
@@ -17,13 +17,8 @@
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
-
-cc_library {
- name: "libextractorfuzzerbase",
-
- srcs: [
- "ExtractorFuzzerBase.cpp",
- ],
+cc_defaults {
+ name: "extractor-fuzzerbase-defaults",
local_include_dirs: [
"include",
@@ -43,16 +38,10 @@
shared_libs: [
"libutils",
"libbinder",
+ "libbase",
+ "libcutils",
],
- /* GETEXTRACTORDEF is not defined as extractor library is not linked in the
- * base class. It will be included when the extractor fuzzer binary is
- * generated.
- */
- allow_undefined_symbols: true,
-
- host_supported: true,
-
target: {
darwin: {
enabled: false,
@@ -60,35 +49,14 @@
},
}
-cc_fuzz {
- name: "mp4_extractor_fuzzer",
-
- srcs: [
- "mp4_extractor_fuzzer.cpp",
- ],
-
- include_dirs: [
- "frameworks/av/media/extractors/mp4",
- ],
+cc_defaults {
+ name: "extractor-fuzzer-defaults",
+ defaults: ["extractor-fuzzerbase-defaults"],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
"libextractorfuzzerbase",
- "libstagefright_id3",
- "libstagefright_esds",
- "libmp4extractor",
],
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
- dictionary: "mp4_extractor_fuzzer.dict",
-
fuzz_config: {
cc: [
"android-media-fuzzing-reports@google.com",
@@ -97,8 +65,73 @@
},
}
+cc_defaults {
+ name: "mpeg2-extractor-fuzzer-defaults",
+ defaults: ["extractor-fuzzer-defaults"],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mpeg2",
+ "frameworks/av/media/libstagefright",
+ ],
+
+ static_libs: [
+ "libstagefright_foundation_without_imemory",
+ "libstagefright_mpeg2support",
+ "libstagefright_mpeg2extractor",
+ "libstagefright_esds",
+ "libmpeg2extractor",
+ ],
+
+ shared_libs: [
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.token@1.0-utils",
+ "android.hidl.allocator@1.0",
+ "libcrypto",
+ "libhidlmemory",
+ "libhidlbase",
+ ],
+}
+
+cc_library_static {
+ name: "libextractorfuzzerbase",
+ defaults: ["extractor-fuzzerbase-defaults"],
+ host_supported: true,
+
+ srcs: [
+ "ExtractorFuzzerBase.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "mp4_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
+ host_supported: true,
+
+ srcs: [
+ "mp4_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mp4",
+ ],
+
+ header_libs: [
+ "libaudioclient_headers",
+ ],
+
+ static_libs: [
+ "libstagefright_id3",
+ "libstagefright_esds",
+ "libmp4extractor",
+ ],
+
+ dictionary: "mp4_extractor_fuzzer.dict",
+}
+
cc_fuzz {
name: "wav_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"wav_extractor_fuzzer.cpp",
@@ -109,32 +142,18 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libfifo",
"libwavextractor",
],
shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
"libbinder_ndk",
- "libbase",
],
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "amr_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"amr_extractor_fuzzer.cpp",
@@ -145,31 +164,15 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libamrextractor",
],
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
dictionary: "amr_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "mkv_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"mkv_extractor_fuzzer.cpp",
@@ -180,10 +183,6 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libwebm",
"libstagefright_flacdec",
"libstagefright_metadatautils",
@@ -191,24 +190,12 @@
"libFLAC",
],
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
dictionary: "mkv_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "ogg_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"ogg_extractor_fuzzer.cpp",
@@ -219,129 +206,43 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libstagefright_metadatautils",
"libvorbisidec",
"liboggextractor",
],
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
dictionary: "ogg_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "mpeg2ps_extractor_fuzzer",
+ defaults: ["mpeg2-extractor-fuzzer-defaults"],
srcs: [
"mpeg2_extractor_fuzzer.cpp",
],
- include_dirs: [
- "frameworks/av/media/extractors/mpeg2",
- "frameworks/av/media/libstagefright",
- ],
-
- static_libs: [
- "liblog",
- "libstagefright_foundation_without_imemory",
- "libmedia",
- "libextractorfuzzerbase",
- "libstagefright_mpeg2support",
- "libstagefright_mpeg2extractor",
- "libstagefright_esds",
- "libmpeg2extractor",
- ],
-
cflags: [
"-DMPEG2PS",
],
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- "android.hardware.cas@1.0",
- "android.hardware.cas.native@1.0",
- "android.hidl.token@1.0-utils",
- "android.hidl.allocator@1.0",
- "libcrypto",
- "libhidlmemory",
- "libhidlbase",
- ],
-
dictionary: "mpeg2ps_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "mpeg2ts_extractor_fuzzer",
+ defaults: ["mpeg2-extractor-fuzzer-defaults"],
srcs: [
"mpeg2_extractor_fuzzer.cpp",
],
- include_dirs: [
- "frameworks/av/media/extractors/mpeg2",
- "frameworks/av/media/libstagefright",
- ],
-
- static_libs: [
- "liblog",
- "libstagefright_foundation_without_imemory",
- "libmedia",
- "libextractorfuzzerbase",
- "libstagefright_mpeg2support",
- "libstagefright_mpeg2extractor",
- "libstagefright_esds",
- "libmpeg2extractor",
- ],
-
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- "android.hardware.cas@1.0",
- "android.hardware.cas.native@1.0",
- "android.hidl.token@1.0-utils",
- "android.hidl.allocator@1.0",
- "libcrypto",
- "libhidlmemory",
- "libhidlbase",
- ],
-
dictionary: "mpeg2ts_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "mp3_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"mp3_extractor_fuzzer.cpp",
@@ -352,31 +253,15 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libfifo",
"libmp3extractor",
"libstagefright_id3",
],
-
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "aac_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"aac_extractor_fuzzer.cpp",
@@ -387,30 +272,14 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libaacextractor",
"libstagefright_metadatautils",
],
-
- shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
- ],
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
cc_fuzz {
name: "flac_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
srcs: [
"flac_extractor_fuzzer.cpp",
@@ -421,29 +290,14 @@
],
static_libs: [
- "liblog",
- "libstagefright_foundation",
- "libmedia",
- "libextractorfuzzerbase",
"libstagefright_metadatautils",
"libFLAC",
"libflacextractor",
],
shared_libs: [
- "libutils",
- "libmediandk",
- "libbinder",
"libbinder_ndk",
- "libbase",
],
dictionary: "flac_extractor_fuzzer.dict",
-
- fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
- },
}
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 592ffa9..8c6f20d 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -11,7 +11,9 @@
static_libs: [
"libmedia_midiiowrapper",
"libsonivox",
- "libstagefright_foundation"
+ "libstagefright_foundation",
+ "libwatchdog",
+ "libbase",
],
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index 9f4f9e6..d0efb2f 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -26,6 +26,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <libsonivox/eas_reverb.h>
+#include <watchdog/Watchdog.h>
namespace android {
@@ -116,6 +117,7 @@
MediaBufferHelper **outBuffer, const ReadOptions *options)
{
ALOGV("MidiSource::read");
+
MediaBufferHelper *buffer;
// process an optional seek request
int64_t seekTimeUs;
@@ -139,6 +141,8 @@
}
// MidiEngine
+using namespace std::chrono_literals;
+static constexpr auto kTimeout = 10s;
MidiEngine::MidiEngine(CDataSource *dataSource,
AMediaFormat *fileMetadata,
@@ -147,6 +151,8 @@
mEasHandle(NULL),
mEasConfig(NULL),
mIsInitialized(false) {
+ Watchdog watchdog(kTimeout);
+
mIoWrapper = new MidiIoWrapper(dataSource);
// spin up a new EAS engine
EAS_I32 temp;
@@ -186,6 +192,8 @@
}
MidiEngine::~MidiEngine() {
+ Watchdog watchdog(kTimeout);
+
if (mEasHandle) {
EAS_CloseFile(mEasData, mEasHandle);
}
@@ -217,12 +225,16 @@
}
status_t MidiEngine::seekTo(int64_t positionUs) {
+ Watchdog watchdog(kTimeout);
+
ALOGV("seekTo %lld", (long long)positionUs);
EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false);
return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR;
}
MediaBufferHelper* MidiEngine::readBuffer() {
+ Watchdog watchdog(kTimeout);
+
EAS_STATE state;
EAS_State(mEasData, mEasHandle, &state);
if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index e48e1b7..afa055f 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -16,4 +16,12 @@
"libstagefright_id3",
"libutils",
],
+
+ host_supported: true,
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 572bd5f..2d92f75 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1062,6 +1062,8 @@
// drop it now to reduce our footprint
free(mLastTrack->mTx3gBuffer);
mLastTrack->mTx3gBuffer = NULL;
+ mLastTrack->mTx3gFilled = 0;
+ mLastTrack->mTx3gSize = 0;
}
} else if (chunk_type == FOURCC("moov")) {
@@ -2644,6 +2646,10 @@
// if those apps are compensating for it, we'd break them with such a change
//
+ if (mLastTrack->mTx3gBuffer == NULL) {
+ mLastTrack->mTx3gSize = 0;
+ mLastTrack->mTx3gFilled = 0;
+ }
if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
size_t growth = kTx3gGrowth;
if (growth < chunk_size) {
@@ -5030,8 +5036,11 @@
}
status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
- off64_t offset, off64_t /* size */) {
+ off64_t offset, off64_t size) {
ALOGV("parseSampleAuxiliaryInformationSizes");
+ if (size < 9) {
+ return -EINVAL;
+ }
// 14496-12 8.7.12
uint8_t version;
if (mDataSource->readAt(
@@ -5044,25 +5053,32 @@
return ERROR_UNSUPPORTED;
}
offset++;
+ size--;
uint32_t flags;
if (!mDataSource->getUInt24(offset, &flags)) {
return ERROR_IO;
}
offset += 3;
+ size -= 3;
if (flags & 1) {
+ if (size < 13) {
+ return -EINVAL;
+ }
uint32_t tmp;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_MALFORMED;
}
mCurrentAuxInfoType = tmp;
offset += 4;
+ size -= 4;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_MALFORMED;
}
mCurrentAuxInfoTypeParameter = tmp;
offset += 4;
+ size -= 4;
}
uint8_t defsize;
@@ -5071,6 +5087,7 @@
}
mCurrentDefaultSampleInfoSize = defsize;
offset++;
+ size--;
uint32_t smplcnt;
if (!mDataSource->getUInt32(offset, &smplcnt)) {
@@ -5078,11 +5095,16 @@
}
mCurrentSampleInfoCount = smplcnt;
offset += 4;
-
+ size -= 4;
if (mCurrentDefaultSampleInfoSize != 0) {
ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
return OK;
}
+ if(smplcnt > size) {
+ ALOGW("b/124525515 - smplcnt(%u) > size(%ld)", (unsigned int)smplcnt, (unsigned long)size);
+ android_errorWriteLog(0x534e4554, "124525515");
+ return -EINVAL;
+ }
if (smplcnt > mCurrentSampleInfoAllocSize) {
uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
if (newPtr == NULL) {
@@ -5098,26 +5120,32 @@
}
status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
- off64_t offset, off64_t /* size */) {
+ off64_t offset, off64_t size) {
ALOGV("parseSampleAuxiliaryInformationOffsets");
+ if (size < 8) {
+ return -EINVAL;
+ }
// 14496-12 8.7.13
uint8_t version;
if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
return ERROR_IO;
}
offset++;
+ size--;
uint32_t flags;
if (!mDataSource->getUInt24(offset, &flags)) {
return ERROR_IO;
}
offset += 3;
+ size -= 3;
uint32_t entrycount;
if (!mDataSource->getUInt32(offset, &entrycount)) {
return ERROR_IO;
}
offset += 4;
+ size -= 4;
if (entrycount == 0) {
return OK;
}
@@ -5143,19 +5171,31 @@
for (size_t i = 0; i < entrycount; i++) {
if (version == 0) {
+ if (size < 4) {
+ ALOGW("b/124526959");
+ android_errorWriteLog(0x534e4554, "124526959");
+ return -EINVAL;
+ }
uint32_t tmp;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_IO;
}
mCurrentSampleInfoOffsets[i] = tmp;
offset += 4;
+ size -= 4;
} else {
+ if (size < 8) {
+ ALOGW("b/124526959");
+ android_errorWriteLog(0x534e4554, "124526959");
+ return -EINVAL;
+ }
uint64_t tmp;
if (!mDataSource->getUInt64(offset, &tmp)) {
return ERROR_IO;
}
mCurrentSampleInfoOffsets[i] = tmp;
offset += 8;
+ size -= 8;
}
}
@@ -5477,16 +5517,12 @@
// apply some sanity (vs strict legality) checks
//
- // clamp the count of entries in the trun box, to avoid spending forever parsing
- // this box. Clamping (vs error) lets us play *something*.
- // 1 million is about 400 msecs on a Pixel3, should be no more than a couple seconds
- // on the slowest devices.
- static constexpr uint32_t kMaxTrunSampleCount = 1000000;
+ static constexpr uint32_t kMaxTrunSampleCount = 10000;
if (sampleCount > kMaxTrunSampleCount) {
- ALOGW("b/123389881 clamp sampleCount(%u) @ kMaxTrunSampleCount(%u)",
+ ALOGW("b/123389881 sampleCount(%u) > kMaxTrunSampleCount(%u)",
sampleCount, kMaxTrunSampleCount);
android_errorWriteLog(0x534e4554, "124389881 count");
-
+ return -EINVAL;
}
}
@@ -5530,7 +5566,12 @@
tmp.duration = sampleDuration;
tmp.compositionOffset = sampleCtsOffset;
memset(tmp.iv, 0, sizeof(tmp.iv));
- mCurrentSamples.add(tmp);
+ if (mCurrentSamples.add(tmp) < 0) {
+ ALOGW("b/123389881 failed saving sample(n=%zu)", mCurrentSamples.size());
+ android_errorWriteLog(0x534e4554, "124389881 allocation");
+ mCurrentSamples.clear();
+ return NO_MEMORY;
+ }
dataOffset += sampleSize;
}
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp
index 9dddf2c..a00812b 100644
--- a/media/extractors/mp4/SampleTable.cpp
+++ b/media/extractors/mp4/SampleTable.cpp
@@ -391,20 +391,11 @@
}
mTimeToSampleCount = U32_AT(&header[4]);
- if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
- // Choose this bound because
- // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
- // time-to-sample entry in the time-to-sample table.
- // 2) mTimeToSampleCount is the number of entries of the time-to-sample
- // table.
- // 3) We hope that the table size does not exceed UINT32_MAX.
+ if (mTimeToSampleCount > (data_size - 8) / (2 * sizeof(uint32_t))) {
ALOGE("Time-to-sample table size too large.");
return ERROR_OUT_OF_RANGE;
}
- // Note: At this point, we know that mTimeToSampleCount * 2 will not
- // overflow because of the above condition.
-
uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
mTotalSize += allocSize;
if (mTotalSize > kMaxTotalSize) {
@@ -540,6 +531,12 @@
}
uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t);
+ if (allocSize > data_size - 8) {
+ ALOGW("b/124771364 - allocSize(%lu) > size(%lu)",
+ (unsigned long)allocSize, (unsigned long)(data_size - 8));
+ android_errorWriteLog(0x534e4554, "124771364");
+ return ERROR_MALFORMED;
+ }
if (allocSize > kMaxTotalSize) {
ALOGE("Sync sample table size too large.");
return ERROR_OUT_OF_RANGE;
@@ -655,12 +652,13 @@
}
mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
- memset(mSampleTimeEntries, 0, sizeof(SampleTimeEntry) * mNumSampleSizes);
+
if (!mSampleTimeEntries) {
ALOGE("Cannot allocate sample entry table with %llu entries.",
(unsigned long long)mNumSampleSizes);
return;
}
+ memset(mSampleTimeEntries, 0, sizeof(SampleTimeEntry) * mNumSampleSizes);
uint32_t sampleIndex = 0;
uint64_t sampleTime = 0;
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index d097941..f6d0b7d 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -12,14 +12,13 @@
shared_libs: [
"libcgrouprc#29",
"libvndksupport#29",
- "libcrypto",
],
header_libs: [
"libaudioclient_headers",
"libbase_headers",
"libstagefright_headers",
- "libmedia_headers",
+ "libmedia_datasource_headers",
],
static_libs: [
diff --git a/media/extractors/tests/Android.bp b/media/extractors/tests/Android.bp
index 059c308..fa39b64 100644
--- a/media/extractors/tests/Android.bp
+++ b/media/extractors/tests/Android.bp
@@ -33,6 +33,7 @@
"libmp4extractor",
"libaudioutils",
"libdatasource",
+ "libwatchdog",
"libstagefright",
"libstagefright_id3",
@@ -65,6 +66,7 @@
"libcrypto",
"libhidlmemory",
"libhidlbase",
+ "libbase",
],
include_dirs: [
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 8ce5c3f..6f5137b 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -18,4 +18,11 @@
"libfifo",
"libstagefright_foundation",
],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index 97ad2b0..e017b3a 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -237,12 +237,12 @@
status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
- aaudio_handle_t streamHandle;
+ aaudio_handle_t streamHandle = 0;
aaudio::AAudioStreamRequest request;
aaudio::AAudioStreamConfiguration configuration;
- pid_t tid;
- int64_t nanoseconds;
- aaudio_result_t result;
+ pid_t tid = 0;
+ int64_t nanoseconds = 0;
+ aaudio_result_t result = AAUDIO_OK;
status_t status = NO_ERROR;
ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
@@ -285,7 +285,11 @@
case CLOSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(CLOSE_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = closeStream(streamHandle);
//ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
// streamHandle, result);
@@ -297,6 +301,7 @@
CHECK_INTERFACE(IAAudioService, data, reply);
status = data.readInt32(&streamHandle);
if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(GET_STREAM_DESCRIPTION) streamHandle failed!", __func__);
return status;
}
aaudio::AudioEndpointParcelable parcelable;
@@ -313,7 +318,11 @@
case START_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(START_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = startStream(streamHandle);
ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -323,7 +332,11 @@
case PAUSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(PAUSE_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = pauseStream(streamHandle);
ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -333,7 +346,11 @@
case STOP_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(STOP_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = stopStream(streamHandle);
ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -343,7 +360,11 @@
case FLUSH_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(FLUSH_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = flushStream(streamHandle);
ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -353,20 +374,40 @@
case REGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
- data.readInt32(&tid);
- data.readInt64(&nanoseconds);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
+ return status;
+ }
+ status = data.readInt32(&tid);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) tid failed!", __func__);
+ return status;
+ }
+ status = data.readInt64(&nanoseconds);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) nanoseconds failed!", __func__);
+ return status;
+ }
result = registerAudioThread(streamHandle, tid, nanoseconds);
- ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
- streamHandle, result);
+ ALOGV("BnAAudioService::%s(REGISTER_AUDIO_THREAD) 0x%08X, result = %d",
+ __func__, streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case UNREGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
- data.readInt32(&tid);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
+ return status;
+ }
+ status = data.readInt32(&tid);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) tid failed!", __func__);
+ return status;
+ }
result = unregisterAudioThread(streamHandle, tid);
ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
streamHandle, result);
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index b9026d4..41002b7 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -1,6 +1,8 @@
cc_library_headers {
name: "libaudioclient_headers",
vendor_available: true,
+ min_sdk_version: "29",
+
header_libs: [
"libaudiofoundation_headers",
],
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 24d7c92..882a5c8 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -1410,6 +1410,7 @@
case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+ case SET_ALLOWED_CAPTURE_POLICY:
case AUDIO_MODULES_UPDATED: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index e361890..a8e6c31 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -1,6 +1,8 @@
cc_library_headers {
name: "libaudiofoundation_headers",
vendor_available: true,
+ min_sdk_version: "29",
+
export_include_dirs: ["include"],
header_libs: [
"libaudio_system_headers",
diff --git a/media/libeffects/downmix/Android.bp b/media/libeffects/downmix/Android.bp
index 9c82b1d..2a2f36e 100644
--- a/media/libeffects/downmix/Android.bp
+++ b/media/libeffects/downmix/Android.bp
@@ -6,6 +6,7 @@
srcs: ["EffectDownmix.c"],
shared_libs: [
+ "libaudioutils",
"libcutils",
"liblog",
],
@@ -23,5 +24,4 @@
"libaudioeffects",
"libhardware_headers",
],
- static_libs: ["libaudioutils" ],
}
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index c87635f..16cd0ad 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -8,12 +8,6 @@
srcs: ["PreProcessing.cpp"],
- include_dirs: [
- "external/webrtc",
- "external/webrtc/webrtc/modules/include",
- "external/webrtc/webrtc/modules/audio_processing/include",
- ],
-
shared_libs: [
"libwebrtc_audio_preprocessing",
"libspeexresampler",
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 5fab5be..c7afe2f 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1240,9 +1240,9 @@
memcpy(outBuffer->s16,
session->outBuf,
fr * session->outChannelCount * sizeof(int16_t));
- memcpy(session->outBuf,
- session->outBuf + fr * session->outChannelCount,
- (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+ memmove(session->outBuf,
+ session->outBuf + fr * session->outChannelCount,
+ (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
session->framesOut -= fr;
framesWr += fr;
}
@@ -1303,9 +1303,9 @@
session->procFrame->data_,
&frOut);
}
- memcpy(session->inBuf,
- session->inBuf + frIn * session->inChannelCount,
- (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
+ memmove(session->inBuf,
+ session->inBuf + frIn * session->inChannelCount,
+ (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
session->framesIn -= frIn;
} else {
size_t fr = session->frameCount - session->framesIn;
@@ -1381,9 +1381,9 @@
memcpy(outBuffer->s16 + framesWr * session->outChannelCount,
session->outBuf,
fr * session->outChannelCount * sizeof(int16_t));
- memcpy(session->outBuf,
- session->outBuf + fr * session->outChannelCount,
- (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+ memmove(session->outBuf,
+ session->outBuf + fr * session->outChannelCount,
+ (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
session->framesOut -= fr;
outBuffer->frameCount += fr;
@@ -1837,9 +1837,9 @@
session->revFrame->data_,
&frOut);
}
- memcpy(session->revBuf,
- session->revBuf + frIn * session->inChannelCount,
- (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
+ memmove(session->revBuf,
+ session->revBuf + frIn * session->inChannelCount,
+ (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
session->framesRev -= frIn;
} else {
size_t fr = session->frameCount - session->framesRev;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index eefea91..e276508 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,6 +1,8 @@
cc_library_headers {
name: "libmedia_headers",
vendor_available: true,
+ min_sdk_version: "29",
+
export_include_dirs: ["include"],
header_libs:[
"libbase_headers",
@@ -28,6 +30,7 @@
"//apex_available:platform",
"com.android.media",
],
+ min_sdk_version: "29",
}
filegroup {
@@ -180,6 +183,8 @@
cc_library_static {
name: "libmedia_midiiowrapper",
+ min_sdk_version: "29",
+
srcs: ["MidiIoWrapper.cpp"],
static_libs: [
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index ae135af..b46c98a 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -1,6 +1,7 @@
cc_library_headers {
name: "libmedia_helper_headers",
vendor_available: true,
+ min_sdk_version: "29",
export_include_dirs: ["include"],
host_supported: true,
target: {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 92df3b7..1761ec0 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -139,8 +139,10 @@
header_libs: [
"libaudioclient_headers",
- "libmedia_headers",
+ "libbase_headers",
+ "libmedia_datasource_headers",
"media_ndk_headers",
+ "media_plugin_headers",
],
cflags: [
@@ -157,6 +159,18 @@
"signed-integer-overflow",
],
},
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ linux: {
+ cflags: [
+ "-DDISABLE_AUDIO_SYSTEM_OFFLOAD",
+ ],
+ }
+ },
}
cc_library {
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 482a1a7..d92a174 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -30,6 +30,8 @@
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/Utils.h>
+#define UNUSED_PARAM __attribute__((unused))
+
namespace android {
static const uint8_t kHevcNalUnitTypes[5] = {
@@ -375,7 +377,7 @@
}
status_t HevcParameterSets::parsePps(
- const uint8_t* data __unused, size_t size __unused) {
+ const uint8_t* data UNUSED_PARAM, size_t size UNUSED_PARAM) {
return OK;
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 02e8ab5..0a98fad 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1073,7 +1073,7 @@
// assertion, let's be lenient for now...
// CHECK((ptr[4] >> 2) == 0x3f); // reserved
- size_t lengthSize __unused = 1 + (ptr[4] & 3);
+ // we can get lengthSize value from 1 + (ptr[4] & 3)
// commented out check below as H264_QVGA_500_NO_AUDIO.3gp
// violates it...
@@ -2075,7 +2075,11 @@
}
// Check if offload is possible for given format, stream type, sample rate,
// bit rate, duration, video and streaming
+#ifdef DISABLE_AUDIO_SYSTEM_OFFLOAD
+ return false;
+#else
return AudioSystem::isOffloadSupported(info);
+#endif
}
HLSTime::HLSTime(const sp<AMessage>& meta) :
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 6719bab..3bed744 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -4,6 +4,7 @@
vndk: {
enabled: true,
},
+ min_sdk_version: "29",
double_loadable: true,
srcs: [
"FrameDropper.cpp",
@@ -41,7 +42,7 @@
"libnativewindow",
"libvndksupport",
],
-
+
static_libs: [
"libgui_bufferqueue_static"
],
diff --git a/media/libstagefright/codecs/flac/enc/Android.bp b/media/libstagefright/codecs/flac/enc/Android.bp
index d7d871a..f35bce1 100644
--- a/media/libstagefright/codecs/flac/enc/Android.bp
+++ b/media/libstagefright/codecs/flac/enc/Android.bp
@@ -15,8 +15,10 @@
},
header_libs: ["libbase_headers"],
- static_libs: [
+ shared_libs: [
"libaudioutils",
+ ],
+ static_libs: [
"libFLAC",
],
}
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 67d3f1a..7975d38 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -295,12 +295,12 @@
<Feature name="bitrate-modes" value="VBR,CBR" />
</MediaCodec>
<MediaCodec name="c2.android.hevc.encoder" type="video/hevc" variant="!slow-cpu">
- <!-- profiles and levels: ProfileMain : MainTierLevel51 -->
- <Limit name="size" min="2x2" max="512x512" />
+ <!-- profiles and levels: ProfileMain : MainTierLevel3 -->
+ <Limit name="size" min="2x2" max="960x544" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="8x8" />
- <Limit name="block-count" range="1-4096" /> <!-- max 512x512 -->
- <Limit name="blocks-per-second" range="1-122880" />
+ <Limit name="block-count" range="1-8160" /> <!-- max 960x544 -->
+ <Limit name="blocks-per-second" range="1-244880" />
<Limit name="frame-rate" range="1-120" />
<Limit name="bitrate" range="1-10000000" />
<Limit name="complexity" range="0-10" default="0" />
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 464bf48..b63353c 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -2,6 +2,7 @@
name: "libstagefright_flacdec",
vendor_available: true,
min_sdk_version: "29",
+ host_supported: true,
srcs: [
"FLACDecoder.cpp",
@@ -19,29 +20,27 @@
cfi: true,
},
- static: {
- whole_static_libs: [
- "libFLAC",
- "libaudioutils",
- ],
- },
-
- shared: {
- static_libs: [
- "libFLAC",
- "libaudioutils",
- ],
- export_static_lib_headers: [
- "libFLAC",
- ],
- },
-
shared_libs: [
+ "libaudioutils",
"liblog",
],
- header_libs: [
- "libmedia_headers",
- "libFLAC-headers",
+ static_libs: [
+ "libFLAC",
],
+
+ export_static_lib_headers: [
+ "libFLAC",
+ ],
+
+ header_libs: [
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ ],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index cef0bc6..f5e9532 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -433,7 +433,7 @@
if (mBuffer == nullptr) {
mBufferDataSize = 0;
mBufferLen = 0;
- ALOGE("decodeOneFrame: failed to allocate memory for input buffer");
+ ALOGE("addDataToBuffer: failed to allocate memory for input buffer");
return NO_MEMORY;
}
mBufferLen = mBufferDataSize + inBufferLen;
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 87ebd00..ebf1035 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -3,6 +3,7 @@
export_include_dirs: ["include"],
vendor_available: true,
host_supported: true,
+ min_sdk_version: "29",
}
cc_defaults {
@@ -104,11 +105,13 @@
cc_library {
name: "libstagefright_foundation",
defaults: ["libstagefright_foundation_defaults"],
+ min_sdk_version: "29",
}
cc_library_static {
name: "libstagefright_foundation_without_imemory",
defaults: ["libstagefright_foundation_defaults"],
+ min_sdk_version: "29",
cflags: [
"-Wno-multichar",
diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/libstagefright/foundation/OpusHeader.cpp
index 42ac026..784e802 100644
--- a/media/libstagefright/foundation/OpusHeader.cpp
+++ b/media/libstagefright/foundation/OpusHeader.cpp
@@ -300,6 +300,10 @@
*opusHeadSize = data_size;
return true;
} else if (memcmp(AOPUS_CSD_MARKER_PREFIX, data, AOPUS_CSD_MARKER_PREFIX_SIZE) == 0) {
+ if (data_size < AOPUS_UNIFIED_CSD_MINSIZE || data_size > AOPUS_UNIFIED_CSD_MAXSIZE) {
+ ALOGD("Unexpected size for unified opus csd %zu", data_size);
+ return false;
+ }
size_t i = 0;
bool found = false;
while (i <= data_size - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE) {
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index 02de2c0..e34504d 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -1,5 +1,6 @@
cc_library_static {
name: "libstagefright_id3",
+ min_sdk_version: "29",
srcs: ["ID3.cpp"],
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index 8d637b1..52fbc0c 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -29,7 +29,6 @@
shared_libs: [
"libcrypto",
- "libmedia",
"libhidlmemory",
"android.hardware.cas.native@1.0",
"android.hidl.memory@1.0",
@@ -37,7 +36,10 @@
],
header_libs: [
+ "libmedia_datasource_headers",
+ "libaudioclient_headers",
"media_ndk_headers",
+ "libstagefright_foundation_headers",
],
export_include_dirs: ["."],
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 7d64d94..2e33a1f 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -36,6 +36,10 @@
#include <inttypes.h>
#include <netinet/in.h>
+#ifndef __ANDROID_APEX__
+#include "HlsSampleDecryptor.h"
+#endif
+
namespace android {
ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
@@ -50,7 +54,13 @@
// Create the decryptor anyway since we don't know the use-case unless key is provided
// Won't decrypt if key info not available (e.g., scanner/extractor just parsing ts files)
- mSampleDecryptor = isSampleEncrypted() ? new HlsSampleDecryptor : NULL;
+ mSampleDecryptor = isSampleEncrypted() ?
+#ifdef __ANDROID_APEX__
+ new SampleDecryptor
+#else
+ new HlsSampleDecryptor
+#endif
+ : NULL;
}
sp<MetaData> ElementaryStreamQueue::getFormat() {
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 3227f47..a06bd6a 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -25,7 +25,7 @@
#include <utils/RefBase.h>
#include <vector>
-#include "HlsSampleDecryptor.h"
+#include "SampleDecryptor.h"
namespace android {
@@ -109,7 +109,7 @@
sp<MetaData> mFormat;
- sp<HlsSampleDecryptor> mSampleDecryptor;
+ sp<SampleDecryptor> mSampleDecryptor;
int mAUIndex;
bool isSampleEncrypted() const {
diff --git a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.h b/media/libstagefright/mpeg2ts/HlsSampleDecryptor.h
index 2c76620..63b4d7b 100644
--- a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.h
+++ b/media/libstagefright/mpeg2ts/HlsSampleDecryptor.h
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#ifndef SAMPLE_AES_PROCESSOR_H_
+#ifndef HLS_SAMPLE_AES_PROCESSOR_H_
-#define SAMPLE_AES_PROCESSOR_H_
+#define HLS_SAMPLE_AES_PROCESSOR_H_
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AString.h>
@@ -28,18 +28,20 @@
#include <utils/RefBase.h>
#include <utils/Vector.h>
+#include "SampleDecryptor.h"
+
namespace android {
-struct HlsSampleDecryptor : RefBase {
+struct HlsSampleDecryptor : SampleDecryptor {
HlsSampleDecryptor();
explicit HlsSampleDecryptor(const sp<AMessage> &sampleAesKeyItem);
- void signalNewSampleAesKey(const sp<AMessage> &sampleAesKeyItem);
+ virtual void signalNewSampleAesKey(const sp<AMessage> &sampleAesKeyItem);
- size_t processNal(uint8_t *nalData, size_t nalSize);
- void processAAC(size_t adtsHdrSize, uint8_t *data, size_t size);
- void processAC3(uint8_t *data, size_t size);
+ virtual size_t processNal(uint8_t *nalData, size_t nalSize);
+ virtual void processAAC(size_t adtsHdrSize, uint8_t *data, size_t size);
+ virtual void processAC3(uint8_t *data, size_t size);
static AString aesBlockToStr(uint8_t block[AES_BLOCK_SIZE]);
@@ -60,4 +62,4 @@
} // namespace android
-#endif // SAMPLE_AES_PROCESSOR_H_
+#endif // HLS_SAMPLE_AES_PROCESSOR_H_
diff --git a/media/libstagefright/mpeg2ts/SampleDecryptor.h b/media/libstagefright/mpeg2ts/SampleDecryptor.h
new file mode 100644
index 0000000..6bc4ac8
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/SampleDecryptor.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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 SAMPLE_AES_PROCESSOR_H_
+
+#define SAMPLE_AES_PROCESSOR_H_
+
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+// Base class of HlsSampleDecryptor which has dummy default implementation.
+struct SampleDecryptor : RefBase {
+
+ SampleDecryptor() { };
+
+ virtual void signalNewSampleAesKey(const sp<AMessage> &) { };
+
+ virtual size_t processNal(uint8_t *, size_t) { return -1; };
+ virtual void processAAC(size_t, uint8_t *, size_t) { };
+ virtual void processAC3(uint8_t *, size_t) { };
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(SampleDecryptor);
+};
+
+} // namespace android
+
+#endif // SAMPLE_AES_PROCESSOR_H_
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 1e434cb..9df3508 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -338,6 +338,12 @@
ABitReader bits(buffer->data() + offset, buffer->size() - offset);
unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
+ if (buffer->size() < auxSize) {
+ ALOGE("b/123940919 auxSize %u", auxSize);
+ android_errorWriteLog(0x534e4554, "123940919");
+ queue->erase(queue->begin());
+ return MALFORMED_PACKET;
+ }
offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
}
@@ -346,6 +352,12 @@
it != headers.end(); ++it) {
const AUHeader &header = *it;
+ if (buffer->size() < header.mSize) {
+ ALOGE("b/123940919 AU_size %u", header.mSize);
+ android_errorWriteLog(0x534e4554, "123940919");
+ queue->erase(queue->begin());
+ return MALFORMED_PACKET;
+ }
if (buffer->size() < offset + header.mSize) {
return MALFORMED_PACKET;
}
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
index f1c599f..4c0add4 100644
--- a/media/libstagefright/tests/writer/WriterTest.cpp
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -49,8 +49,32 @@
int32_t channelCount;
};
+enum inputId {
+ // audio streams
+ AAC_1,
+ AAC_ADTS_1,
+ AMR_NB_1,
+ AMR_WB_1,
+ FLAC_1,
+ OPUS_1,
+ VORBIS_1,
+ // video streams
+ AV1_1,
+ AVC_1,
+ H263_1,
+ HEVC_1,
+ MPEG4_1,
+ VP8_1,
+ VP9_1,
+ // heif stream
+ HEIC_1,
+ UNUSED_ID,
+ UNKNOWN_ID,
+};
+
// LookUpTable of clips and metadata for component testing
static const struct InputData {
+ inputId inpId;
const char *mime;
string inputFile;
string info;
@@ -58,61 +82,67 @@
int32_t secondParam;
bool isAudio;
} kInputData[] = {
- {MEDIA_MIMETYPE_AUDIO_OPUS, "bbb_opus_stereo_128kbps_48000hz.opus",
- "bbb_opus_stereo_128kbps_48000hz.info", 48000, 2, true},
- {MEDIA_MIMETYPE_AUDIO_AAC, "bbb_aac_stereo_128kbps_48000hz.aac",
+ {AAC_1, MEDIA_MIMETYPE_AUDIO_AAC, "bbb_aac_stereo_128kbps_48000hz.aac",
"bbb_aac_stereo_128kbps_48000hz.info", 48000, 2, true},
- {MEDIA_MIMETYPE_AUDIO_AAC_ADTS, "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.adts",
+ {AAC_ADTS_1, MEDIA_MIMETYPE_AUDIO_AAC_ADTS, "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.adts",
"Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.info", 48000, 2, true},
- {MEDIA_MIMETYPE_AUDIO_AMR_NB, "sine_amrnb_1ch_12kbps_8000hz.amrnb",
+ {AMR_NB_1, MEDIA_MIMETYPE_AUDIO_AMR_NB, "sine_amrnb_1ch_12kbps_8000hz.amrnb",
"sine_amrnb_1ch_12kbps_8000hz.info", 8000, 1, true},
- {MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
+ {AMR_WB_1, MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
"bbb_amrwb_1ch_14kbps_16000hz.info", 16000, 1, true},
- {MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_vorbis_stereo_128kbps_48000hz.vorbis",
- "bbb_vorbis_stereo_128kbps_48000hz.info", 48000, 2, true},
- {MEDIA_MIMETYPE_AUDIO_FLAC, "bbb_flac_stereo_680kbps_48000hz.flac",
+ {FLAC_1, MEDIA_MIMETYPE_AUDIO_FLAC, "bbb_flac_stereo_680kbps_48000hz.flac",
"bbb_flac_stereo_680kbps_48000hz.info", 48000, 2, true},
- {MEDIA_MIMETYPE_VIDEO_VP9, "bbb_vp9_176x144_285kbps_60fps.vp9",
- "bbb_vp9_176x144_285kbps_60fps.info", 176, 144, false},
- {MEDIA_MIMETYPE_VIDEO_VP8, "bbb_vp8_176x144_240kbps_60fps.vp8",
- "bbb_vp8_176x144_240kbps_60fps.info", 176, 144, false},
- {MEDIA_MIMETYPE_VIDEO_AVC, "bbb_avc_176x144_300kbps_60fps.h264",
+ {OPUS_1, MEDIA_MIMETYPE_AUDIO_OPUS, "bbb_opus_stereo_128kbps_48000hz.opus",
+ "bbb_opus_stereo_128kbps_48000hz.info", 48000, 2, true},
+ {VORBIS_1, MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_vorbis_stereo_128kbps_48000hz.vorbis",
+ "bbb_vorbis_stereo_128kbps_48000hz.info", 48000, 2, true},
+
+ {AV1_1, MEDIA_MIMETYPE_VIDEO_AV1, "bbb_av1_176_144.av1", "bbb_av1_176_144.info", 176, 144,
+ false},
+ {AVC_1, MEDIA_MIMETYPE_VIDEO_AVC, "bbb_avc_176x144_300kbps_60fps.h264",
"bbb_avc_176x144_300kbps_60fps.info", 176, 144, false},
- {MEDIA_MIMETYPE_VIDEO_HEVC, "bbb_hevc_176x144_176kbps_60fps.hevc",
- "bbb_hevc_176x144_176kbps_60fps.info", 176, 144, false},
- {MEDIA_MIMETYPE_VIDEO_AV1, "bbb_av1_176_144.av1", "bbb_av1_176_144.info", 176, 144, false},
- {MEDIA_MIMETYPE_VIDEO_H263, "bbb_h263_352x288_300kbps_12fps.h263",
+ {H263_1, MEDIA_MIMETYPE_VIDEO_H263, "bbb_h263_352x288_300kbps_12fps.h263",
"bbb_h263_352x288_300kbps_12fps.info", 352, 288, false},
- {MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_mpeg4_352x288_512kbps_30fps.m4v",
+ {HEVC_1, MEDIA_MIMETYPE_VIDEO_HEVC, "bbb_hevc_176x144_176kbps_60fps.hevc",
+ "bbb_hevc_176x144_176kbps_60fps.info", 176, 144, false},
+ {MPEG4_1, MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_mpeg4_352x288_512kbps_30fps.m4v",
"bbb_mpeg4_352x288_512kbps_30fps.info", 352, 288, false},
+ {VP8_1, MEDIA_MIMETYPE_VIDEO_VP8, "bbb_vp8_176x144_240kbps_60fps.vp8",
+ "bbb_vp8_176x144_240kbps_60fps.info", 176, 144, false},
+ {VP9_1, MEDIA_MIMETYPE_VIDEO_VP9, "bbb_vp9_176x144_285kbps_60fps.vp9",
+ "bbb_vp9_176x144_285kbps_60fps.info", 176, 144, false},
+
+ {HEIC_1, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, "bbb_hevc_176x144_176kbps_60fps.hevc",
+ "bbb_heic_176x144_176kbps_60fps.info", 176, 144, false},
};
class WriterTest {
public:
- WriterTest() : mWriter(nullptr), mFileMeta(nullptr), mCurrentTrack(nullptr) {}
+ WriterTest() : mWriter(nullptr), mFileMeta(nullptr) {}
~WriterTest() {
if (mFileMeta) {
mFileMeta.clear();
mFileMeta = nullptr;
}
- if (mCurrentTrack) {
- mCurrentTrack->stop();
- mCurrentTrack.clear();
- mCurrentTrack = nullptr;
- }
if (mWriter) {
mWriter.clear();
mWriter = nullptr;
}
- mBufferInfo.clear();
- if (mInputStream.is_open()) mInputStream.close();
if (gEnv->cleanUp()) remove(OUTPUT_FILE_NAME);
+
+ for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+ mBufferInfo[idx].clear();
+ if (mCurrentTrack[idx]) {
+ mCurrentTrack[idx]->stop();
+ mCurrentTrack[idx].clear();
+ mCurrentTrack[idx] = nullptr;
+ }
+ if (mInputStream[idx].is_open()) mInputStream[idx].close();
+ }
}
void setupWriterType(string writerFormat) {
- mNumCsds = 0;
- mInputFrameId = 0;
mWriterName = unknown_comp;
mDisableTest = false;
static const std::map<std::string, standardWriters> mapWriter = {
@@ -128,11 +158,11 @@
}
}
- void getInputBufferInfo(string inputFileName, string inputInfo);
+ void getInputBufferInfo(string inputFileName, string inputInfo, int32_t idx = 0);
int32_t createWriter(int32_t fd);
- int32_t addWriterSource(bool isAudio, configFormat params);
+ int32_t addWriterSource(bool isAudio, configFormat params, int32_t idx = 0);
enum standardWriters {
OGG,
@@ -149,38 +179,42 @@
standardWriters mWriterName;
sp<MediaWriter> mWriter;
sp<MetaData> mFileMeta;
- sp<MediaAdapter> mCurrentTrack;
+ sp<MediaAdapter> mCurrentTrack[kMaxTrackCount]{};
bool mDisableTest;
- int32_t mNumCsds;
- int32_t mInputFrameId;
- ifstream mInputStream;
- vector<BufferInfo> mBufferInfo;
+ int32_t mNumCsds[kMaxTrackCount]{};
+ int32_t mInputFrameId[kMaxTrackCount]{};
+ ifstream mInputStream[kMaxTrackCount]{};
+ vector<BufferInfo> mBufferInfo[kMaxTrackCount];
};
-class WriteFunctionalityTest : public WriterTest,
- public ::testing::TestWithParam<pair<string, int32_t>> {
+class WriteFunctionalityTest
+ : public WriterTest,
+ public ::testing::TestWithParam<tuple<string /* writerFormat*/, inputId /* inputId0*/,
+ inputId /* inputId1*/, float /* BufferInterval*/>> {
public:
- virtual void SetUp() override { setupWriterType(GetParam().first); }
+ virtual void SetUp() override { setupWriterType(get<0>(GetParam())); }
};
-void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo) {
+void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo, int32_t idx) {
std::ifstream eleInfo;
eleInfo.open(inputInfo.c_str());
ASSERT_EQ(eleInfo.is_open(), true);
int32_t bytesCount = 0;
uint32_t flags = 0;
int64_t timestamp = 0;
+ int32_t numCsds = 0;
while (1) {
if (!(eleInfo >> bytesCount)) break;
eleInfo >> flags;
eleInfo >> timestamp;
- mBufferInfo.push_back({bytesCount, flags, timestamp});
- if (flags == CODEC_CONFIG_FLAG) mNumCsds++;
+ mBufferInfo[idx].push_back({bytesCount, flags, timestamp});
+ if (flags == CODEC_CONFIG_FLAG) numCsds++;
}
eleInfo.close();
- mInputStream.open(inputFileName.c_str(), std::ifstream::binary);
- ASSERT_EQ(mInputStream.is_open(), true);
+ mNumCsds[idx] = numCsds;
+ mInputStream[idx].open(inputFileName.c_str(), std::ifstream::binary);
+ ASSERT_EQ(mInputStream[idx].is_open(), true);
}
int32_t WriterTest::createWriter(int32_t fd) {
@@ -226,10 +260,10 @@
return 0;
}
-int32_t WriterTest::addWriterSource(bool isAudio, configFormat params) {
- if (mInputFrameId) return -1;
+int32_t WriterTest::addWriterSource(bool isAudio, configFormat params, int32_t idx) {
+ if (mInputFrameId[idx]) return -1;
sp<AMessage> format = new AMessage;
- if (mInputStream.is_open()) {
+ if (mInputStream[idx].is_open()) {
format->setString("mime", params.mime);
if (isAudio) {
format->setInt32("channel-count", params.channelCount);
@@ -238,25 +272,34 @@
format->setInt32("width", params.width);
format->setInt32("height", params.height);
}
-
- int32_t status =
- writeHeaderBuffers(mInputStream, mBufferInfo, mInputFrameId, format, mNumCsds);
- if (status != 0) return -1;
+ if (mNumCsds[idx]) {
+ int32_t status = writeHeaderBuffers(mInputStream[idx], mBufferInfo[idx],
+ mInputFrameId[idx], format, mNumCsds[idx]);
+ if (status != 0) return -1;
+ }
}
+
sp<MetaData> trackMeta = new MetaData;
convertMessageToMetaData(format, trackMeta);
- mCurrentTrack = new MediaAdapter(trackMeta);
- if (mCurrentTrack == nullptr) {
+ mCurrentTrack[idx] = new MediaAdapter(trackMeta);
+ if (mCurrentTrack[idx] == nullptr) {
ALOGE("MediaAdapter returned nullptr");
return -1;
}
- status_t result = mWriter->addSource(mCurrentTrack);
+ status_t result = mWriter->addSource(mCurrentTrack[idx]);
return result;
}
void getFileDetails(string &inputFilePath, string &info, configFormat ¶ms, bool &isAudio,
- int32_t streamIndex = 0) {
- if (streamIndex >= sizeof(kInputData) / sizeof(kInputData[0])) {
+ inputId inpId) {
+ int32_t inputDataSize = sizeof(kInputData) / sizeof(kInputData[0]);
+ int32_t streamIndex = 0;
+ for (; streamIndex < inputDataSize; streamIndex++) {
+ if (inpId == kInputData[streamIndex].inpId) {
+ break;
+ }
+ }
+ if (streamIndex == inputDataSize) {
return;
}
inputFilePath += kInputData[streamIndex].inputFile;
@@ -284,14 +327,14 @@
// Creating writer within a test scope. Destructor should be called when the test ends
ASSERT_EQ((status_t)OK, createWriter(fd))
- << "Failed to create writer for output format:" << GetParam().first;
+ << "Failed to create writer for output format:" << get<0>(GetParam());
}
TEST_P(WriteFunctionalityTest, WriterTest) {
if (mDisableTest) return;
ALOGV("Checks if for a given input, a valid muxed file has been created or not");
- string writerFormat = GetParam().first;
+ string writerFormat = get<0>(GetParam());
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
@@ -300,25 +343,49 @@
int32_t status = createWriter(fd);
ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
- string inputFile = gEnv->getRes();
- string inputInfo = gEnv->getRes();
- configFormat param;
- bool isAudio;
- int32_t inputFileIdx = GetParam().second;
- getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
- ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+ inputId inpId[] = {get<1>(GetParam()), get<2>(GetParam())};
+ ASSERT_NE(inpId[0], UNUSED_ID) << "Test expects first inputId to be a valid id";
- ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
- status = addWriterSource(isAudio, param);
- ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+ int32_t numTracks = 1;
+ if (inpId[1] != UNUSED_ID) {
+ numTracks++;
+ }
+ for (int32_t idx = 0; idx < numTracks; idx++) {
+ string inputFile = gEnv->getRes();
+ string inputInfo = gEnv->getRes();
+ configFormat param;
+ bool isAudio;
+ getFileDetails(inputFile, inputInfo, param, isAudio, inpId[idx]);
+ ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+ ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo, idx));
+ status = addWriterSource(isAudio, param, idx);
+ ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+ }
status = mWriter->start(mFileMeta.get());
ASSERT_EQ((status_t)OK, status);
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
- mBufferInfo.size());
- ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
- mCurrentTrack->stop();
+ float interval = get<3>(GetParam());
+ ASSERT_LE(interval, 1.0f) << "Buffer interval invalid. Should be less than or equal to 1.0";
+ size_t range = 0;
+ int32_t loopCount = 0;
+ int32_t offset[kMaxTrackCount]{};
+ while (loopCount < ceil(1.0 / interval)) {
+ for (int32_t idx = 0; idx < numTracks; idx++) {
+ range = mBufferInfo[idx].size() * interval;
+ status = sendBuffersToWriter(mInputStream[idx], mBufferInfo[idx], mInputFrameId[idx],
+ mCurrentTrack[idx], offset[idx], range);
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+ offset[idx] += range;
+ }
+ loopCount++;
+ }
+ for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+ if (mCurrentTrack[idx]) {
+ mCurrentTrack[idx]->stop();
+ }
+ }
status = mWriter->stop();
ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
close(fd);
@@ -328,7 +395,7 @@
if (mDisableTest) return;
ALOGV("Validates the pause() api of writers");
- string writerFormat = GetParam().first;
+ string writerFormat = get<0>(GetParam());
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
@@ -341,8 +408,10 @@
string inputInfo = gEnv->getRes();
configFormat param;
bool isAudio;
- int32_t inputFileIdx = GetParam().second;
- getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+ inputId inpId = get<1>(GetParam());
+ ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+ getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
@@ -351,8 +420,8 @@
status = mWriter->start(mFileMeta.get());
ASSERT_EQ((status_t)OK, status);
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
- mBufferInfo.size() / 4);
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], 0, mBufferInfo[0].size() / 4);
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
bool isPaused = false;
@@ -362,19 +431,19 @@
isPaused = true;
}
// In the pause state, writers shouldn't write anything. Testing the writers for the same
- int32_t numFramesPaused = mBufferInfo.size() / 4;
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
- mInputFrameId, numFramesPaused, isPaused);
+ int32_t numFramesPaused = mBufferInfo[0].size() / 4;
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], mInputFrameId[0], numFramesPaused, isPaused);
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
if (isPaused) {
status = mWriter->start(mFileMeta.get());
ASSERT_EQ((status_t)OK, status);
}
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
- mInputFrameId, mBufferInfo.size());
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], mInputFrameId[0], mBufferInfo[0].size());
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
- mCurrentTrack->stop();
+ mCurrentTrack[0]->stop();
status = mWriter->stop();
ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
@@ -392,7 +461,7 @@
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
- string writerFormat = GetParam().first;
+ string writerFormat = get<0>(GetParam());
int32_t status = createWriter(fd);
ASSERT_EQ(status, (status_t)OK) << "Failed to create writer for output format:" << writerFormat;
@@ -400,8 +469,10 @@
string inputInfo = gEnv->getRes();
configFormat param;
bool isAudio;
- int32_t inputFileIdx = GetParam().second;
- getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+ inputId inpId = get<1>(GetParam());
+ ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+ getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
@@ -418,8 +489,8 @@
mWriter->start(mFileMeta.get());
}
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
- mBufferInfo.size() / 4);
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], 0, mBufferInfo[0].size() / 4);
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
for (int32_t count = 0; count < kMaxCount; count++) {
@@ -428,20 +499,20 @@
}
mWriter->pause();
- int32_t numFramesPaused = mBufferInfo.size() / 4;
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
- mInputFrameId, numFramesPaused, true);
+ int32_t numFramesPaused = mBufferInfo[0].size() / 4;
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], mInputFrameId[0], numFramesPaused, true);
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
for (int32_t count = 0; count < kMaxCount; count++) {
mWriter->start(mFileMeta.get());
}
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
- mInputFrameId, mBufferInfo.size());
+ status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+ mCurrentTrack[0], mInputFrameId[0], mBufferInfo[0].size());
ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
- mCurrentTrack->stop();
+ mCurrentTrack[0]->stop();
// first stop should succeed.
status = mWriter->stop();
@@ -454,15 +525,13 @@
close(fd);
}
-class ListenerTest : public WriterTest,
- public ::testing::TestWithParam<
- tuple<string /* writerFormat*/, int32_t /* inputFileIdx*/,
- float /* FileSizeLimit*/, float /* FileDurationLimit*/>> {
+class ListenerTest
+ : public WriterTest,
+ public ::testing::TestWithParam<tuple<
+ string /* writerFormat*/, inputId /* inputId0*/, inputId /* inputId1*/,
+ float /* FileSizeLimit*/, float /* FileDurationLimit*/, float /* BufferInterval*/>> {
public:
- virtual void SetUp() override {
- tuple<string, int32_t, float, float> params = GetParam();
- setupWriterType(get<0>(params));
- }
+ virtual void SetUp() override { setupWriterType(get<0>(GetParam())); }
};
TEST_P(ListenerTest, SetMaxFileLimitsTest) {
@@ -470,8 +539,7 @@
if (mDisableTest || mWriterName != MPEG4) return;
ALOGV("Validates writer when max file limits are set");
- tuple<string, int32_t, float, float> params = GetParam();
- string writerFormat = get<0>(params);
+ string writerFormat = get<0>(GetParam());
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
@@ -480,30 +548,42 @@
int32_t status = createWriter(fd);
ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
- string inputFile = gEnv->getRes();
- string inputInfo = gEnv->getRes();
- configFormat param;
- bool isAudio;
- int32_t inputFileIdx = get<1>(params);
- getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
- ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+ inputId inpId[] = {get<1>(GetParam()), get<2>(GetParam())};
+ ASSERT_NE(inpId[0], UNUSED_ID) << "Test expects first inputId to be a valid id";
- ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
- status = addWriterSource(isAudio, param);
- ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+ size_t inputFileSize = 0;
+ int64_t lastFrameTimeStampUs = INT_MAX;
+ int32_t numTracks = 1;
+ if (inpId[1] != UNUSED_ID) {
+ numTracks++;
+ }
+ for (int32_t idx = 0; idx < numTracks; idx++) {
+ string inputFile = gEnv->getRes();
+ string inputInfo = gEnv->getRes();
+ configFormat param;
+ bool isAudio;
+ getFileDetails(inputFile, inputInfo, param, isAudio, inpId[idx]);
+ ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
- // Read file properties
- struct stat buf;
- status = stat(inputFile.c_str(), &buf);
- ASSERT_EQ(0, status);
+ ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo, idx));
+ status = addWriterSource(isAudio, param, idx);
+ ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
- float fileSizeLimit = get<2>(params);
- float fileDurationLimit = get<3>(params);
+ // Read file properties
+ struct stat buf;
+ status = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(0, status);
+
+ inputFileSize += buf.st_size;
+ if (lastFrameTimeStampUs > mBufferInfo[idx][mBufferInfo[idx].size() - 1].timeUs) {
+ lastFrameTimeStampUs = mBufferInfo[idx][mBufferInfo[idx].size() - 1].timeUs;
+ }
+ }
+
+ float fileSizeLimit = get<3>(GetParam());
+ float fileDurationLimit = get<4>(GetParam());
int64_t maxFileSize = 0;
int64_t maxFileDuration = 0;
-
- size_t inputFileSize = buf.st_size;
- int64_t lastFrameTimeStampUs = mBufferInfo[mBufferInfo.size() - 1].timeUs;
if (fileSizeLimit > 0) {
maxFileSize = (int64_t)(fileSizeLimit * inputFileSize);
mWriter->setMaxFileSize(maxFileSize);
@@ -518,14 +598,33 @@
mWriter->setListener(listener);
status = mWriter->start(mFileMeta.get());
-
ASSERT_EQ((status_t)OK, status);
- status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
- mBufferInfo.size(), false, listener);
- ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+ float interval = get<5>(GetParam());
+ ASSERT_LE(interval, 1.0f) << "Buffer interval invalid. Should be less than or equal to 1.0";
+
+ size_t range = 0;
+ int32_t loopCount = 0;
+ int32_t offset[kMaxTrackCount]{};
+ while (loopCount < ceil(1.0 / interval)) {
+ for (int32_t idx = 0; idx < numTracks; idx++) {
+ range = mBufferInfo[idx].size() * interval;
+ status = sendBuffersToWriter(mInputStream[idx], mBufferInfo[idx], mInputFrameId[idx],
+ mCurrentTrack[idx], offset[idx], range, false, listener);
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+ offset[idx] += range;
+ }
+ loopCount++;
+ }
+
ASSERT_TRUE(mWriter->reachedEOS()) << "EOS not signalled.";
- mCurrentTrack->stop();
+ for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+ if (mCurrentTrack[idx]) {
+ mCurrentTrack[idx]->stop();
+ }
+ }
+
status = mWriter->stop();
ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
close(fd);
@@ -552,23 +651,57 @@
// TODO: (b/150923387)
// Add WEBM input
-INSTANTIATE_TEST_SUITE_P(
- ListenerTestAll, ListenerTest,
- ::testing::Values(make_tuple("ogg", 0, 0.7, 0.3), make_tuple("aac", 1, 0.6, 0.7),
- make_tuple("mpeg4", 1, 0.4, 0.3), make_tuple("amrnb", 3, 0.2, 0.6),
- make_tuple("amrwb", 4, 0.5, 0.5), make_tuple("mpeg2Ts", 1, 0.2, 1)));
+INSTANTIATE_TEST_SUITE_P(ListenerTestAll, ListenerTest,
+ ::testing::Values(make_tuple("aac", AAC_1, UNUSED_ID, 0.6, 0.7, 1),
+ make_tuple("amrnb", AMR_NB_1, UNUSED_ID, 0.2, 0.6, 1),
+ make_tuple("amrwb", AMR_WB_1, UNUSED_ID, 0.5, 0.5, 1),
+ make_tuple("mpeg2Ts", AAC_1, UNUSED_ID, 0.2, 1, 1),
+ make_tuple("mpeg4", AAC_1, UNUSED_ID, 0.4, 0.3, 0.25),
+ make_tuple("ogg", OPUS_1, UNUSED_ID, 0.7, 0.3, 1)));
// TODO: (b/144476164)
// Add AAC_ADTS, FLAC, AV1 input
-INSTANTIATE_TEST_SUITE_P(WriterTestAll, WriteFunctionalityTest,
- ::testing::Values(make_pair("ogg", 0), make_pair("webm", 0),
- make_pair("aac", 1), make_pair("mpeg4", 1),
- make_pair("amrnb", 3), make_pair("amrwb", 4),
- make_pair("webm", 5), make_pair("webm", 7),
- make_pair("webm", 8), make_pair("mpeg4", 9),
- make_pair("mpeg4", 10), make_pair("mpeg4", 12),
- make_pair("mpeg4", 13), make_pair("mpeg2Ts", 1),
- make_pair("mpeg2Ts", 9)));
+INSTANTIATE_TEST_SUITE_P(
+ WriterTestAll, WriteFunctionalityTest,
+ ::testing::Values(
+ make_tuple("aac", AAC_1, UNUSED_ID, 1),
+
+ make_tuple("amrnb", AMR_NB_1, UNUSED_ID, 1),
+ make_tuple("amrwb", AMR_WB_1, UNUSED_ID, 1),
+
+ // TODO(b/144902018): Enable test for mpeg2ts
+ // make_tuple("mpeg2Ts", AAC_1, UNUSED_ID, 1),
+ // make_tuple("mpeg2Ts", AVC_1, UNUSED_ID, 1),
+ // TODO(b/156355857): Add multitrack for mpeg2ts
+ // make_tuple("mpeg2Ts", AAC_1, AVC_1, 0.50),
+ // make_tuple("mpeg2Ts", AVC_1, AAC_1, 0.25),
+
+ make_tuple("mpeg4", AAC_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", AMR_NB_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", AMR_WB_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", AVC_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", H263_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", HEIC_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", HEVC_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", MPEG4_1, UNUSED_ID, 1),
+ make_tuple("mpeg4", AAC_1, AVC_1, 0.25),
+ make_tuple("mpeg4", AVC_1, AAC_1, 0.75),
+ make_tuple("mpeg4", AMR_WB_1, AAC_1, 0.75),
+ make_tuple("mpeg4", HEVC_1, AMR_WB_1, 0.25),
+ make_tuple("mpeg4", H263_1, AMR_NB_1, 0.50),
+ make_tuple("mpeg4", MPEG4_1, AAC_1, 0.75),
+ make_tuple("mpeg4", AMR_NB_1, AMR_WB_1, 0.25),
+ make_tuple("mpeg4", H263_1, AMR_NB_1, 0.50),
+ make_tuple("mpeg4", MPEG4_1, HEVC_1, 0.75),
+
+ make_tuple("ogg", OPUS_1, UNUSED_ID, 1),
+
+ make_tuple("webm", OPUS_1, UNUSED_ID, 1),
+ make_tuple("webm", VORBIS_1, UNUSED_ID, 1),
+ make_tuple("webm", VP8_1, UNUSED_ID, 1),
+ make_tuple("webm", VP9_1, UNUSED_ID, 1),
+ make_tuple("webm", VP8_1, OPUS_1, 0.50),
+ make_tuple("webm", VORBIS_1, VP8_1, 0.25)));
int main(int argc, char **argv) {
gEnv = new WriterTestEnvironment();
diff --git a/media/libstagefright/tests/writer/WriterUtility.h b/media/libstagefright/tests/writer/WriterUtility.h
index 5e19973..5e79298 100644
--- a/media/libstagefright/tests/writer/WriterUtility.h
+++ b/media/libstagefright/tests/writer/WriterUtility.h
@@ -31,6 +31,7 @@
#define CODEC_CONFIG_FLAG 32
+constexpr uint32_t kMaxTrackCount = 2;
constexpr uint32_t kMaxCSDStrlen = 16;
constexpr uint32_t kMaxCount = 20;
diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp
new file mode 100644
index 0000000..849623a
--- /dev/null
+++ b/media/libwatchdog/Android.bp
@@ -0,0 +1,36 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library {
+ name: "libwatchdog",
+ srcs: [
+ "Watchdog.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "libbase",
+ ],
+ target: {
+ windows: {
+ enabled: false,
+ },
+ darwin: {
+ enabled: false,
+ },
+ },
+ apex_available: ["com.android.media"],
+}
diff --git a/media/libwatchdog/Watchdog.cpp b/media/libwatchdog/Watchdog.cpp
new file mode 100644
index 0000000..bb012b9
--- /dev/null
+++ b/media/libwatchdog/Watchdog.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Watchdog"
+
+#include <watchdog/Watchdog.h>
+
+#include <android-base/logging.h>
+#include <android-base/threads.h>
+#include <signal.h>
+#include <time.h>
+#include <cstring>
+#include <utils/Log.h>
+
+namespace android {
+
+Watchdog::Watchdog(::std::chrono::steady_clock::duration timeout) {
+ // Create the timer.
+ struct sigevent sev;
+ sev.sigev_notify = SIGEV_THREAD_ID;
+ sev.sigev_notify_thread_id = base::GetThreadId();
+ sev.sigev_signo = SIGABRT;
+ sev.sigev_value.sival_ptr = &mTimerId;
+ int err = timer_create(CLOCK_MONOTONIC, &sev, &mTimerId);
+ if (err != 0) {
+ PLOG(FATAL) << "Failed to create timer";
+ }
+
+ // Start the timer.
+ struct itimerspec spec;
+ memset(&spec, 0, sizeof(spec));
+ auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout);
+ LOG_ALWAYS_FATAL_IF(timeout.count() <= 0, "Duration must be positive");
+ spec.it_value.tv_sec = ns.count() / 1000000000;
+ spec.it_value.tv_nsec = ns.count() % 1000000000;
+ err = timer_settime(mTimerId, 0, &spec, nullptr);
+ if (err != 0) {
+ PLOG(FATAL) << "Failed to start timer";
+ }
+}
+
+Watchdog::~Watchdog() {
+ // Delete the timer.
+ int err = timer_delete(mTimerId);
+ if (err != 0) {
+ PLOG(FATAL) << "Failed to delete timer";
+ }
+}
+
+} // namespace android
diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/libwatchdog/include/watchdog/Watchdog.h
new file mode 100644
index 0000000..2819f8a
--- /dev/null
+++ b/media/libwatchdog/include/watchdog/Watchdog.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_WATCHDOG_H
+#define ANDROID_WATCHDOG_H
+
+#include <chrono>
+#include <time.h>
+
+namespace android {
+
+/*
+ * An RAII-style object, which would crash the process if a timeout expires
+ * before the object is destroyed.
+ * The calling thread would be sent a SIGABORT, which would typically result in
+ * a stack trace.
+ *
+ * Sample usage:
+ * {
+ * Watchdog watchdog(std::chrono::milliseconds(10));
+ * DoSomething();
+ * }
+ * // If we got here, the function completed in time.
+ */
+class Watchdog final {
+public:
+ Watchdog(std::chrono::steady_clock::duration timeout);
+ ~Watchdog();
+
+private:
+ timer_t mTimerId;
+};
+
+} // namespace android
+
+#endif // ANDROID_WATCHDOG_H
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index a291939..c76b53d 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -45,6 +45,7 @@
#include "android-base/strings.h"
namespace android {
+static const int SN_EVENT_LOG_ID = 0x534e4554;
static const MtpOperationCode kSupportedOperationCodes[] = {
MTP_OPERATION_GET_DEVICE_INFO,
@@ -967,6 +968,17 @@
if (!parseDateTime(modified, modifiedTime))
modifiedTime = 0;
+ if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0) ||
+ (strchr(name, '/') != NULL)) {
+ char errMsg[80];
+
+ snprintf(errMsg, sizeof(errMsg), "Invalid name: %s", (const char *) name);
+ ALOGE("%s (b/130656917)", errMsg);
+ android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "130656917", -1, errMsg,
+ strlen(errMsg));
+
+ return MTP_RESPONSE_INVALID_PARAMETER;
+ }
if (path[path.size() - 1] != '/')
path.append("/");
path.append(name);
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 8fb6a87..80d5d50 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -114,12 +114,12 @@
int32_t actionCode,
const char *detail);
-struct AMediaCodecOnAsyncNotifyCallback {
+typedef struct AMediaCodecOnAsyncNotifyCallback {
AMediaCodecOnAsyncInputAvailable onAsyncInputAvailable;
AMediaCodecOnAsyncOutputAvailable onAsyncOutputAvailable;
AMediaCodecOnAsyncFormatChanged onAsyncFormatChanged;
AMediaCodecOnAsyncError onAsyncError;
-};
+} AMediaCodecOnAsyncNotifyCallback;
#if __ANDROID_API__ >= 21
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index 14319c4..a1cd9e3 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -36,6 +36,7 @@
#ifndef _NDK_MEDIA_EXTRACTOR_H
#define _NDK_MEDIA_EXTRACTOR_H
+#include <stdbool.h>
#include <sys/cdefs.h>
#include <sys/types.h>
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 35c26f1..77cbf16 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -36,6 +36,7 @@
#ifndef _NDK_MEDIA_FORMAT_H
#define _NDK_MEDIA_FORMAT_H
+#include <stdbool.h>
#include <sys/cdefs.h>
#include <sys/types.h>
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
index a7388da..bc32416 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -65,6 +65,12 @@
</ProductStrategy>
<ProductStrategy name="STRATEGY_MEDIA">
+ <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
+ <Attributes>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANT"/>
+ </Attributes>
+ </AttributesGroup>
<AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
<Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
<Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
@@ -72,12 +78,6 @@
<Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
<Attributes></Attributes>
</AttributesGroup>
- <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
- <Attributes>
- <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
- <Usage value="AUDIO_USAGE_ASSISTANT"/>
- </Attributes>
- </AttributesGroup>
<AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
<Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
</AttributesGroup>
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
index a7388da..bc32416 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -65,6 +65,12 @@
</ProductStrategy>
<ProductStrategy name="STRATEGY_MEDIA">
+ <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
+ <Attributes>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANT"/>
+ </Attributes>
+ </AttributesGroup>
<AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
<Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
<Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
@@ -72,12 +78,6 @@
<Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
<Attributes></Attributes>
</AttributesGroup>
- <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
- <Attributes>
- <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
- <Usage value="AUDIO_USAGE_ASSISTANT"/>
- </Attributes>
- </AttributesGroup>
<AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
<Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
</AttributesGroup>
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2a2e449..67e085c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5614,7 +5614,10 @@
patchBuilder.addSink(filteredDevice);
}
- installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
+ // Add half reported latency to delayMs when muteWaitMs is null in order
+ // to avoid disordered sequence of muting volume and changing devices.
+ installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(),
+ muteWaitMs == 0 ? (delayMs + (outputDesc->latency() / 2)) : delayMs);
}
// update stream volumes according to new device
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 227adc7..f3f546f 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -989,11 +989,6 @@
ALOGV("%s() mAudioPolicyManager == NULL", __func__);
return NO_INIT;
}
- uint_t callingUid = IPCThreadState::self()->getCallingUid();
- if (uid != callingUid) {
- ALOGD("%s() uid invalid %d != %d", __func__, uid, callingUid);
- return PERMISSION_DENIED;
- }
return mAudioPolicyManager->setAllowedCapturePolicy(uid, capturePolicy);
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 595c3e8..69a5267 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -118,6 +118,8 @@
// ----------------------------------------------------------------------------
static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
+static const String16 sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
// Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java
static constexpr int32_t kVendorClientScore = 200;
@@ -377,9 +379,6 @@
clientToDisconnect->notifyError(
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
CaptureResultExtras{});
- // Ensure not in binder RPC so client disconnect PID checks work correctly
- LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(),
- "onDeviceStatusChanged must be called from the camera service process!");
clientToDisconnect->disconnect();
}
@@ -1812,7 +1811,11 @@
}
auto clientUid = CameraThreadState::getCallingUid();
- sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid);
+ auto clientPid = CameraThreadState::getCallingPid();
+ bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
+ clientPid, clientUid);
+ sp<ServiceListener> serviceListener = new ServiceListener(this, listener,
+ clientUid, clientPid, openCloseCallbackAllowed);
auto ret = serviceListener->initialize();
if (ret != NO_ERROR) {
String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
@@ -2516,6 +2519,9 @@
sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
+
return OK;
}
@@ -2556,6 +2562,9 @@
sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName);
+
return OK;
}
@@ -3327,6 +3336,29 @@
});
}
+void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
+ const String16& clientPackageName) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (const auto& it : mListenerList) {
+ if (!it.second->isOpenCloseCallbackAllowed()) {
+ continue;
+ }
+
+ binder::Status ret;
+ String16 cameraId64(cameraId);
+ if (open) {
+ ret = it.second->getListener()->onCameraOpened(cameraId64, clientPackageName);
+ } else {
+ ret = it.second->getListener()->onCameraClosed(cameraId64);
+ }
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed to trigger onCameraOpened/onCameraClosed callback: %d", __FUNCTION__,
+ ret.exceptionCode());
+ }
+ }
+}
+
template<class Func>
void CameraService::CameraState::updateStatus(StatusInternal status,
const String8& cameraId,
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 4e04f0e..0b09619 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -822,7 +822,9 @@
class ServiceListener : public virtual IBinder::DeathRecipient {
public:
ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener,
- int uid) : mParent(parent), mListener(listener), mListenerUid(uid) {}
+ int uid, int pid, bool openCloseCallbackAllowed) : mParent(parent),
+ mListener(listener), mListenerUid(uid), mListenerPid(pid),
+ mOpenCloseCallbackAllowed(openCloseCallbackAllowed) {}
status_t initialize() {
return IInterface::asBinder(mListener)->linkToDeath(this);
@@ -836,12 +838,16 @@
}
int getListenerUid() { return mListenerUid; }
+ int getListenerPid() { return mListenerPid; }
sp<hardware::ICameraServiceListener> getListener() { return mListener; }
+ bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; }
private:
wp<CameraService> mParent;
sp<hardware::ICameraServiceListener> mListener;
int mListenerUid;
+ int mListenerPid;
+ bool mOpenCloseCallbackAllowed = false;
};
// Guarded by mStatusListenerMutex
@@ -864,6 +870,13 @@
void updateStatus(StatusInternal status,
const String8& cameraId);
+ /**
+ * Update the opened/closed status of the given camera id.
+ *
+ * This method acqiures mStatusListenerLock.
+ */
+ void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName);
+
// flashlight control
sp<CameraFlashlight> mFlashlight;
// guard mTorchStatusMap
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 0f6be79..b9e5857 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -54,6 +54,15 @@
// TODO: no implementation yet.
return binder::Status::ok();
}
+ virtual binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
+ const ::android::String16& /*clientPackageId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
+ virtual binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
};
} // implementation
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index e319425..f603b85 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -1,6 +1,7 @@
cc_binary {
name: "mediaswcodec",
vendor_available: true,
+ min_sdk_version: "29",
srcs: [
"main_swcodecservice.cpp",
@@ -58,5 +59,8 @@
src: "seccomp_policy/mediacodec-x86.policy",
},
},
- required: ["crash_dump.policy"],
+ required: [
+ "crash_dump.policy",
+ "code_coverage.policy",
+ ],
}
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index cdd9d0c..88a79e7 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -70,7 +70,7 @@
LOCAL_MODULE := mediacodec.policy
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
+LOCAL_REQUIRED_MODULES := crash_dump.policy code_coverage.policy
# mediacodec runs in 32-bit combatibility mode. For 64 bit architectures,
# use the 32 bit policy
ifdef TARGET_2ND_ARCH
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
index fa5bc4a..50de66a 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/services/mediacodec/registrant/Android.bp
@@ -1,6 +1,7 @@
cc_library_shared {
name: "libmedia_codecserviceregistrant",
vendor_available: true,
+ min_sdk_version: "29",
srcs: [
"CodecServiceRegistrant.cpp",
],
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 51564ca..b4a9ff6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -59,3 +59,5 @@
getrandom: 1
@include /system/etc/seccomp_policy/crash_dump.arm.policy
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index d9c4045..a9d32d6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -69,3 +69,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
new file mode 120000
index 0000000..ab2592a
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
@@ -0,0 +1 @@
+mediacodec-x86.policy
\ No newline at end of file
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 8705cf9..9af0ec7 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -84,3 +84,5 @@
getgid32: 1
getegid32: 1
getgroups32: 1
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index 85fd28d..e8ff2f6 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -79,3 +79,4 @@
getegid: 1
getgroups: 1
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index e906500..15d30ce 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -67,6 +67,9 @@
src: "seccomp_policy/mediaextractor-x86_64.policy",
},
},
- required: ["crash_dump.policy"],
+ required: [
+ "crash_dump.policy",
+ "code_coverage.policy",
+ ],
}
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index c61393d..b062775 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -41,6 +41,9 @@
getgroups32: 1
nanosleep: 1
getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
# for dynamically loading extractors
pread64: 1
@@ -58,3 +61,4 @@
_llseek: 1
@include /system/etc/seccomp_policy/crash_dump.arm.policy
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index e6c676c..481e29e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -30,6 +30,9 @@
getrlimit: 1
nanosleep: 1
getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
# for FileSource
readlinkat: 1
@@ -44,3 +47,4 @@
sched_yield: 1
@include /system/etc/seccomp_policy/crash_dump.arm64.policy
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index 56ad8df..15fb24e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -39,6 +39,9 @@
getgroups32: 1
nanosleep: 1
getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
# for dynamically loading extractors
getdents64: 1
@@ -57,3 +60,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
index 607a03e..4f2646c 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -34,6 +34,9 @@
getrlimit: 1
nanosleep: 1
getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
# for dynamically loading extractors
getdents64: 1
@@ -51,3 +54,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86_64.policy
+@include /system/etc/seccomp_policy/code_coverage.x86_64.policy
diff --git a/services/minijail/Android.bp b/services/minijail/Android.bp
index 0713a87..388cdb3 100644
--- a/services/minijail/Android.bp
+++ b/services/minijail/Android.bp
@@ -18,6 +18,7 @@
name: "libavservices_minijail",
defaults: ["libavservices_minijail_defaults"],
vendor_available: true,
+ min_sdk_version: "29",
export_include_dirs: ["."],
}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 377d30b..51afdcd 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -40,6 +40,32 @@
#define HW_MODULE_PREFIX "primary"
namespace android {
+namespace {
+
+// Given an IMemory, returns a copy of its content along with its size.
+// Returns nullptr on failure or if input is nullptr.
+std::pair<std::unique_ptr<uint8_t[]>,
+ size_t> CopyToArray(const sp<IMemory>& mem) {
+ if (mem == nullptr) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ const size_t size = mem->size();
+ if (size == 0) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ std::unique_ptr<uint8_t[]> ar = std::make_unique<uint8_t[]>(size);
+ if (ar == nullptr) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ memcpy(ar.get(), mem->pointer(), size);
+ return std::make_pair(std::move(ar), size);
+}
+
+}
+
SoundTriggerHwService::SoundTriggerHwService()
: BnSoundTriggerHwService(),
mNextUniqueId(1),
@@ -557,8 +583,13 @@
return NO_INIT;
}
- struct sound_trigger_sound_model *sound_model =
- (struct sound_trigger_sound_model *)modelMemory->pointer();
+ auto immutableMemory = CopyToArray(modelMemory);
+ if (immutableMemory.first == nullptr) {
+ return NO_MEMORY;
+ }
+
+ struct sound_trigger_sound_model* sound_model =
+ (struct sound_trigger_sound_model*) immutableMemory.first.get();
size_t structSize;
if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
@@ -568,9 +599,10 @@
}
if (sound_model->data_offset < structSize ||
- sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
- modelMemory->size() < sound_model->data_offset ||
- sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
+ sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
+ immutableMemory.second < sound_model->data_offset ||
+ sound_model->data_size >
+ (immutableMemory.second - sound_model->data_offset)) {
android_errorWriteLog(0x534e4554, "30148546");
ALOGE("loadSoundModel() data_size is too big");
return BAD_VALUE;
@@ -651,13 +683,19 @@
return NO_INIT;
}
- struct sound_trigger_recognition_config *config =
- (struct sound_trigger_recognition_config *)dataMemory->pointer();
+ auto immutableMemory = CopyToArray(dataMemory);
+ if (immutableMemory.first == nullptr) {
+ return NO_MEMORY;
+ }
+
+ struct sound_trigger_recognition_config* config =
+ (struct sound_trigger_recognition_config*) immutableMemory.first.get();
if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
- config->data_size > (UINT_MAX - config->data_offset) ||
- dataMemory->size() < config->data_offset ||
- config->data_size > (dataMemory->size() - config->data_offset)) {
+ config->data_size > (UINT_MAX - config->data_offset) ||
+ immutableMemory.second < config->data_offset ||
+ config->data_size >
+ (immutableMemory.second - config->data_offset)) {
ALOGE("startRecognition() data_size is too big");
return BAD_VALUE;
}