summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Felipe Leme <felipeal@google.com> 2018-12-10 12:13:31 -0800
committer Felipe Leme <felipeal@google.com> 2018-12-12 13:36:49 -0800
commit4017b209f8eb5f5ff42870658a827d45e6c0866d (patch)
tree720a81afa656bee2fa6cc207306bf4c755726b60
parent7b6e54c3e3a86b74d42111228df21b7aa8fa8edf (diff)
Improved ContentCapture capture by flushing its buffer after some time idle.
Right now the value is hardcoded to 5s, but it will be dynamically configurable. Bug: 119220549 Test: manual verification Test: atest CtsContentCaptureServiceTestCases Change-Id: I230dee32d215d099a323499e55b4347e817907a0
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java63
1 files changed, 60 insertions, 3 deletions
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 1889692ea831..cc0264ac0bc9 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -31,7 +31,9 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
+import android.util.TimeUtils;
import android.view.View;
import android.view.ViewStructure;
import android.view.autofill.AutofillId;
@@ -98,6 +100,12 @@ public final class ContentCaptureManager {
*/
public static final int STATE_DISABLED = 3;
+ /**
+ * Handler message used to flush the buffer.
+ */
+ private static final int MSG_FLUSH = 1;
+
+
private static final String BG_THREAD_NAME = "intel_svc_streamer_thread";
/**
@@ -106,6 +114,12 @@ public final class ContentCaptureManager {
// TODO(b/111276913): use settings
private static final int MAX_BUFFER_SIZE = 100;
+ /**
+ * Frequency the buffer is flushed if stale.
+ */
+ // TODO(b/111276913): use settings
+ private static final int FLUSHING_FREQUENCY_MS = 5_000;
+
@NonNull
private final AtomicBoolean mDisabled = new AtomicBoolean();
@@ -136,6 +150,9 @@ public final class ContentCaptureManager {
// held at the Application level
private final Handler mHandler;
+ // Used just for debugging purposes (on dump)
+ private long mNextFlush;
+
/** @hide */
public ContentCaptureManager(@NonNull Context context,
@Nullable IContentCaptureManager service) {
@@ -207,9 +224,17 @@ public final class ContentCaptureManager {
mEvents = new ArrayList<>(MAX_BUFFER_SIZE);
}
mEvents.add(event);
+
final int numberEvents = mEvents.size();
- if (numberEvents < MAX_BUFFER_SIZE && !forceFlush) {
- // Buffering events, return right away...
+
+ // TODO(b/120784831): need to optimize it so we buffer changes until a number of X are
+ // buffered (either total or per autofillid). For
+ // example, if the user typed "a", "b", "c" and the threshold is 3, we should buffer
+ // "a" and "b" then send "abc".
+ final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE;
+
+ if (bufferEvent && !forceFlush) {
+ handleScheduleFlush();
return;
}
@@ -236,10 +261,38 @@ public final class ContentCaptureManager {
return;
}
+ handleForceFlush();
+ }
+
+ private void handleScheduleFlush() {
+ if (mHandler.hasMessages(MSG_FLUSH)) {
+ // "Renew" the flush message by removing the previous one
+ mHandler.removeMessages(MSG_FLUSH);
+ }
+ mNextFlush = SystemClock.elapsedRealtime() + FLUSHING_FREQUENCY_MS;
+ if (VERBOSE) {
+ Log.v(TAG, "Scheduled to flush in " + FLUSHING_FREQUENCY_MS + "ms: " + mNextFlush);
+ }
+ mHandler.sendMessageDelayed(
+ obtainMessage(ContentCaptureManager::handleFlushIfNeeded, this).setWhat(MSG_FLUSH),
+ FLUSHING_FREQUENCY_MS);
+ }
+
+ private void handleFlushIfNeeded() {
+ if (mEvents.isEmpty()) {
+ if (VERBOSE) Log.v(TAG, "Nothing to flush");
+ return;
+ }
+ handleForceFlush();
+ }
+
+ private void handleForceFlush() {
+ final int numberEvents = mEvents.size();
try {
if (DEBUG) {
Log.d(TAG, "Flushing " + numberEvents + " event(s) for " + getActivityDebugName());
}
+ mHandler.removeMessages(MSG_FLUSH);
mService.sendEvents(mContext.getUserId(), mId, mEvents);
// TODO(b/111276913): decide whether we should clear or set it to null, as each has
// its own advantages: clearing will save extra allocations while the session is
@@ -307,6 +360,7 @@ public final class ContentCaptureManager {
mApplicationToken = null;
mComponentName = null;
mEvents = null;
+ mHandler.removeMessages(MSG_FLUSH);
}
/**
@@ -443,7 +497,7 @@ public final class ContentCaptureManager {
pw.print(prefix2); pw.print("component name: ");
pw.println(mComponentName.flattenToShortString());
}
- if (mEvents != null) {
+ if (mEvents != null && !mEvents.isEmpty()) {
final int numberEvents = mEvents.size();
pw.print(prefix2); pw.print("buffered events: "); pw.print(numberEvents);
pw.print('/'); pw.println(MAX_BUFFER_SIZE);
@@ -455,6 +509,9 @@ public final class ContentCaptureManager {
pw.println();
}
}
+ pw.print(prefix2); pw.print("flush frequency: "); pw.println(FLUSHING_FREQUENCY_MS);
+ pw.print(prefix2); pw.print("next flush: ");
+ TimeUtils.formatDuration(mNextFlush - SystemClock.elapsedRealtime(), pw); pw.println();
}
}