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

Commit e5ae0714 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge "Merge "Address API council feedback" into qt-dev am: 1a5d1728"...

Merge "Merge "Merge "Address API council feedback" into qt-dev am: 1a5d1728" into qt-dev-plus-aosp am: fc4b6581"
parents 9d999296 dacd5056
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -3763,7 +3763,7 @@ package android.app {
    method public void onDetachedFromWindow();
    method public void onEnterAnimationComplete();
    method public boolean onGenericMotionEvent(android.view.MotionEvent);
    method @NonNull public java.util.List<android.app.DirectAction> onGetDirectActions();
    method public void onGetDirectActions(@NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<java.util.List<android.app.DirectAction>>);
    method public boolean onKeyDown(int, android.view.KeyEvent);
    method public boolean onKeyLongPress(int, android.view.KeyEvent);
    method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
@@ -3783,7 +3783,7 @@ package android.app {
    method public void onOptionsMenuClosed(android.view.Menu);
    method public void onPanelClosed(int, @NonNull android.view.Menu);
    method @CallSuper protected void onPause();
    method public void onPerformDirectAction(@NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public void onPerformDirectAction(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
    method @Deprecated public void onPictureInPictureModeChanged(boolean);
    method @CallSuper protected void onPostCreate(@Nullable android.os.Bundle);
@@ -41832,7 +41832,7 @@ package android.service.voice {
    method public void onTaskStarted(android.content.Intent, int);
    method public void onTrimMemory(int);
    method public final void performDirectAction(@NonNull android.app.DirectAction, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public final void requestDirectActions(@NonNull android.service.voice.VoiceInteractionSession.ActivityId, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.DirectAction>>);
    method public final void requestDirectActions(@NonNull android.service.voice.VoiceInteractionSession.ActivityId, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.DirectAction>>);
    method public void setContentView(android.view.View);
    method public void setDisabledShowContext(int);
    method public void setKeepAwake(boolean);
+16 −9
Original line number Diff line number Diff line
@@ -2340,12 +2340,20 @@ public class Activity extends ContextThemeWrapper
     * <p>This method will be called only after {@link #onStart()} is being called and
     * before {@link #onStop()} is being called.
     *
     * @return The currently supported direct actions which cannot be <code>null</code>
     * or contain <code>null</null> elements.
     * <p>You should pass to the callback the currently supported direct actions which
     * cannot be <code>null</code> or contain <code>null</null> elements.
     *
     * <p>You should return the action list as soon as possible to ensure the consumer,
     * for example the assistant, is as responsive as possible which would improve user
     * experience of your app.
     *
     * @param cancellationSignal A signal to cancel the operation in progress.
     * @param callback The callback to send the action list. The actions list cannot
     *     contain <code>null</code> elements.
     */
    @NonNull
    public List<DirectAction> onGetDirectActions() {
        return Collections.emptyList();
    public void onGetDirectActions(@NonNull CancellationSignal cancellationSignal,
            @NonNull Consumer<List<DirectAction>> callback) {
        callback.accept(Collections.emptyList());
    }

    /**
@@ -2354,14 +2362,13 @@ public class Activity extends ContextThemeWrapper
     *
     * @param actionId The ID for the action
     * @param arguments Any additional arguments provided by the caller
     * @param cancellationSignal A signal to cancel the operation in progress, or {@code null}
     *                          if none.
     * @param cancellationSignal A signal to cancel the operation in progress.
     * @param resultListener The callback to provide the result back to the caller
     *
     * @see #onGetDirectActions()
     * @see #onGetDirectActions(CancellationSignal, Consumer)
     */
    public void onPerformDirectAction(@NonNull String actionId,
            @Nullable Bundle arguments, @Nullable CancellationSignal cancellationSignal,
            @NonNull Bundle arguments, @NonNull CancellationSignal cancellationSignal,
            @NonNull Consumer<Bundle> resultListener) { }

    /**
+94 −37
Original line number Diff line number Diff line
@@ -392,6 +392,10 @@ public final class ActivityThread extends ClientTransactionHandler {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final ResourcesManager mResourcesManager;

    // Registry of remote cancellation transports pending a reply with reply handles.
    @GuardedBy("this")
    private @Nullable Map<SafeCancellationTransport, CancellationSignal> mRemoteCancellations;

    private static final class ProviderKey {
        final String authority;
        final int userId;
@@ -1657,32 +1661,85 @@ public final class ActivityThread extends ClientTransactionHandler {

        @Override
        public void requestDirectActions(@NonNull IBinder activityToken,
                @NonNull IVoiceInteractor interactor, @NonNull RemoteCallback callback) {
                @NonNull IVoiceInteractor interactor, @Nullable RemoteCallback cancellationCallback,
                @NonNull RemoteCallback callback) {
            final CancellationSignal cancellationSignal = new CancellationSignal();
            if (cancellationCallback != null) {
                final ICancellationSignal transport = createSafeCancellationTransport(
                        cancellationSignal);
                final Bundle cancellationResult = new Bundle();
                cancellationResult.putBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL,
                        transport.asBinder());
                cancellationCallback.sendResult(cancellationResult);
            }
            mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
                    ActivityThread.this, activityToken, interactor, callback));
                    ActivityThread.this, activityToken, interactor, cancellationSignal, callback));
        }

        @Override
        public void performDirectAction(IBinder activityToken, String actionId, Bundle arguments,
                RemoteCallback cancellationCallback, RemoteCallback resultCallback) {
            final CancellationSignal cancellationSignal;
        public void performDirectAction(@NonNull IBinder activityToken, @NonNull String actionId,
                @Nullable Bundle arguments, @Nullable RemoteCallback cancellationCallback,
                @NonNull RemoteCallback resultCallback) {
            final CancellationSignal cancellationSignal = new CancellationSignal();
            if (cancellationCallback != null) {
                final ICancellationSignal transport = CancellationSignal.createTransport();
                cancellationSignal = CancellationSignal.fromTransport(transport);
                final ICancellationSignal transport = createSafeCancellationTransport(
                        cancellationSignal);
                final Bundle cancellationResult = new Bundle();
                cancellationResult.putBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL,
                        transport.asBinder());
                cancellationCallback.sendResult(cancellationResult);
            } else {
                cancellationSignal = new CancellationSignal();
            }

            mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handlePerformDirectAction,
                    ActivityThread.this, activityToken, actionId, arguments,
                    cancellationSignal, resultCallback));
        }
    }

    private @NonNull SafeCancellationTransport createSafeCancellationTransport(
            @NonNull CancellationSignal cancellationSignal) {
        synchronized (ActivityThread.this) {
            if (mRemoteCancellations == null) {
                mRemoteCancellations = new ArrayMap<>();
            }
            final SafeCancellationTransport transport = new SafeCancellationTransport(
                    this, cancellationSignal);
            mRemoteCancellations.put(transport, cancellationSignal);
            return transport;
        }
    }

    private @NonNull CancellationSignal removeSafeCancellationTransport(
            @NonNull SafeCancellationTransport transport) {
        synchronized (ActivityThread.this) {
            final CancellationSignal cancellation = mRemoteCancellations.remove(transport);
            if (mRemoteCancellations.isEmpty()) {
                mRemoteCancellations = null;
            }
            return cancellation;
        }
    }

    private static final class SafeCancellationTransport extends ICancellationSignal.Stub {
        private final @NonNull WeakReference<ActivityThread> mWeakActivityThread;

        SafeCancellationTransport(@NonNull ActivityThread activityThread,
                @NonNull CancellationSignal cancellation) {
            mWeakActivityThread = new WeakReference<>(activityThread);
        }

        @Override
        public void cancel() {
            final ActivityThread activityThread = mWeakActivityThread.get();
            if (activityThread != null) {
                final CancellationSignal cancellation = activityThread
                        .removeSafeCancellationTransport(this);
                if (cancellation != null) {
                    cancellation.cancel();
                }
            }
        }
    }

    class H extends Handler {
        public static final int BIND_APPLICATION        = 110;
        @UnsupportedAppUsage
@@ -3491,9 +3548,13 @@ public final class ActivityThread extends ClientTransactionHandler {

    /** Fetches the user actions for the corresponding activity */
    private void handleRequestDirectActions(@NonNull IBinder activityToken,
            @NonNull IVoiceInteractor interactor, @NonNull RemoteCallback callback) {
            @NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal,
            @NonNull RemoteCallback callback) {
        final ActivityClientRecord r = mActivities.get(activityToken);
        if (r != null) {
        if (r == null) {
            callback.sendResult(null);
            return;
        }
        final int lifecycleState = r.getLifecycleState();
        if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
            callback.sendResult(null);
@@ -3508,10 +3569,10 @@ public final class ActivityThread extends ClientTransactionHandler {
            r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity,
                    r.activity, Looper.myLooper());
        }
            final List<DirectAction> actions = r.activity.onGetDirectActions();
        r.activity.onGetDirectActions(cancellationSignal, (actions) -> {
            Preconditions.checkNotNull(actions);
            Preconditions.checkCollectionElementsNotNull(actions, "actions");
            if (actions != null && !actions.isEmpty()) {
            if (!actions.isEmpty()) {
                final int actionCount = actions.size();
                for (int i = 0; i < actionCount; i++) {
                    final DirectAction action = actions.get(i);
@@ -3521,10 +3582,11 @@ public final class ActivityThread extends ClientTransactionHandler {
                result.putParcelable(DirectAction.KEY_ACTIONS_LIST,
                        new ParceledListSlice<>(actions));
                callback.sendResult(result);
            }
        }
            } else {
                callback.sendResult(null);
            }
        });
    }

    /** Performs an actions in the corresponding activity */
    private void handlePerformDirectAction(@NonNull IBinder activityToken,
@@ -3539,17 +3601,12 @@ public final class ActivityThread extends ClientTransactionHandler {
                return;
            }
            final Bundle nonNullArguments = (arguments != null) ? arguments : Bundle.EMPTY;
            final WeakReference<RemoteCallback> weakCallback = new WeakReference<>(resultCallback);
            r.activity.onPerformDirectAction(actionId, nonNullArguments, cancellationSignal,
                    (b) -> {
                final RemoteCallback strongCallback = weakCallback.get();
                if (strongCallback != null) {
                    strongCallback.sendResult(b);
                }
            });
        }
                    resultCallback::sendResult);
        } else {
            resultCallback.sendResult(null);
        }
    }

    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
        ActivityClientRecord r = mActivities.get(token);
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ oneway interface IApplicationThread {
    void setNetworkBlockSeq(long procStateSeq);
    void scheduleTransaction(in ClientTransaction transaction);
    void requestDirectActions(IBinder activityToken, IVoiceInteractor intractor,
        in RemoteCallback callback);
            in RemoteCallback cancellationCallback, in RemoteCallback callback);
    void performDirectAction(IBinder activityToken, String actionId,
            in Bundle arguments, in RemoteCallback cancellationCallback,
            in RemoteCallback resultCallback);
+96 −45
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

@@ -171,6 +172,9 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
    final WeakReference<VoiceInteractionSession> mWeakRef
            = new WeakReference<VoiceInteractionSession>(this);

    // Registry of remote callbacks pending a reply with reply handles.
    final Map<SafeResultListener, Consumer<Bundle>> mRemoteCallbacks = new ArrayMap<>();

    ICancellationSignal mKillCallback;

    final IVoiceInteractor mInteractor = new IVoiceInteractor.Stub() {
@@ -1105,6 +1109,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
            } catch (RemoteException e) {
                /* ignore */
            }
            mKillCallback = null;
        }
        if (mInitialized) {
            mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
@@ -1314,8 +1319,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
        }
    }



    /**
     * <p>Ask that a new assistant activity be started.  This will create a new task in the
     * in activity manager: this means that
@@ -1349,19 +1352,57 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
     *
     * @param activityId Ths activity id of the app to get the actions from.
     * @param resultExecutor The handler to receive the callback
     * @param cancellationSignal A signal to cancel the operation in progress,
     *     or {@code null} if none.
     * @param callback The callback to receive the response
     */
    public final void requestDirectActions(@NonNull ActivityId activityId,
            @Nullable CancellationSignal cancellationSignal,
            @NonNull @CallbackExecutor Executor resultExecutor,
            @NonNull Consumer<List<DirectAction>> callback) {
        Preconditions.checkNotNull(activityId);
        Preconditions.checkNotNull(resultExecutor);
        Preconditions.checkNotNull(callback);
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }

        if (cancellationSignal != null) {
            cancellationSignal.throwIfCanceled();
        }

        final RemoteCallback cancellationCallback = (cancellationSignal != null)
                ? new RemoteCallback(b -> {
                    if (b != null) {
                        final IBinder cancellation = b.getBinder(
                                VoiceInteractor.KEY_CANCELLATION_SIGNAL);
                        if (cancellation != null) {
                            cancellationSignal.setRemote(ICancellationSignal.Stub.asInterface(
                                    cancellation));
                        }
                    }
                })
                : null;

        try {
            mSystemService.requestDirectActions(mToken, activityId.getTaskId(),
                    activityId.getAssistToken(), new RemoteCallback(new DirectActionsReceiver(
                            Preconditions.checkNotNull(resultExecutor),
                            Preconditions.checkNotNull(callback))));
                    activityId.getAssistToken(), cancellationCallback,
                    new RemoteCallback(createSafeResultListener((result) -> {
                List<DirectAction> list;
                if (result == null) {
                    list = Collections.emptyList();
                } else {
                    final ParceledListSlice<DirectAction> pls = result.getParcelable(
                            DirectAction.KEY_ACTIONS_LIST);
                    if (pls != null) {
                        final List<DirectAction> receivedList = pls.getList();
                        list = (receivedList != null) ? receivedList : Collections.emptyList();
                    } else {
                        list = Collections.emptyList();
                    }
                }
                resultExecutor.execute(() -> callback.accept(list));
            })));
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
@@ -1390,8 +1431,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
     * @param resultExecutor The handler to receive the callback.
     * @param resultListener The callback to receive the response.
     *
     * @see #requestDirectActions(ActivityId, Executor, Consumer)
     * @see Activity#onGetDirectActions()
     * @see #requestDirectActions(ActivityId, CancellationSignal, Executor, Consumer)
     * @see Activity#onGetDirectActions(CancellationSignal, Consumer)
     */
    public final void performDirectAction(@NonNull DirectAction action, @Nullable Bundle extras,
            @Nullable CancellationSignal cancellationSignal,
@@ -1407,26 +1448,31 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
            cancellationSignal.throwIfCanceled();
        }

        final RemoteCallback remoteCallback = new RemoteCallback(b -> {
        final RemoteCallback cancellationCallback = (cancellationSignal != null)
                ? new RemoteCallback(createSafeResultListener(b -> {
                    if (b != null) {
                final IBinder cancellation = b.getBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL);
                        final IBinder cancellation = b.getBinder(
                                VoiceInteractor.KEY_CANCELLATION_SIGNAL);
                        if (cancellation != null) {
                    if (cancellationSignal != null) {
                            cancellationSignal.setRemote(ICancellationSignal.Stub.asInterface(
                                    cancellation));
                        }
                } else {
                    resultExecutor.execute(() -> resultListener.accept(b));
                    }
                }))
                : null;

        final RemoteCallback resultCallback = new RemoteCallback(createSafeResultListener(b -> {
            if (b != null) {
                resultExecutor.execute(() -> resultListener.accept(b));
            } else {
                resultExecutor.execute(() -> resultListener.accept(Bundle.EMPTY));
            }
        });
        }));

        try {
            mSystemService.performDirectAction(mToken, action.getId(), extras,
                    action.getTaskId(), action.getActivityId(), remoteCallback,
                    remoteCallback);
                    action.getTaskId(), action.getActivityId(), cancellationCallback,
                    resultCallback);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
@@ -1901,33 +1947,18 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
        }
    }

    private static class DirectActionsReceiver implements RemoteCallback.OnResultListener {

        @NonNull
        private final Executor mResultExecutor;
        private final Consumer<List<DirectAction>> mCallback;

        DirectActionsReceiver(Executor resultExecutor, Consumer<List<DirectAction>> callback) {
            mResultExecutor = resultExecutor;
            mCallback = callback;
        }

        @Override
        public void onResult(Bundle result) {
            final List<DirectAction> list;
            if (result == null) {
                list = Collections.emptyList();
            } else {
                final ParceledListSlice<DirectAction> pls = result.getParcelable(
                        DirectAction.KEY_ACTIONS_LIST);
                if (pls != null) {
                    final List<DirectAction> receivedList = pls.getList();
                    list = (receivedList != null) ? receivedList : Collections.emptyList();
                } else {
                    list = Collections.emptyList();
    private SafeResultListener createSafeResultListener(
            @NonNull Consumer<Bundle> consumer) {
        synchronized (this) {
            final SafeResultListener listener = new SafeResultListener(consumer, this);
            mRemoteCallbacks.put(listener, consumer);
            return listener;
        }
    }
            mResultExecutor.execute(() -> mCallback.accept(list));

    private Consumer<Bundle> removeSafeResultListener(@NonNull SafeResultListener listener) {
        synchronized (this) {
            return mRemoteCallbacks.remove(listener);
        }
    }

@@ -2062,4 +2093,24 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
            return result;
        }
    }

    private static class SafeResultListener implements RemoteCallback.OnResultListener {
        private final @NonNull WeakReference<VoiceInteractionSession> mWeakSession;

        SafeResultListener(@NonNull Consumer<Bundle> action,
                @NonNull VoiceInteractionSession session) {
            mWeakSession = new WeakReference<>(session);
        }

        @Override
        public void onResult(Bundle result) {
            final VoiceInteractionSession session = mWeakSession.get();
            if (session != null) {
                final Consumer<Bundle> consumer = session.removeSafeResultListener(this);
                if (consumer != null) {
                    consumer.accept(result);
                }
            }
        }
    }
}
Loading