Grant client app visibility with UID from activity record

this also fixes an NPE b/234828308

Bug: 226167520
Test: atest android.voiceinteraction.cts
Change-Id: Ibe20fb4da91fa80f8539bb19c90515167bf6e85b
Merged-In: Ibe20fb4da91fa80f8539bb19c90515167bf6e85b
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index f75d73b..8e7dde2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -338,14 +338,16 @@
         private final @NonNull IBinder mAssistToken;
         private final @NonNull IBinder mShareableActivityToken;
         private final @NonNull IApplicationThread mAppThread;
+        private final int mUid;
 
         public ActivityTokens(@NonNull IBinder activityToken,
                 @NonNull IBinder assistToken, @NonNull IApplicationThread appThread,
-                @NonNull IBinder shareableActivityToken) {
+                @NonNull IBinder shareableActivityToken, int uid) {
             mActivityToken = activityToken;
             mAssistToken = assistToken;
             mAppThread = appThread;
             mShareableActivityToken = shareableActivityToken;
+            mUid = uid;
         }
 
         /**
@@ -375,6 +377,13 @@
         public @NonNull IApplicationThread getApplicationThread() {
             return mAppThread;
         }
+
+        /**
+         * @return The UID of the activity
+         */
+        public int getUid() {
+            return mUid;
+        }
     }
 
     public abstract void sendActivityResult(int callingUid, IBinder activityToken,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b8162cd..aa15429 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5820,14 +5820,16 @@
                 if (token == null && list.get(0).attachedToProcess()) {
                     ActivityRecord topRecord = list.get(0);
                     return new ActivityTokens(topRecord.token, topRecord.assistToken,
-                            topRecord.app.getThread(), topRecord.shareableActivityToken);
+                            topRecord.app.getThread(), topRecord.shareableActivityToken,
+                            topRecord.getUid());
                 }
                 // find the expected Activity
                 for (int i = 0; i < list.size(); i++) {
                     ActivityRecord record = list.get(i);
                     if (record.shareableActivityToken == token && record.attachedToProcess()) {
                         return new ActivityTokens(record.token, record.assistToken,
-                                record.app.getThread(), record.shareableActivityToken);
+                                record.app.getThread(), record.shareableActivityToken,
+                                record.getUid());
                     }
                 }
                 return null;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 73b2510..bcfee82 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -35,7 +35,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.ShortcutServiceInternal;
@@ -105,7 +104,6 @@
 import com.android.server.soundtrigger.SoundTriggerInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.ActivityTaskManagerInternal;
-import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -128,7 +126,6 @@
     final ActivityManagerInternal mAmInternal;
     final ActivityTaskManagerInternal mAtmInternal;
     final UserManagerInternal mUserManagerInternal;
-    final PackageManagerInternal mPackageManagerInternal;
     final ArrayMap<Integer, VoiceInteractionManagerServiceStub.SoundTriggerSession>
             mLoadedKeyphraseIds = new ArrayMap<>();
     ShortcutServiceInternal mShortcutServiceInternal;
@@ -149,8 +146,6 @@
                 LocalServices.getService(ActivityTaskManagerInternal.class));
         mUserManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(UserManagerInternal.class));
-        mPackageManagerInternal = Objects.requireNonNull(
-                LocalServices.getService(PackageManagerInternal.class));
 
         LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService(
                 LegacyPermissionManagerInternal.class);
@@ -374,21 +369,6 @@
             return new SoundTriggerSessionBinderProxy(session);
         }
 
-        @GuardedBy("this")
-        private void grantImplicitAccessLocked(int grantRecipientUid, @Nullable Intent intent) {
-            if (mImpl == null) {
-                Slog.w(TAG, "Cannot grant implicit access because mImpl is null.");
-                return;
-            }
-
-            final int grantRecipientAppId = UserHandle.getAppId(grantRecipientUid);
-            final int grantRecipientUserId = UserHandle.getUserId(grantRecipientUid);
-            final int voiceInteractionUid = mImpl.mInfo.getServiceInfo().applicationInfo.uid;
-            mPackageManagerInternal.grantImplicitAccess(
-                    grantRecipientUserId, intent, grantRecipientAppId, voiceInteractionUid,
-                    /* direct= */ true);
-        }
-
         private IVoiceInteractionSoundTriggerSession createSoundTriggerSessionForSelfIdentity(
                 IBinder client) {
             Identity identity = new Identity();
@@ -419,9 +399,10 @@
                             @Override
                             public void onShown() {
                                 synchronized (VoiceInteractionManagerServiceStub.this) {
-                                    VoiceInteractionManagerServiceStub.this
-                                            .grantImplicitAccessLocked(callingUid,
-                                                    /* intent= */ null);
+                                    if (mImpl != null) {
+                                        mImpl.grantImplicitAccessLocked(callingUid,
+                                                /* intent= */ null);
+                                    }
                                 }
                                 mAtmInternal.onLocalVoiceInteractionStarted(token,
                                         mImpl.mActiveSession.mSession,
@@ -995,7 +976,7 @@
                             mContext.getPackageManager(), PackageManager.MATCH_ALL);
                     if (activityInfo != null) {
                         final int activityUid = activityInfo.applicationInfo.uid;
-                        grantImplicitAccessLocked(activityUid, intent);
+                        mImpl.grantImplicitAccessLocked(activityUid, intent);
                     } else {
                         Slog.w(TAG, "Cannot find ActivityInfo in startVoiceActivity.");
                     }
@@ -1039,15 +1020,6 @@
                 }
                 final long caller = Binder.clearCallingIdentity();
                 try {
-                    // Getting the UID corresponding to the taskId, and grant the visibility to it.
-                    final ActivityTokens tokens = mAtmInternal
-                            .getAttachedNonFinishingActivityForTask(taskId, /* token= */ null);
-                    final ComponentName componentName = mAtmInternal.getActivityName(
-                            tokens.getActivityToken());
-                    grantImplicitAccessLocked(mPackageManagerInternal.getPackageUid(
-                            componentName.getPackageName(), PackageManager.MATCH_ALL,
-                                    UserHandle.myUserId()), /* intent= */ null);
-
                     mImpl.requestDirectActionsLocked(token, taskId, assistToken,
                             cancellationCallback, resultCallback);
                 } finally {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 0558648..56cfa0f0 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -39,6 +39,7 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ServiceInfo;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
@@ -79,6 +80,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
     final static String TAG = "VoiceInteractionServiceManager";
@@ -95,6 +97,7 @@
     final ComponentName mComponent;
     final IActivityManager mAm;
     final IActivityTaskManager mAtm;
+    final PackageManagerInternal mPackageManagerInternal;
     final VoiceInteractionServiceInfo mInfo;
     final ComponentName mSessionComponentName;
     final IWindowManager mIWindowManager;
@@ -189,6 +192,8 @@
         mComponent = service;
         mAm = ActivityManager.getService();
         mAtm = ActivityTaskManager.getService();
+        mPackageManagerInternal = Objects.requireNonNull(
+                LocalServices.getService(PackageManagerInternal.class));
         VoiceInteractionServiceInfo info;
         try {
             info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
@@ -224,6 +229,15 @@
                 Context.RECEIVER_EXPORTED);
     }
 
+    public void grantImplicitAccessLocked(int grantRecipientUid, @Nullable Intent intent) {
+        final int grantRecipientAppId = UserHandle.getAppId(grantRecipientUid);
+        final int grantRecipientUserId = UserHandle.getUserId(grantRecipientUid);
+        final int voiceInteractionUid = mInfo.getServiceInfo().applicationInfo.uid;
+        mPackageManagerInternal.grantImplicitAccess(
+                grantRecipientUserId, intent, grantRecipientAppId, voiceInteractionUid,
+                /* direct= */ true);
+    }
+
     public boolean showSessionLocked(Bundle args, int flags,
             IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
         if (mActiveSession == null) {
@@ -345,6 +359,7 @@
             Slog.w(TAG, "Unknown activity to query for direct actions");
             callback.sendResult(null);
         } else {
+            grantImplicitAccessLocked(tokens.getUid(), /* intent= */ null);
             try {
                 tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
                         mActiveSession.mInteractor, cancellationCallback, callback);