Merge "Camera: Skip session parameters in case of abandoned streams" into rvc-dev
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index 8620f36..487b8b0 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -143,6 +143,11 @@
if (data.dataAvail() > 0) {
metadata = new camera_frame_metadata_t;
metadata->number_of_faces = data.readInt32();
+ if (metadata->number_of_faces <= 0 ||
+ metadata->number_of_faces > (int32_t)(INT32_MAX / sizeof(camera_face_t))) {
+ ALOGE("%s: Too large face count: %d", __FUNCTION__, metadata->number_of_faces);
+ return BAD_VALUE;
+ }
metadata->faces = (camera_face_t *) data.readInplace(
sizeof(camera_face_t) * metadata->number_of_faces);
}
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
new file mode 100644
index 0000000..a6dfb21
--- /dev/null
+++ b/media/TEST_MAPPING
@@ -0,0 +1,32 @@
+{
+ "presubmit": [
+ {
+ "name": "GtsMediaTestCases",
+ "options" : [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ }
+ ]
+ },
+ {
+ "name": "GtsExoPlayerTestCases",
+ "options" : [
+ {
+ "include-annotation": "android.platform.test.annotations.SocPresubmit"
+ },
+ {
+ "include-filter": "com.google.android.exoplayer.gts.DashTest#testWidevine23FpsH264Fixed"
+ }
+ ]
+ }
+ ],
+ "imports": [
+ {
+ "path": "frameworks/av/drm/mediadrm/plugins"
+ }
+ ]
+}
+
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
index 119ce14..6122225 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -330,7 +330,7 @@
TEST_P(Codec2ComponentInputTests, InputBufferTest) {
description("Tests for different inputs");
- uint32_t flags = std::stol(std::get<2>(GetParam()));
+ uint32_t flags = std::stoul(std::get<2>(GetParam()));
bool isNullBuffer = !std::get<3>(GetParam()).compare("true");
if (isNullBuffer)
ALOGD("Testing for null input buffer with flag : %u", flags);
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index edc09a9..a47f189 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -406,6 +406,7 @@
* Use this preset for capturing audio meant to be processed in real time
* and played back for live performance (e.g karaoke).
* The capture path will minimize latency and coupling with playback path.
+ * Available since API level 29.
*/
AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE = 10,
};
diff --git a/media/libmedia/aidl/android/media/IResourceManagerService.aidl b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
index 3dd0859..1b2d522 100644
--- a/media/libmedia/aidl/android/media/IResourceManagerService.aidl
+++ b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
@@ -94,4 +94,12 @@
* remove existing override on originalPid if newPid is -1.
*/
void overridePid(int originalPid, int newPid);
+
+ /**
+ * Mark a client for pending removal
+ *
+ * @param pid pid from which the client's resources will be removed.
+ * @param clientId clientId within the pid that will be removed.
+ */
+ void markClientForPendingRemoval(int pid, long clientId);
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index b597583..11f2f38 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -199,6 +199,7 @@
void addResource(const MediaResourceParcel &resource);
void removeResource(const MediaResourceParcel &resource);
void removeClient();
+ void markClientForPendingRemoval();
bool reclaimResource(const std::vector<MediaResourceParcel> &resources);
private:
@@ -280,6 +281,14 @@
mService->removeClient(mPid, getId(mClient));
}
+void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() {
+ Mutex::Autolock _l(mLock);
+ if (mService == nullptr) {
+ return;
+ }
+ mService->markClientForPendingRemoval(mPid, getId(mClient));
+}
+
bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
const std::vector<MediaResourceParcel> &resources) {
Mutex::Autolock _l(mLock);
@@ -297,6 +306,33 @@
////////////////////////////////////////////////////////////////////////////////
+class MediaCodec::ReleaseSurface {
+public:
+ ReleaseSurface() {
+ BufferQueue::createBufferQueue(&mProducer, &mConsumer);
+ mSurface = new Surface(mProducer, false /* controlledByApp */);
+ struct ConsumerListener : public BnConsumerListener {
+ void onFrameAvailable(const BufferItem&) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+ sp<ConsumerListener> listener{new ConsumerListener};
+ mConsumer->consumerConnect(listener, false);
+ mConsumer->setConsumerName(String8{"MediaCodec.release"});
+ }
+
+ const sp<Surface> &getSurface() {
+ return mSurface;
+ }
+
+private:
+ sp<IGraphicBufferProducer> mProducer;
+ sp<IGraphicBufferConsumer> mConsumer;
+ sp<Surface> mSurface;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace {
enum {
@@ -1432,7 +1468,13 @@
status_t MediaCodec::release() {
sp<AMessage> msg = new AMessage(kWhatRelease, this);
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+status_t MediaCodec::releaseAsync() {
+ sp<AMessage> msg = new AMessage(kWhatRelease, this);
+ msg->setInt32("async", 1);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
@@ -2600,7 +2642,9 @@
mResourceManagerProxy->removeClient();
- (new AMessage)->postReply(mReplyID);
+ if (mReplyID != nullptr) {
+ (new AMessage)->postReply(mReplyID);
+ }
break;
}
@@ -2987,6 +3031,26 @@
break;
}
+ int32_t async = 0;
+ if (msg->findInt32("async", &async) && async) {
+ if ((mState == CONFIGURED || mState == STARTED || mState == FLUSHED)
+ && mSurface != NULL) {
+ if (!mReleaseSurface) {
+ mReleaseSurface.reset(new ReleaseSurface);
+ }
+ status_t err = connectToSurface(mReleaseSurface->getSurface());
+ ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
+ if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
+ err = mCodec->setSurface(mReleaseSurface->getSurface());
+ ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
+ }
+ if (err == OK) {
+ (void)disconnectFromSurface();
+ mSurface = mReleaseSurface->getSurface();
+ }
+ }
+ }
+
mReplyID = replyID;
setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
@@ -2999,6 +3063,12 @@
pushBlankBuffersToNativeWindow(mSurface.get());
}
+ if (async) {
+ mResourceManagerProxy->markClientForPendingRemoval();
+ (new AMessage)->postReply(mReplyID);
+ mReplyID = 0;
+ }
+
break;
}
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 022c48e..63a9dad 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -139,6 +139,8 @@
// object.
status_t release();
+ status_t releaseAsync();
+
status_t flush();
status_t queueInputBuffer(
@@ -509,6 +511,9 @@
// when low latency is on
int64_t mInputBufferCounter; // number of input buffers queued since last reset/flush
+ class ReleaseSurface;
+ std::unique_ptr<ReleaseSurface> mReleaseSurface;
+
sp<BatteryChecker> mBatteryChecker;
void statsBufferSent(int64_t presentationUs);
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 886e4c9..d31e443 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -320,7 +320,7 @@
{
String8 devAddress = (address == nullptr || !matchAddress) ? String8("") : String8(address);
// handle legacy remote submix case where the address was not always specified
- if (device_distinguishes_on_address(deviceType) && (devAddress.length() == 0)) {
+ if (audio_is_remote_submix_device(deviceType) && (devAddress.length() == 0)) {
devAddress = String8("0");
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5683e69..13e2093 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3072,7 +3072,7 @@
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
devices[i].mType, devices[i].mAddress.c_str(), String8(),
- AUDIO_FORMAT_DEFAULT, false /*allowToCreate*/, false /*matchAddress*/);
+ AUDIO_FORMAT_DEFAULT, false /*allowToCreate*/, true /*matchAddress*/);
if (devDesc == nullptr || (predicate != nullptr && !predicate(devices[i].mType))) {
ALOGE("%s: device type %#x address %s not supported or not an output device",
context, devices[i].mType, devices[i].mAddress.c_str());
@@ -4837,7 +4837,7 @@
if (output != AUDIO_IO_HANDLE_NONE) {
addOutput(output, desc);
- if (device_distinguishes_on_address(deviceType) && address != "0") {
+ if (audio_is_remote_submix_device(deviceType) && address != "0") {
sp<AudioPolicyMix> policyMix;
if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix)
== NO_ERROR) {
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index be5af00..ff45c87 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -114,6 +114,7 @@
info.uid = uid;
info.clientId = clientId;
info.client = client;
+ info.pendingRemoval = false;
index = infos.add(clientId, info);
}
@@ -648,6 +649,36 @@
return Status::ok();
}
+Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) {
+ String8 log = String8::format(
+ "markClientForPendingRemoval(pid %d, clientId %lld)",
+ pid, (long long) clientId);
+ mServiceLog->add(log);
+
+ Mutex::Autolock lock(mLock);
+ if (!mProcessInfo->isValidPid(pid)) {
+ ALOGE("Rejected markClientForPendingRemoval call with invalid pid.");
+ return Status::fromServiceSpecificError(BAD_VALUE);
+ }
+ ssize_t index = mMap.indexOfKey(pid);
+ if (index < 0) {
+ ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
+ pid, (long long)clientId);
+ return Status::ok();
+ }
+ ResourceInfos &infos = mMap.editValueAt(index);
+
+ index = infos.indexOfKey(clientId);
+ if (index < 0) {
+ ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
+ return Status::ok();
+ }
+
+ ResourceInfo &info = infos.editValueAt(index);
+ info.pendingRemoval = true;
+ return Status::ok();
+}
+
bool ResourceManagerService::getPriority_l(int pid, int* priority) {
int newPid = pid;
@@ -693,6 +724,12 @@
int lowestPriorityPid;
int lowestPriority;
int callingPriority;
+
+ // Before looking into other processes, check if we have clients marked for
+ // pending removal in the same process.
+ if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) {
+ return true;
+ }
if (!getPriority_l(callingPid, &callingPriority)) {
ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
callingPid);
@@ -761,7 +798,8 @@
}
bool ResourceManagerService::getBiggestClient_l(
- int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) {
+ int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client,
+ bool pendingRemovalOnly) {
ssize_t index = mMap.indexOfKey(pid);
if (index < 0) {
ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid);
@@ -773,6 +811,9 @@
const ResourceInfos &infos = mMap.valueAt(index);
for (size_t i = 0; i < infos.size(); ++i) {
const ResourceList &resources = infos[i].resources;
+ if (pendingRemovalOnly && !infos[i].pendingRemoval) {
+ continue;
+ }
for (auto it = resources.begin(); it != resources.end(); it++) {
const MediaResourceParcel &resource = it->second;
if (resource.type == type) {
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index f500c62..ee982b7 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -18,6 +18,8 @@
#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
+#include <map>
+
#include <aidl/android/media/BnResourceManagerService.h>
#include <arpa/inet.h>
#include <media/MediaResource.h>
@@ -50,6 +52,7 @@
std::shared_ptr<IResourceManagerClient> client;
sp<DeathNotifier> deathNotifier;
ResourceList resources;
+ bool pendingRemoval{false};
};
// TODO: convert these to std::map
@@ -122,6 +125,8 @@
int originalPid,
int newPid) override;
+ Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;
+
Status removeResource(int pid, int64_t clientId, bool checkValid);
private:
@@ -146,7 +151,8 @@
// Gets the client who owns biggest piece of specified resource type from pid.
// Returns false if failed. The client will remain unchanged if failed.
bool getBiggestClient_l(int pid, MediaResource::Type type,
- std::shared_ptr<IResourceManagerClient> *client);
+ std::shared_ptr<IResourceManagerClient> *client,
+ bool pendingRemovalOnly = false);
bool isCallingPriorityHigher_l(int callingPid, int pid);
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 5d839fa..702935d 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -472,6 +472,56 @@
}
}
+ void testMarkClientForPendingRemoval() {
+ bool result;
+
+ {
+ addResource();
+ mService->mSupportsSecureWithNonSecureCodec = true;
+
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+
+ // Remove low priority clients
+ mService->removeClient(kTestPid1, getId(mTestClient1));
+
+ // no lower priority client
+ CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
+ verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
+
+ mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
+
+ // client marked for pending removal from the same process got reclaimed
+ CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+
+ // clean up client 3 which still left
+ mService->removeClient(kTestPid2, getId(mTestClient3));
+ }
+
+ {
+ addResource();
+ mService->mSupportsSecureWithNonSecureCodec = true;
+
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+
+ mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
+
+ // client marked for pending removal from the same process got reclaimed
+ // first, even though there are lower priority process
+ CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+
+ // lower priority client got reclaimed
+ CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+
+ // clean up client 3 which still left
+ mService->removeClient(kTestPid2, getId(mTestClient3));
+ }
+ }
+
void testRemoveClient() {
addResource();
@@ -900,4 +950,8 @@
testOverridePid();
}
+TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) {
+ testMarkClientForPendingRemoval();
+}
+
} // namespace android