Merge "Use noteOpNoThrow instead of checkOpNoThrow in AssistDataRequester"

This commit is contained in:
Ivan Chiang
2022-08-03 07:13:55 +00:00
committed by Android (Google) Code Review
17 changed files with 173 additions and 98 deletions

View File

@@ -39,7 +39,6 @@ Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()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

View File

@@ -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.

View File

@@ -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

View File

@@ -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) {
}
}

View File

@@ -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) {
}
}

View File

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

View File

@@ -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);
/**

View File

@@ -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;
}

View File

@@ -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() {

View File

@@ -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<IBinder> 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<IBinder> activityTokens, final boolean fetchData,
public void requestAssistData(@NonNull List<IBinder> 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<IBinder> activityTokens, final boolean fetchData,
public void requestAssistData(@NonNull List<IBinder> 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<IBinder> 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<IBinder> 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++;

View File

@@ -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

View File

@@ -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;
}

View File

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

View File

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

View File

@@ -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<String> commands,

View File

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

View File

@@ -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<ActivityAssistInfo> topActivities) {
public boolean showLocked(@NonNull Bundle args, int flags, @Nullable String attributionTag,
int disabledContext, @Nullable IVoiceInteractionSessionShowCallback showCallback,
@NonNull List<ActivityAssistInfo> 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;