Merge changes from topic "Fix for 65483665 (lmp-mr1-dev)" into lmp-mr1-dev
* changes:
RESTRICT AUTOMERGE SimpleSoftOMXComponent: change CHECK to error notification.
RESTRICT AUTOMERGE SoftHEVC: Handle error in reInitDecoder()
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 81edcb4..11cf98b 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -1023,6 +1023,10 @@
bool haveVideo = false;
for (size_t i = 0; i < numTracks; ++i) {
sp<MediaSource> source = extractor->getTrack(i);
+ if (source == NULL) {
+ fprintf(stderr, "skip NULL track %zu, track count %zu.\n", i, numTracks);
+ continue;
+ }
const char *mime;
CHECK(source->getFormat()->findCString(
@@ -1082,6 +1086,10 @@
}
mediaSource = extractor->getTrack(i);
+ if (mediaSource == NULL) {
+ fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
+ return -1;
+ }
}
}
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 0566d14..3c4187d 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -171,7 +171,8 @@
mWriter = new MPEG2TSWriter(
this, &MyConvertingStreamSource::WriteDataWrapper);
- for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ size_t numTracks = extractor->countTracks();
+ for (size_t i = 0; i < numTracks; ++i) {
const sp<MetaData> &meta = extractor->getTrackMetaData(i);
const char *mime;
@@ -181,7 +182,12 @@
continue;
}
- CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
+ sp<MediaSource> track = extractor->getTrack(i);
+ if (track == NULL) {
+ fprintf(stderr, "skip NULL track %zu, total tracks %zu\n", i, numTracks);
+ continue;
+ }
+ CHECK_EQ(mWriter->addSource(track), (status_t)OK);
}
CHECK_EQ(mWriter->start(), (status_t)OK);
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
index 01f8d65..f7106b2 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
@@ -36,6 +36,11 @@
uint8_t previousEncryptedCounter[kBlockSize];
memset(previousEncryptedCounter, 0, kBlockSize);
+ if (key.size() != kBlockSize || (sizeof(Iv) / sizeof(uint8_t)) != kBlockSize) {
+ android_errorWriteLog(0x534e4554, "63982768");
+ return android::ERROR_DRM_DECRYPT;
+ }
+
size_t offset = 0;
AES_KEY opensslKey;
AES_set_encrypt_key(key.array(), kBlockBitCount, &opensslKey);
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
index b416266..edb8445 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
@@ -18,6 +18,7 @@
#define CLEARKEY_AES_CTR_DECRYPTOR_H_
#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaErrors.h>
#include <Utils.h>
#include <utils/Errors.h>
#include <utils/Vector.h>
diff --git a/drm/mediadrm/plugins/clearkey/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/InitDataParser.cpp
index c22d73a..c9c2a38 100644
--- a/drm/mediadrm/plugins/clearkey/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/InitDataParser.cpp
@@ -109,7 +109,7 @@
memcpy(&keyIdCount, &initData[readPosition], sizeof(keyIdCount));
keyIdCount = ntohl(keyIdCount);
readPosition += sizeof(keyIdCount);
- if (readPosition + (keyIdCount * kKeyIdSize) !=
+ if (readPosition + ((uint64_t)keyIdCount * kKeyIdSize) !=
initData.size() - sizeof(uint32_t)) {
return android::ERROR_DRM_CANNOT_HANDLE;
}
diff --git a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
index 039e402..5db8290 100644
--- a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
+++ b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
@@ -34,7 +34,7 @@
uint8_t* destination, const SubSample* subSamples,
size_t numSubSamples, size_t* bytesDecryptedOut) {
Vector<uint8_t> keyVector;
- keyVector.appendArray(key, kBlockSize);
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
AesCtrDecryptor decryptor;
return decryptor.decrypt(keyVector, iv, source, destination, subSamples,
@@ -57,6 +57,67 @@
}
};
+TEST_F(AesCtrDecryptorTest, DecryptsWithEmptyKey) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.clear();
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
+TEST_F(AesCtrDecryptorTest, DecryptsWithKeyTooLong) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ uint8_t key[kBlockSize * 2] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+ };
+
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
TEST_F(AesCtrDecryptorTest, DecryptsContiguousEncryptedBlock) {
const size_t kTotalSize = 64;
const size_t kNumSubsamples = 1;
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 4a41037..74733ee 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -414,6 +414,10 @@
return -EINVAL;
}
effect_param_t *cmd = (effect_param_t *) pCmdData;
+ if (cmd->psize != sizeof(int32_t)) {
+ android_errorWriteLog(0x534e4554, "63662938");
+ return -EINVAL;
+ }
*(int *)pReplyData = Downmix_setParameter(pDownmixer, *(int32_t *)cmd->data,
cmd->vsize, cmd->data + sizeof(int32_t));
break;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 593580f..eda2618 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -32,6 +32,15 @@
// effect_handle_t interface implementation for bass boost
extern "C" const struct effect_interface_s gLvmEffectInterface;
+// Turn on VERY_VERY_VERBOSE_LOGGING to log parameter get and set for effects.
+
+//#define VERY_VERY_VERBOSE_LOGGING
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while (false)
+#endif
+
#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
if (LvmStatus == LVM_NULLADDRESS){\
ALOGV("\tLVM_ERROR : Parameter error - "\
@@ -137,23 +146,43 @@
void LvmEffect_free (EffectContext *pContext);
int Effect_setConfig (EffectContext *pContext, effect_config_t *pConfig);
void Effect_getConfig (EffectContext *pContext, effect_config_t *pConfig);
-int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue);
+int BassBoost_setParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue);
int BassBoost_getParameter (EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue);
-int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValue);
-int Virtualizer_getParameter (EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue);
-int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue);
-int Equalizer_getParameter (EffectContext *pContext,
+ uint32_t paramSize,
void *pParam,
uint32_t *pValueSize,
void *pValue);
-int Volume_setParameter (EffectContext *pContext, void *pParam, void *pValue);
+int Virtualizer_setParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue);
+int Virtualizer_getParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue);
+int Equalizer_setParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue);
+int Equalizer_getParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue);
+int Volume_setParameter (EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue);
int Volume_getParameter (EffectContext *pContext,
+ uint32_t paramSize,
void *pParam,
uint32_t *pValueSize,
void *pValue);
@@ -1967,61 +1996,54 @@
//
//----------------------------------------------------------------------------
-int BassBoost_getParameter(EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue){
+int BassBoost_getParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue) {
int status = 0;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
- int32_t param2;
- char *name;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tBassBoost_getParameter start");
+ ALOGVV("%s start", __func__);
- switch (param){
- case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
- if (*pValueSize != sizeof(uint32_t)){
- ALOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize1 %d", *pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(uint32_t);
- break;
- case BASSBOOST_PARAM_STRENGTH:
- if (*pValueSize != sizeof(int16_t)){
- ALOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize2 %d", *pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(int16_t);
- break;
-
- default:
- ALOGV("\tLVM_ERROR : BassBoost_getParameter() invalid param %d", param);
- return -EINVAL;
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
}
-
- switch (param){
+ switch (params[0]) {
case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
- *(uint32_t *)pValue = 1;
+ if (*pValueSize != sizeof(uint32_t)) { // legacy: check equality here.
+ ALOGV("%s BASSBOOST_PARAM_STRENGTH_SUPPORTED invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
- //ALOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH_SUPPORTED Value is %d",
- // *(uint32_t *)pValue);
+ *(uint32_t *)pValue = 1;
+ ALOGVV("%s BASSBOOST_PARAM_STRENGTH_SUPPORTED %u", __func__, *(uint32_t *)pValue);
break;
case BASSBOOST_PARAM_STRENGTH:
- *(int16_t *)pValue = BassGetStrength(pContext);
+ if (*pValueSize != sizeof(int16_t)) { // legacy: check equality here.
+ ALOGV("%s BASSBOOST_PARAM_STRENGTH invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
- //ALOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH Value is %d",
- // *(int16_t *)pValue);
+ *(int16_t *)pValue = BassGetStrength(pContext);
+ ALOGVV("%s BASSBOOST_PARAM_STRENGTH %d", __func__, *(int16_t *)pValue);
break;
default:
- ALOGV("\tLVM_ERROR : BassBoost_getParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
status = -EINVAL;
break;
}
- //ALOGV("\tBassBoost_getParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end BassBoost_getParameter */
@@ -2040,27 +2062,42 @@
//
//----------------------------------------------------------------------------
-int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue){
+int BassBoost_setParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue) {
int status = 0;
- int16_t strength;
- int32_t *pParamTemp = (int32_t *)pParam;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tBassBoost_setParameter start");
+ ALOGVV("%s start", __func__);
- switch (*pParamTemp){
- case BASSBOOST_PARAM_STRENGTH:
- strength = *(int16_t *)pValue;
- //ALOGV("\tBassBoost_setParameter() BASSBOOST_PARAM_STRENGTH value is %d", strength);
- //ALOGV("\tBassBoost_setParameter() Calling pBassBoost->BassSetStrength");
+ if (paramSize != sizeof(int32_t)) { // legacy: check equality here.
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s BASSBOOST_PARAM_STRENGTH invalid valueSize: %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
+
+ const int16_t strength = *(int16_t *)pValue;
+ ALOGVV("%s BASSBOOST_PARAM_STRENGTH %d", __func__, strength);
+ ALOGVV("%s BASSBOOST_PARAM_STRENGTH Calling BassSetStrength", __func__);
BassSetStrength(pContext, (int32_t)strength);
- //ALOGV("\tBassBoost_setParameter() Called pBassBoost->BassSetStrength");
- break;
+ ALOGVV("%s BASSBOOST_PARAM_STRENGTH Called BassSetStrength", __func__);
+ } break;
+
default:
- ALOGV("\tLVM_ERROR : BassBoost_setParameter() invalid param %d", *pParamTemp);
+ ALOGV("%s invalid param %d", __func__, params[0]);
+ status = -EINVAL;
break;
}
- //ALOGV("\tBassBoost_setParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end BassBoost_setParameter */
@@ -2085,93 +2122,97 @@
//
//----------------------------------------------------------------------------
-int Virtualizer_getParameter(EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue){
+int Virtualizer_getParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue) {
int status = 0;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
- char *name;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tVirtualizer_getParameter start");
+ ALOGVV("%s start", __func__);
- switch (param){
- case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
- if (*pValueSize != sizeof(uint32_t)){
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(uint32_t);
- break;
- case VIRTUALIZER_PARAM_STRENGTH:
- if (*pValueSize != sizeof(int16_t)){
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize2 %d",*pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(int16_t);
- break;
- case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES:
- // return value size can only be interpreted as relative to input value,
- // deferring validity check to below
- break;
- case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
- if (*pValueSize != sizeof(uint32_t)){
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(uint32_t);
- break;
- default:
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid param %d", param);
- return -EINVAL;
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
}
-
- switch (param){
+ switch (params[0]) {
case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
- *(uint32_t *)pValue = 1;
+ if (*pValueSize != sizeof(uint32_t)) { // legacy: check equality here.
+ ALOGV("%s VIRTUALIZER_PARAM_STRENGTH_SUPPORTED invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
- //ALOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH_SUPPORTED Value is %d",
- // *(uint32_t *)pValue);
+ *(uint32_t *)pValue = 1;
+ ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH_SUPPORTED %d", __func__, *(uint32_t *)pValue);
break;
case VIRTUALIZER_PARAM_STRENGTH:
+ if (*pValueSize != sizeof(int16_t)) { // legacy: check equality here.
+ ALOGV("%s VIRTUALIZER_PARAM_STRENGTH invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
+
*(int16_t *)pValue = VirtualizerGetStrength(pContext);
- //ALOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH Value is %d",
- // *(int16_t *)pValue);
+ ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH %d", __func__, *(int16_t *)pValue);
break;
case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: {
- const audio_channel_mask_t channelMask = (audio_channel_mask_t) *pParamTemp++;
- const audio_devices_t deviceType = (audio_devices_t) *pParamTemp;
- uint32_t nbChannels = audio_channel_count_from_out_mask(channelMask);
- if (*pValueSize < 3 * nbChannels * sizeof(int32_t)){
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
- return -EINVAL;
+ if (paramSize < 3 * sizeof(int32_t)) {
+ ALOGV("%s VIRTUALIZER_PARAM_SPEAKER_ANGLES invalid paramSize: %u",
+ __func__, paramSize);
+ status = -EINVAL;
+ break;
}
+
+ const audio_channel_mask_t channelMask = (audio_channel_mask_t) params[1];
+ const audio_devices_t deviceType = (audio_devices_t) params[2];
+ const uint32_t nbChannels = audio_channel_count_from_out_mask(channelMask);
+ const uint32_t valueSizeRequired = 3 * nbChannels * sizeof(int32_t);
+ if (*pValueSize < valueSizeRequired) {
+ ALOGV("%s VIRTUALIZER_PARAM_SPEAKER_ANGLES invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = valueSizeRequired;
+
// verify the configuration is supported
status = VirtualizerIsConfigurationSupported(channelMask, deviceType);
if (status == 0) {
- ALOGV("VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES supports mask=0x%x device=0x%x",
- channelMask, deviceType);
+ ALOGV("%s VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES mask=0x%x device=0x%x",
+ __func__, channelMask, deviceType);
// configuration is supported, get the angles
VirtualizerGetSpeakerAngles(channelMask, deviceType, (int32_t *)pValue);
}
- }
- break;
+ } break;
case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
- *(uint32_t *)pValue = (uint32_t) VirtualizerGetVirtualizationMode(pContext);
+ if (*pValueSize != sizeof(uint32_t)) { // legacy: check equality here.
+ ALOGV("%s VIRTUALIZER_PARAM_VIRTUALIZATION_MODE invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
+
+ *(uint32_t *)pValue = (uint32_t) VirtualizerGetVirtualizationMode(pContext);
break;
default:
- ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
status = -EINVAL;
break;
}
- ALOGV("\tVirtualizer_getParameter end returning status=%d", status);
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Virtualizer_getParameter */
@@ -2190,37 +2231,57 @@
//
//----------------------------------------------------------------------------
-int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValue){
+int Virtualizer_setParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue) {
int status = 0;
- int16_t strength;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tVirtualizer_setParameter start");
+ ALOGVV("%s start", __func__);
- switch (param){
- case VIRTUALIZER_PARAM_STRENGTH:
- strength = *(int16_t *)pValue;
- //ALOGV("\tVirtualizer_setParameter() VIRTUALIZER_PARAM_STRENGTH value is %d", strength);
- //ALOGV("\tVirtualizer_setParameter() Calling pVirtualizer->setStrength");
+ if (paramSize != sizeof(int32_t)) { // legacy: check equality here.
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
+ case VIRTUALIZER_PARAM_STRENGTH: {
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s VIRTUALIZER_PARAM_STRENGTH invalid valueSize: %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
+
+ const int16_t strength = *(int16_t *)pValue;
+ ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH %d", __func__, strength);
+ ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH Calling VirtualizerSetStrength", __func__);
VirtualizerSetStrength(pContext, (int32_t)strength);
- //ALOGV("\tVirtualizer_setParameter() Called pVirtualizer->setStrength");
- break;
+ ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH Called VirtualizerSetStrength", __func__);
+ } break;
case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: {
- const audio_devices_t deviceType = *(audio_devices_t *) pValue;
- status = VirtualizerForceVirtualizationMode(pContext, deviceType);
- //ALOGV("VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE device=0x%x result=%d",
- // deviceType, status);
+ if (valueSize < sizeof(int32_t)) {
+ ALOGV("%s VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE invalid valueSize: %u",
+ __func__, valueSize);
+ android_errorWriteLog(0x534e4554, "64478003");
+ status = -EINVAL;
+ break;
}
- break;
+
+ const audio_devices_t deviceType = (audio_devices_t)*(int32_t *)pValue;
+ status = VirtualizerForceVirtualizationMode(pContext, deviceType);
+ ALOGVV("%s VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE device=%#x result=%d",
+ __func__, deviceType, status);
+ } break;
default:
- ALOGV("\tLVM_ERROR : Virtualizer_setParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
+ status = -EINVAL;
break;
}
- //ALOGV("\tVirtualizer_setParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Virtualizer_setParameter */
@@ -2244,168 +2305,215 @@
// Side Effects:
//
//----------------------------------------------------------------------------
-int Equalizer_getParameter(EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue){
+int Equalizer_getParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue) {
int status = 0;
- int bMute = 0;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
- int32_t param2;
- char *name;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tEqualizer_getParameter start");
+ ALOGVV("%s start", __func__);
- switch (param) {
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
case EQ_PARAM_NUM_BANDS:
+ if (*pValueSize < sizeof(uint16_t)) {
+ ALOGV("%s EQ_PARAM_NUM_BANDS invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(uint16_t);
+
+ *(uint16_t *)pValue = (uint16_t)FIVEBAND_NUMBANDS;
+ ALOGVV("%s EQ_PARAM_NUM_BANDS %u", __func__, *(uint16_t *)pValue);
+ break;
+
case EQ_PARAM_CUR_PRESET:
+ if (*pValueSize < sizeof(uint16_t)) {
+ ALOGV("%s EQ_PARAM_CUR_PRESET invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(uint16_t);
+
+ *(uint16_t *)pValue = (uint16_t)EqualizerGetPreset(pContext);
+ ALOGVV("%s EQ_PARAM_CUR_PRESET %u", __func__, *(uint16_t *)pValue);
+ break;
+
case EQ_PARAM_GET_NUM_OF_PRESETS:
- case EQ_PARAM_BAND_LEVEL:
- case EQ_PARAM_GET_BAND:
+ if (*pValueSize < sizeof(uint16_t)) {
+ ALOGV("%s EQ_PARAM_GET_NUM_OF_PRESETS invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(uint16_t);
+
+ *(uint16_t *)pValue = (uint16_t)EqualizerGetNumPresets();
+ ALOGVV("%s EQ_PARAM_GET_NUM_OF_PRESETS %u", __func__, *(uint16_t *)pValue);
+ break;
+
+ case EQ_PARAM_GET_BAND: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_GET_BAND invalid paramSize: %u", __func__, paramSize);
+ status = -EINVAL;
+ break;
+ }
+ if (*pValueSize < sizeof(uint16_t)) {
+ ALOGV("%s EQ_PARAM_GET_BAND invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(uint16_t);
+
+ const int32_t frequency = params[1];
+ *(uint16_t *)pValue = (uint16_t)EqualizerGetBand(pContext, frequency);
+ ALOGVV("%s EQ_PARAM_GET_BAND frequency %d, band %u",
+ __func__, frequency, *(uint16_t *)pValue);
+ } break;
+
+ case EQ_PARAM_BAND_LEVEL: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_BAND_LEVEL invalid paramSize %u", __func__, paramSize);
+ status = -EINVAL;
+ break;
+ }
if (*pValueSize < sizeof(int16_t)) {
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1 %d", *pValueSize);
- return -EINVAL;
+ ALOGV("%s EQ_PARAM_BAND_LEVEL invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
}
*pValueSize = sizeof(int16_t);
- break;
+
+ const int32_t band = params[1];
+ if (band < 0 || band >= FIVEBAND_NUMBANDS) {
+ if (band < 0) {
+ android_errorWriteLog(0x534e4554, "32438598");
+ ALOGW("%s EQ_PARAM_BAND_LEVEL invalid band %d", __func__, band);
+ }
+ status = -EINVAL;
+ break;
+ }
+ *(int16_t *)pValue = (int16_t)EqualizerGetBandLevel(pContext, band);
+ ALOGVV("%s EQ_PARAM_BAND_LEVEL band %d, level %d",
+ __func__, band, *(int16_t *)pValue);
+ } break;
case EQ_PARAM_LEVEL_RANGE:
if (*pValueSize < 2 * sizeof(int16_t)) {
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 2 %d", *pValueSize);
- return -EINVAL;
+ ALOGV("%s EQ_PARAM_LEVEL_RANGE invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
}
*pValueSize = 2 * sizeof(int16_t);
- break;
- case EQ_PARAM_BAND_FREQ_RANGE:
- if (*pValueSize < 2 * sizeof(int32_t)) {
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 3 %d", *pValueSize);
- return -EINVAL;
- }
- *pValueSize = 2 * sizeof(int32_t);
- break;
- case EQ_PARAM_CENTER_FREQ:
- if (*pValueSize < sizeof(int32_t)) {
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 5 %d", *pValueSize);
- return -EINVAL;
- }
- *pValueSize = sizeof(int32_t);
- break;
-
- case EQ_PARAM_GET_PRESET_NAME:
- break;
-
- case EQ_PARAM_PROPERTIES:
- if (*pValueSize < (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t)) {
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1 %d", *pValueSize);
- return -EINVAL;
- }
- *pValueSize = (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t);
- break;
-
- default:
- ALOGV("\tLVM_ERROR : Equalizer_getParameter unknown param %d", param);
- return -EINVAL;
- }
-
- switch (param) {
- case EQ_PARAM_NUM_BANDS:
- *(uint16_t *)pValue = (uint16_t)FIVEBAND_NUMBANDS;
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
- break;
-
- case EQ_PARAM_LEVEL_RANGE:
*(int16_t *)pValue = -1500;
*((int16_t *)pValue + 1) = 1500;
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
- // *(int16_t *)pValue, *((int16_t *)pValue + 1));
+ ALOGVV("%s EQ_PARAM_LEVEL_RANGE min %d, max %d",
+ __func__, *(int16_t *)pValue, *((int16_t *)pValue + 1));
break;
- case EQ_PARAM_BAND_LEVEL:
- param2 = *pParamTemp;
- if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
+ case EQ_PARAM_BAND_FREQ_RANGE: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_BAND_FREQ_RANGE invalid paramSize: %u", __func__, paramSize);
status = -EINVAL;
- if (param2 < 0) {
- android_errorWriteLog(0x534e4554, "32438598");
- ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d", param2);
- }
break;
}
- *(int16_t *)pValue = (int16_t)EqualizerGetBandLevel(pContext, param2);
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
- // param2, *(int32_t *)pValue);
- break;
-
- case EQ_PARAM_CENTER_FREQ:
- param2 = *pParamTemp;
- if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
+ if (*pValueSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_BAND_FREQ_RANGE invalid *pValueSize %u", __func__, *pValueSize);
status = -EINVAL;
- if (param2 < 0) {
- android_errorWriteLog(0x534e4554, "32436341");
- ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d", param2);
- }
break;
}
- *(int32_t *)pValue = EqualizerGetCentreFrequency(pContext, param2);
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
- // param2, *(int32_t *)pValue);
- break;
+ *pValueSize = 2 * sizeof(int32_t);
- case EQ_PARAM_BAND_FREQ_RANGE:
- param2 = *pParamTemp;
- if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
- status = -EINVAL;
- if (param2 < 0) {
+ const int32_t band = params[1];
+ if (band < 0 || band >= FIVEBAND_NUMBANDS) {
+ if (band < 0) {
android_errorWriteLog(0x534e4554, "32247948");
- ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d", param2);
+ ALOGW("%s EQ_PARAM_BAND_FREQ_RANGE invalid band %d",
+ __func__, band);
}
- break;
- }
- EqualizerGetBandFreqRange(pContext, param2, (uint32_t *)pValue, ((uint32_t *)pValue + 1));
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
- // param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
- break;
-
- case EQ_PARAM_GET_BAND:
- param2 = *pParamTemp;
- *(uint16_t *)pValue = (uint16_t)EqualizerGetBand(pContext, param2);
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
- // param2, *(uint16_t *)pValue);
- break;
-
- case EQ_PARAM_CUR_PRESET:
- *(uint16_t *)pValue = (uint16_t)EqualizerGetPreset(pContext);
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
- break;
-
- case EQ_PARAM_GET_NUM_OF_PRESETS:
- *(uint16_t *)pValue = (uint16_t)EqualizerGetNumPresets();
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
- break;
-
- case EQ_PARAM_GET_PRESET_NAME:
- param2 = *pParamTemp;
- if ((param2 < 0 && param2 != PRESET_CUSTOM) || param2 >= EqualizerGetNumPresets()) {
status = -EINVAL;
- if (param2 < 0) {
- android_errorWriteLog(0x534e4554, "32448258");
- ALOGE("\tERROR Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d",
- param2);
+ break;
+ }
+ EqualizerGetBandFreqRange(pContext, band, (uint32_t *)pValue, ((uint32_t *)pValue + 1));
+ ALOGVV("%s EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
+ __func__, band, *(int32_t *)pValue, *((int32_t *)pValue + 1));
+
+ } break;
+
+ case EQ_PARAM_CENTER_FREQ: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_CENTER_FREQ invalid paramSize: %u", __func__, paramSize);
+ status = -EINVAL;
+ break;
+ }
+ if (*pValueSize < sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_CENTER_FREQ invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(int32_t);
+
+ const int32_t band = params[1];
+ if (band < 0 || band >= FIVEBAND_NUMBANDS) {
+ status = -EINVAL;
+ if (band < 0) {
+ android_errorWriteLog(0x534e4554, "32436341");
+ ALOGW("%s EQ_PARAM_CENTER_FREQ invalid band %d", __func__, band);
}
break;
}
- name = (char *)pValue;
- strncpy(name, EqualizerGetPresetName(param2), *pValueSize - 1);
+ *(int32_t *)pValue = EqualizerGetCentreFrequency(pContext, band);
+ ALOGVV("%s EQ_PARAM_CENTER_FREQ band %d, frequency %d",
+ __func__, band, *(int32_t *)pValue);
+ } break;
+
+ case EQ_PARAM_GET_PRESET_NAME: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_PRESET_NAME invalid paramSize: %u", __func__, paramSize);
+ status = -EINVAL;
+ break;
+ }
+ if (*pValueSize < 1) {
+ android_errorWriteLog(0x534e4554, "37536407");
+ status = -EINVAL;
+ break;
+ }
+
+ const int32_t preset = params[1];
+ if ((preset < 0 && preset != PRESET_CUSTOM) || preset >= EqualizerGetNumPresets()) {
+ if (preset < 0) {
+ android_errorWriteLog(0x534e4554, "32448258");
+ ALOGE("%s EQ_PARAM_GET_PRESET_NAME preset %d", __func__, preset);
+ }
+ status = -EINVAL;
+ break;
+ }
+
+ char * const name = (char *)pValue;
+ strncpy(name, EqualizerGetPresetName(preset), *pValueSize - 1);
name[*pValueSize - 1] = 0;
*pValueSize = strlen(name) + 1;
- //ALOGV("\tEqualizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
- // param2, gEqualizerPresets[param2].name, *pValueSize);
- break;
+ ALOGVV("%s EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
+ __func__, preset, gEqualizerPresets[preset].name, *pValueSize);
+
+ } break;
case EQ_PARAM_PROPERTIES: {
+ const uint32_t requiredValueSize = (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t);
+ if (*pValueSize < requiredValueSize) {
+ ALOGV("%s EQ_PARAM_PROPERTIES invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = requiredValueSize;
+
int16_t *p = (int16_t *)pValue;
- ALOGV("\tEqualizer_getParameter() EQ_PARAM_PROPERTIES");
+ ALOGV("%s EQ_PARAM_PROPERTIES", __func__);
p[0] = (int16_t)EqualizerGetPreset(pContext);
p[1] = (int16_t)FIVEBAND_NUMBANDS;
for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
@@ -2414,12 +2522,12 @@
} break;
default:
- ALOGV("\tLVM_ERROR : Equalizer_getParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
status = -EINVAL;
break;
}
- //GV("\tEqualizer_getParameter end\n");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Equalizer_getParameter */
@@ -2432,57 +2540,96 @@
// Inputs:
// pEqualizer - handle to instance data
// pParam - pointer to parameter
+// valueSize - value size
// pValue - pointer to value
+
//
// Outputs:
//
//----------------------------------------------------------------------------
-int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue){
+int Equalizer_setParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue) {
int status = 0;
- int32_t preset;
- int32_t band;
- int32_t level;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
+ int32_t *params = (int32_t *)pParam;
+ ALOGVV("%s start", __func__);
- //ALOGV("\tEqualizer_setParameter start");
- switch (param) {
- case EQ_PARAM_CUR_PRESET:
- preset = (int32_t)(*(uint16_t *)pValue);
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
+ case EQ_PARAM_CUR_PRESET: {
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s EQ_PARAM_CUR_PRESET invalid valueSize %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
+ const int32_t preset = (int32_t)*(uint16_t *)pValue;
- //ALOGV("\tEqualizer_setParameter() EQ_PARAM_CUR_PRESET %d", preset);
- if ((preset >= EqualizerGetNumPresets())||(preset < 0)) {
+ ALOGVV("%s EQ_PARAM_CUR_PRESET %d", __func__, preset);
+ if (preset >= EqualizerGetNumPresets() || preset < 0) {
+ ALOGV("%s EQ_PARAM_CUR_PRESET invalid preset %d", __func__, preset);
status = -EINVAL;
break;
}
EqualizerSetPreset(pContext, preset);
- break;
- case EQ_PARAM_BAND_LEVEL:
- band = *pParamTemp;
- level = (int32_t)(*(int16_t *)pValue);
- //ALOGV("\tEqualizer_setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
- if (band < 0 || band >= FIVEBAND_NUMBANDS) {
+ } break;
+
+ case EQ_PARAM_BAND_LEVEL: {
+ if (paramSize < 2 * sizeof(int32_t)) {
+ ALOGV("%s EQ_PARAM_BAND_LEVEL invalid paramSize: %u", __func__, paramSize);
status = -EINVAL;
+ break;
+ }
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s EQ_PARAM_BAND_LEVEL invalid valueSize %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
+ const int32_t band = params[1];
+ const int32_t level = (int32_t)*(int16_t *)pValue;
+ ALOGVV("%s EQ_PARAM_BAND_LEVEL band %d, level %d", __func__, band, level);
+ if (band < 0 || band >= FIVEBAND_NUMBANDS) {
if (band < 0) {
android_errorWriteLog(0x534e4554, "32095626");
- ALOGE("\tERROR Equalizer_setParameter() EQ_PARAM_BAND_LEVEL band %d", band);
+ ALOGE("%s EQ_PARAM_BAND_LEVEL invalid band %d", __func__, band);
}
+ status = -EINVAL;
break;
}
EqualizerSetBandLevel(pContext, band, level);
- break;
+ } break;
+
case EQ_PARAM_PROPERTIES: {
- //ALOGV("\tEqualizer_setParameter() EQ_PARAM_PROPERTIES");
+ ALOGVV("%s EQ_PARAM_PROPERTIES", __func__);
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s EQ_PARAM_PROPERTIES invalid valueSize %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
int16_t *p = (int16_t *)pValue;
if ((int)p[0] >= EqualizerGetNumPresets()) {
+ ALOGV("%s EQ_PARAM_PROPERTIES invalid preset %d", __func__, (int)p[0]);
status = -EINVAL;
break;
}
if (p[0] >= 0) {
EqualizerSetPreset(pContext, (int)p[0]);
} else {
+ const uint32_t valueSizeRequired = (2 + FIVEBAND_NUMBANDS) * sizeof(int16_t);
+ if (valueSize < valueSizeRequired) {
+ android_errorWriteLog(0x534e4554, "37563371");
+ ALOGE("%s EQ_PARAM_PROPERTIES invalid valueSize %u < %u",
+ __func__, valueSize, valueSizeRequired);
+ status = -EINVAL;
+ break;
+ }
if ((int)p[1] != FIVEBAND_NUMBANDS) {
+ ALOGV("%s EQ_PARAM_PROPERTIES invalid bands %d", __func__, (int)p[1]);
status = -EINVAL;
break;
}
@@ -2491,13 +2638,14 @@
}
}
} break;
+
default:
- ALOGV("\tLVM_ERROR : Equalizer_setParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
status = -EINVAL;
break;
}
- //ALOGV("\tEqualizer_setParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Equalizer_setParameter */
@@ -2522,81 +2670,92 @@
//
//----------------------------------------------------------------------------
-int Volume_getParameter(EffectContext *pContext,
- void *pParam,
- uint32_t *pValueSize,
- void *pValue){
+int Volume_getParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t *pValueSize,
+ void *pValue) {
int status = 0;
- int bMute = 0;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;;
- char *name;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tVolume_getParameter start");
+ ALOGVV("%s start", __func__);
- switch (param){
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
case VOLUME_PARAM_LEVEL:
- case VOLUME_PARAM_MAXLEVEL:
- case VOLUME_PARAM_STEREOPOSITION:
- if (*pValueSize != sizeof(int16_t)){
- ALOGV("\tLVM_ERROR : Volume_getParameter() invalid pValueSize 1 %d", *pValueSize);
- return -EINVAL;
+ if (*pValueSize != sizeof(int16_t)) { // legacy: check equality here.
+ ALOGV("%s VOLUME_PARAM_LEVEL invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
}
- *pValueSize = sizeof(int16_t);
+ // no need to set *pValueSize
+
+ status = VolumeGetVolumeLevel(pContext, (int16_t *)(pValue));
+ ALOGVV("%s VOLUME_PARAM_LEVEL %d", __func__, *(int16_t *)pValue);
+ break;
+
+ case VOLUME_PARAM_MAXLEVEL:
+ if (*pValueSize != sizeof(int16_t)) { // legacy: check equality here.
+ ALOGV("%s VOLUME_PARAM_MAXLEVEL invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
+
+ // in millibel
+ *(int16_t *)pValue = 0;
+ ALOGVV("%s VOLUME_PARAM_MAXLEVEL %d", __func__, *(int16_t *)pValue);
+ break;
+
+ case VOLUME_PARAM_STEREOPOSITION:
+ if (*pValueSize != sizeof(int16_t)) { // legacy: check equality here.
+ ALOGV("%s VOLUME_PARAM_STEREOPOSITION invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ // no need to set *pValueSize
+
+ VolumeGetStereoPosition(pContext, (int16_t *)pValue);
+ ALOGVV("%s VOLUME_PARAM_STEREOPOSITION %d", __func__, *(int16_t *)pValue);
break;
case VOLUME_PARAM_MUTE:
+ if (*pValueSize < sizeof(uint32_t)) {
+ ALOGV("%s VOLUME_PARAM_MUTE invalid *pValueSize %u", __func__, *pValueSize);
+ status = -EINVAL;
+ break;
+ }
+ *pValueSize = sizeof(uint32_t);
+
+ status = VolumeGetMute(pContext, (uint32_t *)pValue);
+ ALOGV("%s VOLUME_PARAM_MUTE %u", __func__, *(uint32_t *)pValue);
+ break;
+
case VOLUME_PARAM_ENABLESTEREOPOSITION:
- if (*pValueSize < sizeof(int32_t)){
- ALOGV("\tLVM_ERROR : Volume_getParameter() invalid pValueSize 2 %d", *pValueSize);
- return -EINVAL;
+ if (*pValueSize < sizeof(int32_t)) {
+ ALOGV("%s VOLUME_PARAM_ENABLESTEREOPOSITION invalid *pValueSize %u",
+ __func__, *pValueSize);
+ status = -EINVAL;
+ break;
}
*pValueSize = sizeof(int32_t);
- break;
- default:
- ALOGV("\tLVM_ERROR : Volume_getParameter unknown param %d", param);
- return -EINVAL;
- }
-
- switch (param){
- case VOLUME_PARAM_LEVEL:
- status = VolumeGetVolumeLevel(pContext, (int16_t *)(pValue));
- //ALOGV("\tVolume_getParameter() VOLUME_PARAM_LEVEL Value is %d",
- // *(int16_t *)pValue);
- break;
-
- case VOLUME_PARAM_MAXLEVEL:
- *(int16_t *)pValue = 0;
- //ALOGV("\tVolume_getParameter() VOLUME_PARAM_MAXLEVEL Value is %d",
- // *(int16_t *)pValue);
- break;
-
- case VOLUME_PARAM_STEREOPOSITION:
- VolumeGetStereoPosition(pContext, (int16_t *)pValue);
- //ALOGV("\tVolume_getParameter() VOLUME_PARAM_STEREOPOSITION Value is %d",
- // *(int16_t *)pValue);
- break;
-
- case VOLUME_PARAM_MUTE:
- status = VolumeGetMute(pContext, (uint32_t *)pValue);
- ALOGV("\tVolume_getParameter() VOLUME_PARAM_MUTE Value is %d",
- *(uint32_t *)pValue);
- break;
-
- case VOLUME_PARAM_ENABLESTEREOPOSITION:
*(int32_t *)pValue = pContext->pBundledContext->bStereoPositionEnabled;
- //ALOGV("\tVolume_getParameter() VOLUME_PARAM_ENABLESTEREOPOSITION Value is %d",
- // *(uint32_t *)pValue);
+ ALOGVV("%s VOLUME_PARAM_ENABLESTEREOPOSITION %d", __func__, *(int32_t *)pValue);
+
break;
default:
- ALOGV("\tLVM_ERROR : Volume_getParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
status = -EINVAL;
break;
}
- //ALOGV("\tVolume_getParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Volume_getParameter */
@@ -2616,55 +2775,87 @@
//
//----------------------------------------------------------------------------
-int Volume_setParameter (EffectContext *pContext, void *pParam, void *pValue){
- int status = 0;
- int16_t level;
- int16_t position;
- uint32_t mute;
- uint32_t positionEnabled;
- int32_t *pParamTemp = (int32_t *)pParam;
- int32_t param = *pParamTemp++;
+int Volume_setParameter(EffectContext *pContext,
+ uint32_t paramSize,
+ void *pParam,
+ uint32_t valueSize,
+ void *pValue) {
+ int status = 0;
+ int32_t *params = (int32_t *)pParam;
- //ALOGV("\tVolume_setParameter start");
+ ALOGVV("%s start", __func__);
- switch (param){
- case VOLUME_PARAM_LEVEL:
- level = *(int16_t *)pValue;
- //ALOGV("\tVolume_setParameter() VOLUME_PARAM_LEVEL value is %d", level);
- //ALOGV("\tVolume_setParameter() Calling pVolume->setVolumeLevel");
- status = VolumeSetVolumeLevel(pContext, (int16_t)level);
- //ALOGV("\tVolume_setParameter() Called pVolume->setVolumeLevel");
- break;
+ if (paramSize < sizeof(int32_t)) {
+ ALOGV("%s invalid paramSize: %u", __func__, paramSize);
+ return -EINVAL;
+ }
+ switch (params[0]) {
+ case VOLUME_PARAM_LEVEL: {
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s VOLUME_PARAM_LEVEL invalid valueSize %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
- case VOLUME_PARAM_MUTE:
- mute = *(uint32_t *)pValue;
- //ALOGV("\tVolume_setParameter() Calling pVolume->setMute, mute is %d", mute);
- //ALOGV("\tVolume_setParameter() Calling pVolume->setMute");
+ const int16_t level = *(int16_t *)pValue;
+ ALOGVV("%s VOLUME_PARAM_LEVEL %d", __func__, level);
+ ALOGVV("%s VOLUME_PARAM_LEVEL Calling VolumeSetVolumeLevel", __func__);
+ status = VolumeSetVolumeLevel(pContext, level);
+ ALOGVV("%s VOLUME_PARAM_LEVEL Called VolumeSetVolumeLevel", __func__);
+ } break;
+
+ case VOLUME_PARAM_MUTE: {
+ if (valueSize < sizeof(uint32_t)) {
+ ALOGV("%s VOLUME_PARAM_MUTE invalid valueSize %u", __func__, valueSize);
+ android_errorWriteLog(0x534e4554, "64477217");
+ status = -EINVAL;
+ break;
+ }
+
+ const uint32_t mute = *(uint32_t *)pValue;
+ ALOGVV("%s VOLUME_PARAM_MUTE %d", __func__, mute);
+ ALOGVV("%s VOLUME_PARAM_MUTE Calling VolumeSetMute", __func__);
status = VolumeSetMute(pContext, mute);
- //ALOGV("\tVolume_setParameter() Called pVolume->setMute");
- break;
+ ALOGVV("%s VOLUME_PARAM_MUTE Called VolumeSetMute", __func__);
+ } break;
- case VOLUME_PARAM_ENABLESTEREOPOSITION:
- positionEnabled = *(uint32_t *)pValue;
- status = VolumeEnableStereoPosition(pContext, positionEnabled);
- status = VolumeSetStereoPosition(pContext, pContext->pBundledContext->positionSaved);
- //ALOGV("\tVolume_setParameter() VOLUME_PARAM_ENABLESTEREOPOSITION called");
- break;
+ case VOLUME_PARAM_ENABLESTEREOPOSITION: {
+ if (valueSize < sizeof(uint32_t)) {
+ ALOGV("%s VOLUME_PARAM_ENABLESTEREOPOSITION invalid valueSize %u",
+ __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
- case VOLUME_PARAM_STEREOPOSITION:
- position = *(int16_t *)pValue;
- //ALOGV("\tVolume_setParameter() VOLUME_PARAM_STEREOPOSITION value is %d", position);
- //ALOGV("\tVolume_setParameter() Calling pVolume->VolumeSetStereoPosition");
- status = VolumeSetStereoPosition(pContext, (int16_t)position);
- //ALOGV("\tVolume_setParameter() Called pVolume->VolumeSetStereoPosition");
- break;
+ const uint32_t positionEnabled = *(uint32_t *)pValue;
+ status = VolumeEnableStereoPosition(pContext, positionEnabled)
+ ?: VolumeSetStereoPosition(pContext, pContext->pBundledContext->positionSaved);
+ ALOGVV("%s VOLUME_PARAM_ENABLESTEREOPOSITION called", __func__);
+ } break;
+
+ case VOLUME_PARAM_STEREOPOSITION: {
+ if (valueSize < sizeof(int16_t)) {
+ ALOGV("%s VOLUME_PARAM_STEREOPOSITION invalid valueSize %u", __func__, valueSize);
+ status = -EINVAL;
+ break;
+ }
+
+ const int16_t position = *(int16_t *)pValue;
+ ALOGVV("%s VOLUME_PARAM_STEREOPOSITION %d", __func__, position);
+ ALOGVV("%s VOLUME_PARAM_STEREOPOSITION Calling VolumeSetStereoPosition",
+ __func__);
+ status = VolumeSetStereoPosition(pContext, position);
+ ALOGVV("%s VOLUME_PARAM_STEREOPOSITION Called VolumeSetStereoPosition",
+ __func__);
+ } break;
default:
- ALOGV("\tLVM_ERROR : Volume_setParameter() invalid param %d", param);
+ ALOGV("%s invalid param %d", __func__, params[0]);
+ status = -EINVAL;
break;
}
- //ALOGV("\tVolume_setParameter end");
+ ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
return status;
} /* end Volume_setParameter */
@@ -2982,6 +3173,13 @@
return status;
} /* end Effect_process */
+// The value offset of an effect parameter is computed by rounding up
+// the parameter size to the next 32 bit alignment.
+static inline uint32_t computeParamVOffset(const effect_param_t *p) {
+ return ((p->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) *
+ sizeof(int32_t);
+}
+
/* Effect Control Interface Implementation: Command */
int Effect_command(effect_handle_t self,
uint32_t cmdCode,
@@ -3093,8 +3291,7 @@
ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: psize too big");
return -EINVAL;
}
- uint32_t paddedParamSize = ((p->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) *
- sizeof(int32_t);
+ const uint32_t paddedParamSize = computeParamVOffset(p);
if ((EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) < paddedParamSize) ||
(EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) - paddedParamSize <
p->vsize)) {
@@ -3116,6 +3313,7 @@
uint32_t voffset = paddedParamSize;
if(pContext->EffectType == LVM_BASS_BOOST){
p->status = android::BassBoost_getParameter(pContext,
+ p->psize,
p->data,
&p->vsize,
p->data + voffset);
@@ -3128,6 +3326,7 @@
if(pContext->EffectType == LVM_VIRTUALIZER){
p->status = android::Virtualizer_getParameter(pContext,
+ p->psize,
(void *)p->data,
&p->vsize,
p->data + voffset);
@@ -3142,6 +3341,7 @@
//ALOGV("\tEqualizer_command cmdCode Case: "
// "EFFECT_CMD_GET_PARAM start");
p->status = android::Equalizer_getParameter(pContext,
+ p->psize,
p->data,
&p->vsize,
p->data + voffset);
@@ -3156,6 +3356,7 @@
if(pContext->EffectType == LVM_VOLUME){
//ALOGV("\tVolume_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
p->status = android::Volume_getParameter(pContext,
+ p->psize,
(void *)p->data,
&p->vsize,
p->data + voffset);
@@ -3185,13 +3386,9 @@
"EFFECT_CMD_SET_PARAM: ERROR");
return -EINVAL;
}
- effect_param_t *p = (effect_param_t *) pCmdData;
- if (p->psize != sizeof(int32_t)){
- ALOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
- "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
- return -EINVAL;
- }
+ effect_param_t * const p = (effect_param_t *) pCmdData;
+ const uint32_t voffset = computeParamVOffset(p);
//ALOGV("\tnBassBoost_command cmdSize is %d\n"
// "\tsizeof(effect_param_t) is %d\n"
@@ -3201,8 +3398,10 @@
// cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
*(int *)pReplyData = android::BassBoost_setParameter(pContext,
- (void *)p->data,
- p->data + p->psize);
+ p->psize,
+ (void *)p->data,
+ p->vsize,
+ p->data + voffset);
}
if(pContext->EffectType == LVM_VIRTUALIZER){
// Warning this log will fail to properly read an int32_t value, assumes int16_t
@@ -3220,13 +3419,9 @@
"EFFECT_CMD_SET_PARAM: ERROR");
return -EINVAL;
}
- effect_param_t *p = (effect_param_t *) pCmdData;
- if (p->psize != sizeof(int32_t)){
- ALOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
- "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
- return -EINVAL;
- }
+ effect_param_t * const p = (effect_param_t *) pCmdData;
+ const uint32_t voffset = computeParamVOffset(p);
//ALOGV("\tnVirtualizer_command cmdSize is %d\n"
// "\tsizeof(effect_param_t) is %d\n"
@@ -3236,8 +3431,10 @@
// cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
*(int *)pReplyData = android::Virtualizer_setParameter(pContext,
- (void *)p->data,
- p->data + p->psize);
+ p->psize,
+ (void *)p->data,
+ p->vsize,
+ p->data + voffset);
}
if(pContext->EffectType == LVM_EQUALIZER){
//ALOGV("\tEqualizer_command cmdCode Case: "
@@ -3253,11 +3450,15 @@
"EFFECT_CMD_SET_PARAM: ERROR");
return -EINVAL;
}
- effect_param_t *p = (effect_param_t *) pCmdData;
+
+ effect_param_t * const p = (effect_param_t *) pCmdData;
+ const uint32_t voffset = computeParamVOffset(p);
*(int *)pReplyData = android::Equalizer_setParameter(pContext,
- (void *)p->data,
- p->data + p->psize);
+ p->psize,
+ (void *)p->data,
+ p->vsize,
+ p->data + voffset);
}
if(pContext->EffectType == LVM_VOLUME){
//ALOGV("\tVolume_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
@@ -3274,11 +3475,15 @@
"EFFECT_CMD_SET_PARAM: ERROR");
return -EINVAL;
}
- effect_param_t *p = (effect_param_t *) pCmdData;
+
+ effect_param_t * const p = (effect_param_t *) pCmdData;
+ const uint32_t voffset = computeParamVOffset(p);
*(int *)pReplyData = android::Volume_setParameter(pContext,
- (void *)p->data,
- p->data + p->psize);
+ p->psize,
+ (void *)p->data,
+ p->vsize,
+ p->data + voffset);
}
//ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM end");
} break;
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 4dc8b45..80c8a38 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -180,12 +180,13 @@
void Reverb_free (ReverbContext *pContext);
int Reverb_setConfig (ReverbContext *pContext, effect_config_t *pConfig);
void Reverb_getConfig (ReverbContext *pContext, effect_config_t *pConfig);
-int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue);
+int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue, int vsize);
int Reverb_getParameter (ReverbContext *pContext,
void *pParam,
uint32_t *pValueSize,
void *pValue);
int Reverb_LoadPreset (ReverbContext *pContext);
+int Reverb_paramValueSize (int32_t param);
/* Effect Library Interface Implementation */
@@ -1747,12 +1748,13 @@
// pContext - handle to instance data
// pParam - pointer to parameter
// pValue - pointer to value
+// vsize - value size
//
// Outputs:
//
//----------------------------------------------------------------------------
-int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){
+int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue, int vsize){
int status = 0;
int16_t level;
int16_t ratio;
@@ -1766,6 +1768,10 @@
if (param != REVERB_PARAM_PRESET) {
return -EINVAL;
}
+ if (vsize < (int)sizeof(uint16_t)) {
+ android_errorWriteLog(0x534e4554, "67647856");
+ return -EINVAL;
+ }
uint16_t preset = *(uint16_t *)pValue;
ALOGV("set REVERB_PARAM_PRESET, preset %d", preset);
@@ -1776,6 +1782,11 @@
return 0;
}
+ if (vsize < Reverb_paramValueSize(param)) {
+ android_errorWriteLog(0x534e4554, "63526567");
+ return -EINVAL;
+ }
+
switch (param){
case REVERB_PARAM_PROPERTIES:
ALOGV("\tReverb_setParameter() REVERB_PARAM_PROPERTIES");
@@ -1851,6 +1862,31 @@
return status;
} /* end Reverb_setParameter */
+
+/**
+ * returns the size in bytes of the value of each environmental reverb parameter
+ */
+int Reverb_paramValueSize(int32_t param) {
+ switch (param) {
+ case REVERB_PARAM_ROOM_LEVEL:
+ case REVERB_PARAM_ROOM_HF_LEVEL:
+ case REVERB_PARAM_REFLECTIONS_LEVEL:
+ case REVERB_PARAM_REVERB_LEVEL:
+ return sizeof(int16_t); // millibel
+ case REVERB_PARAM_DECAY_TIME:
+ case REVERB_PARAM_REFLECTIONS_DELAY:
+ case REVERB_PARAM_REVERB_DELAY:
+ return sizeof(uint32_t); // milliseconds
+ case REVERB_PARAM_DECAY_HF_RATIO:
+ case REVERB_PARAM_DIFFUSION:
+ case REVERB_PARAM_DENSITY:
+ return sizeof(int16_t); // permille
+ case REVERB_PARAM_PROPERTIES:
+ return sizeof(s_reverb_settings); // struct of all reverb properties
+ }
+ return sizeof(int32_t);
+}
+
} // namespace
} // namespace
@@ -2022,7 +2058,8 @@
*(int *)pReplyData = android::Reverb_setParameter(pContext,
(void *)p->data,
- p->data + p->psize);
+ p->data + p->psize,
+ p->vsize);
} break;
case EFFECT_CMD_ENABLE:
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 7e74de9..54e0878 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -476,8 +476,13 @@
void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
uint32_t size = data.readInt32();
- vector.insertAt((size_t)0, size);
- data.read(vector.editArray(), size);
+ if (vector.insertAt((size_t)0, size) < 0) {
+ vector.clear();
+ }
+ if (data.read(vector.editArray(), size) != NO_ERROR) {
+ vector.clear();
+ android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
+ }
}
void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a39bb65..547556c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -83,6 +83,9 @@
#include "HTTPBase.h"
#include "RemoteDisplay.h"
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleepUs = 20000;
+
namespace {
using android::media::Metadata;
using android::status_t;
@@ -441,12 +444,32 @@
snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n",
mPid, mConnId, mStatus, mLoop?"true": "false");
result.append(buffer);
- write(fd, result.string(), result.size());
- if (mPlayer != NULL) {
- mPlayer->dump(fd, args);
+
+ sp<MediaPlayerBase> p;
+ sp<AudioOutput> audioOutput;
+ bool locked = false;
+ for (int i = 0; i < kDumpLockRetries; ++i) {
+ if (mLock.tryLock() == NO_ERROR) {
+ locked = true;
+ break;
+ }
+ usleep(kDumpLockSleepUs);
}
- if (mAudioOutput != 0) {
- mAudioOutput->dump(fd, args);
+
+ if (locked) {
+ p = mPlayer;
+ audioOutput = mAudioOutput;
+ mLock.unlock();
+ } else {
+ result.append(" lock is taken, no dump from player and audio output\n");
+ }
+ write(fd, result.string(), result.size());
+
+ if (p != NULL) {
+ p->dump(fd, args);
+ }
+ if (audioOutput != 0) {
+ audioOutput->dump(fd, args);
}
write(fd, "\n", 1);
return NO_ERROR;
@@ -604,7 +627,10 @@
MediaPlayerService::Client::~Client()
{
ALOGV("Client(%d) destructor pid = %d", mConnId, mPid);
- mAudioOutput.clear();
+ {
+ Mutex::Autolock l(mLock);
+ mAudioOutput.clear();
+ }
wp<Client> client(this);
disconnect();
mService->removeClient(client);
@@ -623,10 +649,9 @@
Mutex::Autolock l(mLock);
p = mPlayer;
mClient.clear();
+ mPlayer.clear();
}
- mPlayer.clear();
-
// clear the notification to prevent callbacks to dead client
// and reset the player. We assume the player will serialize
// access to itself if necessary.
@@ -647,7 +672,7 @@
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
// determine if we have the right player type
- sp<MediaPlayerBase> p = mPlayer;
+ sp<MediaPlayerBase> p = getPlayer();
if ((p != NULL) && (p->playerType() != playerType)) {
ALOGV("delete player");
p.clear();
@@ -703,6 +728,7 @@
}
if (mStatus == OK) {
+ Mutex::Autolock l(mLock);
mPlayer = p;
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5d98d98..6cc43fd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -368,7 +368,10 @@
ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
msg->setBuffer("buffer", buffer);
mCSDsToSubmit.removeAt(0);
- CHECK(onInputBufferFetched(msg));
+ if (!onInputBufferFetched(msg)) {
+ handleError(UNKNOWN_ERROR);
+ return false;
+ }
return true;
}
@@ -748,7 +751,11 @@
// copy into codec buffer
if (buffer != codecBuffer) {
- CHECK_LE(buffer->size(), codecBuffer->capacity());
+ if (buffer->size() > codecBuffer->capacity()) {
+ handleError(ERROR_BUFFER_TOO_SMALL);
+ mDequeuedInputBuffers.push_back(bufferIx);
+ return false;
+ }
codecBuffer->setRange(0, buffer->size());
memcpy(codecBuffer->data(), buffer->data(), buffer->size());
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 313dbdf..cefae66 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -890,6 +890,12 @@
ALOGE("moov: depth %d", depth);
return ERROR_MALFORMED;
}
+
+ if (chunk_type == FOURCC('m', 'o', 'o', 'v') && mInitCheck == OK) {
+ ALOGE("duplicate moov");
+ return ERROR_MALFORMED;
+ }
+
if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
@@ -957,6 +963,12 @@
if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
mLastTrack->skipTrack = true;
}
+
+ status_t err = verifyTrack(mLastTrack);
+ if (err != OK) {
+ mLastTrack->skipTrack = true;
+ }
+
if (mLastTrack->skipTrack) {
Track *cur = mFirstTrack;
@@ -974,12 +986,6 @@
return OK;
}
-
- status_t err = verifyTrack(mLastTrack);
-
- if (err != OK) {
- return err;
- }
} else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
mInitCheck = OK;
@@ -1547,6 +1553,9 @@
// ratio. Use compression ratio of 1.
max_size = width * height * 3 / 2;
}
+ // HACK: allow 10% overhead
+ // TODO: read sample size from traf atom for fragmented MPEG4.
+ max_size += max_size / 10;
mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
}
@@ -2485,6 +2494,7 @@
if (sscanf(mLastCommentData,
" %*x %x %x %*x", &delay, &padding) == 2) {
if (mLastTrack == NULL) {
+ delete[] buffer;
return ERROR_MALFORMED;
}
mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
@@ -2597,6 +2607,13 @@
}
case FOURCC('y', 'r', 'r', 'c'):
{
+ if (size < 6) {
+ delete[] buffer;
+ buffer = NULL;
+ ALOGE("b/62133227");
+ android_errorWriteLog(0x534e4554, "62133227");
+ return ERROR_MALFORMED;
+ }
char tmp[5];
uint16_t year = U16_AT(&buffer[4]);
@@ -2619,6 +2636,8 @@
// smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
if (size < 6) {
+ delete[] buffer;
+ buffer = NULL;
return ERROR_MALFORMED;
}
@@ -3307,7 +3326,8 @@
while (true) {
if (mDataSource->readAt(*offset, hdr, 8) < 8) {
- return ERROR_END_OF_STREAM;
+ // no more box to the end of file.
+ break;
}
chunk_size = ntohl(hdr[0]);
chunk_type = ntohl(hdr[1]);
@@ -3964,6 +3984,8 @@
}
if (size > mBuffer->size()) {
ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
+ mBuffer->release();
+ mBuffer = NULL;
return ERROR_BUFFER_TOO_SMALL;
}
}
@@ -4239,6 +4261,8 @@
}
if (size > mBuffer->size()) {
ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
+ mBuffer->release();
+ mBuffer = NULL;
return ERROR_BUFFER_TOO_SMALL;
}
}
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 6de2bb3..d6d7d83 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -280,7 +280,14 @@
sp<MediaSource> source = mImpl->getTrack(index);
- CHECK_EQ((status_t)OK, source->start());
+ if (source == NULL) {
+ return ERROR_MALFORMED;
+ }
+
+ status_t ret = source->start();
+ if (ret != OK) {
+ return ret;
+ }
mSelectedTracks.push();
TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 1dd631a..411a251 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -255,13 +255,28 @@
mSignalledError = true;
return;
}
+
+ // Need to check if header contains new info, e.g., width/height, etc.
+ VopHeaderInfo header_info;
+ uint8_t *bitstreamTmp = bitstream;
+ if (PVDecodeVopHeader(
+ mHandle, &bitstreamTmp, ×tamp, &tmp,
+ &header_info, &useExtTimestamp,
+ outHeader->pBuffer) != PV_TRUE) {
+ ALOGE("failed to decode vop header.");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+ if (handlePortSettingsChange()) {
+ return;
+ }
+
// The PV decoder is lying to us, sometimes it'll claim to only have
// consumed a subset of the buffer when it clearly consumed all of it.
// ignore whatever it says...
- if (PVDecodeVideoFrame(
- mHandle, &bitstream, ×tamp, &tmp,
- &useExtTimestamp,
- outHeader->pBuffer) != PV_TRUE) {
+ if (PVDecodeVopBody(mHandle, &tmp) != PV_TRUE) {
ALOGE("failed to decode video frame.");
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
index f7192b1c..7202f98 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
@@ -560,7 +560,7 @@
BitstreamShow13Bits(stream, &code);
- if (code == 0)
+ if (code < 8)
{
return VLC_CODE_ERROR;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
index 60c79a6..f18f789 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -15,6 +15,8 @@
* and limitations under the License.
* -------------------------------------------------------------------
*/
+#include "log/log.h"
+
#include "mp4dec_lib.h"
#include "bitstream.h"
#include "vlc_decode.h"
@@ -1336,8 +1338,7 @@
}
tmpvar = BitstreamReadBits16(stream, 9);
- video->displayWidth = (tmpvar + 1) << 2;
- video->width = (video->displayWidth + 15) & -16;
+ int tmpDisplayWidth = (tmpvar + 1) << 2;
/* marker bit */
if (!BitstreamRead1Bits(stream))
{
@@ -1350,14 +1351,21 @@
status = PV_FAIL;
goto return_point;
}
- video->displayHeight = tmpvar << 2;
- video->height = (video->displayHeight + 15) & -16;
+ int tmpDisplayHeight = tmpvar << 2;
+ int tmpHeight = (tmpDisplayHeight + 15) & -16;
+ int tmpWidth = (tmpDisplayWidth + 15) & -16;
- if (video->height * video->width > video->size)
+ if (tmpHeight * tmpWidth > video->size)
{
+ // This is just possibly "b/37079296".
+ ALOGE("b/37079296");
status = PV_FAIL;
goto return_point;
}
+ video->displayWidth = tmpDisplayWidth;
+ video->width = tmpWidth;
+ video->displayHeight = tmpDisplayHeight;
+ video->height = tmpHeight;
video->nTotalMB = video->width / MB_SIZE * video->height / MB_SIZE;
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp
index c2b7c8d..7ab8f45 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp
@@ -773,7 +773,7 @@
|| (size_t)(size + (size >> 1)) > SIZE_MAX / sizeof(PIXEL)) {
goto CLEAN_UP;
}
- video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */
+ video->currVop->allChan = video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */
if (video->currVop->yChan == NULL) goto CLEAN_UP;
video->currVop->uChan = video->currVop->yChan + size;/* Memory for currVop U */
video->currVop->vChan = video->currVop->uChan + (size >> 2);/* Memory for currVop V */
@@ -791,7 +791,7 @@
video->prevBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Base Vop */
if (video->prevBaseVop == NULL) goto CLEAN_UP;
- video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */
+ video->prevBaseVop->allChan = video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */
if (video->prevBaseVop->yChan == NULL) goto CLEAN_UP;
video->prevBaseVop->uChan = video->prevBaseVop->yChan + size; /* Memory for prevBaseVop U */
video->prevBaseVop->vChan = video->prevBaseVop->uChan + (size >> 2); /* Memory for prevBaseVop V */
@@ -808,7 +808,7 @@
{
video->nextBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Next Base Vop */
if (video->nextBaseVop == NULL) goto CLEAN_UP;
- video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */
+ video->nextBaseVop->allChan = video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */
if (video->nextBaseVop->yChan == NULL) goto CLEAN_UP;
video->nextBaseVop->uChan = video->nextBaseVop->yChan + size; /* Memory for nextBaseVop U */
video->nextBaseVop->vChan = video->nextBaseVop->uChan + (size >> 2); /* Memory for nextBaseVop V */
@@ -825,7 +825,7 @@
{
video->prevEnhanceVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Enhancement Vop */
if (video->prevEnhanceVop == NULL) goto CLEAN_UP;
- video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */
+ video->prevEnhanceVop->allChan = video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */
if (video->prevEnhanceVop->yChan == NULL) goto CLEAN_UP;
video->prevEnhanceVop->uChan = video->prevEnhanceVop->yChan + size; /* Memory for Previous Enhancement U */
video->prevEnhanceVop->vChan = video->prevEnhanceVop->uChan + (size >> 2); /* Memory for Previous Enhancement V */
@@ -1196,39 +1196,35 @@
if (video->currVop)
{
- if (video->currVop->yChan)
+ if (video->currVop->allChan)
{
- video->currVop->yChan -= offset;
- M4VENC_FREE(video->currVop->yChan);
+ M4VENC_FREE(video->currVop->allChan);
}
M4VENC_FREE(video->currVop);
}
if (video->nextBaseVop)
{
- if (video->nextBaseVop->yChan)
+ if (video->nextBaseVop->allChan)
{
- video->nextBaseVop->yChan -= offset;
- M4VENC_FREE(video->nextBaseVop->yChan);
+ M4VENC_FREE(video->nextBaseVop->allChan);
}
M4VENC_FREE(video->nextBaseVop);
}
if (video->prevBaseVop)
{
- if (video->prevBaseVop->yChan)
+ if (video->prevBaseVop->allChan)
{
- video->prevBaseVop->yChan -= offset;
- M4VENC_FREE(video->prevBaseVop->yChan);
+ M4VENC_FREE(video->prevBaseVop->allChan);
}
M4VENC_FREE(video->prevBaseVop);
}
if (video->prevEnhanceVop)
{
- if (video->prevEnhanceVop->yChan)
+ if (video->prevEnhanceVop->allChan)
{
- video->prevEnhanceVop->yChan -= offset;
- M4VENC_FREE(video->prevEnhanceVop->yChan);
+ M4VENC_FREE(video->prevEnhanceVop->allChan);
}
M4VENC_FREE(video->prevEnhanceVop);
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h
index 3bc9421..b05099c 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h
@@ -39,6 +39,7 @@
typedef struct tagVOP
{
+ PIXEL *allChan; /* [yuv]Chan point into this buffer */
PIXEL *yChan; /* The Y component */
PIXEL *uChan; /* The U component */
PIXEL *vChan; /* The V component */
diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp
index 7da7db9..cc89064 100644
--- a/media/libstagefright/foundation/base64.cpp
+++ b/media/libstagefright/foundation/base64.cpp
@@ -78,8 +78,7 @@
accum = (accum << 6) | value;
if (((i + 1) % 4) == 0) {
- out[j++] = (accum >> 16);
-
+ if (j < outLen) { out[j++] = (accum >> 16); }
if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
if (j < outLen) { out[j++] = accum & 0xff; }
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 3a94abd..ede8ecf 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -392,7 +392,12 @@
--mSize;
--dataSize;
}
- mData[writeOffset++] = mData[readOffset++];
+ if (i + 1 < dataSize) {
+ // Only move data if there's actually something to move.
+ // This handles the special case of the data being only [0xff, 0x00]
+ // which should be converted to just 0xff if unsynchronization is on.
+ mData[writeOffset++] = mData[readOffset++];
+ }
}
// move the remaining data following this frame
if (readOffset <= oldSize) {
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 616dda1..28f373f 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -157,8 +157,9 @@
KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
- // metadata mode tracking
+ // metadata and graphic buffer mode tracking
bool mUsingMetadata[2];
+ bool mGraphicBufferEnabled[2];
// For debug support
char *mName;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 2ed3ccc..a1494dc 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -669,6 +669,11 @@
bits.skipBits(2);
unsigned aac_frame_length = bits.getBits(13);
+ if (aac_frame_length == 0){
+ ALOGE("b/62673179, Invalid AAC frame length!");
+ android_errorWriteLog(0x534e4554, "62673179");
+ return NULL;
+ }
bits.skipBits(11); // adts_buffer_fullness
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 44c7edc..13ae8b1 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -283,7 +283,7 @@
// has dropped that GraphicBuffer, and there's nothing for us to release.
int id = codecBuffer.mBuf;
if (mBufferSlot[id] != NULL &&
- mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
+ mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
ALOGV("cbi %d matches bq slot %d, handle=%p",
cbi, id, mBufferSlot[id]->handle);
@@ -369,6 +369,12 @@
} else if (err != OK) {
ALOGW("suspend: acquireBuffer returned err=%d", err);
break;
+ } else if (item.mBuf < 0 ||
+ item.mBuf >= BufferQueue::NUM_BUFFER_SLOTS) {
+ // Invalid buffer index
+ ALOGW("suspend: corrupted buffer index (%d)",
+ item.mBuf);
+ break;
}
--mNumFramesAvailable;
@@ -419,6 +425,10 @@
// now what? fake end-of-stream?
ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
return false;
+ } else if (item.mBuf < 0 || item.mBuf >= BufferQueue::NUM_BUFFER_SLOTS) {
+ // Invalid buffer index
+ ALOGW("fillCodecBuffer_l: corrupted buffer index (%d)", item.mBuf);
+ return false;
}
mNumFramesAvailable--;
@@ -769,6 +779,13 @@
BufferQueue::BufferItem item;
status_t err = mConsumer->acquireBuffer(&item, 0);
if (err == OK) {
+ if (item.mBuf < 0 ||
+ item.mBuf >= BufferQueue::NUM_BUFFER_SLOTS) {
+ // Invalid buffer index
+ ALOGW("onFrameAvailable: corrupted buffer index (%d)",
+ item.mBuf);
+ return;
+ }
// If this is the first time we're seeing this buffer, add it to our
// slot table.
if (item.mGraphicBuffer != NULL) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 07499fc..6ea4b99 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -206,6 +206,8 @@
mDebugLevelBumpPendingBuffers[1] = 0;
mUsingMetadata[0] = false;
mUsingMetadata[1] = false;
+ mGraphicBufferEnabled[0] = false;
+ mGraphicBufferEnabled[1] = false;
mIsSecure = AString(name).endsWith(".secure");
}
@@ -343,6 +345,8 @@
break;
}
+ Mutex::Autolock _l(mLock);
+
ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);
OMX_ERRORTYPE err = master->destroyComponentInstance(
static_cast<OMX_COMPONENTTYPE *>(mHandle));
@@ -542,6 +546,11 @@
err = OMX_SetParameter(mHandle, index, ¶ms);
CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
portString(portIndex), portIndex, enable);
+ if (err == OMX_ErrorNone) {
+ mGraphicBufferEnabled[portIndex] = enable;
+ } else if (enable) {
+ mGraphicBufferEnabled[portIndex] = false;
+ }
return StatusFromOMXError(err);
}
@@ -746,6 +755,12 @@
return BAD_VALUE;
}
+ if (!mUsingMetadata[portIndex] && mGraphicBufferEnabled[portIndex]) {
+ ALOGE("b/62948670");
+ android_errorWriteLog(0x534e4554, "62948670");
+ return INVALID_OPERATION;
+ }
+
// metadata buffers are not connected cross process
BufferMeta *buffer_meta;
bool isMeta = mUsingMetadata[portIndex];
@@ -855,6 +870,12 @@
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
+ if (!mGraphicBufferEnabled[portIndex] || mUsingMetadata[portIndex]) {
+ // Report error if this is not in graphic buffer mode.
+ ALOGE("b/62948670");
+ android_errorWriteLog(0x534e4554, "62948670");
+ return INVALID_OPERATION;
+ }
// See if the newer version of the extension is present.
OMX_INDEXTYPE index;
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 36c1a0d..bad1bf1 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -199,6 +199,13 @@
Mutex::Autolock autoLock(mLock);
CHECK_LT(portIndex, mPorts.size());
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ if (size < port->mDef.nBufferSize) {
+ ALOGE("b/63522430, Buffer size is too small.");
+ android_errorWriteLog(0x534e4554, "63522430");
+ return OMX_ErrorBadParameter;
+ }
+
*header = new OMX_BUFFERHEADERTYPE;
(*header)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
(*header)->nVersion.s.nVersionMajor = 1;
@@ -221,8 +228,6 @@
(*header)->nOutputPortIndex = portIndex;
(*header)->nInputPortIndex = portIndex;
- PortInfo *port = &mPorts.editItemAt(portIndex);
-
CHECK(mState == OMX_StateLoaded || port->mDef.bEnabled == OMX_FALSE);
CHECK_LT(port->mBuffers.size(), port->mDef.nBufferCountActual);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 2e43344..39635cb 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1273,6 +1273,24 @@
ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
cmdCode, mHasControl, mEffect.unsafe_get());
+ // reject commands reserved for internal use by audio framework if coming from outside
+ // of audioserver
+ switch(cmdCode) {
+ case EFFECT_CMD_ENABLE:
+ case EFFECT_CMD_DISABLE:
+ case EFFECT_CMD_SET_PARAM:
+ case EFFECT_CMD_SET_PARAM_DEFERRED:
+ case EFFECT_CMD_SET_PARAM_COMMIT:
+ case EFFECT_CMD_GET_PARAM:
+ break;
+ default:
+ if (cmdCode >= EFFECT_CMD_FIRST_PROPRIETARY) {
+ break;
+ }
+ android_errorWriteLog(0x534e4554, "62019992");
+ return BAD_VALUE;
+ }
+
if (cmdCode == EFFECT_CMD_ENABLE) {
if (*replySize < sizeof(int)) {
android_errorWriteLog(0x534e4554, "32095713");
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1839262..783c731 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -143,9 +143,11 @@
return;
}
} else {
- // this syntax avoids calling the audio_track_cblk_t constructor twice
- mCblk = (audio_track_cblk_t *) new uint8_t[size];
- // assume mCblk != NULL
+ mCblk = (audio_track_cblk_t *) malloc(size);
+ if (mCblk == NULL) {
+ ALOGE("not enough memory for AudioTrack size=%zu", size);
+ return;
+ }
}
// construct the shared structure in-place.
@@ -237,10 +239,9 @@
// delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
delete mServerProxy;
if (mCblk != NULL) {
+ mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
if (mClient == 0) {
- delete mCblk;
- } else {
- mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
+ free(mCblk);
}
}
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
@@ -437,6 +438,21 @@
mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
mFrameSize, !isExternalTrack(), sampleRate);
} else {
+ // Is the shared buffer of sufficient size?
+ // (frameCount * mFrameSize) is <= SIZE_MAX, checked in TrackBase.
+ if (sharedBuffer->size() < frameCount * mFrameSize) {
+ // Workaround: clear out mCblk to indicate track hasn't been properly created.
+ mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
+ if (mClient == 0) {
+ free(mCblk);
+ }
+ mCblk = NULL;
+
+ mSharedBuffer.clear(); // release shared buffer early
+ android_errorWriteLog(0x534e4554, "38340117");
+ return;
+ }
+
mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
mFrameSize);
}
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 091ef07..0735b28 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -631,6 +631,7 @@
audio_io_handle_t *ioHandle,
audio_devices_t *device)
{
+ Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
@@ -640,6 +641,7 @@
status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
{
+ Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 665672f..5ae3862 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -497,6 +497,8 @@
if (!captureHotwordAllowed()) {
return;
}
+ Vector<audio_session_t> releasedSessions;
+
{
AutoMutex lock(mLock);
for (size_t i = 0; i < mModels.size(); i++) {
@@ -506,9 +508,16 @@
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
}
mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
+ releasedSessions.add(model->mCaptureSession);
}
mModels.clear();
}
+
+ for (size_t i = 0; i < releasedSessions.size(); i++) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
+ }
+
if (mClient != 0) {
mClient->asBinder()->unlinkToDeath(this);
}
@@ -550,37 +559,52 @@
return BAD_VALUE;
}
- AutoMutex lock(mLock);
-
- if (mModels.size() >= mDescriptor.properties.max_sound_models) {
- if (mModels.size() == 0) {
- return INVALID_OPERATION;
- }
- ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
- mDescriptor.properties.max_sound_models);
- unloadSoundModel_l(mModels.valueAt(0)->mHandle);
- }
-
- status_t status = mHwDevice->load_sound_model(mHwDevice,
- sound_model,
- SoundTriggerHwService::soundModelCallback,
- this,
- handle);
- if (status != NO_ERROR) {
- return status;
- }
audio_session_t session;
+ audio_session_t freedSession = AUDIO_SESSION_ALLOCATE;
audio_io_handle_t ioHandle;
audio_devices_t device;
-
- status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
+ // do not call AudioSystem methods with mLock held
+ status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
if (status != NO_ERROR) {
return status;
}
- sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
- mModels.replaceValueFor(*handle, model);
+ {
+ AutoMutex lock(mLock);
+
+ if (mModels.size() >= mDescriptor.properties.max_sound_models) {
+ if (mModels.size() == 0) {
+ status = INVALID_OPERATION;
+ goto exit;
+ }
+ ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
+ mDescriptor.properties.max_sound_models);
+ unloadSoundModel_l(mModels.valueAt(0)->mHandle, &freedSession);
+ }
+
+ status_t status = mHwDevice->load_sound_model(mHwDevice,
+ sound_model,
+ SoundTriggerHwService::soundModelCallback,
+ this,
+ handle);
+ if (status != NO_ERROR) {
+ goto exit;
+ }
+
+ sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
+ mModels.replaceValueFor(*handle, model);
+ }
+
+exit:
+ if (freedSession != AUDIO_SESSION_ALLOCATE) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(freedSession);
+ }
+ if (status != NO_ERROR) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(session);
+ }
return status;
}
@@ -591,12 +615,21 @@
return PERMISSION_DENIED;
}
- AutoMutex lock(mLock);
- return unloadSoundModel_l(handle);
+ status_t status;
+ audio_session_t freedSession = AUDIO_SESSION_ALLOCATE;
+ {
+ AutoMutex lock(mLock);
+ status = unloadSoundModel_l(handle, &freedSession);
+ }
+ if (freedSession != AUDIO_SESSION_ALLOCATE) {
+ AudioSystem::releaseSoundTriggerSession(freedSession);
+ }
+ return status;
}
-status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
+status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle, audio_session_t *session)
{
+ *session = AUDIO_SESSION_ALLOCATE;
ssize_t index = mModels.indexOfKey(handle);
if (index < 0) {
return BAD_VALUE;
@@ -607,7 +640,7 @@
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
model->mState = Model::STATE_IDLE;
}
- AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
+ *session = model->mCaptureSession;
return mHwDevice->unload_sound_model(mHwDevice, handle);
}
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index 2619a5f..f0e7a5f 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -141,7 +141,7 @@
private:
- status_t unloadSoundModel_l(sound_model_handle_t handle);
+ status_t unloadSoundModel_l(sound_model_handle_t handle, audio_session_t *session);
Mutex mLock;