Provide referrer package with respect to package visibility

Otherwise the app can easily get the caller package name by
Activity#getReferrer() with removing intent extra or use
reflection to get Activity#mReferrer directly.

Bug: 191954233
Test: atest ActivityTaskSupervisorTests#testFilteredReferred
Change-Id: I59bfa69ae19e3bec8d9619fbdae3626675fb0d26
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c2cfe0b..d13c8ba 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4148,7 +4148,7 @@
         // The activity now gets access to the data associated with this Intent.
         mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
                 getUriPermissionsLocked());
-        final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
+        final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer));
         boolean unsent = true;
         final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
 
@@ -8505,6 +8505,19 @@
     }
 
     /**
+     * Gets the referrer package name with respect to package visibility. This method returns null
+     * if the given package is not visible to this activity.
+     */
+    String getFilteredReferrer(String referrerPackage) {
+        if (referrerPackage == null || (!referrerPackage.equals(packageName)
+                && mWmService.mPmInternal.filterAppAccess(
+                        referrerPackage, info.applicationInfo.uid, mUserId))) {
+            return null;
+        }
+        return referrerPackage;
+    }
+
+    /**
      * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
      * {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord
      * should be visible depending on Keyguard state.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index e3459a1..efa67e9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -848,9 +848,9 @@
                         // and override configs.
                         mergedConfiguration.getGlobalConfiguration(),
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
-                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
-                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
-                        r.takeOptions(), isTransitionForward,
+                        r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
+                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
+                        results, newIntents, r.takeOptions(), isTransitionForward,
                         proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                         r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                         r.getLaunchedFromBubble()));
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 0d177c1..19f9b75 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -30,6 +30,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -40,8 +41,10 @@
 
 import android.app.WaitResult;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.os.ConditionVariable;
+import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 
@@ -187,6 +190,24 @@
         verify(taskChangeNotifier, never()).notifyActivityDismissingDockedRootTask();
     }
 
+    /** Ensures that the calling package name passed to client complies with package visibility. */
+    @Test
+    public void testFilteredReferred() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setLaunchedFromPackage("other.package").setCreateTask(true).build();
+        assertNotNull(activity.launchedFromPackage);
+        try {
+            mSupervisor.realStartActivityLocked(activity, activity.app, false /* andResume */,
+                    false /* checkConfig */);
+        } catch (RemoteException ignored) {
+        }
+        verify(activity).getFilteredReferrer(eq(activity.launchedFromPackage));
+
+        activity.deliverNewIntentLocked(ActivityBuilder.DEFAULT_FAKE_UID,
+                new Intent(), null /* intentGrants */, "other.package2");
+        verify(activity).getFilteredReferrer(eq("other.package2"));
+    }
+
     /**
      * Ensures that notify focus task changes.
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 5880899..611b3f5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -801,6 +801,7 @@
         private int mConfigChanges;
         private int mLaunchedFromPid;
         private int mLaunchedFromUid;
+        private String mLaunchedFromPackage;
         private WindowProcessController mWpc;
         private Bundle mIntentExtras;
         private boolean mOnTop = false;
@@ -911,6 +912,11 @@
             return this;
         }
 
+        ActivityBuilder setLaunchedFromPackage(String packageName) {
+            mLaunchedFromPackage = packageName;
+            return this;
+        }
+
         ActivityBuilder setUseProcess(WindowProcessController wpc) {
             mWpc = wpc;
             return this;
@@ -1000,6 +1006,7 @@
             final ActivityRecord activity = new ActivityRecord.Builder(mService)
                     .setLaunchedFromPid(mLaunchedFromPid)
                     .setLaunchedFromUid(mLaunchedFromUid)
+                    .setLaunchedFromPackage(mLaunchedFromPackage)
                     .setIntent(intent)
                     .setActivityInfo(aInfo)
                     .setActivityOptions(options)