Restrict the getter of where the app launched from

It may reveal the package name and user behavior. Though the methods
are hidden, the app can still bypass the guard of hidden api and
use reflection to invoke the methods.

Currently the methods are only used by system, Settings, Nfc, SystemUI,
CertInstaller and PackageInstaller. So by enforcing platform signature,
most of cases are protected. Except PackageInstaller can be signed with
different key, hence there is a special case to check it.

Bug: 191954233
Test: Use reflection to call the methods from an app without
      platform signature.
Change-Id: I69a1774e8db63baca4e0d05c238911208b4cd1e9
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 3a4faf7..e02e867 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -21,6 +21,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.os.Process.INVALID_UID;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -53,6 +55,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
@@ -64,6 +67,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.service.voice.VoiceInteractionManagerInternal;
 import android.util.Slog;
 import android.view.RemoteAnimationDefinition;
@@ -74,6 +78,7 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.Watchdog;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.uri.NeededUriGrants;
 import com.android.server.vr.VrManagerInternal;
 
@@ -557,20 +562,45 @@
 
     @Override
     public int getLaunchedFromUid(IBinder token) {
+        if (!canGetLaunchedFrom()) {
+            return INVALID_UID;
+        }
         synchronized (mGlobalLock) {
             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            return r != null ? r.launchedFromUid : android.os.Process.INVALID_UID;
+            return r != null ? r.launchedFromUid : INVALID_UID;
         }
     }
 
     @Override
     public String getLaunchedFromPackage(IBinder token) {
+        if (!canGetLaunchedFrom()) {
+            return null;
+        }
         synchronized (mGlobalLock) {
             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
             return r != null ? r.launchedFromPackage : null;
         }
     }
 
+    /** Whether the caller can get the package or uid that launched its activity. */
+    private boolean canGetLaunchedFrom() {
+        final int uid = Binder.getCallingUid();
+        if (UserHandle.getAppId(uid) == SYSTEM_UID) {
+            return true;
+        }
+        final PackageManagerInternal pm = mService.mWindowManager.mPmInternal;
+        final AndroidPackage callingPkg = pm.getPackage(uid);
+        if (callingPkg == null) {
+            return false;
+        }
+        if (callingPkg.isSignedWithPlatformKey()) {
+            return true;
+        }
+        final String[] installerNames = pm.getKnownPackageNames(
+                PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.getUserId(uid));
+        return installerNames.length > 0 && callingPkg.getPackageName().equals(installerNames[0]);
+    }
+
     @Override
     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
         final long origId = Binder.clearCallingIdentity();