Merge "CCodec: bypass crypto / descrambler if input is empty" into rvc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index 3098001..259558c 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -44,7 +44,7 @@
// Use a custom AndroidManifest.xml used for API targeting.
androidManifest: ":com.android.media-androidManifest",
-
+ min_sdk_version: "29",
legacy_android10_support: true,
}
@@ -84,7 +84,7 @@
// Use a custom AndroidManifest.xml used for API targeting.
androidManifest: ":com.android.media.swcodec-androidManifest",
-
+ min_sdk_version: "29",
legacy_android10_support: true,
}
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index 81657fd..c54813c 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -89,4 +89,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 836e037..7fba188 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -97,6 +97,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/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index a95fe2a..e2097b5 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -735,9 +735,8 @@
if (!serviceRet.isOk() || status != Status::NO_ERROR) {
ALOGE("%s: connect camera device failed", __FUNCTION__);
- // TODO: Convert serviceRet to camera_status_t
delete device;
- return ACAMERA_ERROR_UNKNOWN;
+ return utils::convertFromHidl(status);
}
if (deviceRemote == nullptr) {
ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 571cf59..8ccded2 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -101,6 +101,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/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 74fdc8b..9fc0e17 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -59,7 +59,6 @@
enum drc_compression_mode_t : int32_t; ///< DRC compression mode
enum drc_effect_type_t : int32_t; ///< DRC effect type
enum drc_album_mode_t : int32_t; ///< DRC album mode
- enum drc_output_loudness : int32_t; ///< DRC output loudness
enum intra_refresh_mode_t : uint32_t; ///< intra refresh modes
enum level_t : uint32_t; ///< coding level
enum ordinal_key_t : uint32_t; ///< work ordering keys
@@ -248,7 +247,7 @@
kParamIndexSurfaceAllocator, // u32
- // low latency mode for decoders
+ // low latency mode
kParamIndexLowLatencyMode, // bool
};
@@ -812,9 +811,10 @@
constexpr char C2_PARAMKEY_PIPELINE_DELAY[] = "algo.delay";
/**
- * Enable/disable low latency decoding mode.
- * If true, low latency decoding mode is enabled, and the decoder doesn't hold input and output
- * data more than required by the codec standards.
+ * Enable/disable low latency mode.
+ * If true, low latency is preferred over low power. Disable power optimizations that
+ * may result in increased latency. For decoders, this means that the decoder does not
+ * hold input and output data more than required by the codec standards.
*/
typedef C2GlobalParam<C2Tuning, C2EasyBoolValue, kParamIndexLowLatencyMode>
C2GlobalLowLatencyModeTuning;
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 49b49a4..0acab49 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -678,8 +678,13 @@
<< ") -- transaction failed.";
return C2_TRANSACTION_FAILED;
} else if (status != C2_OK) {
- LOG(ERROR) << "createComponent(" << name.c_str()
- << ") -- call failed: " << status << ".";
+ if (status == C2_NOT_FOUND) {
+ LOG(VERBOSE) << "createComponent(" << name.c_str()
+ << ") -- component not found.";
+ } else {
+ LOG(ERROR) << "createComponent(" << name.c_str()
+ << ") -- call failed: " << status << ".";
+ }
return status;
} else if (!*component) {
LOG(ERROR) << "createComponent(" << name.c_str()
@@ -718,8 +723,13 @@
<< ") -- transaction failed.";
return C2_TRANSACTION_FAILED;
} else if (status != C2_OK) {
- LOG(ERROR) << "createComponent(" << name.c_str()
- << ") -- call failed: " << status << ".";
+ if (status == C2_NOT_FOUND) {
+ LOG(VERBOSE) << "createInterface(" << name.c_str()
+ << ") -- component not found.";
+ } else {
+ LOG(ERROR) << "createInterface(" << name.c_str()
+ << ") -- call failed: " << status << ".";
+ }
return status;
}
@@ -946,11 +956,11 @@
std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
std::string const& name = GetServiceNames()[index];
- LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
+ LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\"";
sp<Base> baseStore = Base::getService(name);
CHECK(baseStore) << "Codec2 service \"" << name << "\""
" inaccessible for unknown reasons.";
- LOG(INFO) << "Client to Codec2 service \"" << name << "\" created";
+ LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created";
return std::make_shared<Codec2Client>(baseStore, index);
}
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index 46bea2e..a16b106 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -47,6 +47,11 @@
"libbinder",
],
required: ["android.hardware.media.c2@1.1-default-seccomp_policy"],
+
+ // The content in manifest_media_c2_V1_1_default.xml can be included
+ // directly in the main device manifest.xml file or via vintf_fragments.
+ // (Remove the line below if the entry is already in the main manifest.)
+ vintf_fragments: ["manifest_media_c2_V1_1_default.xml"],
}
// seccomp policy file.
diff --git a/media/codec2/hidl/services/manifest_media_c2_V1_0_default.xml b/media/codec2/hidl/services/manifest_media_c2_V1_0_default.xml
new file mode 100644
index 0000000..e97c3ce
--- /dev/null
+++ b/media/codec2/hidl/services/manifest_media_c2_V1_0_default.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal>
+ <name>android.hardware.media.c2</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IComponentStore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/media/codec2/hidl/services/manifest_media_c2_V1_1_default.xml b/media/codec2/hidl/services/manifest_media_c2_V1_1_default.xml
new file mode 100644
index 0000000..bf0d72f
--- /dev/null
+++ b/media/codec2/hidl/services/manifest_media_c2_V1_1_default.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal>
+ <name>android.hardware.media.c2</name>
+ <transport>hwbinder</transport>
+ <version>1.1</version>
+ <interface>
+ <name>IComponentStore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 51d6ffa..f3e37e0 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -95,6 +95,10 @@
name: "libcodec2-internal-defaults",
defaults: ["libcodec2-impl-defaults"],
+ header_libs: [
+ "libcodec2_internal",
+ ],
+
shared_libs: [
"libcutils", // for properties
],
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index ca721df..bdb724b 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -13,6 +13,9 @@
"libsonivox",
"libstagefright_foundation",
"libwatchdog",
+ ],
+
+ shared_libs: [
"libbase",
- ]
+ ],
}
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index d7c4b5c..bc8632c 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -10,6 +10,7 @@
],
shared_libs: [
+ "libbase",
"libcgrouprc#29",
"libvndksupport#29",
],
@@ -28,7 +29,6 @@
"android.hidl.memory@1.0",
"android.hidl.token@1.0",
"android.hidl.token@1.0-utils",
- "libbase",
"libcutils",
"libhidlbase",
"libhidlmemory",
diff --git a/media/libmedia/aidl/android/media/IResourceManagerService.aidl b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
index 1b2d522..3dd0859 100644
--- a/media/libmedia/aidl/android/media/IResourceManagerService.aidl
+++ b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
@@ -94,12 +94,4 @@
* remove existing override on originalPid if newPid is -1.
*/
void overridePid(int originalPid, int newPid);
-
- /**
- * Mark a client for pending removal
- *
- * @param pid pid from which the client's resources will be removed.
- * @param clientId clientId within the pid that will be removed.
- */
- void markClientForPendingRemoval(int pid, long clientId);
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index cb6798e..af8096d 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -3148,11 +3148,17 @@
if (buffer->meta_data().findInt32(kKeyIsEndOfStream, &isEOS) && isEOS) {
int64_t eosSampleTimestampUs = -1;
CHECK(buffer->meta_data().findInt64(kKeyTime, &eosSampleTimestampUs));
- ALOGV("eosSampleTimestampUs:%" PRId64, eosSampleTimestampUs);
- lastSampleDurationUs = eosSampleTimestampUs - previousSampleTimestampWithoutFudgeUs
- - previousPausedDurationUs;
- CHECK(lastSampleDurationUs >= 0);
- lastSampleDurationTicks = (lastSampleDurationUs * mTimeScale + 500000LL)/1000000LL;
+ if (eosSampleTimestampUs > 0) {
+ lastSampleDurationUs = eosSampleTimestampUs -
+ previousSampleTimestampWithoutFudgeUs -
+ previousPausedDurationUs;
+ if (lastSampleDurationUs >= 0) {
+ lastSampleDurationTicks = (lastSampleDurationUs * mTimeScale + 500000LL) /
+ 1000000LL;
+ } else {
+ ALOGW("lastSampleDurationUs %" PRId64 " is negative", lastSampleDurationUs);
+ }
+ }
buffer->release();
buffer = nullptr;
mSource->stop();
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 3e39c6d..b597583 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -199,7 +199,6 @@
void addResource(const MediaResourceParcel &resource);
void removeResource(const MediaResourceParcel &resource);
void removeClient();
- void markClientForPendingRemoval();
bool reclaimResource(const std::vector<MediaResourceParcel> &resources);
private:
@@ -281,14 +280,6 @@
mService->removeClient(mPid, getId(mClient));
}
-void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() {
- Mutex::Autolock _l(mLock);
- if (mService == nullptr) {
- return;
- }
- mService->markClientForPendingRemoval(mPid, getId(mClient));
-}
-
bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
const std::vector<MediaResourceParcel> &resources) {
Mutex::Autolock _l(mLock);
@@ -1441,13 +1432,7 @@
status_t MediaCodec::release() {
sp<AMessage> msg = new AMessage(kWhatRelease, this);
- sp<AMessage> response;
- return PostAndAwaitResponse(msg, &response);
-}
-status_t MediaCodec::releaseAsync() {
- sp<AMessage> msg = new AMessage(kWhatRelease, this);
- msg->setInt32("async", 1);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
@@ -2615,9 +2600,7 @@
mResourceManagerProxy->removeClient();
- if (mReplyID != nullptr) {
- (new AMessage)->postReply(mReplyID);
- }
+ (new AMessage)->postReply(mReplyID);
break;
}
@@ -3016,14 +2999,6 @@
pushBlankBuffersToNativeWindow(mSurface.get());
}
- int32_t async = 0;
- if (msg->findInt32("async", &async) && async) {
- mResourceManagerProxy->markClientForPendingRemoval();
- handleSetSurface(NULL);
- (new AMessage)->postReply(mReplyID);
- mReplyID = 0;
- }
-
break;
}
diff --git a/media/libstagefright/codecs/amrnb/common/Android.bp b/media/libstagefright/codecs/amrnb/common/Android.bp
index ea8b073..bcf63d5 100644
--- a/media/libstagefright/codecs/amrnb/common/Android.bp
+++ b/media/libstagefright/codecs/amrnb/common/Android.bp
@@ -1,6 +1,7 @@
cc_library {
name: "libstagefright_amrnb_common",
vendor_available: true,
+ host_supported: true,
srcs: [
"src/add.cpp",
@@ -73,6 +74,12 @@
"-Werror",
],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
//addressing b/25409744
//sanitize: {
// misc_undefined: [
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index e18117e..3381d2e 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -1,6 +1,7 @@
cc_library_static {
name: "libstagefright_amrnbdec",
vendor_available: true,
+ host_supported: true,
srcs: [
"src/a_refl.cpp",
@@ -61,6 +62,12 @@
"libstagefright_amrnb_common",
"liblog",
],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
@@ -100,6 +107,7 @@
cc_test {
name: "libstagefright_amrnbdec_test",
gtest: false,
+ host_supported: true,
srcs: ["test/amrnbdec_test.cpp"],
@@ -118,6 +126,12 @@
"liblog",
],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
//sanitize: {
// misc_undefined: [
// "signed-integer-overflow",
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/Android.bp b/media/libstagefright/codecs/amrnb/fuzzer/Android.bp
new file mode 100644
index 0000000..54de1cc
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/fuzzer/Android.bp
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "amrnb_dec_fuzzer",
+ host_supported: true,
+ srcs: [
+ "amrnb_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libstagefright_amrnbdec",
+ "libstagefright_amrnb_common",
+ "liblog",
+ ],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/README.md b/media/libstagefright/codecs/amrnb/fuzzer/README.md
new file mode 100644
index 0000000..7791b83
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/fuzzer/README.md
@@ -0,0 +1,62 @@
+# Fuzzer for libstagefright_amrnbdec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR-NB is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+AMR-NB supports the following parameters:
+1. Stream format (parameter name: `input_format`)
+2. 3GPP frame type (parameter name: `frame_type`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `input_format` | 0. `MIME_IETF` 1. `IF2` | Bit 0 (LSB) of 1st byte of data. |
+| `frame_type` | 0. `AMR_475` 1. `AMR_515` 2. `AMR_59` 3. `AMR_67` 4. `AMR_74` 5. `AMR_795` 6. `AMR_102` 7. `AMR_122` | Bits 3, 4 and 5 of 1st byte of data. |
+
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+If the decode operation was successful, the input is advanced by the frame size
+which is based on `input_format` and `frame_type` selected.
+If the decode operation was un-successful, the input is still advanced by frame size so
+that the fuzzer can proceed to feed the next frame.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build amrnb_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) amrnb_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some amrnb files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/amrnb_dec_fuzzer/amrnb_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/amrnb_dec_fuzzer/amrnb_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
new file mode 100644
index 0000000..d4e7e5c
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <string.h>
+#include <algorithm>
+#include "gsmamr_dec.h"
+
+// Constants for AMR-NB
+constexpr int32_t kSamplesPerFrame = L_FRAME;
+constexpr int32_t kBitsPerSample = 16;
+constexpr int32_t kOutputBufferSize = kSamplesPerFrame * kBitsPerSample / 8;
+const bitstream_format kBitStreamFormats[2] = {MIME_IETF, IF2};
+const int32_t kLocalWmfDecBytesPerFrame[8] = {12, 13, 15, 17, 19, 20, 26, 31};
+const int32_t kLocalIf2DecBytesPerFrame[8] = {13, 14, 16, 18, 19, 21, 26, 31};
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ int16_t initDecoder();
+ void deInitDecoder();
+ void decodeFrames(const uint8_t *data, size_t size);
+
+ private:
+ void *mAmrHandle = nullptr;
+};
+
+int16_t Codec::initDecoder() { return GSMInitDecode(&mAmrHandle, (Word8 *)"AMRNBDecoder"); }
+
+void Codec::deInitDecoder() { GSMDecodeFrameExit(&mAmrHandle); }
+
+void Codec::decodeFrames(const uint8_t *data, size_t size) {
+ while (size > 0) {
+ uint8_t mode = *data;
+ bool bit = mode & 0x01;
+ bitstream_format bitsreamFormat = kBitStreamFormats[bit];
+ int32_t frameSize = 0;
+ /* Find frame type */
+ Frame_Type_3GPP frameType = static_cast<Frame_Type_3GPP>((mode >> 3) & 0x07);
+ ++data;
+ --size;
+ if (bit) {
+ frameSize = kLocalIf2DecBytesPerFrame[frameType];
+ } else {
+ frameSize = kLocalWmfDecBytesPerFrame[frameType];
+ }
+ int16_t outputBuf[kOutputBufferSize];
+ uint8_t *inputBuf = new uint8_t[frameSize];
+ if (!inputBuf) {
+ return;
+ }
+ int32_t minSize = std::min((int32_t)size, frameSize);
+ memcpy(inputBuf, data, minSize);
+ AMRDecode(mAmrHandle, frameType, inputBuf, outputBuf, bitsreamFormat);
+ /* AMRDecode() decodes minSize number of bytes if decode is successful.
+ * AMRDecode() returns -1 if decode fails.
+ * Even if no bytes are decoded, increment by minSize to ensure fuzzer proceeds
+ * to feed next data */
+ data += minSize;
+ size -= minSize;
+ delete[] inputBuf;
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < 2) {
+ return 0;
+ }
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder() == 0) {
+ codec->decodeFrames(data, size);
+ }
+ delete codec;
+ return 0;
+}
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 0e983b2..022c48e 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -139,8 +139,6 @@
// object.
status_t release();
- status_t releaseAsync();
-
status_t flush();
status_t queueInputBuffer(
diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp
index 849623a..2aefa7d 100644
--- a/media/libwatchdog/Android.bp
+++ b/media/libwatchdog/Android.bp
@@ -19,10 +19,8 @@
],
export_include_dirs: ["include"],
shared_libs: [
- "liblog",
- ],
- static_libs: [
"libbase",
+ "liblog",
],
target: {
windows: {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index dd51658..aaa28bc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -33,7 +33,10 @@
namespace android {
-DeviceTypeSet APM_AUDIO_OUT_DEVICE_REMOTE_ALL = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
+static const DeviceTypeSet& getAllOutRemoteDevices() {
+ static const DeviceTypeSet allOutRemoteDevices = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
+ return allOutRemoteDevices;
+}
AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
AudioPolicyClientInterface *clientInterface)
@@ -681,7 +684,7 @@
const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
&& (!(outputDesc->devices()
- .containsDeviceAmongTypes(APM_AUDIO_OUT_DEVICE_REMOTE_ALL)))) {
+ .containsDeviceAmongTypes(getAllOutRemoteDevices())))) {
return true;
}
}
@@ -693,7 +696,7 @@
nsecs_t sysTime = systemTime();
for (size_t i = 0; i < size(); i++) {
const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
- if (outputDesc->devices().containsDeviceAmongTypes(APM_AUDIO_OUT_DEVICE_REMOTE_ALL) &&
+ if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
// do not consider re routing (when the output is going to a dynamic policy)
// as "remote playback"
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index a7d7cf6..b14d2bb 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -41,20 +41,23 @@
{
struct legacy_strategy_map { const char *name; legacy_strategy id; };
-static const std::vector<legacy_strategy_map> gLegacyStrategy = {
- { "STRATEGY_NONE", STRATEGY_NONE },
- { "STRATEGY_MEDIA", STRATEGY_MEDIA },
- { "STRATEGY_PHONE", STRATEGY_PHONE },
- { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
- { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
- { "STRATEGY_DTMF", STRATEGY_DTMF },
- { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
- { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
- { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
- { "STRATEGY_REROUTING", STRATEGY_REROUTING },
- { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
- { "STRATEGY_CALL_ASSISTANT", STRATEGY_CALL_ASSISTANT },
-};
+static const std::vector<legacy_strategy_map>& getLegacyStrategy() {
+ static const std::vector<legacy_strategy_map> legacyStrategy = {
+ { "STRATEGY_NONE", STRATEGY_NONE },
+ { "STRATEGY_MEDIA", STRATEGY_MEDIA },
+ { "STRATEGY_PHONE", STRATEGY_PHONE },
+ { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
+ { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
+ { "STRATEGY_DTMF", STRATEGY_DTMF },
+ { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
+ { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
+ { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
+ { "STRATEGY_REROUTING", STRATEGY_REROUTING },
+ { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
+ { "STRATEGY_CALL_ASSISTANT", STRATEGY_CALL_ASSISTANT },
+ };
+ return legacyStrategy;
+}
Engine::Engine()
{
@@ -63,7 +66,8 @@
"Policy Engine configuration is partially invalid, skipped %zu elements",
result.nbSkippedElement);
- for (const auto &strategy : gLegacyStrategy) {
+ auto legacyStrategy = getLegacyStrategy();
+ for (const auto &strategy : legacyStrategy) {
mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
}
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 453984e..e0884f4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -126,6 +126,8 @@
static const String16 sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
static const String16
sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
+static const String16 sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
// Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java
static constexpr int32_t kVendorClientScore = 200;
@@ -2146,6 +2148,8 @@
auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
+ bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
+ clientPid, clientUid);
Mutex::Autolock lock(mServiceLock);
@@ -2160,7 +2164,8 @@
}
sp<ServiceListener> serviceListener =
- new ServiceListener(this, listener, clientUid, clientPid, isVendorListener);
+ new ServiceListener(this, listener, clientUid, clientPid, isVendorListener,
+ openCloseCallbackAllowed);
auto ret = serviceListener->initialize();
if (ret != NO_ERROR) {
String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
@@ -2923,6 +2928,9 @@
sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
+
return OK;
}
@@ -2963,6 +2971,9 @@
sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName);
+
return OK;
}
@@ -3759,6 +3770,29 @@
});
}
+void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
+ const String16& clientPackageName) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (const auto& it : mListenerList) {
+ if (!it->isOpenCloseCallbackAllowed()) {
+ continue;
+ }
+
+ binder::Status ret;
+ String16 cameraId64(cameraId);
+ if (open) {
+ ret = it->getListener()->onCameraOpened(cameraId64, clientPackageName);
+ } else {
+ ret = it->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 265a572..f12b4cc 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -912,9 +912,10 @@
class ServiceListener : public virtual IBinder::DeathRecipient {
public:
ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener,
- int uid, int pid, bool isVendorClient)
+ int uid, int pid, bool isVendorClient, bool openCloseCallbackAllowed)
: mParent(parent), mListener(listener), mListenerUid(uid), mListenerPid(pid),
- mIsVendorListener(isVendorClient) { }
+ mIsVendorListener(isVendorClient),
+ mOpenCloseCallbackAllowed(openCloseCallbackAllowed) { }
status_t initialize() {
return IInterface::asBinder(mListener)->linkToDeath(this);
@@ -931,6 +932,7 @@
int getListenerPid() { return mListenerPid; }
sp<hardware::ICameraServiceListener> getListener() { return mListener; }
bool isVendorListener() { return mIsVendorListener; }
+ bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; }
private:
wp<CameraService> mParent;
@@ -938,6 +940,7 @@
int mListenerUid = -1;
int mListenerPid = -1;
bool mIsVendorListener = false;
+ bool mOpenCloseCallbackAllowed = false;
};
// Guarded by mStatusListenerMutex
@@ -960,6 +963,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 95493a1..7148035 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -58,6 +58,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/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 835f8bb..b4a9ff6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -23,7 +23,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
mprotect: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm64.policy b/services/mediacodec/seccomp_policy/mediacodec-arm64.policy
index 835f8bb..b4a9ff6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm64.policy
@@ -23,7 +23,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
mprotect: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 512e675..9058f10 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -31,7 +31,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
prctl: 1
getuid32: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index d9603ef..4c51a9c 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -35,7 +35,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
prctl: 1
writev: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 07536fc..e1f7fe7 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -48,6 +48,14 @@
# for dynamically loading extractors
pread64: 1
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
+
# for FileSource
readlinkat: 1
_llseek: 1
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index ff45c87..be5af00 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -114,7 +114,6 @@
info.uid = uid;
info.clientId = clientId;
info.client = client;
- info.pendingRemoval = false;
index = infos.add(clientId, info);
}
@@ -649,36 +648,6 @@
return Status::ok();
}
-Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) {
- String8 log = String8::format(
- "markClientForPendingRemoval(pid %d, clientId %lld)",
- pid, (long long) clientId);
- mServiceLog->add(log);
-
- Mutex::Autolock lock(mLock);
- if (!mProcessInfo->isValidPid(pid)) {
- ALOGE("Rejected markClientForPendingRemoval call with invalid pid.");
- return Status::fromServiceSpecificError(BAD_VALUE);
- }
- ssize_t index = mMap.indexOfKey(pid);
- if (index < 0) {
- ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
- pid, (long long)clientId);
- return Status::ok();
- }
- ResourceInfos &infos = mMap.editValueAt(index);
-
- index = infos.indexOfKey(clientId);
- if (index < 0) {
- ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
- return Status::ok();
- }
-
- ResourceInfo &info = infos.editValueAt(index);
- info.pendingRemoval = true;
- return Status::ok();
-}
-
bool ResourceManagerService::getPriority_l(int pid, int* priority) {
int newPid = pid;
@@ -724,12 +693,6 @@
int lowestPriorityPid;
int lowestPriority;
int callingPriority;
-
- // Before looking into other processes, check if we have clients marked for
- // pending removal in the same process.
- if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) {
- return true;
- }
if (!getPriority_l(callingPid, &callingPriority)) {
ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
callingPid);
@@ -798,8 +761,7 @@
}
bool ResourceManagerService::getBiggestClient_l(
- int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client,
- bool pendingRemovalOnly) {
+ int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) {
ssize_t index = mMap.indexOfKey(pid);
if (index < 0) {
ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid);
@@ -811,9 +773,6 @@
const ResourceInfos &infos = mMap.valueAt(index);
for (size_t i = 0; i < infos.size(); ++i) {
const ResourceList &resources = infos[i].resources;
- if (pendingRemovalOnly && !infos[i].pendingRemoval) {
- continue;
- }
for (auto it = resources.begin(); it != resources.end(); it++) {
const MediaResourceParcel &resource = it->second;
if (resource.type == type) {
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index ee982b7..f500c62 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -18,8 +18,6 @@
#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
-#include <map>
-
#include <aidl/android/media/BnResourceManagerService.h>
#include <arpa/inet.h>
#include <media/MediaResource.h>
@@ -52,7 +50,6 @@
std::shared_ptr<IResourceManagerClient> client;
sp<DeathNotifier> deathNotifier;
ResourceList resources;
- bool pendingRemoval{false};
};
// TODO: convert these to std::map
@@ -125,8 +122,6 @@
int originalPid,
int newPid) override;
- Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;
-
Status removeResource(int pid, int64_t clientId, bool checkValid);
private:
@@ -151,8 +146,7 @@
// Gets the client who owns biggest piece of specified resource type from pid.
// Returns false if failed. The client will remain unchanged if failed.
bool getBiggestClient_l(int pid, MediaResource::Type type,
- std::shared_ptr<IResourceManagerClient> *client,
- bool pendingRemovalOnly = false);
+ std::shared_ptr<IResourceManagerClient> *client);
bool isCallingPriorityHigher_l(int callingPid, int pid);
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 702935d..5d839fa 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -472,56 +472,6 @@
}
}
- void testMarkClientForPendingRemoval() {
- bool result;
-
- {
- addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
-
- std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
-
- // Remove low priority clients
- mService->removeClient(kTestPid1, getId(mTestClient1));
-
- // no lower priority client
- CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
-
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
-
- // client marked for pending removal from the same process got reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
-
- // clean up client 3 which still left
- mService->removeClient(kTestPid2, getId(mTestClient3));
- }
-
- {
- addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
-
- std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
-
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
-
- // client marked for pending removal from the same process got reclaimed
- // first, even though there are lower priority process
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
-
- // lower priority client got reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
-
- // clean up client 3 which still left
- mService->removeClient(kTestPid2, getId(mTestClient3));
- }
- }
-
void testRemoveClient() {
addResource();
@@ -950,8 +900,4 @@
testOverridePid();
}
-TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) {
- testMarkClientForPendingRemoval();
-}
-
} // namespace android