Merge "Camera: Use fully qualified name for camera eviction logic" into pi-dev
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index fc60fd4..1826cc1 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -37,7 +37,9 @@
#include <media/stagefright/MetaDataUtils.h>
#include <utils/String8.h>
+#include <arpa/inet.h>
#include <inttypes.h>
+#include <vector>
namespace android {
@@ -584,31 +586,15 @@
}
const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset();
- bool blockEncrypted = data[0] & 0x1;
- if (blockEncrypted && mbuf->range_length() < 9) {
+ bool encrypted = data[0] & 0x1;
+ bool partitioned = data[0] & 0x2;
+ if (encrypted && mbuf->range_length() < 9) {
// 1-byte signal + 8-byte IV
return ERROR_MALFORMED;
}
MetaDataBase &meta = mbuf->meta_data();
- if (blockEncrypted) {
- /*
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Signal Byte | |
- * +-+-+-+-+-+-+-+-+ IV |
- * | |
- * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |
- * |-+-+-+-+-+-+-+-+ |
- * : Bytes 1..N of encrypted frame :
- * | |
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- int32_t plainSizes[] = { 0 };
- int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
+ if (encrypted) {
uint8_t ctrCounter[16] = { 0 };
uint32_t type;
const uint8_t *keyId;
@@ -618,9 +604,83 @@
meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize);
memcpy(ctrCounter, data + 1, 8);
meta.setData(kKeyCryptoIV, 0, ctrCounter, 16);
- meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
- meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
- mbuf->set_range(9, mbuf->range_length() - 9);
+ if (partitioned) {
+ /* 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Signal Byte | |
+ * +-+-+-+-+-+-+-+-+ IV |
+ * | |
+ * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | num_partition | Partition 0 offset -> |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+ * | -> Partition 0 offset | ... |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+ * | ... | Partition n-1 offset -> |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+ * | -> Partition n-1 offset | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * | Clear/encrypted sample data |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ if (mbuf->range_length() < 10) {
+ return ERROR_MALFORMED;
+ }
+ uint8_t numPartitions = data[9];
+ if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) {
+ return ERROR_MALFORMED;
+ }
+ std::vector<uint32_t> plainSizes, encryptedSizes;
+ uint32_t prev = 0;
+ uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t);
+ const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10);
+ for (uint32_t i = 0; i <= numPartitions; ++i) {
+ uint32_t p_i = i < numPartitions
+ ? ntohl(partitions[i])
+ : (mbuf->range_length() - frameOffset);
+ if (p_i < prev) {
+ return ERROR_MALFORMED;
+ }
+ uint32_t size = p_i - prev;
+ prev = p_i;
+ if (i % 2) {
+ encryptedSizes.push_back(size);
+ } else {
+ plainSizes.push_back(size);
+ }
+ }
+ if (plainSizes.size() > encryptedSizes.size()) {
+ encryptedSizes.push_back(0);
+ }
+ uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
+ uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
+ meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes);
+ meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes);
+ mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
+ } else {
+ /*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Signal Byte | |
+ * +-+-+-+-+-+-+-+-+ IV |
+ * | |
+ * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |
+ * |-+-+-+-+-+-+-+-+ |
+ * : Bytes 1..N of encrypted frame :
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ int32_t plainSizes[] = { 0 };
+ int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
+ meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
+ meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+ mbuf->set_range(9, mbuf->range_length() - 9);
+ }
} else {
/*
* 0 1 2 3
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 99f32d5..dad36ec 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -321,8 +321,13 @@
case FOURCC('h', 'e', 'v', '1'):
return MEDIA_MIMETYPE_VIDEO_HEVC;
default:
- CHECK(!"should not be here.");
- return NULL;
+ ALOGW("Unknown fourcc: %c%c%c%c",
+ (fourcc >> 24) & 0xff,
+ (fourcc >> 16) & 0xff,
+ (fourcc >> 8) & 0xff,
+ fourcc & 0xff
+ );
+ return "application/octet-stream";
}
}
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index 9b9744e..b09258e 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -22,6 +22,8 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <algorithm>
+
#include "FifoControllerBase.h"
#include "FifoController.h"
#include "FifoControllerIndirect.h"
@@ -85,15 +87,14 @@
wrappingBuffer->data[1] = nullptr;
wrappingBuffer->numFrames[1] = 0;
if (framesAvailable > 0) {
-
uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
// Does the available data cross the end of the FIFO?
if ((startIndex + framesAvailable) > mFrameCapacity) {
wrappingBuffer->data[0] = source;
- wrappingBuffer->numFrames[0] = mFrameCapacity - startIndex;
+ fifo_frames_t firstFrames = mFrameCapacity - startIndex;
+ wrappingBuffer->numFrames[0] = firstFrames;
wrappingBuffer->data[1] = &mStorage[0];
- wrappingBuffer->numFrames[1] = mFrameCapacity - startIndex;
-
+ wrappingBuffer->numFrames[1] = framesAvailable - firstFrames;
} else {
wrappingBuffer->data[0] = source;
wrappingBuffer->numFrames[0] = framesAvailable;
@@ -102,18 +103,19 @@
wrappingBuffer->data[0] = nullptr;
wrappingBuffer->numFrames[0] = 0;
}
-
}
fifo_frames_t FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
- fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
+ // The FIFO might be overfull so clip to capacity.
+ fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(), mFrameCapacity);
fifo_frames_t startIndex = mFifo->getReadIndex();
fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
return framesAvailable;
}
fifo_frames_t FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
- fifo_frames_t framesAvailable = mFifo->getEmptyFramesAvailable();
+ // The FIFO might have underrun so clip to capacity.
+ fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(), mFrameCapacity);
fifo_frames_t startIndex = mFifo->getWriteIndex();
fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
return framesAvailable;
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index b4c179d..dced3c4 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -725,12 +725,13 @@
const size_t mask = overflowBit - 1;
int32_t newRear = (rear & ~mask) | (stop & mask);
ssize_t filled = newRear - front;
- if (filled < 0) {
+ // overflowBit is unsigned, so cast to signed for comparison.
+ if (filled >= (ssize_t)overflowBit) {
// front and rear offsets span the overflow bit of the p2 mask
- // so rebasing newrear.
+ // so rebasing newRear on the rear offset is off by the overflow bit.
ALOGV("stop wrap: filled %zx >= overflowBit %zx", filled, overflowBit);
- newRear += overflowBit;
- filled += overflowBit;
+ newRear -= overflowBit;
+ filled -= overflowBit;
}
if (0 <= filled && (size_t) filled <= mFrameCount) {
// we're stopped, return the stop level as newRear
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3bbba49..0296dd8 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -6777,9 +6777,14 @@
sp<RefBase> obj;
CHECK(msg->findObject("input-surface", &obj));
+ if (obj == NULL) {
+ ALOGE("[%s] NULL input surface", mCodec->mComponentName.c_str());
+ mCodec->mCallback->onInputSurfaceDeclined(BAD_VALUE);
+ return;
+ }
+
sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
mCodec->mGraphicBufferSource = surface->getBufferSource();
-
status_t err = setupInputSurface();
if (err == OK) {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 949b570..3c4f500 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3388,8 +3388,7 @@
// They would both traverse the directory, but the result would simply be
// failures at unlink() which are ignored. It's also unlikely since
// normally dumpsys is only done by bugreport or from the command line.
- char teePath[32+256];
- strcpy(teePath, "/data/misc/audioserver");
+ char teePath[PATH_MAX] = "/data/misc/audioserver";
size_t teePathLen = strlen(teePath);
DIR *dir = opendir(teePath);
teePath[teePathLen++] = '/';
@@ -3399,27 +3398,19 @@
struct Entry entries[TEE_MAX_SORT];
size_t entryCount = 0;
while (entryCount < TEE_MAX_SORT) {
- struct dirent de;
- struct dirent *result = NULL;
- int rc = readdir_r(dir, &de, &result);
- if (rc != 0) {
- ALOGW("readdir_r failed %d", rc);
- break;
- }
- if (result == NULL) {
- break;
- }
- if (result != &de) {
- ALOGW("readdir_r returned unexpected result %p != %p", result, &de);
+ errno = 0; // clear errno before readdir() to track potential errors.
+ const struct dirent *result = readdir(dir);
+ if (result == nullptr) {
+ ALOGW_IF(errno != 0, "tee readdir() failure %s", strerror(errno));
break;
}
// ignore non .wav file entries
- size_t nameLen = strlen(de.d_name);
+ const size_t nameLen = strlen(result->d_name);
if (nameLen <= 4 || nameLen >= TEE_MAX_FILENAME ||
- strcmp(&de.d_name[nameLen - 4], ".wav")) {
+ strcmp(&result->d_name[nameLen - 4], ".wav")) {
continue;
}
- strcpy(entries[entryCount++].mFileName, de.d_name);
+ (void)audio_utils_strlcpy(entries[entryCount++].mFileName, result->d_name);
}
(void) closedir(dir);
if (entryCount > TEE_MAX_KEEP) {
@@ -3490,8 +3481,13 @@
// FIXME not big-endian safe
write(teeFd, &temp, sizeof(temp));
close(teeFd);
- if (fd >= 0) {
- dprintf(fd, "tee copied to %s\n", teePath);
+ // TODO Should create file with temporary name and then rename to final if non-empty.
+ if (total > 0) {
+ if (fd >= 0) {
+ dprintf(fd, "tee copied to %s\n", teePath);
+ }
+ } else {
+ unlink(teePath);
}
} else {
if (fd >= 0) {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1fa9e37..20de97c 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7898,7 +7898,9 @@
mSessionId(AUDIO_SESSION_NONE),
mDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE),
mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
- mActiveTracks(&this->mLocalLog), mNoCallbackWarningCount(0)
+ mActiveTracks(&this->mLocalLog),
+ mHalVolFloat(-1.0f), // Initialize to illegal value so it always gets set properly later.
+ mNoCallbackWarningCount(0)
{
mStandby = true;
readHalParameters_l();
@@ -8065,7 +8067,10 @@
return PERMISSION_DENIED;
}
- if (!isOutput() && !silenced) {
+ if (isOutput()) {
+ // force volume update when a new track is added
+ mHalVolFloat = -1.0f;
+ } else if (!silenced) {
for (const sp<MmapTrack> &track : mActiveTracks) {
if (track->isSilenced_l() && track->uid() != client.clientUid)
track->invalidate();
@@ -8620,7 +8625,6 @@
mStreamType(AUDIO_STREAM_MUSIC),
mStreamVolume(1.0),
mStreamMute(false),
- mHalVolFloat(-1.0f), // Initialize to illegal value so it always gets set properly later.
mOutput(output)
{
snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index bc4a534..28d4482 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1641,6 +1641,7 @@
sp<DeviceHalInterface> mHalDevice;
AudioHwDevice* const mAudioHwDev;
ActiveTracks<MmapTrack> mActiveTracks;
+ float mHalVolFloat;
int32_t mNoCallbackWarningCount;
static constexpr int32_t kMaxNoCallbackWarnings = 5;
@@ -1692,7 +1693,6 @@
float mStreamVolume;
bool mMasterMute;
bool mStreamMute;
- float mHalVolFloat;
AudioStreamOut* mOutput;
};
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a54a71f..bb00c3f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -26,7 +26,8 @@
#define AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH 128
#define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"
-#define AUDIO_POLICY_A2DP_OFFLOAD_XML_CONFIG_FILE_NAME "audio_policy_a2dp_offload_configuration.xml"
+#define AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME \
+ "audio_policy_configuration_a2dp_offload_disabled.xml"
#include <inttypes.h>
#include <math.h>
@@ -589,6 +590,16 @@
setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
}
}
+
+ // reevaluate routing on all outputs in case tracks have been started during the call
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
+ if (state != AUDIO_MODE_IN_CALL || desc != mPrimaryOutput) {
+ setOutputDevice(desc, newDevice, (newDevice != AUDIO_DEVICE_NONE), delayMs);
+ }
+ }
+
// if entering in call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
if (isStateInCall(state)) {
@@ -3532,21 +3543,25 @@
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
+ std::vector<const char*> fileNames;
status_t ret;
- for (int i = 0; i < kConfigLocationListSize; i++) {
- PolicySerializer serializer;
- bool use_a2dp_offload_config =
- property_get_bool("persist.bluetooth.a2dp_offload.enable", false);
- snprintf(audioPolicyXmlConfigFile,
- sizeof(audioPolicyXmlConfigFile),
- "%s/%s",
- kConfigLocationList[i],
- use_a2dp_offload_config ? AUDIO_POLICY_A2DP_OFFLOAD_XML_CONFIG_FILE_NAME :
- AUDIO_POLICY_XML_CONFIG_FILE_NAME);
- ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
- if (ret == NO_ERROR) {
- break;
+ if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&
+ property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
+ // A2DP offload supported but disabled: try to use special XML file
+ fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
+ }
+ fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
+
+ for (const char* fileName : fileNames) {
+ for (int i = 0; i < kConfigLocationListSize; i++) {
+ PolicySerializer serializer;
+ snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
+ "%s/%s", kConfigLocationList[i], fileName);
+ ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
+ if (ret == NO_ERROR) {
+ return ret;
+ }
}
}
return ret;