diff options
12 files changed, 352 insertions, 17 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index ee767af010fa..f013b6df9369 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4935,6 +4935,7 @@ package android.service.intelligence { public abstract class IntelligenceService extends android.app.Service { ctor public IntelligenceService(); + method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData); method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>); method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId); method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId); @@ -4959,6 +4960,15 @@ package android.service.intelligence { field public static final android.os.Parcelable.Creator<android.service.intelligence.InteractionSessionId> CREATOR; } + public final class SnapshotData implements android.os.Parcelable { + method public int describeContents(); + method public android.app.assist.AssistContent getAssistContent(); + method public android.os.Bundle getAssistData(); + method public android.app.assist.AssistStructure getAssistStructure(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.intelligence.SnapshotData> CREATOR; + } + } package android.service.notification { diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl index bacad8b44783..709c3b720579 100644 --- a/core/java/android/service/intelligence/IIntelligenceService.aidl +++ b/core/java/android/service/intelligence/IIntelligenceService.aidl @@ -18,6 +18,7 @@ package android.service.intelligence; import android.service.intelligence.InteractionSessionId; import android.service.intelligence.InteractionContext; +import android.service.intelligence.SnapshotData; import android.view.intelligence.ContentCaptureEvent; @@ -36,4 +37,7 @@ oneway interface IIntelligenceService { void onContentCaptureEvents(in InteractionSessionId sessionId, in List<ContentCaptureEvent> events); + + void onActivitySnapshot(in InteractionSessionId sessionId, + in SnapshotData snapshotData); } diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/IntelligenceService.java index a2b60f044657..27569b6003c5 100644 --- a/core/java/android/service/intelligence/IntelligenceService.java +++ b/core/java/android/service/intelligence/IntelligenceService.java @@ -70,6 +70,7 @@ public abstract class IntelligenceService extends Service { IntelligenceService.this, sessionId)); } } + @Override public void onContentCaptureEvents(InteractionSessionId sessionId, List<ContentCaptureEvent> events) { @@ -78,6 +79,14 @@ public abstract class IntelligenceService extends Service { IntelligenceService.this, sessionId, events)); } + + @Override + public void onActivitySnapshot(InteractionSessionId sessionId, + SnapshotData snapshotData) { + mHandler.sendMessage( + obtainMessage(IntelligenceService::onActivitySnapshot, + IntelligenceService.this, sessionId, snapshotData)); + } }; @CallSuper @@ -118,6 +127,16 @@ public abstract class IntelligenceService extends Service { @NonNull List<ContentCaptureEvent> events); /** + * Notifies the service of {@link IntelligenceSnapshotData snapshot data} associated with a + * session. + * + * @param sessionId the session's Id + * @param snapshotData the data + */ + public void onActivitySnapshot(@NonNull InteractionSessionId sessionId, + @NonNull SnapshotData snapshotData) {} + + /** * Destroys the interaction session. * * @param sessionId the id of the session to destroy diff --git a/core/java/android/service/intelligence/SnapshotData.aidl b/core/java/android/service/intelligence/SnapshotData.aidl new file mode 100644 index 000000000000..31d13390d2b8 --- /dev/null +++ b/core/java/android/service/intelligence/SnapshotData.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.intelligence; + +parcelable SnapshotData; diff --git a/core/java/android/service/intelligence/SnapshotData.java b/core/java/android/service/intelligence/SnapshotData.java new file mode 100644 index 000000000000..b9310eae6cb5 --- /dev/null +++ b/core/java/android/service/intelligence/SnapshotData.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.intelligence; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A container class for data taken from a snapshot of an activity. + * + * @hide + */ +@SystemApi +public final class SnapshotData implements Parcelable { + + private final @NonNull Bundle mAssistData; + private final @NonNull AssistStructure mAssistStructure; + private final @Nullable AssistContent mAssistContent; + + /** + * Creates a new instance. + * + * @hide + */ + public SnapshotData(@NonNull Bundle assistData, @NonNull AssistStructure assistStructure, + @Nullable AssistContent assistContent) { + mAssistData = assistData; + mAssistStructure = assistStructure; + mAssistContent = assistContent; + } + + SnapshotData(@NonNull Parcel parcel) { + mAssistData = parcel.readBundle(); + mAssistStructure = parcel.readParcelable(null); + mAssistContent = parcel.readParcelable(null); + } + + /** + * Returns the assist data for this snapshot. + */ + public Bundle getAssistData() { + return mAssistData; + } + + /** + * Returns the assist structure for this snapshot. + */ + public AssistStructure getAssistStructure() { + return mAssistStructure; + } + + /** + * Returns the assist context for this snapshot. + */ + public AssistContent getAssistContent() { + return mAssistContent; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel parcel, int flags) { + parcel.writeBundle(mAssistData); + parcel.writeParcelable(mAssistStructure, flags); + parcel.writeParcelable(mAssistContent, flags); + } + + public static final Creator<SnapshotData> CREATOR = + new Creator<SnapshotData>() { + + @Override + public SnapshotData createFromParcel(@NonNull Parcel parcel) { + return new SnapshotData(parcel); + } + + @Override + public SnapshotData[] newArray(int size) { + return new SnapshotData[size]; + } + }; +} diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java index 395b0da15f45..330c91704364 100644 --- a/services/core/java/com/android/server/am/AssistDataRequester.java +++ b/services/core/java/com/android/server/am/AssistDataRequester.java @@ -19,6 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.ASSIST_CONTEXT_FULL; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_NONE; + import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; import android.app.ActivityTaskManager; @@ -82,7 +83,9 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { * is true. */ @GuardedBy("mCallbacksLock") - void onAssistDataReceivedLocked(Bundle data, int activityIndex, int activityCount); + default void onAssistDataReceivedLocked(Bundle data, int activityIndex, int activityCount) { + // Do nothing + } /** * Called when we receive asynchronous assist screenshot. This call is only made if @@ -92,7 +95,9 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { * {@link #canHandleReceivedAssistDataLocked()} is true. */ @GuardedBy("mCallbacksLock") - void onAssistScreenshotReceivedLocked(Bitmap screenshot); + default void onAssistScreenshotReceivedLocked(Bitmap screenshot) { + // Do nothing + } /** * Called when there is no more pending assist data or screenshots for the last request. diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java index 0ed56ff4ca13..aac83b62b0a5 100644 --- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java +++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java @@ -15,7 +15,10 @@ */ package com.android.server.intelligence; +import android.annotation.NonNull; import android.annotation.UserIdInt; +import android.os.Bundle; +import android.os.IBinder; /** * Intelligence Manager local system service interface. @@ -30,4 +33,12 @@ public abstract class IntelligenceManagerInternal { * given {@code userId}. */ public abstract boolean isIntelligenceServiceForUser(int uid, @UserIdInt int userId); + + /** + * Notifies the intelligence service of new assist data for the given activity. + * + * @return {@code false} if there was no service set for the given user + */ + public abstract boolean sendActivityAssistData(@UserIdInt int userId, + @NonNull IBinder activityToken, @NonNull Bundle data); } diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 067b01a1b6ad..e549d285deee 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -26,6 +26,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.WindowManager.TRANSIT_NONE; + import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; @@ -37,14 +38,20 @@ import android.app.IAssistDataReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; import android.util.Slog; import android.view.IRecentsAnimationRunner; +import com.android.server.LocalServices; import com.android.server.am.AssistDataRequester; +import com.android.server.intelligence.IntelligenceManagerInternal; import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks; +import java.util.List; + /** * Manages the recents animation, including the reordering of the stacks for the transition and * cleanup. See {@link com.android.server.wm.RecentsAnimationController}. @@ -80,7 +87,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner, ComponentName recentsComponent, int recentsUid, - IAssistDataReceiver assistDataReceiver) { + @Deprecated IAssistDataReceiver assistDataReceiver) { if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent + " assistDataReceiver=" + assistDataReceiver); Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity"); @@ -127,19 +134,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mWindowManager.deferSurfaceLayout(); try { + final int userId = mService.getCurrentUserId(); + // Kick off the assist data request in the background before showing the target activity - if (assistDataReceiver != null) { - final AppOpsManager appOpsManager = (AppOpsManager) - mService.mContext.getSystemService(Context.APP_OPS_SERVICE); - final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy( - assistDataReceiver, recentsComponent.getPackageName()); - mAssistDataRequester = new AssistDataRequester(mService.mContext, - mWindowManager, appOpsManager, proxy, this, OP_ASSIST_STRUCTURE, OP_NONE); - mAssistDataRequester.requestAssistData(mStackSupervisor.getTopVisibleActivities(), - true /* fetchData */, false /* fetchScreenshots */, - true /* allowFetchData */, false /* allowFetchScreenshots */, - recentsUid, recentsComponent.getPackageName()); - } + requestAssistData(recentsComponent, recentsUid, assistDataReceiver, userId); if (hasExistingActivity) { // Move the recents activity into place for the animation if it is not top most @@ -166,7 +164,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, .setCallingUid(recentsUid) .setCallingPackage(recentsComponent.getPackageName()) .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle())) - .setMayWait(mService.getCurrentUserId()) + .setMayWait(userId) .execute(); mWindowManager.prepareAppTransition(TRANSIT_NONE, false); mWindowManager.executeAppTransition(); @@ -210,6 +208,63 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } } + /** + * Requests assist data for the top visible activities. + */ + private void requestAssistData(ComponentName recentsComponent, int recentsUid, + @Deprecated IAssistDataReceiver assistDataReceiver, int userId) { + final AppOpsManager appOpsManager = (AppOpsManager) + mService.mContext.getSystemService(Context.APP_OPS_SERVICE); + final List<IBinder> topActivities = mStackSupervisor.getTopVisibleActivities(); + final AssistDataRequester.AssistDataRequesterCallbacks assistDataCallbacks; + if (assistDataReceiver != null) { + assistDataCallbacks = new AssistDataReceiverProxy(assistDataReceiver, + recentsComponent.getPackageName()) { + @Override + public void onAssistDataReceivedLocked(Bundle data, int activityIndex, + int activityCount) { + // Try to notify the intelligence service first + final IntelligenceManagerInternal imService = + LocalServices.getService(IntelligenceManagerInternal.class); + final IBinder activityToken = topActivities.get(activityIndex); + if (imService == null + || !imService.sendActivityAssistData(userId, activityToken, data)) { + // Otherwise, use the provided assist data receiver + super.onAssistDataReceivedLocked(data, activityIndex, activityCount); + } + } + }; + } else { + final IntelligenceManagerInternal imService = + LocalServices.getService(IntelligenceManagerInternal.class); + if (imService == null) { + // There is no intelligence service, so there is no point requesting assist data + return; + } + + assistDataCallbacks = new AssistDataRequester.AssistDataRequesterCallbacks() { + @Override + public boolean canHandleReceivedAssistDataLocked() { + return true; + } + + @Override + public void onAssistDataReceivedLocked(Bundle data, int activityIndex, + int activityCount) { + // Try to notify the intelligence service + final IBinder activityToken = topActivities.get(activityIndex); + imService.sendActivityAssistData(userId, activityToken, data); + } + }; + } + mAssistDataRequester = new AssistDataRequester(mService.mContext, mWindowManager, + appOpsManager, assistDataCallbacks, this, OP_ASSIST_STRUCTURE, OP_NONE); + mAssistDataRequester.requestAssistData(topActivities, + true /* fetchData */, false /* fetchScreenshots */, + true /* allowFetchData */, false /* allowFetchScreenshots */, + recentsUid, recentsComponent.getPackageName()); + } + private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { synchronized (mService.mGlobalLock) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java index b7d34d7a8025..57e954f10fa7 100644 --- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java +++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java @@ -22,6 +22,7 @@ import android.os.IBinder; import android.service.intelligence.IntelligenceService; import android.service.intelligence.InteractionContext; import android.service.intelligence.InteractionSessionId; +import android.service.intelligence.SnapshotData; import android.util.Slog; import android.view.intelligence.ContentCaptureEvent; @@ -61,6 +62,13 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks } /** + * Returns whether this session is for the given activity. + */ + boolean isActivitySession(@NonNull IBinder activityToken) { + return mActivityToken.equals(activityToken); + } + + /** * Notifies the {@link IntelligenceService} that the service started. */ @GuardedBy("mLock") @@ -71,11 +79,19 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks /** * Notifies the {@link IntelligenceService} of a batch of events. */ - public void sendEventsLocked(List<ContentCaptureEvent> events) { + public void sendEventsLocked(@NonNull List<ContentCaptureEvent> events) { mRemoteService.onContentCaptureEventsRequest(mId, events); } /** + * Notifies the {@link IntelligenceService} of a snapshot of an activity. + */ + @GuardedBy("mLock") + public void sendActivitySnapshotLocked(@NonNull SnapshotData snapshotData) { + mRemoteService.onActivitySnapshotRequest(mId, snapshotData); + } + + /** * Cleans up the session and removes it from the service. * * @param notifyRemoteService whether it should trigger a {@link diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java index 3d1357074ae4..a7f45ee4c9bf 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java @@ -23,6 +23,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.content.ComponentName; import android.content.Context; +import android.os.Bundle; import android.os.IBinder; import android.os.UserManager; import android.service.intelligence.InteractionSessionId; @@ -85,6 +86,20 @@ public final class IntelligenceManagerService extends service.destroyLocked(); } + /** + * Notifies the intelligence service of new assist data for the given activity. + * + * @return {@code false} if there was no service set for the given user + */ + private boolean sendActivityAssistDataLocked(@UserIdInt int userId, + @NonNull IBinder activityToken, @NonNull Bundle data) { + final IntelligencePerUserService service = peekServiceForUserLocked(userId); + if (service != null) { + return service.sendActivityAssistDataLocked(activityToken, data); + } + return false; + } + private ActivityManagerInternal getAmInternal() { synchronized (mLock) { if (mAm == null) { @@ -163,5 +178,13 @@ public final class IntelligenceManagerService extends return false; } + + @Override + public boolean sendActivityAssistData(@UserIdInt int userId, @NonNull IBinder activityToken, + @NonNull Bundle data) { + synchronized (mLock) { + return sendActivityAssistDataLocked(userId, activityToken, data); + } + } } } diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java index 3b9c4e250878..9694ab968e71 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java @@ -16,16 +16,24 @@ package com.android.server.intelligence; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; + import android.Manifest; import android.annotation.NonNull; import android.app.AppGlobals; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.service.intelligence.InteractionSessionId; +import android.service.intelligence.SnapshotData; import android.util.ArrayMap; import android.util.Slog; import android.view.intelligence.ContentCaptureEvent; @@ -174,6 +182,25 @@ final class IntelligencePerUserService } @GuardedBy("mLock") + public boolean sendActivityAssistDataLocked(@NonNull IBinder activityToken, + @NonNull Bundle data) { + final InteractionSessionId id = getInteractionSessionId(activityToken); + if (id != null) { + final ContentCaptureSession session = mSessions.get(id); + final Bundle assistData = data.getBundle(ASSIST_KEY_DATA); + final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE); + final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT); + final SnapshotData snapshotData = new SnapshotData(assistData, + assistStructure, assistContent); + session.sendActivitySnapshotLocked(snapshotData); + return true; + } else { + Slog.e(TAG, "Failed to notify activity assist data for activity: " + activityToken); + } + return false; + } + + @GuardedBy("mLock") public void removeSessionLocked(@NonNull InteractionSessionId sessionId) { mSessions.remove(sessionId); } @@ -216,6 +243,20 @@ final class IntelligencePerUserService } } + /** + * Returns the InteractionSessionId associated with the given activity. + */ + @GuardedBy("mLock") + private InteractionSessionId getInteractionSessionId(@NonNull IBinder activityToken) { + for (int i = 0; i < mSessions.size(); i++) { + ContentCaptureSession session = mSessions.valueAt(i); + if (session.isActivitySession(activityToken)) { + return mSessions.keyAt(i); + } + } + return null; + } + private static void sendToClient(@NonNull IResultReceiver resultReceiver, int value) { try { resultReceiver.send(value, null); diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java index 9d241fbf820d..a27c1cf98a9a 100644 --- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java +++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java @@ -25,6 +25,7 @@ import android.os.RemoteException; import android.service.intelligence.IIntelligenceService; import android.service.intelligence.InteractionContext; import android.service.intelligence.InteractionSessionId; +import android.service.intelligence.SnapshotData; import android.text.format.DateUtils; import android.util.Slog; import android.view.intelligence.ContentCaptureEvent; @@ -91,6 +92,15 @@ final class RemoteIntelligenceService extends AbstractRemoteService { scheduleRequest(new PendingOnContentCaptureEventsRequest(this, sessionId, events)); } + /** + * Called by {@link ContentCaptureSession} to send snapshot data to the service. + */ + public void onActivitySnapshotRequest(@NonNull InteractionSessionId sessionId, + @NonNull SnapshotData snapshotData) { + cancelScheduledUnbind(); + scheduleRequest(new PendingOnActivitySnapshotRequest(this, sessionId, snapshotData)); + } + private abstract static class MyPendingRequest extends PendingRequest<RemoteIntelligenceService> { @@ -163,6 +173,24 @@ final class RemoteIntelligenceService extends AbstractRemoteService { } } + private static final class PendingOnActivitySnapshotRequest extends MyPendingRequest { + + private final SnapshotData mSnapshotData; + + protected PendingOnActivitySnapshotRequest(@NonNull RemoteIntelligenceService service, + @NonNull InteractionSessionId sessionId, + @NonNull SnapshotData snapshotData) { + super(service, sessionId); + mSnapshotData = snapshotData; + } + + @Override // from MyPendingRequest + protected void myRun(@NonNull RemoteIntelligenceService remoteService) + throws RemoteException { + remoteService.mService.onActivitySnapshot(mSessionId, mSnapshotData); + } + } + public interface RemoteIntelligenceServiceCallbacks extends VultureCallback { // To keep it simple, we use the same callback for all failures / timeouts. void onFailureOrTimeout(boolean timedOut); |