diff --git a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt index dbc3b5102efee..f5184e7963d76 100644 --- a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt +++ b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt @@ -39,7 +39,6 @@ Lcom/android/ims/internal/uce/options/IOptionsService$Stub;->()V Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;->()V Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;->()V Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;->()V -Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String; Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 0bf16a0c471bb..3459d0e7265cb 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -231,7 +231,7 @@ interface IActivityTaskManager { in IBinder activityToken, int flags); boolean isAssistDataAllowedOnCurrentActivity(); boolean requestAssistDataForTask(in IAssistDataReceiver receiver, int taskId, - in String callingPackageName); + in String callingPackageName, String callingAttributionTag); /** * Notify the system that the keyguard is going away. diff --git a/core/java/android/service/voice/VoiceInteractionManagerInternal.java b/core/java/android/service/voice/VoiceInteractionManagerInternal.java index a09b74de486a0..c47fdd39e30cf 100644 --- a/core/java/android/service/voice/VoiceInteractionManagerInternal.java +++ b/core/java/android/service/voice/VoiceInteractionManagerInternal.java @@ -16,6 +16,7 @@ package android.service.voice; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.os.Bundle; @@ -33,9 +34,12 @@ public abstract class VoiceInteractionManagerInternal { * Start a new voice interaction session when requested from within an activity * by Activity.startLocalVoiceInteraction() * @param callingActivity The binder token representing the calling activity. - * @param options + * @param attributionTag The attribution tag of the calling context or {@code null} for default + * attribution + * @param options A Bundle of private arguments to the current voice interaction service */ - public abstract void startLocalVoiceInteraction(IBinder callingActivity, Bundle options); + public abstract void startLocalVoiceInteraction(@NonNull IBinder callingActivity, + @Nullable String attributionTag, @NonNull Bundle options); /** * Returns whether the currently selected voice interaction service supports local voice diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index 1170237a346eb..1b46107de02cf 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -242,7 +242,7 @@ public class VoiceInteractionService extends Service { throw new IllegalStateException("Not available until onReady() is called"); } try { - mSystemService.showSession(args, flags); + mSystemService.showSession(args, flags, getAttributionTag()); } catch (RemoteException e) { } } diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index b7ec486d48304..d08a67e686761 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -1384,7 +1384,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall throw new IllegalStateException("Can't call before onCreate()"); } try { - mSystemService.showSessionFromSession(mToken, args, flags); + mSystemService.showSessionFromSession(mToken, args, flags, + mContext.getAttributionTag()); } catch (RemoteException e) { } } diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index c056e26e46746..f8433182db9e4 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.annotation.NonNull; +import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; @@ -67,12 +68,53 @@ public class AssistUtils { ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)); } - public boolean showSessionForActiveService(Bundle args, int sourceFlags, - IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { + /** + * Shows the session for the currently active service. Used to start a new session from system + * affordances. + * + * @param args the bundle to pass as arguments to the voice interaction session + * @param sourceFlags flags indicating the source of this show + * @param showCallback optional callback to be notified when the session was shown + * @param activityToken optional token of activity that needs to be on top + * + * @deprecated Use {@link #showSessionForActiveService(Bundle, int, String, + * IVoiceInteractionSessionShowCallback, IBinder)} instead + */ + @Deprecated + public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags, + @Nullable IVoiceInteractionSessionShowCallback showCallback, + @Nullable IBinder activityToken) { + return showSessionForActiveServiceInternal(args, sourceFlags, /* attributionTag */ null, + showCallback, activityToken); + } + + /** + * Shows the session for the currently active service. Used to start a new session from system + * affordances. + * + * @param args the bundle to pass as arguments to the voice interaction session + * @param sourceFlags flags indicating the source of this show + * @param attributionTag the attribution tag of the calling context or {@code null} for default + * attribution + * @param showCallback optional callback to be notified when the session was shown + * @param activityToken optional token of activity that needs to be on top + */ + public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags, + @Nullable String attributionTag, + @Nullable IVoiceInteractionSessionShowCallback showCallback, + @Nullable IBinder activityToken) { + return showSessionForActiveServiceInternal(args, sourceFlags, attributionTag, showCallback, + activityToken); + } + + private boolean showSessionForActiveServiceInternal(@NonNull Bundle args, int sourceFlags, + @Nullable String attributionTag, + @Nullable IVoiceInteractionSessionShowCallback showCallback, + @Nullable IBinder activityToken) { try { if (mVoiceInteractionManagerService != null) { return mVoiceInteractionManagerService.showSessionForActiveService(args, - sourceFlags, showCallback, activityToken); + sourceFlags, attributionTag, showCallback, activityToken); } } catch (RemoteException e) { Log.w(TAG, "Failed to call showSessionForActiveService", e); diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 4b01357877edc..83bf801391f04 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -39,15 +39,16 @@ import android.service.voice.IVoiceInteractionSession; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; interface IVoiceInteractionManagerService { - void showSession(in Bundle sessionArgs, int flags); + void showSession(in Bundle sessionArgs, int flags, String attributionTag); boolean deliverNewSession(IBinder token, IVoiceInteractionSession session, IVoiceInteractor interactor); - boolean showSessionFromSession(IBinder token, in Bundle sessionArgs, int flags); + boolean showSessionFromSession(IBinder token, in Bundle sessionArgs, int flags, + String attributionTag); boolean hideSessionFromSession(IBinder token); int startVoiceActivity(IBinder token, in Intent intent, String resolvedType, - String callingFeatureId); + String attributionTag); int startAssistantActivity(IBinder token, in Intent intent, String resolvedType, - String callingFeatureId); + String attributionTag); void setKeepAwake(IBinder token, boolean keepAwake); void closeSystemDialogs(IBinder token); void finish(IBinder token); @@ -125,12 +126,14 @@ interface IVoiceInteractionManagerService { * * @param args the bundle to pass as arguments to the voice interaction session * @param sourceFlags flags indicating the source of this show + * @param attributionTag the attribution tag of the calling context or {@code null} for default + * attribution * @param showCallback optional callback to be notified when the session was shown * @param activityToken optional token of activity that needs to be on top * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE */ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE") - boolean showSessionForActiveService(in Bundle args, int sourceFlags, + boolean showSessionForActiveService(in Bundle args, int sourceFlags, String attributionTag, IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken); /** diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 916526d0efac6..ee30972296fb4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -19,7 +19,6 @@ package com.android.systemui.shared.system; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; -import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; import static android.app.ActivityTaskManager.getService; import android.annotation.NonNull; @@ -27,7 +26,6 @@ import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityClient; import android.app.ActivityManager; -import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityOptions; import android.app.ActivityTaskManager; @@ -337,7 +335,8 @@ public class ActivityManagerWrapper { * Shows a voice session identified by {@code token} * @return true if the session was shown, false otherwise */ - public boolean showVoiceSession(IBinder token, Bundle args, int flags) { + public boolean showVoiceSession(@NonNull IBinder token, @NonNull Bundle args, int flags, + @Nullable String attributionTag) { IVoiceInteractionManagerService service = IVoiceInteractionManagerService.Stub.asInterface( ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)); if (service == null) { @@ -346,7 +345,7 @@ public class ActivityManagerWrapper { args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime()); try { - return service.showSessionFromSession(token, args, flags); + return service.showSessionFromSession(token, args, flags, attributionTag); } catch (RemoteException e) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 7c2673c31bf5d..57ffdab50b253 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -310,7 +310,8 @@ public class AssistManager { private void startVoiceInteractor(Bundle args) { mAssistUtils.showSessionForActiveService(args, - VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE, null, null); + VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE, mContext.getAttributionTag(), + null, null); } public void launchVoiceAssistFromKeyguard() { diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java index 98ad81d7d9def..98129ed12afef 100644 --- a/services/core/java/com/android/server/am/AssistDataRequester.java +++ b/services/core/java/com/android/server/am/AssistDataRequester.java @@ -23,6 +23,8 @@ import static android.app.AppOpsManager.OP_NONE; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityTaskManager; import android.app.AppOpsManager; import android.app.IActivityTaskManager; @@ -41,6 +43,7 @@ import com.android.internal.logging.MetricsLogger; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * Helper class to asynchronously fetch the assist data and screenshot from the current running @@ -140,51 +143,36 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { mRequestScreenshotAppOps = requestScreenshotAppOps; } - /** - * Request that autofill data be loaded asynchronously. The resulting data will be provided - * through the {@link AssistDataRequesterCallbacks}. - * - * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int, - * String, boolean)}. - */ - public void requestAutofillData(List activityTokens, int callingUid, - String callingPackage) { - requestData(activityTokens, true /* requestAutofillData */, - true /* fetchData */, false /* fetchScreenshot */, - true /* fetchStructure */, true /* allowFetchData */, - false /* allowFetchScreenshot */, false /* ignoreTopActivityCheck */, callingUid, - callingPackage); - } - /** * Request that assist data be loaded asynchronously. The resulting data will be provided * through the {@link AssistDataRequesterCallbacks}. * - * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int, - * String, boolean)}. + * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, boolean, + * int, String, String)}. */ - public void requestAssistData(List activityTokens, final boolean fetchData, + public void requestAssistData(@NonNull List activityTokens, final boolean fetchData, final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot, - int callingUid, String callingPackage) { + int callingUid, @NonNull String callingPackage, + @Nullable String callingAttributionTag) { requestAssistData(activityTokens, fetchData, fetchScreenshot, true /* fetchStructure */, allowFetchData, allowFetchScreenshot, false /* ignoreTopActivityCheck */, - callingUid, callingPackage); + callingUid, callingPackage, callingAttributionTag); } /** * Request that assist data be loaded asynchronously. The resulting data will be provided * through the {@link AssistDataRequesterCallbacks}. * - * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int, - * String, boolean)}. + * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, boolean, + * int, String, String)}. */ - public void requestAssistData(List activityTokens, final boolean fetchData, + public void requestAssistData(@NonNull List activityTokens, final boolean fetchData, final boolean fetchScreenshot, final boolean fetchStructure, boolean allowFetchData, boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid, - String callingPackage) { + @NonNull String callingPackage, @Nullable String callingAttributionTag) { requestData(activityTokens, false /* requestAutofillData */, fetchData, fetchScreenshot, fetchStructure, allowFetchData, allowFetchScreenshot, ignoreTopActivityCheck, - callingUid, callingPackage); + callingUid, callingPackage, callingAttributionTag); } /** @@ -208,14 +196,22 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { * requester is allowed to fetch the assist screenshot * @param ignoreTopActivityCheck overrides the check for whether the activity is in focus when * making the request. Used when passing an activity from Recents. + * @param callingUid the uid of the real caller + * @param callingPackage the package name of the real caller + * @param callingAttributionTag The {@link Context#createAttributionContext attribution tag} + * of the calling context or {@code null} for default attribution */ - private void requestData(List activityTokens, final boolean requestAutofillData, - final boolean fetchData, final boolean fetchScreenshot, final boolean fetchStructure, - boolean allowFetchData, boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, - int callingUid, String callingPackage) { + private void requestData(@NonNull List activityTokens, + final boolean requestAutofillData, final boolean fetchData, + final boolean fetchScreenshot, final boolean fetchStructure, boolean allowFetchData, + boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid, + @NonNull String callingPackage, @Nullable String callingAttributionTag) { // TODO(b/34090158): Known issue, if the assist data is not allowed on the current activity, // then no assist data is requested for any of the other activities + Objects.requireNonNull(activityTokens); + Objects.requireNonNull(callingPackage); + // Early exit if there are no activity to fetch for if (activityTokens.isEmpty()) { // No activities, just dispatch request-complete @@ -241,8 +237,9 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { mAssistScreenshot.clear(); if (fetchData) { - if (mAppOpsManager.checkOpNoThrow(mRequestStructureAppOps, callingUid, callingPackage) - == MODE_ALLOWED && allowFetchData) { + if (mAppOpsManager.noteOpNoThrow(mRequestStructureAppOps, callingUid, + callingPackage, callingAttributionTag, /* message */ null) == MODE_ALLOWED + && allowFetchData) { final int numActivities = activityTokens.size(); for (int i = 0; i < numActivities; i++) { IBinder topActivity = activityTokens.get(i); @@ -291,8 +288,9 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { } if (fetchScreenshot) { - if (mAppOpsManager.checkOpNoThrow(mRequestScreenshotAppOps, callingUid, callingPackage) - == MODE_ALLOWED && allowFetchScreenshot) { + if (mAppOpsManager.noteOpNoThrow(mRequestScreenshotAppOps, callingUid, + callingPackage, callingAttributionTag, /* message */ null) == MODE_ALLOWED + && allowFetchScreenshot) { try { MetricsLogger.count(mContext, "assist_with_screen", 1); mPendingScreenshotCount++; diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index d2a00af245f64..cceb58d74562a 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -1020,6 +1020,7 @@ class ActivityClientController extends IActivityClientController.Stub { public boolean showAssistFromActivity(IBinder token, Bundle args) { final long ident = Binder.clearCallingIdentity(); try { + final String callingAttributionTag; synchronized (mGlobalLock) { final ActivityRecord caller = ActivityRecord.forTokenLocked(token); final Task topRootTask = mService.getTopDisplayFocusedRootTask(); @@ -1035,9 +1036,10 @@ class ActivityClientController extends IActivityClientController.Stub { + " is not visible"); return false; } + callingAttributionTag = top.launchedFromFeatureId; } return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, - null /* showCallback */, token); + callingAttributionTag, null /* showCallback */, token); } finally { Binder.restoreCallingIdentity(ident); } @@ -1054,6 +1056,7 @@ class ActivityClientController extends IActivityClientController.Stub { @Override public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { Slog.i(TAG, "Activity tried to startLocalVoiceInteraction"); + final String callingAttributionTag; synchronized (mGlobalLock) { final Task topRootTask = mService.getTopDisplayFocusedRootTask(); final ActivityRecord activity = topRootTask != null @@ -1071,9 +1074,10 @@ class ActivityClientController extends IActivityClientController.Stub { return; } activity.pendingVoiceInteractionStart = true; + callingAttributionTag = activity.launchedFromFeatureId; } LocalServices.getService(VoiceInteractionManagerInternal.class) - .startLocalVoiceInteraction(callingActivity, options); + .startLocalVoiceInteraction(callingActivity, callingAttributionTag, options); } @Override diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 471424bd86e4b..3aa7489ec8906 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2986,7 +2986,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean requestAssistDataForTask(IAssistDataReceiver receiver, int taskId, - String callingPackageName) { + String callingPackageName, @Nullable String callingAttributionTag) { mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, "requestAssistDataForTask()"); final long callingId = Binder.clearCallingIdentity(); @@ -3013,7 +3013,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { requester.requestAssistData(topActivityToken, true /* fetchData */, false /* fetchScreenshot */, false /* fetchStructure */, true /* allowFetchData */, false /* allowFetchScreenshot*/, true /* ignoreFocusCheck */, - Binder.getCallingUid(), callingPackageName); + Binder.getCallingUid(), callingPackageName, callingAttributionTag); return true; } diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java index 2e85897b6fee4..06b4ad975a872 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java @@ -87,6 +87,7 @@ public class AssistDataRequesterTest { private static final int TEST_UID = 0; private static final String TEST_PACKAGE = ""; + private static final String TEST_ATTRIBUTION_TAG = ""; private AssistDataRequester mDataRequester; private Callbacks mCallbacks; @@ -148,9 +149,9 @@ public class AssistDataRequesterTest { boolean assistScreenshotAllowed) throws Exception { doReturn(currentActivityAssistAllowed).when(mAtm).isAssistDataAllowedOnCurrentActivity(); doReturn(assistStructureAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager) - .checkOpNoThrow(eq(OP_ASSIST_STRUCTURE), anyInt(), anyString()); + .noteOpNoThrow(eq(OP_ASSIST_STRUCTURE), anyInt(), anyString(), any(), any()); doReturn(assistScreenshotAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager) - .checkOpNoThrow(eq(OP_ASSIST_SCREENSHOT), anyInt(), anyString()); + .noteOpNoThrow(eq(OP_ASSIST_SCREENSHOT), anyInt(), anyString(), any(), any()); } @Test @@ -160,7 +161,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(5, 5, 1, 1); } @@ -170,7 +172,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(0), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(0, 0, 0, 0); } @@ -180,7 +183,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(0, 1, 0, 1); } @@ -191,7 +195,8 @@ public class AssistDataRequesterTest { mCallbacks.mCanHandleReceivedData = false; mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertEquals(5, mDataRequester.getPendingDataCount()); assertEquals(1, mDataRequester.getPendingScreenshotCount()); mGate.countDown(); @@ -226,7 +231,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), !FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(0, 0, 0, 1); } @@ -236,7 +242,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); // Expect a single null data when the appops is denied assertReceivedDataCount(0, 1, 0, 1); } @@ -249,7 +256,8 @@ public class AssistDataRequesterTest { anyBoolean(), anyBoolean()); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); // Expect a single null data when requestAssistContextExtras() fails assertReceivedDataCount(0, 1, 0, 1); } @@ -261,7 +269,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, !FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(5, 5, 0, 0); } @@ -272,7 +281,8 @@ public class AssistDataRequesterTest { !CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); // Expect a single null screenshot when the appops is denied assertReceivedDataCount(5, 5, 0, 1); } @@ -284,7 +294,8 @@ public class AssistDataRequesterTest { mCallbacks.mCanHandleReceivedData = false; mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); mGate.countDown(); waitForIdle(mHandler); assertThat(mCallbacks.mReceivedData).isEmpty(); @@ -297,7 +308,8 @@ public class AssistDataRequesterTest { CALLER_ASSIST_SCREENSHOT_ALLOWED); mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS, - !ALLOW_FETCH_DATA, !ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE); + !ALLOW_FETCH_DATA, !ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE, + TEST_ATTRIBUTION_TAG); assertReceivedDataCount(0, 1, 0, 1); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 53427246225dc..4b9b4a9781deb 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -227,12 +227,13 @@ public class VoiceInteractionManagerService extends SystemService { class LocalService extends VoiceInteractionManagerInternal { @Override - public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { + public void startLocalVoiceInteraction(@NonNull IBinder callingActivity, + @Nullable String attributionTag, @NonNull Bundle options) { if (DEBUG) { Slog.i(TAG, "startLocalVoiceInteraction " + callingActivity); } VoiceInteractionManagerService.this.mServiceStub.startLocalVoiceInteraction( - callingActivity, options); + callingActivity, attributionTag, options); } @Override @@ -408,14 +409,15 @@ public class VoiceInteractionManagerService extends SystemService { } // TODO: VI Make sure the caller is the current user or profile - void startLocalVoiceInteraction(final IBinder token, Bundle options) { + void startLocalVoiceInteraction(@NonNull final IBinder token, + @Nullable String attributionTag, @NonNull Bundle options) { if (mImpl == null) return; final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { mImpl.showSessionLocked(options, - VoiceInteractionSession.SHOW_SOURCE_ACTIVITY, + VoiceInteractionSession.SHOW_SOURCE_ACTIVITY, attributionTag, new IVoiceInteractionSessionShowCallback.Stub() { @Override public void onFailed() { @@ -923,13 +925,13 @@ public class VoiceInteractionManagerService extends SystemService { } @Override - public void showSession(Bundle args, int flags) { + public void showSession(@NonNull Bundle args, int flags, @Nullable String attributionTag) { synchronized (this) { enforceIsCurrentVoiceInteractionService(); final long caller = Binder.clearCallingIdentity(); try { - mImpl.showSessionLocked(args, flags, null, null); + mImpl.showSessionLocked(args, flags, attributionTag, null, null); } finally { Binder.restoreCallingIdentity(caller); } @@ -954,7 +956,8 @@ public class VoiceInteractionManagerService extends SystemService { } @Override - public boolean showSessionFromSession(IBinder token, Bundle sessionArgs, int flags) { + public boolean showSessionFromSession(@NonNull IBinder token, @NonNull Bundle sessionArgs, + int flags, @Nullable String attributionTag) { synchronized (this) { if (mImpl == null) { Slog.w(TAG, "showSessionFromSession without running voice interaction service"); @@ -962,7 +965,7 @@ public class VoiceInteractionManagerService extends SystemService { } final long caller = Binder.clearCallingIdentity(); try { - return mImpl.showSessionLocked(sessionArgs, flags, null, null); + return mImpl.showSessionLocked(sessionArgs, flags, attributionTag, null, null); } finally { Binder.restoreCallingIdentity(caller); } @@ -986,8 +989,8 @@ public class VoiceInteractionManagerService extends SystemService { } @Override - public int startVoiceActivity(IBinder token, Intent intent, String resolvedType, - String callingFeatureId) { + public int startVoiceActivity(@NonNull IBinder token, @NonNull Intent intent, + @Nullable String resolvedType, @Nullable String attributionTag) { synchronized (this) { if (mImpl == null) { Slog.w(TAG, "startVoiceActivity without running voice interaction service"); @@ -1005,8 +1008,8 @@ public class VoiceInteractionManagerService extends SystemService { } else { Slog.w(TAG, "Cannot find ActivityInfo in startVoiceActivity."); } - return mImpl.startVoiceActivityLocked( - callingFeatureId, callingPid, callingUid, token, intent, resolvedType); + return mImpl.startVoiceActivityLocked(attributionTag, callingPid, callingUid, + token, intent, resolvedType); } finally { Binder.restoreCallingIdentity(caller); } @@ -1014,8 +1017,8 @@ public class VoiceInteractionManagerService extends SystemService { } @Override - public int startAssistantActivity(IBinder token, Intent intent, String resolvedType, - String callingFeatureId) { + public int startAssistantActivity(@NonNull IBinder token, @NonNull Intent intent, + @Nullable String resolvedType, @Nullable String attributionTag) { synchronized (this) { if (mImpl == null) { Slog.w(TAG, "startAssistantActivity without running voice interaction service"); @@ -1025,7 +1028,7 @@ public class VoiceInteractionManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - return mImpl.startAssistantActivityLocked(callingFeatureId, callingPid, + return mImpl.startAssistantActivityLocked(attributionTag, callingPid, callingUid, token, intent, resolvedType); } finally { Binder.restoreCallingIdentity(caller); @@ -1694,8 +1697,10 @@ public class VoiceInteractionManagerService extends SystemService { @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE) @Override - public boolean showSessionForActiveService(Bundle args, int sourceFlags, - IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { + public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags, + @Nullable String attributionTag, + @Nullable IVoiceInteractionSessionShowCallback showCallback, + @Nullable IBinder activityToken) { if (DEBUG_USER) Slog.d(TAG, "showSessionForActiveService()"); synchronized (this) { @@ -1716,7 +1721,7 @@ public class VoiceInteractionManagerService extends SystemService { sourceFlags | VoiceInteractionSession.SHOW_WITH_ASSIST | VoiceInteractionSession.SHOW_WITH_SCREENSHOT, - showCallback, activityToken); + attributionTag, showCallback, activityToken); } finally { Binder.restoreCallingIdentity(caller); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index b9793cafb6fed..9f66059b81d47 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -244,8 +244,10 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne /* direct= */ true); } - public boolean showSessionLocked(Bundle args, int flags, - IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { + public boolean showSessionLocked(@NonNull Bundle args, int flags, + @Nullable String attributionTag, + @Nullable IVoiceInteractionSessionShowCallback showCallback, + @Nullable IBinder activityToken) { if (mActiveSession == null) { mActiveSession = new VoiceInteractionSessionConnection(mServiceStub, mSessionComponentName, mUser, mContext, this, @@ -269,8 +271,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } else { visibleActivities = allVisibleActivities; } - return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback, - visibleActivities); + return mActiveSession.showLocked(args, flags, attributionTag, mDisabledShowContext, + showCallback, visibleActivities); } public void getActiveServiceSupportedActions(List commands, diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java index 9bdf4e418a527..80f5dc53c105e 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java @@ -114,8 +114,8 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand { try { Bundle args = new Bundle(); - boolean ok = mService.showSessionForActiveService(args, /* sourceFlags= */ 0, callback, - /* activityToken= */ null); + boolean ok = mService.showSessionForActiveService(args, /* sourceFlags= */ 0, + /* attributionTag= */ null, callback, /* activityToken= */ null); if (!ok) { pw.println("showSessionForActiveService() returned false"); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index 093e97614b5a4..63781cca4b96c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -29,6 +29,8 @@ import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_TASK_ID; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.AppOpsManager; @@ -263,9 +265,9 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, return flags; } - public boolean showLocked(Bundle args, int flags, int disabledContext, - IVoiceInteractionSessionShowCallback showCallback, - List topActivities) { + public boolean showLocked(@NonNull Bundle args, int flags, @Nullable String attributionTag, + int disabledContext, @Nullable IVoiceInteractionSessionShowCallback showCallback, + @NonNull List topActivities) { if (mBound) { if (!mFullyBound) { mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection, @@ -291,12 +293,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, for (int i = 0; i < topActivitiesCount; i++) { topActivitiesToken.add(topActivities.get(i).getActivityToken()); } + mAssistDataRequester.requestAssistData(topActivitiesToken, fetchData, fetchScreenshot, (disabledContext & VoiceInteractionSession.SHOW_WITH_ASSIST) == 0, (disabledContext & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0, - mCallingUid, mSessionComponentName.getPackageName()); + mCallingUid, + mSessionComponentName.getPackageName(), + attributionTag); boolean needDisclosure = mAssistDataRequester.getPendingDataCount() > 0 || mAssistDataRequester.getPendingScreenshotCount() > 0;