diff options
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 4 | ||||
-rw-r--r-- | media/libmedia/IEffect.cpp | 27 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 4 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/OggExtractor.cpp | 20 | ||||
-rw-r--r-- | media/libstagefright/Utils.cpp | 36 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TextDescriptions.cpp | 627 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TextDescriptions.h | 4 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 5 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 2 |
10 files changed, 456 insertions, 278 deletions
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 3348441..7e6b9fc 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -877,7 +877,7 @@ status_t BnAudioPolicyService::onTransact( if (hasOffloadInfo) { data.read(&offloadInfo, sizeof(audio_offload_info_t)); } - audio_io_handle_t output; + audio_io_handle_t output = 0; status_t status = getOutputForAttr(hasAttributes ? &attr : NULL, &output, session, &stream, uid, samplingRate, format, channelMask, @@ -994,7 +994,7 @@ status_t BnAudioPolicyService::onTransact( audio_stream_type_t stream = static_cast <audio_stream_type_t>(data.readInt32()); audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); - int index; + int index = 0; status_t status = getStreamVolumeIndex(stream, &index, device); reply->writeInt32(index); reply->writeInt32(static_cast <uint32_t>(status)); diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp index 761b243..faf5795 100644 --- a/media/libmedia/IEffect.cpp +++ b/media/libmedia/IEffect.cpp @@ -85,13 +85,15 @@ public: data.writeInt32(size); status_t status = remote()->transact(COMMAND, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } if (status != NO_ERROR) { if (pReplySize != NULL) *pReplySize = 0; return status; } - status = reply.readInt32(); size = reply.readInt32(); if (size != 0 && pReplyData != NULL && pReplySize != NULL) { reply.read(pReplyData, size); @@ -155,6 +157,10 @@ status_t BnEffect::onTransact( char *cmd = NULL; if (cmdSize) { cmd = (char *)calloc(cmdSize, 1); + if (cmd == NULL) { + reply->writeInt32(NO_MEMORY); + return NO_ERROR; + } data.read(cmd, cmdSize); } uint32_t replySize = data.readInt32(); @@ -162,15 +168,22 @@ status_t BnEffect::onTransact( char *resp = NULL; if (replySize) { resp = (char *)calloc(replySize, 1); + if (resp == NULL) { + free(cmd); + reply->writeInt32(NO_MEMORY); + return NO_ERROR; + } } status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp); reply->writeInt32(status); - if (replySz < replySize) { - replySize = replySz; - } - reply->writeInt32(replySize); - if (replySize) { - reply->write(resp, replySize); + if (status == NO_ERROR) { + if (replySz < replySize) { + replySize = replySz; + } + reply->writeInt32(replySize); + if (replySize) { + reply->write(resp, replySize); + } } if (cmd) { free(cmd); diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 7387a79..942aec3 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -566,7 +566,7 @@ status_t BnMediaPlayer::onTransact( } break; case GET_CURRENT_POSITION: { CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; + int msec = 0; status_t ret = getCurrentPosition(&msec); reply->writeInt32(msec); reply->writeInt32(ret); @@ -574,7 +574,7 @@ status_t BnMediaPlayer::onTransact( } break; case GET_DURATION: { CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; + int msec = 0; status_t ret = getDuration(&msec); reply->writeInt32(msec); reply->writeInt32(ret); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 4de08ff..0ac29a8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -945,6 +945,10 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { int64_t NuPlayer::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) { int32_t sampleRate = offloadingAudio() ? mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate; + if (sampleRate == 0) { + ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload"); + return 0; + } // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate); } @@ -1789,6 +1793,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink( } if (err != OK) { ALOGW("openAudioSink: non offloaded open failed status: %d", err); + mAudioSink->close(); mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; return err; } diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index 6fba8e1..d5c929e 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -1220,11 +1220,14 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { } } - size_t outLen = 3 * size / 4 - padding; - - *outSize = outLen; + // We divide first to avoid overflow. It's OK to do this because we + // already made sure that size % 4 == 0. + size_t outLen = (size / 4) * 3 - padding; void *buffer = malloc(outLen); + if (buffer == NULL) { + return NULL; + } uint8_t *out = (uint8_t *)buffer; size_t j = 0; @@ -1243,10 +1246,10 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { } else if (c == '/') { value = 63; } else if (c != '=') { - return NULL; + break; } else { if (i < n - padding) { - return NULL; + break; } value = 0; @@ -1264,6 +1267,13 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { } } + // Check if we exited the loop early. + if (j < outLen) { + free(buffer); + return NULL; + } + + *outSize = outLen; return (uint8_t *)buffer; } diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index f0a7277..7c8d441 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -211,8 +211,10 @@ status_t convertMetaDataToMessage( const uint8_t *ptr = (const uint8_t *)data; - CHECK(size >= 7); - CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 + if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 + ALOGE("b/23680780"); + return BAD_VALUE; + } uint8_t profile __unused = ptr[1]; uint8_t level __unused = ptr[3]; @@ -238,7 +240,10 @@ status_t convertMetaDataToMessage( buffer->setRange(0, 0); for (size_t i = 0; i < numSeqParameterSets; ++i) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; @@ -267,13 +272,19 @@ status_t convertMetaDataToMessage( } buffer->setRange(0, 0); - CHECK(size >= 1); + if (size < 1) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t numPictureParameterSets = *ptr; ++ptr; --size; for (size_t i = 0; i < numPictureParameterSets; ++i) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; @@ -297,8 +308,10 @@ status_t convertMetaDataToMessage( } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { const uint8_t *ptr = (const uint8_t *)data; - CHECK(size >= 7); - CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 + if (size < 23 || ptr[0] != 1) { // configurationVersion == 1 + ALOGE("b/23680780"); + return BAD_VALUE; + } uint8_t profile __unused = ptr[1] & 31; uint8_t level __unused = ptr[12]; ptr += 22; @@ -317,6 +330,10 @@ status_t convertMetaDataToMessage( buffer->setRange(0, 0); for (i = 0; i < numofArrays; i++) { + if (size < 3) { + ALOGE("b/23680780"); + return BAD_VALUE; + } ptr += 1; size -= 1; @@ -327,7 +344,10 @@ status_t convertMetaDataToMessage( size -= 2; for (j = 0; j < numofNals; j++) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp index f9c1fe0..c762a74 100644 --- a/media/libstagefright/timedtext/TextDescriptions.cpp +++ b/media/libstagefright/timedtext/TextDescriptions.cpp @@ -30,9 +30,9 @@ status_t TextDescriptions::getParcelOfDescriptions( if (flags & IN_BAND_TEXT_3GPP) { if (flags & GLOBAL_DESCRIPTIONS) { - return extract3GPPGlobalDescriptions(data, size, parcel, 0); + return extract3GPPGlobalDescriptions(data, size, parcel); } else if (flags & LOCAL_DESCRIPTIONS) { - return extract3GPPLocalDescriptions(data, size, timeMs, parcel, 0); + return extract3GPPLocalDescriptions(data, size, timeMs, parcel); } } else if (flags & OUT_OF_BAND_TEXT_SRT) { if (flags & LOCAL_DESCRIPTIONS) { @@ -69,314 +69,437 @@ status_t TextDescriptions::extractSRTLocalDescriptions( // styles, and 'krok' box contains karaoke timing and positions. status_t TextDescriptions::extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, - int timeMs, Parcel *parcel, int depth) { - if (depth == 0) { - parcel->writeInt32(KEY_LOCAL_SETTING); - - // write start time to display this text sample - parcel->writeInt32(KEY_START_TIME); - parcel->writeInt32(timeMs); - - ssize_t textLen = (*data) << 8 | (*(data + 1)); - - // write text sample length and text sample itself - parcel->writeInt32(KEY_STRUCT_TEXT); - parcel->writeInt32(textLen); - parcel->writeInt32(textLen); - parcel->write(data + 2, textLen); - - if (size > textLen) { - data += (textLen + 2); - size -= (textLen + 2); - } else { - return OK; - } + int timeMs, Parcel *parcel) { + + parcel->writeInt32(KEY_LOCAL_SETTING); + + // write start time to display this text sample + parcel->writeInt32(KEY_START_TIME); + parcel->writeInt32(timeMs); + + if (size < 2) { + return OK; } + ssize_t textLen = (*data) << 8 | (*(data + 1)); - const uint8_t *tmpData = data; - ssize_t chunkSize = U32_AT(tmpData); - uint32_t chunkType = U32_AT(tmpData + 4); + if (size < textLen + 2) { + return OK; + } - if (chunkSize <= 0) { + // write text sample length and text sample itself + parcel->writeInt32(KEY_STRUCT_TEXT); + parcel->writeInt32(textLen); + parcel->writeInt32(textLen); + parcel->write(data + 2, textLen); + + if (size > textLen + 2) { + data += (textLen + 2); + size -= (textLen + 2); + } else { return OK; } - tmpData += 8; + while (size >= 8) { + const uint8_t *tmpData = data; + ssize_t chunkSize = U32_AT(tmpData); // size includes size and type + uint32_t chunkType = U32_AT(tmpData + 4); - switch(chunkType) { - // 'styl' box specifies the style of the text. - case FOURCC('s', 't', 'y', 'l'): - { - uint16_t count = U16_AT(tmpData); + if (chunkSize <= 8 || chunkSize > size) { + return OK; + } - tmpData += 2; + size_t remaining = chunkSize - 8; - for (int i = 0; i < count; i++) { - parcel->writeInt32(KEY_STRUCT_STYLE_LIST); - parcel->writeInt32(KEY_START_CHAR); - parcel->writeInt32(U16_AT(tmpData)); + tmpData += 8; - parcel->writeInt32(KEY_END_CHAR); - parcel->writeInt32(U16_AT(tmpData + 2)); + switch(chunkType) { + // 'styl' box specifies the style of the text. + case FOURCC('s', 't', 'y', 'l'): + { + if (remaining < 2) { + return OK; + } + size_t dataPos = parcel->dataPosition(); + uint16_t count = U16_AT(tmpData); - parcel->writeInt32(KEY_FONT_ID); - parcel->writeInt32(U16_AT(tmpData + 4)); + tmpData += 2; + remaining -= 2; - parcel->writeInt32(KEY_STYLE_FLAGS); - parcel->writeInt32(*(tmpData + 6)); + for (int i = 0; i < count; i++) { + if (remaining < 12) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + parcel->writeInt32(KEY_STRUCT_STYLE_LIST); + parcel->writeInt32(KEY_START_CHAR); + parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(KEY_FONT_SIZE); - parcel->writeInt32(*(tmpData + 7)); + parcel->writeInt32(KEY_END_CHAR); + parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(KEY_TEXT_COLOR_RGBA); - uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 - | *(tmpData + 10) << 8 | *(tmpData + 11); - parcel->writeInt32(rgba); + parcel->writeInt32(KEY_FONT_ID); + parcel->writeInt32(U16_AT(tmpData + 4)); - tmpData += 12; + parcel->writeInt32(KEY_STYLE_FLAGS); + parcel->writeInt32(*(tmpData + 6)); + + parcel->writeInt32(KEY_FONT_SIZE); + parcel->writeInt32(*(tmpData + 7)); + + parcel->writeInt32(KEY_TEXT_COLOR_RGBA); + uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 + | *(tmpData + 10) << 8 | *(tmpData + 11); + parcel->writeInt32(rgba); + + tmpData += 12; + remaining -= 12; + } + + break; + } + // 'krok' box. The number of highlight events is specified, and each + // event is specified by a starting and ending char offset and an end + // time for the event. + case FOURCC('k', 'r', 'o', 'k'): + { + if (remaining < 6) { + return OK; + } + size_t dataPos = parcel->dataPosition(); + + parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); + + int startTime = U32_AT(tmpData); + uint16_t count = U16_AT(tmpData + 4); + parcel->writeInt32(count); + + tmpData += 6; + remaining -= 6; + int lastEndTime = 0; + + for (int i = 0; i < count; i++) { + if (remaining < 8) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + parcel->writeInt32(startTime + lastEndTime); + + lastEndTime = U32_AT(tmpData); + parcel->writeInt32(lastEndTime); + + parcel->writeInt32(U16_AT(tmpData + 4)); + parcel->writeInt32(U16_AT(tmpData + 6)); + + tmpData += 8; + remaining -= 8; + } + + break; } + // 'hlit' box specifies highlighted text + case FOURCC('h', 'l', 'i', 't'): + { + if (remaining < 4) { + return OK; + } - break; - } - // 'krok' box. The number of highlight events is specified, and each - // event is specified by a starting and ending char offset and an end - // time for the event. - case FOURCC('k', 'r', 'o', 'k'): - { + parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); - parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); + // the start char offset to highlight + parcel->writeInt32(U16_AT(tmpData)); + // the last char offset to highlight + parcel->writeInt32(U16_AT(tmpData + 2)); - int startTime = U32_AT(tmpData); - uint16_t count = U16_AT(tmpData + 4); - parcel->writeInt32(count); + tmpData += 4; + remaining -= 4; + break; + } + // 'hclr' box specifies the RGBA color: 8 bits each of + // red, green, blue, and an alpha(transparency) value + case FOURCC('h', 'c', 'l', 'r'): + { + if (remaining < 4) { + return OK; + } + parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); + + uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 + | *(tmpData + 2) << 8 | *(tmpData + 3); + parcel->writeInt32(rgba); + + tmpData += 4; + remaining -= 4; + break; + } + // 'dlay' box specifies a delay after a scroll in and/or + // before scroll out. + case FOURCC('d', 'l', 'a', 'y'): + { + if (remaining < 4) { + return OK; + } + parcel->writeInt32(KEY_SCROLL_DELAY); + + uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 + | *(tmpData + 2) << 8 | *(tmpData + 3); + parcel->writeInt32(delay); + + tmpData += 4; + remaining -= 4; + break; + } + // 'href' box for hyper text link + case FOURCC('h', 'r', 'e', 'f'): + { + if (remaining < 5) { + return OK; + } - tmpData += 6; - int lastEndTime = 0; + size_t dataPos = parcel->dataPosition(); - for (int i = 0; i < count; i++) { - parcel->writeInt32(startTime + lastEndTime); + parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); - lastEndTime = U32_AT(tmpData); - parcel->writeInt32(lastEndTime); + // the start offset of the text to be linked + parcel->writeInt32(U16_AT(tmpData)); + // the end offset of the text + parcel->writeInt32(U16_AT(tmpData + 2)); + // the number of bytes in the following URL + size_t len = *(tmpData + 4); + parcel->writeInt32(len); + + remaining -= 5; + + if (remaining < len) { + parcel->setDataPosition(dataPos); + return OK; + } + // the linked-to URL + parcel->writeInt32(len); + parcel->write(tmpData + 5, len); + + tmpData += (5 + len); + remaining -= len; + + if (remaining < 1) { + parcel->setDataPosition(dataPos); + return OK; + } + + // the number of bytes in the following "alt" string + len = *tmpData; + parcel->writeInt32(len); + + tmpData += 1; + remaining -= 1; + if (remaining < len) { + parcel->setDataPosition(dataPos); + return OK; + } + + // an "alt" string for user display + parcel->writeInt32(len); + parcel->write(tmpData, len); + + tmpData += 1; + remaining -= 1; + break; + } + // 'tbox' box to indicate the position of the text with values + // of top, left, bottom and right + case FOURCC('t', 'b', 'o', 'x'): + { + if (remaining < 8) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_TEXT_POS); + parcel->writeInt32(U16_AT(tmpData)); + parcel->writeInt32(U16_AT(tmpData + 2)); parcel->writeInt32(U16_AT(tmpData + 4)); parcel->writeInt32(U16_AT(tmpData + 6)); tmpData += 8; + remaining -= 8; + break; } + // 'blnk' to specify the char range to be blinked + case FOURCC('b', 'l', 'n', 'k'): + { + if (remaining < 4) { + return OK; + } - break; - } - // 'hlit' box specifies highlighted text - case FOURCC('h', 'l', 'i', 't'): - { - parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); + parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); - // the start char offset to highlight - parcel->writeInt32(U16_AT(tmpData)); - // the last char offset to highlight - parcel->writeInt32(U16_AT(tmpData + 2)); + // start char offset + parcel->writeInt32(U16_AT(tmpData)); + // end char offset + parcel->writeInt32(U16_AT(tmpData + 2)); - break; + tmpData += 4; + remaining -= 4; + break; + } + // 'twrp' box specifies text wrap behavior. If the value if 0x00, + // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. + // 0x02-0xff are reserved. + case FOURCC('t', 'w', 'r', 'p'): + { + if (remaining < 1) { + return OK; + } + parcel->writeInt32(KEY_WRAP_TEXT); + parcel->writeInt32(*tmpData); + + tmpData += 1; + remaining -= 1; + break; + } + default: + { + break; + } } - // 'hclr' box specifies the RGBA color: 8 bits each of - // red, green, blue, and an alpha(transparency) value - case FOURCC('h', 'c', 'l', 'r'): - { - parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); - uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 - | *(tmpData + 2) << 8 | *(tmpData + 3); - parcel->writeInt32(rgba); + data += chunkSize; + size -= chunkSize; + } + + return OK; +} - break; - } - // 'dlay' box specifies a delay after a scroll in and/or - // before scroll out. - case FOURCC('d', 'l', 'a', 'y'): - { - parcel->writeInt32(KEY_SCROLL_DELAY); +// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel +status_t TextDescriptions::extract3GPPGlobalDescriptions( + const uint8_t *data, ssize_t size, Parcel *parcel) { + + parcel->writeInt32(KEY_GLOBAL_SETTING); - uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 - | *(tmpData + 2) << 8 | *(tmpData + 3); - parcel->writeInt32(delay); + while (size >= 8) { + ssize_t chunkSize = U32_AT(data); + uint32_t chunkType = U32_AT(data + 4); + const uint8_t *tmpData = data; + tmpData += 8; + size_t remaining = size - 8; - break; + if (size < chunkSize) { + return OK; } - // 'href' box for hyper text link - case FOURCC('h', 'r', 'e', 'f'): - { - parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); + switch(chunkType) { + case FOURCC('t', 'x', '3', 'g'): + { + if (remaining < 18) { // 8 just below, and another 10 a little further down + return OK; + } + tmpData += 8; // skip the first 8 bytes + remaining -=8; + parcel->writeInt32(KEY_DISPLAY_FLAGS); + parcel->writeInt32(U32_AT(tmpData)); + + parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); + parcel->writeInt32(tmpData[4]); + parcel->writeInt32(tmpData[5]); + + parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); + uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 + | *(tmpData + 8) << 8 | *(tmpData + 9); + parcel->writeInt32(rgba); - // the start offset of the text to be linked - parcel->writeInt32(U16_AT(tmpData)); - // the end offset of the text - parcel->writeInt32(U16_AT(tmpData + 2)); + tmpData += 10; + remaining -= 10; - // the number of bytes in the following URL - int len = *(tmpData + 4); - parcel->writeInt32(len); + if (remaining < 8) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_TEXT_POS); + parcel->writeInt32(U16_AT(tmpData)); + parcel->writeInt32(U16_AT(tmpData + 2)); + parcel->writeInt32(U16_AT(tmpData + 4)); + parcel->writeInt32(U16_AT(tmpData + 6)); - // the linked-to URL - parcel->writeInt32(len); - parcel->write(tmpData + 5, len); + tmpData += 8; + remaining -= 8; - tmpData += (5 + len); + if (remaining < 12) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_STYLE_LIST); + parcel->writeInt32(KEY_START_CHAR); + parcel->writeInt32(U16_AT(tmpData)); - // the number of bytes in the following "alt" string - len = *tmpData; - parcel->writeInt32(len); + parcel->writeInt32(KEY_END_CHAR); + parcel->writeInt32(U16_AT(tmpData + 2)); - // an "alt" string for user display - parcel->writeInt32(len); - parcel->write(tmpData + 1, len); + parcel->writeInt32(KEY_FONT_ID); + parcel->writeInt32(U16_AT(tmpData + 4)); - break; - } - // 'tbox' box to indicate the position of the text with values - // of top, left, bottom and right - case FOURCC('t', 'b', 'o', 'x'): - { - parcel->writeInt32(KEY_STRUCT_TEXT_POS); - parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(U16_AT(tmpData + 4)); - parcel->writeInt32(U16_AT(tmpData + 6)); - - break; - } - // 'blnk' to specify the char range to be blinked - case FOURCC('b', 'l', 'n', 'k'): - { - parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); + parcel->writeInt32(KEY_STYLE_FLAGS); + parcel->writeInt32(*(tmpData + 6)); - // start char offset - parcel->writeInt32(U16_AT(tmpData)); - // end char offset - parcel->writeInt32(U16_AT(tmpData + 2)); + parcel->writeInt32(KEY_FONT_SIZE); + parcel->writeInt32(*(tmpData + 7)); - break; - } - // 'twrp' box specifies text wrap behavior. If the value if 0x00, - // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. - // 0x02-0xff are reserved. - case FOURCC('t', 'w', 'r', 'p'): - { - parcel->writeInt32(KEY_WRAP_TEXT); - parcel->writeInt32(*tmpData); - - break; - } - default: - { - break; - } - } + parcel->writeInt32(KEY_TEXT_COLOR_RGBA); + rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 + | *(tmpData + 10) << 8 | *(tmpData + 11); + parcel->writeInt32(rgba); - if (size > chunkSize) { - data += chunkSize; - size -= chunkSize; - // continue to parse next box - return extract3GPPLocalDescriptions(data, size, 0, parcel, 1); - } + tmpData += 12; + remaining -= 12; - return OK; -} + if (remaining < 2) { + return OK; + } -// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel -status_t TextDescriptions::extract3GPPGlobalDescriptions( - const uint8_t *data, ssize_t size, Parcel *parcel, int depth) { + size_t dataPos = parcel->dataPosition(); - ssize_t chunkSize = U32_AT(data); - uint32_t chunkType = U32_AT(data + 4); - const uint8_t *tmpData = data; - tmpData += 8; + parcel->writeInt32(KEY_STRUCT_FONT_LIST); + uint16_t count = U16_AT(tmpData); + parcel->writeInt32(count); - if (size < chunkSize) { - return OK; - } + tmpData += 2; + remaining -= 2; - if (depth == 0) { - parcel->writeInt32(KEY_GLOBAL_SETTING); - } - switch(chunkType) { - case FOURCC('t', 'x', '3', 'g'): - { - tmpData += 8; // skip the first 8 bytes - parcel->writeInt32(KEY_DISPLAY_FLAGS); - parcel->writeInt32(U32_AT(tmpData)); - - parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); - parcel->writeInt32(tmpData[4]); - parcel->writeInt32(tmpData[5]); - - parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); - uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 - | *(tmpData + 8) << 8 | *(tmpData + 9); - parcel->writeInt32(rgba); - - tmpData += 10; - parcel->writeInt32(KEY_STRUCT_TEXT_POS); - parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(U16_AT(tmpData + 4)); - parcel->writeInt32(U16_AT(tmpData + 6)); - - tmpData += 8; - parcel->writeInt32(KEY_STRUCT_STYLE_LIST); - parcel->writeInt32(KEY_START_CHAR); - parcel->writeInt32(U16_AT(tmpData)); - - parcel->writeInt32(KEY_END_CHAR); - parcel->writeInt32(U16_AT(tmpData + 2)); - - parcel->writeInt32(KEY_FONT_ID); - parcel->writeInt32(U16_AT(tmpData + 4)); - - parcel->writeInt32(KEY_STYLE_FLAGS); - parcel->writeInt32(*(tmpData + 6)); - - parcel->writeInt32(KEY_FONT_SIZE); - parcel->writeInt32(*(tmpData + 7)); - - parcel->writeInt32(KEY_TEXT_COLOR_RGBA); - rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 - | *(tmpData + 10) << 8 | *(tmpData + 11); - parcel->writeInt32(rgba); - - tmpData += 12; - parcel->writeInt32(KEY_STRUCT_FONT_LIST); - uint16_t count = U16_AT(tmpData); - parcel->writeInt32(count); - - tmpData += 2; - for (int i = 0; i < count; i++) { - // font ID - parcel->writeInt32(U16_AT(tmpData)); + for (int i = 0; i < count; i++) { + if (remaining < 3) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + // font ID + parcel->writeInt32(U16_AT(tmpData)); - // font name length - parcel->writeInt32(*(tmpData + 2)); + // font name length + parcel->writeInt32(*(tmpData + 2)); - int len = *(tmpData + 2); + size_t len = *(tmpData + 2); - parcel->write(tmpData + 3, len); - tmpData += 3 + len; - } + tmpData += 3; + remaining -= 3; - break; - } - default: - { - break; - } - } + if (remaining < len) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } - data += chunkSize; - size -= chunkSize; + parcel->write(tmpData, len); + tmpData += len; + remaining -= len; + } - if (size > 0) { - // continue to extract next 'tx3g' - return extract3GPPGlobalDescriptions(data, size, parcel, 1); + // there is a "DisparityBox" after this according to the spec, but we ignore it + break; + } + default: + { + break; + } + } + + data += chunkSize; + size -= chunkSize; } return OK; diff --git a/media/libstagefright/timedtext/TextDescriptions.h b/media/libstagefright/timedtext/TextDescriptions.h index 0144917..bf67f3f 100644 --- a/media/libstagefright/timedtext/TextDescriptions.h +++ b/media/libstagefright/timedtext/TextDescriptions.h @@ -72,10 +72,10 @@ private: int timeMs, Parcel *parcel); static status_t extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, - Parcel *parcel, int depth); + Parcel *parcel); static status_t extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, - int timeMs, Parcel *parcel, int depth); + int timeMs, Parcel *parcel); DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions); }; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index d289704..f5a0887 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -602,6 +602,11 @@ int CameraService::getCameraPriorityFromProcState(int procState) { procState); return -1; } + // Treat sleeping TOP processes the same as regular TOP processes, for + // access priority. This is important for lock-screen camera launch scenarios + if (procState == PROCESS_STATE_TOP_SLEEPING) { + procState = PROCESS_STATE_TOP; + } return INT_MAX - procState; } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index a8c6b6c..330a19d 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -75,6 +75,8 @@ public: // Process state (mirrors frameworks/base/core/java/android/app/ActivityManager.java) static const int PROCESS_STATE_NONEXISTENT = -1; + static const int PROCESS_STATE_TOP = 2; + static const int PROCESS_STATE_TOP_SLEEPING = 5; // 3 second busy timeout when other clients are connecting static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000; |