Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c81c7cc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Log history of Content Capture flushes."

parents ea60fcd5 1af85ea1
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.ContentCaptureSession;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -1034,13 +1035,15 @@ public class Activity extends ContextThemeWrapper
    }

    /** @hide */ private static final int CONTENT_CAPTURE_START = 1;
    /** @hide */ private static final int CONTENT_CAPTURE_FLUSH = 2;
    /** @hide */ private static final int CONTENT_CAPTURE_STOP = 3;
    /** @hide */ private static final int CONTENT_CAPTURE_PAUSE = 2;
    /** @hide */ private static final int CONTENT_CAPTURE_RESUME = 3;
    /** @hide */ private static final int CONTENT_CAPTURE_STOP = 4;

    /** @hide */
    @IntDef(prefix = { "CONTENT_CAPTURE_" }, value = {
            CONTENT_CAPTURE_START,
            CONTENT_CAPTURE_FLUSH,
            CONTENT_CAPTURE_PAUSE,
            CONTENT_CAPTURE_RESUME,
            CONTENT_CAPTURE_STOP
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -1062,8 +1065,11 @@ public class Activity extends ContextThemeWrapper
                }
                cm.onActivityStarted(mToken, getComponentName(), flags);
                break;
            case CONTENT_CAPTURE_FLUSH:
                cm.flush();
            case CONTENT_CAPTURE_PAUSE:
                cm.flush(ContentCaptureSession.FLUSH_REASON_ACTIVITY_PAUSED);
                break;
            case CONTENT_CAPTURE_RESUME:
                cm.flush(ContentCaptureSession.FLUSH_REASON_ACTIVITY_RESUMED);
                break;
            case CONTENT_CAPTURE_STOP:
                cm.onActivityStopped();
@@ -1755,7 +1761,7 @@ public class Activity extends ContextThemeWrapper
            }
        }
        mCalled = true;
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_FLUSH);
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_RESUME);
    }

    /**
@@ -2149,7 +2155,7 @@ public class Activity extends ContextThemeWrapper
            }
        }
        mCalled = true;
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_FLUSH);
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_PAUSE);
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ final class ChildContentCaptureSession extends ContentCaptureSession {
    }

    @Override
    void flush() {
        mParent.flush();
    void flush(@FlushReason int reason) {
        mParent.flush(reason);
    }

    @Override
+3 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.contentcapture.ContentCaptureSession.FlushReason;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
@@ -154,8 +155,8 @@ public final class ContentCaptureManager {
     *
     * @hide
     */
    public void flush() {
        getMainContentCaptureSession().flush();
    public void flush(@FlushReason int reason) {
        getMainContentCaptureSession().flush(reason);
    }

    /**
+53 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.view.contentcapture.ContentCaptureManager.DEBUG;
import static android.view.contentcapture.ContentCaptureManager.VERBOSE;

import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.DebugUtils;
@@ -35,6 +36,8 @@ import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.UUID;

@@ -125,6 +128,32 @@ public abstract class ContentCaptureSession implements AutoCloseable {

    private static final int INITIAL_CHILDREN_CAPACITY = 5;

    /** @hide */
    public static final int FLUSH_REASON_FULL = 1;
    /** @hide */
    public static final int FLUSH_REASON_ACTIVITY_PAUSED = 2;
    /** @hide */
    public static final int FLUSH_REASON_ACTIVITY_RESUMED = 3;
    /** @hide */
    public static final int FLUSH_REASON_SESSION_STARTED = 4;
    /** @hide */
    public static final int FLUSH_REASON_SESSION_FINISHED = 5;
    /** @hide */
    public static final int FLUSH_REASON_IDLE_TIMEOUT = 6;

    /** @hide */
    @IntDef(prefix = { "FLUSH_REASON_" }, value = {
            FLUSH_REASON_FULL,
            FLUSH_REASON_ACTIVITY_PAUSED,
            FLUSH_REASON_ACTIVITY_RESUMED,
            FLUSH_REASON_SESSION_STARTED,
            FLUSH_REASON_SESSION_FINISHED,
            FLUSH_REASON_IDLE_TIMEOUT
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface FlushReason{}


    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final Object mLock = new Object();
@@ -212,7 +241,7 @@ public abstract class ContentCaptureSession implements AutoCloseable {
    /**
     * Flushes the buffered events to the service.
     */
    abstract void flush();
    abstract void flush(@FlushReason int reason);

    /**
     * Destroys this session, flushing out all pending notifications to the service.
@@ -250,7 +279,7 @@ public abstract class ContentCaptureSession implements AutoCloseable {
        }

        try {
            flush();
            flush(FLUSH_REASON_SESSION_FINISHED);
        } finally {
            onDestroy();
        }
@@ -407,12 +436,31 @@ public abstract class ContentCaptureSession implements AutoCloseable {
        return mId;
    }

    /**
     * @hide
     */
    /** @hide */
    @NonNull
    protected static String getStateAsString(int state) {
        return state + " (" + (state == UNKNWON_STATE ? "UNKNOWN"
                : DebugUtils.flagsToString(ContentCaptureSession.class, "STATE_", state)) + ")";
    }

    /** @hide */
    @NonNull
    static String getflushReasonAsString(@FlushReason int reason) {
        switch (reason) {
            case FLUSH_REASON_FULL:
                return "FULL";
            case FLUSH_REASON_ACTIVITY_PAUSED:
                return "PAUSED";
            case FLUSH_REASON_ACTIVITY_RESUMED:
                return "RESUMED";
            case FLUSH_REASON_SESSION_STARTED:
                return "STARTED";
            case FLUSH_REASON_SESSION_FINISHED:
                return "FINISHED";
            case FLUSH_REASON_IDLE_TIMEOUT:
                return "IDLE";
            default:
                return "UNKOWN-" + reason;
        }
    }
}
+52 −25
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.LocalLog;
import android.util.Log;
import android.util.TimeUtils;
import android.view.autofill.AutofillId;
@@ -131,6 +131,9 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
    // Used just for debugging purposes (on dump)
    private long mNextFlush;

    // TODO(b/121044064): use settings to set size
    private final LocalLog mFlushHistory = new LocalLog(10);

    /** @hide */
    protected MainContentCaptureSession(@NonNull Context context, @NonNull Handler handler,
            @Nullable IContentCaptureManager systemServerInterface,
@@ -172,8 +175,9 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
    }

    @Override
    void flush() {
        mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleForceFlush, this));
    void flush(@FlushReason int reason) {
        mHandler.sendMessage(
                obtainMessage(MainContentCaptureSession::handleForceFlush, this, reason));
    }

    @Override
@@ -264,24 +268,25 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
    }

    private void handleSendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
        if (!handleHasStarted()
                && event.getType() != ContentCaptureEvent.TYPE_SESSION_STARTED) {
        final int eventType = event.getType();
        if (!handleHasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED) {
            // TODO(b/120494182): comment when this could happen (dialogs?)
            Log.v(TAG, "handleSendEvent(" + getDebugState() + ", "
                    + ContentCaptureEvent.getTypeAsString(event.getType())
                    + ContentCaptureEvent.getTypeAsString(eventType)
                    + "): session not started yet");
            return;
        }
        if (VERBOSE) Log.v(TAG, "handleSendEvent(" + getDebugState() + "): " + event);
        if (mEvents == null) {
            if (VERBOSE) {
                Log.v(TAG, "handleSendEvent(" + getDebugState() + ", "
                        + ContentCaptureEvent.getTypeAsString(event.getType())
                        + "): cCreating buffer for " + MAX_BUFFER_SIZE + " events");
                        + ContentCaptureEvent.getTypeAsString(eventType)
                        + "): creating buffer for " + MAX_BUFFER_SIZE + " events");
            }
            mEvents = new ArrayList<>(MAX_BUFFER_SIZE);
        }

        if (!mEvents.isEmpty() && event.getType() == TYPE_VIEW_TEXT_CHANGED) {
        if (!mEvents.isEmpty() && eventType == TYPE_VIEW_TEXT_CHANGED) {
            final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1);

            // TODO(b/121045053): check if flags match
@@ -304,7 +309,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
        final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE;

        if (bufferEvent && !forceFlush) {
            handleScheduleFlush(/* checkExisting= */ true);
            handleScheduleFlush(FLUSH_REASON_IDLE_TIMEOUT, /* checkExisting= */ true);
            return;
        }

@@ -323,15 +328,26 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
            // when it's launched again
            return;
        }
        final int flushReason;
        switch (eventType) {
            case ContentCaptureEvent.TYPE_SESSION_STARTED:
                flushReason = FLUSH_REASON_SESSION_STARTED;
                break;
            case ContentCaptureEvent.TYPE_SESSION_FINISHED:
                flushReason = FLUSH_REASON_SESSION_FINISHED;
                break;
            default:
                flushReason = FLUSH_REASON_FULL;
        }

        handleForceFlush();
        handleForceFlush(flushReason);
    }

    private boolean handleHasStarted() {
        return mState != UNKNWON_STATE;
    }

    private void handleScheduleFlush(boolean checkExisting) {
    private void handleScheduleFlush(@FlushReason int reason, boolean checkExisting) {
        if (!handleHasStarted()) {
            Log.v(TAG, "handleScheduleFlush(" + getDebugState() + "): session not started yet");
            return;
@@ -340,43 +356,51 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
            // "Renew" the flush message by removing the previous one
            mHandler.removeMessages(MSG_FLUSH);
        }
        mNextFlush = SystemClock.elapsedRealtime() + FLUSHING_FREQUENCY_MS;
        mNextFlush = System.currentTimeMillis() + FLUSHING_FREQUENCY_MS;
        if (VERBOSE) {
            Log.v(TAG, "handleScheduleFlush(" + getDebugState() + "): scheduled to flush in "
                    + FLUSHING_FREQUENCY_MS + "ms: " + TimeUtils.formatUptime(mNextFlush));
            Log.v(TAG, "handleScheduleFlush(" + getDebugState()
                    + ", reason=" + getflushReasonAsString(reason) + "): scheduled to flush in "
                    + FLUSHING_FREQUENCY_MS + "ms: " + TimeUtils.logTimeOfDay(mNextFlush));
        }
        mHandler.sendMessageDelayed(
                obtainMessage(MainContentCaptureSession::handleFlushIfNeeded, this)
                obtainMessage(MainContentCaptureSession::handleFlushIfNeeded, this, reason)
                .setWhat(MSG_FLUSH), FLUSHING_FREQUENCY_MS);
    }

    private void handleFlushIfNeeded() {
    private void handleFlushIfNeeded(@FlushReason int reason) {
        if (mEvents.isEmpty()) {
            if (VERBOSE) Log.v(TAG, "Nothing to flush");
            return;
        }
        handleForceFlush();
        handleForceFlush(reason);
    }

    private void handleForceFlush() {
    private void handleForceFlush(@FlushReason int reason) {
        if (mEvents == null) return;

        if (mDirectServiceInterface == null) {
            if (VERBOSE) {
                Log.v(TAG, "handleForceFlush(" + getDebugState()
                        + ", reason=" + getflushReasonAsString(reason)
                        + "): hold your horses, client not ready: " + mEvents);
            }
            if (!mHandler.hasMessages(MSG_FLUSH)) {
                handleScheduleFlush(/* checkExisting= */ false);
                handleScheduleFlush(reason, /* checkExisting= */ false);
            }
            return;
        }

        final int numberEvents = mEvents.size();
        try {
        final String reasonString = getflushReasonAsString(reason);
        if (DEBUG) {
                Log.d(TAG, "Flushing " + numberEvents + " event(s) for " + getDebugState());
            Log.d(TAG, "Flushing " + numberEvents + " event(s) for " + getDebugState()
                    + ". Reason: " + reasonString);
        }
        // Logs reason, size, max size, idle timeout
        final String logRecord = "r=" + reasonString + " s=" + numberEvents
                + " m=" + MAX_BUFFER_SIZE + " i=" + FLUSHING_FREQUENCY_MS;
        try {
            mFlushHistory.log(logRecord);
            mHandler.removeMessages(MSG_FLUSH);

            final ParceledListSlice<ContentCaptureEvent> events = handleClearEvents();
@@ -500,7 +524,6 @@ public final class MainContentCaptureSession extends ContentCaptureSession {

    @Override
    void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
        pw.print(prefix); pw.print("id: "); pw.println(mId);
        pw.print(prefix); pw.print("mContext: "); pw.println(mContext);
        pw.print(prefix); pw.print("user: "); pw.println(mContext.getUserId());
        if (mSystemServerInterface != null) {
@@ -535,8 +558,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
            }
            pw.print(prefix); pw.print("flush frequency: "); pw.println(FLUSHING_FREQUENCY_MS);
            pw.print(prefix); pw.print("next flush: ");
            TimeUtils.formatDuration(mNextFlush - SystemClock.elapsedRealtime(), pw); pw.println();
            TimeUtils.formatDuration(mNextFlush - System.currentTimeMillis(), pw);
            pw.print(" ("); pw.print(TimeUtils.logTimeOfDay(mNextFlush)); pw.println(")");
        }
        pw.print(prefix); pw.println("flush history:");
        mFlushHistory.reverseDump(/* fd= */ null, pw, /* args= */ null); pw.println();

        super.dump(prefix, pw);
    }

Loading