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

Commit f8342c8d authored by lpeter's avatar lpeter
Browse files

Postpone the request direct actions before onStart

By the original design, we register the activity event in the
ActivityManagerService. After getting the activity event, we will
query current visible activities and report them to Assistant.
Assistant will start to get direct actions of those visible
activities. But sometimes they can not get the direct actions
due to the stage of activity lifecycle before onStart().

We will postpone the request direct actions a few times
before onStart().

Bug: 224789902
Test: atest CtsVoiceInteractionTestCases
Change-Id: If7cd52c5ba749523e575c0be5595e8f20704c4f2
parent c7c60d5e
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -298,6 +298,11 @@ public final class ActivityThread extends ClientTransactionHandler
    /** Use background GC policy and default JIT threshold. */
    private static final int VM_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;

    /** The delay time for retrying to request DirectActions. */
    private static final long REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS = 200;
    /** The max count for retrying to request DirectActions. */
    private static final int REQUEST_DIRECT_ACTIONS_RETRY_MAX_COUNT = 3;

    /**
     * Denotes an invalid sequence number corresponding to a process state change.
     */
@@ -1861,7 +1866,8 @@ public final class ActivityThread extends ClientTransactionHandler
                cancellationCallback.sendResult(cancellationResult);
            }
            mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
                    ActivityThread.this, activityToken, interactor, cancellationSignal, callback));
                    ActivityThread.this, activityToken, interactor, cancellationSignal, callback,
                    REQUEST_DIRECT_ACTIONS_RETRY_MAX_COUNT));
        }

        @Override
@@ -3955,7 +3961,7 @@ public final class ActivityThread extends ClientTransactionHandler
    /** Fetches the user actions for the corresponding activity */
    private void handleRequestDirectActions(@NonNull IBinder activityToken,
            @NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal,
            @NonNull RemoteCallback callback) {
            @NonNull RemoteCallback callback, int retryCount) {
        final ActivityClientRecord r = mActivities.get(activityToken);
        if (r == null) {
            Log.w(TAG, "requestDirectActions(): no activity for " + activityToken);
@@ -3963,7 +3969,20 @@ public final class ActivityThread extends ClientTransactionHandler
            return;
        }
        final int lifecycleState = r.getLifecycleState();
        if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
        if (lifecycleState < ON_START) {
            // TODO(b/234173463): requestDirectActions callback should indicate errors
            if (retryCount > 0) {
                mH.sendMessageDelayed(
                        PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
                                ActivityThread.this, activityToken, interactor, cancellationSignal,
                                callback, retryCount - 1), REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS);
                return;
            }
            Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState);
            callback.sendResult(null);
            return;
        }
        if (lifecycleState >= ON_STOP) {
            Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState);
            callback.sendResult(null);
            return;
+37 −1
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import com.android.internal.app.IHotwordRecognitionStatusCallback;
import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.wm.ActivityAssistInfo;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -86,10 +87,14 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne

    final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";

    /** The delay time for retrying to request DirectActions. */
    private static final long REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS = 200;

    final boolean mValid;

    final Context mContext;
    final Handler mHandler;
    final Handler mDirectActionsHandler;
    final VoiceInteractionManagerService.VoiceInteractionManagerServiceStub mServiceStub;
    final int mUser;
    final ComponentName mComponent;
@@ -184,6 +189,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
            int userHandle, ComponentName service) {
        mContext = context;
        mHandler = handler;
        mDirectActionsHandler = new Handler(true);
        mServiceStub = stub;
        mUser = userHandle;
        mComponent = service;
@@ -343,6 +349,35 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
                .getAttachedNonFinishingActivityForTask(taskId, null);
        if (tokens == null || tokens.getAssistToken() != assistToken) {
            Slog.w(TAG, "Unknown activity to query for direct actions");
            mDirectActionsHandler.sendMessageDelayed(PooledLambda.obtainMessage(
                    VoiceInteractionManagerServiceImpl::retryRequestDirectActions,
                    VoiceInteractionManagerServiceImpl.this, token, taskId, assistToken,
                    cancellationCallback, callback), REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS);
        } else {
            try {
                tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
                        mActiveSession.mInteractor, cancellationCallback, callback);
            } catch (RemoteException e) {
                Slog.w("Unexpected remote error", e);
                callback.sendResult(null);
            }
        }
    }

    private void retryRequestDirectActions(@NonNull IBinder token, int taskId,
            @NonNull IBinder assistToken,  @Nullable RemoteCallback cancellationCallback,
            @NonNull RemoteCallback callback) {
        synchronized (mServiceStub) {
            if (mActiveSession == null || token != mActiveSession.mToken) {
                Slog.w(TAG, "retryRequestDirectActions does not match active session");
                callback.sendResult(null);
                return;
            }
            final ActivityTokens tokens = LocalServices.getService(
                            ActivityTaskManagerInternal.class)
                    .getAttachedNonFinishingActivityForTask(taskId, null);
            if (tokens == null || tokens.getAssistToken() != assistToken) {
                Slog.w(TAG, "Unknown activity to query for direct actions during retrying");
                callback.sendResult(null);
            } else {
                try {
@@ -354,6 +389,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
                }
            }
        }
    }

    void performDirectActionLocked(@NonNull IBinder token, @NonNull String actionId,
            @Nullable Bundle arguments, int taskId, IBinder assistToken,