Merge "aaudio: control MMAP mode using system properties" into oc-dev
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 1d835f9..bf04a89 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -88,14 +88,9 @@
}
status_t DrmManager::loadPlugIns() {
-
- String8 vendorPluginDirPath("/vendor/lib/drm");
- loadPlugIns(vendorPluginDirPath);
-
String8 pluginDirPath("/system/lib/drm");
loadPlugIns(pluginDirPath);
return DRM_NO_ERROR;
-
}
status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 3596f12..f54954a 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -410,6 +410,7 @@
}
setListener(NULL);
+ mPlugin->setListener(NULL);
mPlugin.clear();
return OK;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 22b09d4..00a1f9c 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -98,6 +98,7 @@
mBufferingMonitor->stop();
mIsDrmProtected = false;
+ mIsDrmReleased = false;
mIsSecure = false;
mMimes.clear();
}
@@ -690,6 +691,17 @@
break;
}
+ case kWhatReleaseDrm:
+ {
+ status_t status = onReleaseDrm();
+ sp<AMessage> response = new AMessage;
+ response->setInt32("status", status);
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ response->postReply(replyID);
+ break;
+ }
+
default:
Source::onMessageReceived(msg);
break;
@@ -839,6 +851,13 @@
return -EWOULDBLOCK;
}
+ // If has gone through stop/releaseDrm sequence, we no longer send down any buffer b/c
+ // the codec's crypto object has gone away (b/37960096).
+ // Note: This will be unnecessary when stop() changes behavior and releases codec (b/35248283).
+ if (!mStarted && mIsDrmReleased) {
+ return -EWOULDBLOCK;
+ }
+
Track *track = audio ? &mAudioTrack : &mVideoTrack;
if (track->mSource == NULL) {
@@ -1897,11 +1916,31 @@
return status;
}
+status_t NuPlayer::GenericSource::releaseDrm()
+{
+ ALOGV("releaseDrm");
+
+ sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
+
+ // synchronous call to update the source states before the player proceedes with crypto cleanup
+ sp<AMessage> response;
+ status_t status = msg->postAndAwaitResponse(&response);
+
+ if (status == OK && response != NULL) {
+ ALOGD("releaseDrm ret: OK ");
+ } else {
+ ALOGE("releaseDrm err: %d", status);
+ }
+
+ return status;
+}
+
status_t NuPlayer::GenericSource::onPrepareDrm(const sp<AMessage> &msg)
{
ALOGV("onPrepareDrm ");
mIsDrmProtected = false;
+ mIsDrmReleased = false;
mIsSecure = false;
uint8_t *uuid;
@@ -1949,8 +1988,26 @@
return status;
}
+status_t NuPlayer::GenericSource::onReleaseDrm()
+{
+ if (mIsDrmProtected) {
+ mIsDrmProtected = false;
+ // to prevent returning any more buffer after stop/releaseDrm (b/37960096)
+ mIsDrmReleased = true;
+ ALOGV("onReleaseDrm: mIsDrmProtected is reset.");
+ } else {
+ ALOGE("onReleaseDrm: mIsDrmProtected is already false.");
+ }
+
+ return OK;
+}
+
status_t NuPlayer::GenericSource::checkDrmInfo()
{
+ // clearing the flag at prepare in case the player is reused after stop/releaseDrm with the
+ // same source without being reset (called by prepareAsync/initFromDataSource)
+ mIsDrmReleased = false;
+
if (mFileMeta == NULL) {
ALOGI("checkDrmInfo: No metadata");
return OK; // letting the caller responds accordingly
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 64f21a6..b0c6695 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -91,6 +91,8 @@
virtual status_t prepareDrm(
const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId, sp<ICrypto> *crypto);
+ virtual status_t releaseDrm();
+
protected:
virtual ~GenericSource();
@@ -119,6 +121,7 @@
kWhatSecureDecodersInstantiated,
// Modular DRM
kWhatPrepareDrm,
+ kWhatReleaseDrm,
};
struct Track {
@@ -308,10 +311,12 @@
// Modular DRM
bool mIsDrmProtected;
+ bool mIsDrmReleased;
Vector<String8> mMimes;
status_t checkDrmInfo();
status_t onPrepareDrm(const sp<AMessage> &msg);
+ status_t onReleaseDrm();
DISALLOW_EVIL_CONSTRUCTORS(GenericSource);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 0d4c730..6ded392 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2787,6 +2787,11 @@
status_t status;
if (mCrypto != NULL) {
+ // notifying the source first before removing crypto from codec
+ if (mSource != NULL) {
+ mSource->releaseDrm();
+ }
+
status=OK;
// first making sure the codecs have released their crypto reference
const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f2a4d06..0bb4dbb 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -469,6 +469,22 @@
const char *mime;
CHECK(track->meta->findCString(kKeyMIMEType, &mime));
if (!strncasecmp("video/", mime, 6)) {
+ // MPEG2 tracks do not provide CSD, so read the stream header
+ if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
+ off64_t offset;
+ size_t size;
+ if (track->sampleTable->getMetaDataForSample(
+ 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
+ if (size > kMaxTrackHeaderSize) {
+ size = kMaxTrackHeaderSize;
+ }
+ uint8_t header[kMaxTrackHeaderSize];
+ if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
+ track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
+ }
+ }
+ }
+
if (mMoofOffset > 0) {
int64_t duration;
if (track->meta->findInt64(kKeyDuration, &duration)) {
@@ -489,22 +505,6 @@
((int64_t)sampleTime * 1000000) / track->timescale);
}
}
-
- // MPEG2 tracks do not provide CSD, so read the stream header
- if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
- off64_t offset;
- size_t size;
- if (track->sampleTable->getMetaDataForSample(
- 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
- if (size > kMaxTrackHeaderSize) {
- size = kMaxTrackHeaderSize;
- }
- uint8_t header[kMaxTrackHeaderSize];
- if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
- track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
- }
- }
- }
}
}
@@ -1240,6 +1240,7 @@
ALOGV("allocated pssh @ %p", pssh.data);
ssize_t requested = (ssize_t) pssh.datalen;
if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
+ delete[] pssh.data;
return ERROR_IO;
}
mPssh.push_back(pssh);
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 0343786..e31c37c 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -697,7 +697,21 @@
if (buffer != NULL) {
fullSize += buffer->range_length();
}
- MediaBuffer *tmp = new MediaBuffer(fullSize);
+ if (fullSize > 16 * 1024 * 1024) { // arbitrary limit of 16 MB packet size
+ if (buffer != NULL) {
+ buffer->release();
+ }
+ ALOGE("b/36592202");
+ return ERROR_MALFORMED;
+ }
+ MediaBuffer *tmp = new (std::nothrow) MediaBuffer(fullSize);
+ if (tmp == NULL) {
+ if (buffer != NULL) {
+ buffer->release();
+ }
+ ALOGE("b/36592202");
+ return ERROR_MALFORMED;
+ }
if (buffer != NULL) {
memcpy(tmp->data(), buffer->data(), buffer->range_length());
tmp->set_range(0, buffer->range_length());
diff --git a/media/mtp/IMtpHandle.h b/media/mtp/IMtpHandle.h
index 9185255..0557596 100644
--- a/media/mtp/IMtpHandle.h
+++ b/media/mtp/IMtpHandle.h
@@ -27,7 +27,7 @@
virtual int write(const void *data, int len) = 0;
// Return 0 if send/receive is successful, or -1 and errno is set
- virtual int receiveFile(mtp_file_range mfr) = 0;
+ virtual int receiveFile(mtp_file_range mfr, bool zero_packet) = 0;
virtual int sendFile(mtp_file_range mfr) = 0;
virtual int sendEvent(mtp_event me) = 0;
diff --git a/media/mtp/MtpDevHandle.cpp b/media/mtp/MtpDevHandle.cpp
index afc0525..9aa0aec 100644
--- a/media/mtp/MtpDevHandle.cpp
+++ b/media/mtp/MtpDevHandle.cpp
@@ -45,7 +45,7 @@
int read(void *data, int len);
int write(const void *data, int len);
- int receiveFile(mtp_file_range mfr);
+ int receiveFile(mtp_file_range mfr, bool);
int sendFile(mtp_file_range mfr);
int sendEvent(mtp_event me);
@@ -68,7 +68,7 @@
return ::write(mFd, data, len);
}
-int MtpDevHandle::receiveFile(mtp_file_range mfr) {
+int MtpDevHandle::receiveFile(mtp_file_range mfr, bool) {
return ioctl(mFd, MTP_RECEIVE_FILE, reinterpret_cast<unsigned long>(&mfr));
}
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index c78002c..c50af2f 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -516,7 +516,7 @@
}
/* Read from USB and write to a local file. */
-int MtpFfsHandle::receiveFile(mtp_file_range mfr) {
+int MtpFfsHandle::receiveFile(mtp_file_range mfr, bool zero_packet) {
// When receiving files, the incoming length is given in 32 bits.
// A >4G file is given as 0xFFFFFFFF
uint32_t file_length = mfr.length;
@@ -538,7 +538,7 @@
aio.aio_fildes = mfr.fd;
aio.aio_buf = nullptr;
struct aiocb *aiol[] = {&aio};
- int ret;
+ int ret = -1;
size_t length;
bool read = false;
bool write = false;
@@ -590,11 +590,6 @@
} else {
// Receive an empty packet if size is a multiple of the endpoint size.
file_length -= ret;
- if (file_length == 0 && ret % packet_size == 0) {
- if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
- return -1;
- }
- }
}
// Enqueue a new write request
aio.aio_buf = data;
@@ -610,6 +605,11 @@
read = false;
}
}
+ if (ret % packet_size == 0 || zero_packet) {
+ if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
+ return -1;
+ }
+ }
return 0;
}
@@ -660,10 +660,9 @@
sizeof(mtp_data_header), init_read_len, offset))
!= init_read_len) return -1;
if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
- if (file_length == static_cast<unsigned>(init_read_len)) return 0;
file_length -= init_read_len;
offset += init_read_len;
- ret = 0;
+ ret = init_read_len + sizeof(mtp_data_header);
// Break down the file into pieces that fit in buffers
while(file_length > 0) {
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index 7491a1b..98669ff 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -55,7 +55,7 @@
int read(void *data, int len);
int write(const void *data, int len);
- int receiveFile(mtp_file_range mfr);
+ int receiveFile(mtp_file_range mfr, bool zero_packet);
int sendFile(mtp_file_range mfr);
int sendEvent(mtp_event me);
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 88dabff..5c33265 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -1052,23 +1052,22 @@
ALOGE("failed to write initial data");
result = MTP_RESPONSE_GENERAL_ERROR;
} else {
- if (mSendObjectFileSize - initialData > 0) {
- mfr.offset = initialData;
- if (mSendObjectFileSize == 0xFFFFFFFF) {
- // tell driver to read until it receives a short packet
- mfr.length = 0xFFFFFFFF;
- } else {
- mfr.length = mSendObjectFileSize - initialData;
- }
+ mfr.offset = initialData;
+ if (mSendObjectFileSize == 0xFFFFFFFF) {
+ // tell driver to read until it receives a short packet
+ mfr.length = 0xFFFFFFFF;
+ } else {
+ mfr.length = mSendObjectFileSize - initialData;
+ }
- mfr.command = 0;
- mfr.transaction_id = 0;
+ mfr.command = 0;
+ mfr.transaction_id = 0;
- // transfer the file
- ret = sHandle->receiveFile(mfr);
- if ((ret < 0) && (errno == ECANCELED)) {
- isCanceled = true;
- }
+ // transfer the file
+ ret = sHandle->receiveFile(mfr, mfr.length == 0 &&
+ initialData == MTP_BUFFER_SIZE - MTP_CONTAINER_HEADER_SIZE);
+ if ((ret < 0) && (errno == ECANCELED)) {
+ isCanceled = true;
}
}
struct stat sstat;
@@ -1256,19 +1255,18 @@
if (ret < 0) {
ALOGE("failed to write initial data");
} else {
- if (length > 0) {
- mtp_file_range mfr;
- mfr.fd = edit->mFD;
- mfr.offset = offset;
- mfr.length = length;
- mfr.command = 0;
- mfr.transaction_id = 0;
+ mtp_file_range mfr;
+ mfr.fd = edit->mFD;
+ mfr.offset = offset;
+ mfr.length = length;
+ mfr.command = 0;
+ mfr.transaction_id = 0;
- // transfer the file
- ret = sHandle->receiveFile(mfr);
- if ((ret < 0) && (errno == ECANCELED)) {
- isCanceled = true;
- }
+ // transfer the file
+ ret = sHandle->receiveFile(mfr, mfr.length == 0 &&
+ initialData == MTP_BUFFER_SIZE - MTP_CONTAINER_HEADER_SIZE);
+ if ((ret < 0) && (errno == ECANCELED)) {
+ isCanceled = true;
}
}
if (ret < 0) {
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandle_test.cpp
index e575148..554f867 100644
--- a/media/mtp/tests/MtpFfsHandle_test.cpp
+++ b/media/mtp/tests/MtpFfsHandle_test.cpp
@@ -116,7 +116,7 @@
ss << dummyDataStr;
EXPECT_EQ(write(bulk_out, ss.str().c_str(), size), size);
- EXPECT_EQ(handle->receiveFile(mfr), 0);
+ EXPECT_EQ(handle->receiveFile(mfr, false), 0);
EXPECT_EQ(read(dummy_file.fd, buf, size), size);
@@ -136,7 +136,7 @@
ss << dummyDataStr;
EXPECT_EQ(write(bulk_out, ss.str().c_str(), size), size);
- EXPECT_EQ(handle->receiveFile(mfr), 0);
+ EXPECT_EQ(handle->receiveFile(mfr, false), 0);
EXPECT_EQ(read(dummy_file.fd, buf, size), size);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 65633db..b9d6843 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -87,11 +87,7 @@
int count = 0;
for (auto& provider : mProviders) {
if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
- for (auto& device : provider->mDevices) {
- if (device->isAPI1Compatible()) {
- count++;
- }
- }
+ count += provider->mUniqueAPI1CompatibleCameraIds.size();
}
}
return count;
@@ -113,10 +109,8 @@
std::vector<std::string> deviceIds;
for (auto& provider : mProviders) {
if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
- for (auto& device : provider->mDevices) {
- if (device->isAPI1Compatible()) {
- deviceIds.push_back(device->mId);
- }
+ for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
+ deviceIds.push_back(id);
}
}
}
@@ -466,6 +460,7 @@
mProviderName(providerName),
mInterface(interface),
mProviderTagid(generateVendorTagId(providerName)),
+ mUniqueDeviceCount(0),
mManager(manager) {
(void) mManager;
}
@@ -539,6 +534,9 @@
for (auto& device : mDevices) {
mUniqueCameraIds.insert(device->mId);
+ if (device->isAPI1Compatible()) {
+ mUniqueAPI1CompatibleCameraIds.insert(device->mId);
+ }
}
mUniqueDeviceCount = mUniqueCameraIds.size();
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 9ba7f91..e82282f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -315,6 +315,7 @@
std::vector<std::unique_ptr<DeviceInfo>> mDevices;
std::set<std::string> mUniqueCameraIds;
int mUniqueDeviceCount;
+ std::set<std::string> mUniqueAPI1CompatibleCameraIds;
// HALv1-specific camera fields, including the actual device interface
struct DeviceInfo1 : public DeviceInfo {