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);