Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b6509f3 authored by Jon Spivack's avatar Jon Spivack
Browse files

Support getting AssistContent for recents in Launcher

The goal is to allow Launcher's Recents View to obtain the AssistContent for the recent activity shown in the view. This is accomplished by:
1. Adding a way to pass an AssistDataReceiver to ActivityTaskManager
2. Adding the 'recents' protection level to the GET_TOP_ACTIVITY_INFO permission so that Launcher can call the new method

Bug: 180157890
Test: Manual (tested getting the AssistContent from Launcher recents on local device)
Change-Id: Ibb3d6b68e2b8f22e79a7b6dbbeb1a3e89d2d6a36
parent b4dfa621
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -244,6 +244,8 @@ interface IActivityTaskManager {
    boolean requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras,
            in IBinder activityToken, int flags);
    boolean isAssistDataAllowedOnCurrentActivity();
    boolean requestAssistDataForTask(in IAssistDataReceiver receiver, int taskId,
            in String callingPackageName);

    /**
     * Notify the system that the keyguard is going away.
+1 −1
Original line number Diff line number Diff line
@@ -3537,7 +3537,7 @@
         @hide
    -->
    <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
        android:protectionLevel="signature" />
        android:protectionLevel="signature|recents" />

    <!-- Allows an application to retrieve the current state of keys and
         switches.
+28 −6
Original line number Diff line number Diff line
@@ -143,27 +143,45 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub {
     * 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, int, String)}.
     * See {@link #requestData(List, 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 /* allowFetchData */, false /* allowFetchScreenshot */,
                callingUid, callingPackage);
                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, int, String)}.
     * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
     * boolean)}.
     */
    public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
            final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
            int callingUid, String callingPackage) {
        requestAssistData(activityTokens, fetchData, fetchScreenshot, allowFetchData,
                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, int, String,
     * boolean)}.
     */
    public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
            final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
            boolean ignoreTopActivityCheck, int callingUid, String callingPackage) {
        requestData(activityTokens, false /* requestAutofillData */, fetchData, fetchScreenshot,
                allowFetchData, allowFetchScreenshot, callingUid, callingPackage);
                allowFetchData, allowFetchScreenshot, ignoreTopActivityCheck, callingUid,
                callingPackage);
    }

    /**
@@ -183,10 +201,13 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub {
     *     is allowed to fetch the assist data
     * @param allowFetchScreenshot to be joined with other checks, determines whether or not the
     *     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.
     */
    private void requestData(List<IBinder> activityTokens, final boolean requestAutofillData,
            final boolean fetchData, final boolean fetchScreenshot, boolean allowFetchData,
            boolean allowFetchScreenshot, int callingUid, String callingPackage) {
            boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid,
            String callingPackage) {
        // 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

@@ -230,7 +251,8 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub {
                                        receiverExtras, topActivity, 0 /* flags */)
                                : mActivityTaskManager.requestAssistContextExtras(
                                        ASSIST_CONTEXT_FULL, this, receiverExtras, topActivity,
                                        /* focused= */ i == 0, /* newSessionId= */ i == 0);
                                        /* checkActivityIsTop= */ (i == 0)
                                        && !ignoreTopActivityCheck, /* newSessionId= */ i == 0);
                        if (result) {
                            mPendingDataCount++;
                        } else if (i == 0) {
+43 −7
Original line number Diff line number Diff line
@@ -250,6 +250,7 @@ import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.AssistDataRequester;
import com.android.server.am.BaseErrorDialog;
import com.android.server.am.PendingIntentController;
import com.android.server.am.PendingIntentRecord;
@@ -2826,10 +2827,45 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    @Override
    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
            Bundle receiverExtras, IBinder activityToken, boolean checkActivityIsTop,
            boolean newSessionId) {
        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
                activityToken, checkActivityIsTop, newSessionId, UserHandle.getCallingUserId(),
                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
    }

    @Override
    public boolean requestAssistDataForTask(IAssistDataReceiver receiver, int taskId,
            String callingPackageName) {
        mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
                "requestAssistDataForTask()");
        final long callingId = Binder.clearCallingIdentity();
        LocalService.ActivityTokens tokens = null;
        try {
            tokens = mInternal.getTopActivityForTask(taskId);
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        if (tokens == null) {
            Log.e(TAG, "Could not find activity for task " + taskId);
            return false;
        }

        final AssistDataReceiverProxy proxy =
                new AssistDataReceiverProxy(receiver, callingPackageName);
        Object lock = new Object();
        AssistDataRequester requester = new AssistDataRequester(mContext, mWindowManager,
                getAppOpsManager(), proxy, lock, AppOpsManager.OP_ASSIST_STRUCTURE,
                AppOpsManager.OP_NONE);

        List<IBinder> topActivityToken = new ArrayList<>();
        topActivityToken.add(tokens.getActivityToken());
        requester.requestAssistData(topActivityToken, true /* fetchData */,
                false /* fetchScreenshot */, true /* allowFetchData */,
                false /* allowFetchScreenshot*/, true /* ignoreFocusCheck */,
                Binder.getCallingUid(), callingPackageName);

        return true;
    }

    @Override
@@ -2843,7 +2879,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    @Override
    public Bundle getAssistContextExtras(int requestType) {
        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
                null, null, true /* focused */, true /* newSessionId */,
                null, null, true /* checkActivityIsTop */, true /* newSessionId */,
                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
        if (pae == null) {
            return null;
@@ -3046,8 +3082,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
            int flags) {
            boolean checkActivityIsTop, boolean newSessionId, int userHandle, Bundle args,
            long timeout, int flags) {
        mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
                "enqueueAssistContext()");

@@ -3063,7 +3099,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
                return null;
            }
            if (focused) {
            if (checkActivityIsTop) {
                if (activityToken != null) {
                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
                    if (activity != caller) {