summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorFelipe Leme <felipeal@google.com>2018-11-07 01:21:47 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-11-07 01:21:47 +0000
commit15fe040f8726a71e5221e2759960ff4a217c40dc (patch)
treefa14164eca6aa35771f596700ee5fc18e36b1d7b /core/java/android
parentb95e7b7bc210b142b1d64cf16cf8634d768ac236 (diff)
parent7a53408d196d6a288d9a6745d98db697cb2a411f (diff)
Merge "Initial implementation of IntelligenceService.onContentCaptureEvents()"
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java41
-rw-r--r--core/java/android/service/intelligence/IIntelligenceService.aidl8
-rw-r--r--core/java/android/service/intelligence/IntelligenceService.java9
-rw-r--r--core/java/android/view/intelligence/ContentCaptureEvent.aidl19
-rw-r--r--core/java/android/view/intelligence/ContentCaptureEvent.java66
-rw-r--r--core/java/android/view/intelligence/IIntelligenceManager.aidl14
-rw-r--r--core/java/android/view/intelligence/IntelligenceManager.java36
7 files changed, 177 insertions, 16 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 8d54e91b93e4..86ed267eafdb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -120,6 +120,7 @@ import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManager.AutofillClient;
import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
+import android.view.intelligence.ContentCaptureEvent;
import android.view.intelligence.IntelligenceManager;
import android.widget.AdapterView;
import android.widget.Toast;
@@ -1023,6 +1024,31 @@ public class Activity extends ContextThemeWrapper
return mIntelligenceManager;
}
+ private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
+ final IntelligenceManager im = getIntelligenceManager();
+ if (im == null || !im.isContentCaptureEnabled()) {
+ return;
+ }
+ switch (event) {
+ case ContentCaptureEvent.TYPE_ACTIVITY_CREATED:
+ //TODO(b/111276913): decide whether the InteractionSessionId should be
+ // saved / restored in the activity bundle.
+ im.onActivityCreated(mToken, getComponentName());
+ break;
+ case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
+ im.onActivityDestroyed();
+ break;
+ case ContentCaptureEvent.TYPE_ACTIVITY_STARTED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED:
+ im.onActivityLifecycleEvent(event);
+ break;
+ default:
+ Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event);
+ }
+ }
+
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
@@ -1099,11 +1125,7 @@ public class Activity extends ContextThemeWrapper
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
- if (getIntelligenceManager() != null) {
- //TODO(b/111276913): decide whether the screen_obs session id should be saved / restored
- // in the activity bundle.
- mIntelligenceManager.onActivityCreated(mToken, getComponentName());
- }
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
}
/**
@@ -1337,6 +1359,7 @@ public class Activity extends ContextThemeWrapper
if (mAutoFillResetNeeded) {
getAutofillManager().onVisibleForAutofill();
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
}
/**
@@ -1419,6 +1442,7 @@ public class Activity extends ContextThemeWrapper
}
}
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
mCalled = true;
}
@@ -1812,6 +1836,7 @@ public class Activity extends ContextThemeWrapper
mAutoFillIgnoreFirstResumePause = false;
}
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
mCalled = true;
}
@@ -2000,6 +2025,7 @@ public class Activity extends ContextThemeWrapper
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
}
}
@@ -2071,9 +2097,8 @@ public class Activity extends ContextThemeWrapper
getApplication().dispatchActivityDestroyed(this);
- if (getIntelligenceManager() != null) {
- mIntelligenceManager.onActivityDestroyed();
- }
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
+
}
/**
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
index ee93326d2e3c..bacad8b44783 100644
--- a/core/java/android/service/intelligence/IIntelligenceService.aidl
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -19,6 +19,11 @@ package android.service.intelligence;
import android.service.intelligence.InteractionSessionId;
import android.service.intelligence.InteractionContext;
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+
/**
* Interface from the system to an intelligence service.
*
@@ -28,4 +33,7 @@ oneway interface IIntelligenceService {
// Called when session is created (context not null) or destroyed (context null)
void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId);
+
+ void onContentCaptureEvents(in InteractionSessionId sessionId,
+ in List<ContentCaptureEvent> events);
}
diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/IntelligenceService.java
index ce0a88a3faca..a2b60f044657 100644
--- a/core/java/android/service/intelligence/IntelligenceService.java
+++ b/core/java/android/service/intelligence/IntelligenceService.java
@@ -70,6 +70,14 @@ public abstract class IntelligenceService extends Service {
IntelligenceService.this, sessionId));
}
}
+ @Override
+ public void onContentCaptureEvents(InteractionSessionId sessionId,
+ List<ContentCaptureEvent> events) {
+ mHandler.sendMessage(
+ obtainMessage(IntelligenceService::onContentCaptureEvent,
+ IntelligenceService.this, sessionId, events));
+
+ }
};
@CallSuper
@@ -105,6 +113,7 @@ public abstract class IntelligenceService extends Service {
* @param sessionId the session's Id
* @param events the events
*/
+ // TODO(b/111276913): rename to onContentCaptureEvents
public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId,
@NonNull List<ContentCaptureEvent> events);
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.aidl b/core/java/android/view/intelligence/ContentCaptureEvent.aidl
new file mode 100644
index 000000000000..c66a6cb0d486
--- /dev/null
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.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.view.intelligence;
+
+parcelable ContentCaptureEvent;
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
index d6aec344171d..2530ae3b3124 100644
--- a/core/java/android/view/intelligence/ContentCaptureEvent.java
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -30,6 +30,11 @@ import java.lang.annotation.RetentionPolicy;
@SystemApi
public final class ContentCaptureEvent implements Parcelable {
+ /** @hide */
+ public static final int TYPE_ACTIVITY_DESTROYED = -2;
+ /** @hide */
+ public static final int TYPE_ACTIVITY_CREATED = -1;
+
/**
* Called when the activity is started.
*/
@@ -85,10 +90,18 @@ public final class ContentCaptureEvent implements Parcelable {
TYPE_VIEW_TEXT_CHANGED
})
@Retention(RetentionPolicy.SOURCE)
- @interface EventType{}
+ public @interface EventType{}
+
+ private final int mType;
+ private final long mEventTime;
+ private final int mFlags;
+
/** @hide */
- ContentCaptureEvent() {
+ public ContentCaptureEvent(int type, long eventTime, int flags) {
+ mType = type;
+ mEventTime = eventTime;
+ mFlags = flags;
}
/**
@@ -99,14 +112,14 @@ public final class ContentCaptureEvent implements Parcelable {
* {@link #TYPE_VIEW_ADDED}, {@link #TYPE_VIEW_REMOVED}, or {@link #TYPE_VIEW_TEXT_CHANGED}.
*/
public @EventType int getType() {
- return 42;
+ return mType;
}
/**
* Gets when the event was generated, in ms.
*/
public long getEventTime() {
- return 48151623;
+ return mEventTime;
}
/**
@@ -116,7 +129,7 @@ public final class ContentCaptureEvent implements Parcelable {
* {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}.
*/
public int getFlags() {
- return 0;
+ return mFlags;
}
/**
@@ -150,13 +163,25 @@ public final class ContentCaptureEvent implements Parcelable {
}
@Override
+ public String toString() {
+ final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
+ .append(getTypeAsString(mType)).append(", time=").append(mEventTime);
+ if (mFlags > 0) {
+ string.append(", flags=").append(mFlags);
+ }
+ return string.append(']').toString();
+ }
+
+ @Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
- // TODO(b/111276913): implement
+ parcel.writeInt(mType);
+ parcel.writeLong(mEventTime);
+ parcel.writeInt(mFlags);
}
public static final Parcelable.Creator<ContentCaptureEvent> CREATOR =
@@ -164,8 +189,10 @@ public final class ContentCaptureEvent implements Parcelable {
@Override
public ContentCaptureEvent createFromParcel(Parcel parcel) {
- // TODO(b/111276913): implement
- return null;
+ final int type = parcel.readInt();
+ final long eventTime = parcel.readLong();
+ final int flags = parcel.readInt();
+ return new ContentCaptureEvent(type, eventTime, flags);
}
@Override
@@ -173,4 +200,27 @@ public final class ContentCaptureEvent implements Parcelable {
return new ContentCaptureEvent[size];
}
};
+
+
+ /** @hide */
+ public static String getTypeAsString(@EventType int type) {
+ switch (type) {
+ case TYPE_ACTIVITY_STARTED:
+ return "ACTIVITY_STARTED";
+ case TYPE_ACTIVITY_RESUMED:
+ return "ACTIVITY_RESUMED";
+ case TYPE_ACTIVITY_PAUSED:
+ return "ACTIVITY_PAUSED";
+ case TYPE_ACTIVITY_STOPPED:
+ return "ACTIVITY_STOPPED";
+ case TYPE_VIEW_ADDED:
+ return "VIEW_ADDED";
+ case TYPE_VIEW_REMOVED:
+ return "VIEW_REMOVED";
+ case TYPE_VIEW_TEXT_CHANGED:
+ return "VIEW_TEXT_CHANGED";
+ default:
+ return "UKNOWN_TYPE: " + type;
+ }
+ }
}
diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl
index f4901c371614..7bbe99a9ad48 100644
--- a/core/java/android/view/intelligence/IIntelligenceManager.aidl
+++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl
@@ -17,9 +17,15 @@
package android.view.intelligence;
import android.content.ComponentName;
+
import android.os.IBinder;
+
+import android.view.intelligence.ContentCaptureEvent;
+
import com.android.internal.os.IResultReceiver;
+import java.util.List;
+
/**
* {@hide}
*/
@@ -33,6 +39,14 @@ oneway interface IIntelligenceManager {
/**
* Finishes a session.
*/
+ // TODO(b/111276913): pass just (global) session id
void finishSession(int userId, IBinder activityToken, in ComponentName componentName,
int localSessionId, int globalSessionId);
+
+ /**
+ * Sends a batch of events
+ */
+ // TODO(b/111276913): pass just (global) session id
+ void sendEvents(int userId, IBinder activityToken, in ComponentName componentName,
+ int localSessionId, int globalSessionId, in List<ContentCaptureEvent> events);
}
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/IntelligenceManager.java
index b1d06f7fccfd..a30d77e4d446 100644
--- a/core/java/android/view/intelligence/IntelligenceManager.java
+++ b/core/java/android/view/intelligence/IntelligenceManager.java
@@ -24,13 +24,17 @@ import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
+import android.view.intelligence.ContentCaptureEvent.EventType;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.Preconditions;
import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
import java.util.Set;
/**
@@ -161,6 +165,38 @@ public final class IntelligenceManager {
}
}
+ /**
+ * Used for intermediate events (i.e, other than created and destroyed).
+ *
+ * @hide
+ */
+ public void onActivityLifecycleEvent(@EventType int type) {
+ if (!isContentCaptureEnabled()) return;
+
+ //TODO(b/111276913): should buffer event (and call service on handler thread), instead of
+ // calling right away
+ final ContentCaptureEvent event = new ContentCaptureEvent(type, SystemClock.uptimeMillis(),
+ 0);
+ final List<ContentCaptureEvent> events = Arrays.asList(event);
+
+ synchronized (mLock) {
+ //TODO(b/111276913): check session state; for example, how to handle if it's waiting for
+ // remote id
+
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityLifecycleEvent() for " + mComponentName.flattenToShortString()
+ + ": " + ContentCaptureEvent.getTypeAsString(type));
+ }
+
+ try {
+ mService.sendEvents(mContext.getUserId(), mApplicationToken, mComponentName,
+ mLocalSessionId, mRemoteSessionId, events);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
/** @hide */
public void onActivityDestroyed() {
if (!isContentCaptureEnabled()) return;