transcoding: trust MediaProvider to set uid for jobs

bug: 154733526
test: manually check that MediaProvider uid is obtained
successfully, and isTrustedCallingUid() is true

Change-Id: I5577adcfc1acdac343ec3d98a1e33a9fc2fe36d6
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index 3f79705..82a6dde 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -23,12 +23,16 @@
 #include <inttypes.h>
 #include <media/TranscodingClientManager.h>
 #include <media/TranscodingRequest.h>
+#include <media/TranscodingUidPolicy.h>
 #include <private/android_filesystem_config.h>
 #include <utils/Log.h>
+#include <utils/String16.h>
 namespace android {
 
 static_assert(sizeof(ClientIdType) == sizeof(void*), "ClientIdType should be pointer-sized");
 
+static constexpr const char* MEDIA_PROVIDER_PKG_NAME = "com.google.android.providers.media.module";
+
 using ::aidl::android::media::BnTranscodingClient;
 using ::aidl::android::media::IMediaTranscodingService;  // For service error codes
 using ::aidl::android::media::TranscodingJobParcel;
@@ -51,20 +55,6 @@
             errorCode,                                \
             String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, ##__VA_ARGS__))
 
-// Can MediaTranscoding service trust the caller based on the calling UID?
-// TODO(hkuang): Add MediaProvider's UID.
-static bool isTrustedCallingUid(uid_t uid) {
-    switch (uid) {
-    case AID_ROOT:  // root user
-    case AID_SYSTEM:
-    case AID_SHELL:
-    case AID_MEDIA:  // mediaserver
-        return true;
-    default:
-        return false;
-    }
-}
-
 /**
  * ClientImpl implements a single client and contains all its information.
  */
@@ -143,7 +133,7 @@
         in_clientUid = callingUid;
     } else if (in_clientUid < 0) {
         return Status::ok();
-    } else if (in_clientUid != callingUid && !isTrustedCallingUid(callingUid)) {
+    } else if (in_clientUid != callingUid && !owner->isTrustedCallingUid(callingUid)) {
         ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
               "(don't trust callingUid %d)",
               in_clientPid, in_clientUid, callingUid);
@@ -160,7 +150,7 @@
         in_clientPid = callingPid;
     } else if (in_clientPid < 0) {
         return Status::ok();
-    } else if (in_clientPid != callingPid && !isTrustedCallingUid(callingUid)) {
+    } else if (in_clientPid != callingPid && !owner->isTrustedCallingUid(callingUid)) {
         ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
               "(don't trust callingUid %d)",
               in_clientPid, in_clientUid, callingUid);
@@ -267,8 +257,18 @@
 
 TranscodingClientManager::TranscodingClientManager(
         const std::shared_ptr<SchedulerClientInterface>& scheduler)
-      : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)), mJobScheduler(scheduler) {
+      : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)),
+        mJobScheduler(scheduler),
+        mMediaProviderUid(-1) {
     ALOGD("TranscodingClientManager started");
+    uid_t mpuid;
+    if (TranscodingUidPolicy::getUidForPackage(String16(MEDIA_PROVIDER_PKG_NAME), mpuid) ==
+        NO_ERROR) {
+        ALOGI("Found MediaProvider uid: %d", mpuid);
+        mMediaProviderUid = mpuid;
+    } else {
+        ALOGW("Couldn't get uid for MediaProvider.");
+    }
 }
 
 TranscodingClientManager::~TranscodingClientManager() {
@@ -299,6 +299,22 @@
     write(fd, result.string(), result.size());
 }
 
+bool TranscodingClientManager::isTrustedCallingUid(uid_t uid) {
+    if (uid > 0 && uid == mMediaProviderUid) {
+        return true;
+    }
+
+    switch (uid) {
+    case AID_ROOT:  // root user
+    case AID_SYSTEM:
+    case AID_SHELL:
+    case AID_MEDIA:  // mediaserver
+        return true;
+    default:
+        return false;
+    }
+}
+
 status_t TranscodingClientManager::addClient(
         const std::shared_ptr<ITranscodingClientCallback>& callback, const std::string& clientName,
         const std::string& opPackageName, std::shared_ptr<ITranscodingClient>* outClient) {
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/libmediatranscoding/TranscodingUidPolicy.cpp
index f0d4945..9763921 100644
--- a/media/libmediatranscoding/TranscodingUidPolicy.cpp
+++ b/media/libmediatranscoding/TranscodingUidPolicy.cpp
@@ -24,7 +24,9 @@
 #include <android/content/pm/IPackageManagerNative.h>
 #include <binder/ActivityManager.h>
 #include <binder/IServiceManager.h>
+#include <binder/PermissionController.h>
 #include <cutils/misc.h>  // FIRST_APPLICATION_UID
+#include <cutils/multiuser.h>
 #include <inttypes.h>
 #include <media/TranscodingUidPolicy.h>
 #include <utils/Log.h>
@@ -133,6 +135,19 @@
     return true;
 }
 
+//static
+status_t TranscodingUidPolicy::getUidForPackage(String16 packageName, /*inout*/ uid_t& uid) {
+    PermissionController pc;
+    uid = pc.getPackageUid(packageName, 0);
+    if (uid <= 0) {
+        ALOGE("Unknown package: '%s'", String8(packageName).string());
+        return BAD_VALUE;
+    }
+
+    uid = multiuser_get_uid(0 /*userId*/, uid);
+    return NO_ERROR;
+}
+
 TranscodingUidPolicy::TranscodingUidPolicy()
       : mAm(std::make_shared<ActivityManager>()),
         mUidObserver(new UidObserver(this)),
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/libmediatranscoding/include/media/TranscodingClientManager.h
index 015a83a..be03bc4 100644
--- a/media/libmediatranscoding/include/media/TranscodingClientManager.h
+++ b/media/libmediatranscoding/include/media/TranscodingClientManager.h
@@ -86,6 +86,9 @@
     // Only allow MediaTranscodingService and unit tests to instantiate.
     TranscodingClientManager(const std::shared_ptr<SchedulerClientInterface>& scheduler);
 
+    // Checks if a user is trusted (and allowed to submit jobs on behalf of other uids)
+    bool isTrustedCallingUid(uid_t uid);
+
     /**
      * Removes an existing client from the manager.
      *
@@ -106,6 +109,7 @@
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 
     std::shared_ptr<SchedulerClientInterface> mJobScheduler;
+    uid_t mMediaProviderUid;
 
     static std::atomic<ClientIdType> sCookieCounter;
     static std::mutex sCookie2ClientLock;
diff --git a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
index 42052cb..f02b591 100644
--- a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
+++ b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
@@ -50,6 +50,7 @@
     // ~UidPolicyInterface
 
     static bool getNamesForUids(const std::vector<int32_t>& uids, std::vector<std::string>* names);
+    static status_t getUidForPackage(String16 packageName, /*inout*/ uid_t& uid);
 
 private:
     void onUidStateChanged(uid_t uid, int32_t procState);