summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Svet Ganov <svetoslavganov@google.com> 2019-04-28 10:21:01 -0700
committer Svet Ganov <svetoslavganov@google.com> 2019-04-28 23:01:30 -0700
commit3b6be08c3d42c3fedeb9dbb4c7b079c04445c880 (patch)
tree2a5d7cbe503b726e806170cb8f1979525d779e25
parent8eccead1be0aec61ea83b32ec180b72a286e1ae7 (diff)
Address API council feedback
Make the get actions API async. Also fix a potenrial memory leak when exchaning callbacks. Test: atest CtsVoiceInteractionTestCases bug:129705716 Change-Id: I91f1beb3dc7a395c6c6307ca4601fe7b7097f6e3
-rw-r--r--api/current.txt6
-rw-r--r--core/java/android/app/Activity.java25
-rw-r--r--core/java/android/app/ActivityThread.java131
-rw-r--r--core/java/android/app/IApplicationThread.aidl2
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java141
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl2
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java4
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java10
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java5
9 files changed, 222 insertions, 104 deletions
diff --git a/api/current.txt b/api/current.txt
index 13ebbb0daf25..1700603aaca5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -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);
@@ -41836,7 +41836,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);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9ae0aa0e2978..43531eddf638 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -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) { }
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 134ab1043904..4b37461866d0 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -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,27 +3548,31 @@ 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) {
- final int lifecycleState = r.getLifecycleState();
- if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
- callback.sendResult(null);
- return;
- }
- if (r.activity.mVoiceInteractor == null
- || r.activity.mVoiceInteractor.mInteractor.asBinder()
- != interactor.asBinder()) {
- if (r.activity.mVoiceInteractor != null) {
- r.activity.mVoiceInteractor.destroy();
- }
- r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity,
- r.activity, Looper.myLooper());
+ if (r == null) {
+ callback.sendResult(null);
+ return;
+ }
+ final int lifecycleState = r.getLifecycleState();
+ if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
+ callback.sendResult(null);
+ return;
+ }
+ if (r.activity.mVoiceInteractor == null
+ || r.activity.mVoiceInteractor.mInteractor.asBinder()
+ != interactor.asBinder()) {
+ if (r.activity.mVoiceInteractor != null) {
+ r.activity.mVoiceInteractor.destroy();
}
- final List<DirectAction> actions = r.activity.onGetDirectActions();
+ r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity,
+ r.activity, Looper.myLooper());
+ }
+ 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,9 +3582,10 @@ public final class ActivityThread extends ClientTransactionHandler {
result.putParcelable(DirectAction.KEY_ACTIONS_LIST,
new ParceledListSlice<>(actions));
callback.sendResult(result);
+ } else {
+ callback.sendResult(null);
}
- }
- callback.sendResult(null);
+ });
}
/** Performs an actions in the corresponding activity */
@@ -3539,16 +3601,11 @@ 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);
}
- resultCallback.sendResult(null);
}
public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index ac55c53d2257..66c438393bd6 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -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);
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 81b84e1f7070..cd8c7aea1bab 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -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 -> {
- if (b != null) {
- final IBinder cancellation = b.getBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL);
- if (cancellation != null) {
- if (cancellationSignal != null) {
- cancellationSignal.setRemote(ICancellationSignal.Stub.asInterface(
- cancellation));
+ final RemoteCallback cancellationCallback = (cancellationSignal != null)
+ ? new RemoteCallback(createSafeResultListener(b -> {
+ if (b != null) {
+ final IBinder cancellation = b.getBinder(
+ VoiceInteractor.KEY_CANCELLATION_SIGNAL);
+ if (cancellation != 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;
+ private SafeResultListener createSafeResultListener(
+ @NonNull Consumer<Bundle> consumer) {
+ synchronized (this) {
+ final SafeResultListener listener = new SafeResultListener(consumer, this);
+ mRemoteCallbacks.put(listener, consumer);
+ return listener;
}
+ }
- @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();
- }
- }
- 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);
+ }
+ }
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index fb5e006d4873..f462f5d2571d 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -163,7 +163,7 @@ interface IVoiceInteractionManagerService {
* Requests a list of supported actions from a specific activity.
*/
void requestDirectActions(in IBinder token, int taskId, IBinder assistToken,
- in RemoteCallback callback);
+ in RemoteCallback cancellationCallback, in RemoteCallback callback);
/**
* Requests performing an action from a specific activity.
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 1b63b7e702bd..36ed88fbe8d5 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -628,8 +628,8 @@ public class TransactionParcelTests {
}
@Override
- public void requestDirectActions(IBinder activityToken, IVoiceInteractor intractor,
- RemoteCallback callback) {
+ public void requestDirectActions(IBinder activityToken, IVoiceInteractor interactor,
+ RemoteCallback cancellationCallback, RemoteCallback resultCallback) {
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 5903005e39b0..e1ffb0f179f8 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -714,17 +714,19 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
- public void requestDirectActions(@NonNull IBinder token, int taskId, IBinder assistToken,
- @NonNull RemoteCallback callback) {
+ public void requestDirectActions(@NonNull IBinder token, int taskId,
+ @NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback,
+ @NonNull RemoteCallback resultCallback) {
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "requestDirectActions without running voice interaction service");
- callback.sendResult(null);
+ resultCallback.sendResult(null);
return;
}
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.requestDirectActionsLocked(token, taskId, assistToken, callback);
+ mImpl.requestDirectActionsLocked(token, taskId, assistToken,
+ cancellationCallback, resultCallback);
} 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 0d80e6060301..2a5b70bf77f2 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -263,7 +263,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
public void requestDirectActionsLocked(@NonNull IBinder token, int taskId,
- IBinder assistToken, @NonNull RemoteCallback callback) {
+ @NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback,
+ @NonNull RemoteCallback callback) {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "requestDirectActionsLocked does not match active session");
callback.sendResult(null);
@@ -277,7 +278,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
} else {
try {
tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
- mActiveSession.mInteractor, callback);
+ mActiveSession.mInteractor, cancellationCallback, callback);
} catch (RemoteException e) {
Slog.w("Unexpected remote error", e);
callback.sendResult(null);