Add pid override feature to MediaResourceManager
Current MediaResourceManager assume that the calling process actually use the resource.
In TV Input Framework, the actually user of the resource is different application.
To allow MediaResourceManager to use pid of actual user, we add overridePid method
bug: 139809797
Test: Manual
Change-Id: Ia113ca2387dfbcc092eb150d19b4751448e9f27a
diff --git a/media/libmedia/aidl/android/media/IResourceManagerService.aidl b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
index 3e6f8db..3dd0859 100644
--- a/media/libmedia/aidl/android/media/IResourceManagerService.aidl
+++ b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
@@ -84,4 +84,14 @@
* @return true if the reclaim was successful and false otherwise.
*/
boolean reclaimResource(int callingPid, in MediaResourceParcel[] resources);
+
+ /**
+ * Override the pid of original calling process with the pid of the process
+ * who actually use the requested resources.
+ *
+ * @param originalPid pid of the original calling process.
+ * @param newPid pid of the actual process who use the resources.
+ * remove existing override on originalPid if newPid is -1.
+ */
+ void overridePid(int originalPid, int newPid);
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 877c44d..be5af00 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -58,6 +58,8 @@
return;
}
service->removeResource(mPid, mClientId, false);
+
+ service->overridePid(mPid, -1);
}
template <typename T>
@@ -150,6 +152,7 @@
PidResourceInfosMap mapCopy;
bool supportsMultipleSecureCodecs;
bool supportsSecureWithNonSecureCodec;
+ std::map<int, int> overridePidMapCopy;
String8 serviceLog;
{
Mutex::Autolock lock(mLock);
@@ -157,6 +160,7 @@
supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
serviceLog = mServiceLog->toString(" " /* linePrefix */);
+ overridePidMapCopy = mOverridePidMap;
}
const size_t SIZE = 256;
@@ -197,6 +201,12 @@
}
}
}
+ result.append(" Process Pid override:\n");
+ for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
+ snprintf(buffer, SIZE, " Original Pid: %d, Override Pid: %d\n",
+ it->first, it->second);
+ result.append(buffer);
+ }
result.append(" Events logs (most recent at top):\n");
result.append(serviceLog);
@@ -608,6 +618,48 @@
return Status::ok();
}
+Status ResourceManagerService::overridePid(
+ int originalPid,
+ int newPid) {
+ String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
+ originalPid, newPid);
+ mServiceLog->add(log);
+
+ // allow if this is called from the same process or the process has
+ // permission.
+ if ((AIBinder_getCallingPid() != getpid()) &&
+ (checkCallingPermission(String16(
+ "android.permission.MEDIA_RESOURCE_OVERRIDE_PID")) == false)) {
+ ALOGE(
+ "Permission Denial: can't access overridePid method from pid=%d, "
+ "self pid=%d\n",
+ AIBinder_getCallingPid(), getpid());
+ return Status::fromServiceSpecificError(PERMISSION_DENIED);
+ }
+
+ {
+ Mutex::Autolock lock(mLock);
+ mOverridePidMap.erase(originalPid);
+ if (newPid != -1) {
+ mOverridePidMap.emplace(originalPid, newPid);
+ }
+ }
+
+ return Status::ok();
+}
+
+bool ResourceManagerService::getPriority_l(int pid, int* priority) {
+ int newPid = pid;
+
+ if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
+ newPid = mOverridePidMap[pid];
+ ALOGD("getPriority_l: use override pid %d instead original pid %d",
+ newPid, pid);
+ }
+
+ return mProcessInfo->getPriority(newPid, priority);
+}
+
bool ResourceManagerService::getAllClients_l(
int callingPid, MediaResource::Type type,
Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
@@ -641,7 +693,7 @@
int lowestPriorityPid;
int lowestPriority;
int callingPriority;
- if (!mProcessInfo->getPriority(callingPid, &callingPriority)) {
+ if (!getPriority_l(callingPid, &callingPriority)) {
ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
callingPid);
return false;
@@ -676,7 +728,7 @@
}
int tempPid = mMap.keyAt(i);
int tempPriority;
- if (!mProcessInfo->getPriority(tempPid, &tempPriority)) {
+ if (!getPriority_l(tempPid, &tempPriority)) {
ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
// TODO: remove this pid from mMap?
continue;
@@ -696,12 +748,12 @@
bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) {
int callingPidPriority;
- if (!mProcessInfo->getPriority(callingPid, &callingPidPriority)) {
+ if (!getPriority_l(callingPid, &callingPidPriority)) {
return false;
}
int priority;
- if (!mProcessInfo->getPriority(pid, &priority)) {
+ if (!getPriority_l(pid, &priority)) {
return false;
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index ae12d7b..f500c62 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -118,6 +118,10 @@
const std::vector<MediaResourceParcel>& resources,
bool* _aidl_return) override;
+ Status overridePid(
+ int originalPid,
+ int newPid) override;
+
Status removeResource(int pid, int64_t clientId, bool checkValid);
private:
@@ -157,6 +161,9 @@
// Merge r2 into r1
void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
+ // Get priority from process's pid
+ bool getPriority_l(int pid, int* priority);
+
mutable Mutex mLock;
sp<ProcessInfoInterface> mProcessInfo;
sp<SystemCallbackInterface> mSystemCB;
@@ -166,6 +173,7 @@
bool mSupportsSecureWithNonSecureCodec;
int32_t mCpuBoostCount;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+ std::map<int, int> mOverridePidMap;
};
// ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 168fde9..5d839fa 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -446,6 +446,32 @@
expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
}
+ void testOverridePid() {
+
+ bool result;
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+ resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
+
+ // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
+ {
+ addResource();
+ mService->mSupportsMultipleSecureCodecs = false;
+ mService->mSupportsSecureWithNonSecureCodec = true;
+
+ // priority too low to reclaim resource
+ CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+
+ // override Low Priority Pid with High Priority Pid
+ mService->overridePid(kLowPriorityPid, kHighPriorityPid);
+ CHECK_STATUS_TRUE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+
+ // restore Low Priority Pid
+ mService->overridePid(kLowPriorityPid, -1);
+ CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ }
+ }
+
void testRemoveClient() {
addResource();
@@ -870,4 +896,8 @@
testCpusetBoost();
}
+TEST_F(ResourceManagerServiceTest, overridePid) {
+ testOverridePid();
+}
+
} // namespace android