summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt10
-rw-r--r--core/java/android/service/intelligence/IIntelligenceService.aidl4
-rw-r--r--core/java/android/service/intelligence/IntelligenceService.java19
-rw-r--r--core/java/android/service/intelligence/SnapshotData.aidl19
-rw-r--r--core/java/android/service/intelligence/SnapshotData.java104
-rw-r--r--services/core/java/com/android/server/am/AssistDataRequester.java9
-rw-r--r--services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java83
-rw-r--r--services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java18
-rw-r--r--services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java23
-rw-r--r--services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java41
-rw-r--r--services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java28
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);