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
gugelfrei
Henry Fang 5 years ago
parent b5c0071bb7
commit 3276292949

@ -84,4 +84,14 @@ interface IResourceManagerService {
* @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);
}

@ -58,6 +58,8 @@ void DeathNotifier::binderDied() {
return;
}
service->removeResource(mPid, mClientId, false);
service->overridePid(mPid, -1);
}
template <typename T>
@ -150,6 +152,7 @@ binder_status_t ResourceManagerService::dump(
PidResourceInfosMap mapCopy;
bool supportsMultipleSecureCodecs;
bool supportsSecureWithNonSecureCodec;
std::map<int, int> overridePidMapCopy;
String8 serviceLog;
{
Mutex::Autolock lock(mLock);
@ -157,6 +160,7 @@ binder_status_t ResourceManagerService::dump(
supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
serviceLog = mServiceLog->toString(" " /* linePrefix */);
overridePidMapCopy = mOverridePidMap;
}
const size_t SIZE = 256;
@ -197,6 +201,12 @@ binder_status_t ResourceManagerService::dump(
}
}
}
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 @@ Status ResourceManagerService::reclaimResource(
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 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l(
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 @@ bool ResourceManagerService::getLowestPriorityPid_l(
}
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::getLowestPriorityPid_l(
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;
}

@ -118,6 +118,10 @@ public:
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 @@ private:
// 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 @@ private:
bool mSupportsSecureWithNonSecureCodec;
int32_t mCpuBoostCount;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
std::map<int, int> mOverridePidMap;
};
// ----------------------------------------------------------------------------

@ -446,6 +446,32 @@ protected:
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 @@ TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
testCpusetBoost();
}
TEST_F(ResourceManagerServiceTest, overridePid) {
testOverridePid();
}
} // namespace android

Loading…
Cancel
Save