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

Commit 785ca590 authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Track ImeTrackerService active capacity" into main

parents 7c275d66 9b50b2b2
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -133,6 +133,11 @@ public final class ImeTrackerService extends IImeTracker.Stub {
                    complete(id, entry);
                }
            } else {
                if (mHistory.isActiveFull()) {
                    log("%s: onStart while active entries are full, not tracking request", tag);
                    return;
                }

                final var newEntry = new History.Entry();
                // Prefer current time to startTime when creating the entry in onStart.
                newEntry.onStart(tag, uid, type, origin, reason, fromUser,
@@ -165,6 +170,11 @@ public final class ImeTrackerService extends IImeTracker.Stub {
                    return;
                }

                if (mHistory.isActiveFull()) {
                    log("%s: onProgress while active entries are full, not tracking request", tag);
                    return;
                }

                final var newEntry = new History.Entry();
                newEntry.mTag = tag;
                newEntry.onProgress(phase);
@@ -217,6 +227,14 @@ public final class ImeTrackerService extends IImeTracker.Stub {
                return;
            }

            if (mHistory.isActiveFull()) {
                log("%s: onFinished at %s with %s while active entries are full,"
                        + " not tracking request", tag,
                        ImeTracker.Debug.phaseToString(phase),
                        ImeTracker.Debug.statusToString(status));
                return;
            }

            final var newEntry = new History.Entry();
            newEntry.mTag = tag;
            newEntry.onFinish(status, phase);
@@ -384,20 +402,26 @@ public final class ImeTrackerService extends IImeTracker.Stub {
    static final class History {

        /** The maximum number of completed entries to store in {@link #mCompletedEntries}. */
        private static final int CAPACITY = 100;
        private static final int COMPLETED_CAPACITY = 200;

        /**
         * The maximum number of active entries to track in {@link #mActiveEntries} simultaneously.
         */
        @VisibleForTesting
        static final int ACTIVE_CAPACITY = 1000;

        /**
         * Circular buffer of completed requests, mapped by their unique ID. The buffer has a fixed
         * capacity ({@link #CAPACITY}), with older entries overwritten when the capacity
         * capacity ({@link #COMPLETED_CAPACITY}), with older entries overwritten when the capacity
         * is reached.
         */
        @GuardedBy("mLock")
        private final LinkedHashMap<Long, History.Entry> mCompletedEntries =
                new LinkedHashMap<>(CAPACITY) {
                new LinkedHashMap<>(COMPLETED_CAPACITY) {

                    @Override
                    protected boolean removeEldestEntry(Map.Entry<Long, History.Entry> eldest) {
                        return size() > CAPACITY;
                        return size() > COMPLETED_CAPACITY;
                    }
                };

@@ -460,6 +484,12 @@ public final class ImeTrackerService extends IImeTracker.Stub {
            return mCompletedEntries.containsKey(id);
        }

        /** Checks whether the collection of active entries is full. */
        @GuardedBy("mLock")
        boolean isActiveFull() {
            return mActiveEntries.size() >= ACTIVE_CAPACITY;
        }

        /**
         * Dump the internal state to the history to the given print writer.
         *
+70 −0
Original line number Diff line number Diff line
@@ -834,6 +834,76 @@ public class ImeTrackerServiceTest {
                origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser);
    }

    /**
     * Verifies that no new request entries can be created when the collection of active entries
     * is full.
     */
    @Test
    public void testCannotCreateWhenActiveFull() {
        ImeTracker.Token token = null;
        final int uid = 10;
        final int type = ImeTracker.TYPE_SHOW;
        final int origin = ImeTracker.ORIGIN_CLIENT;
        final int reason = SoftInputShowHideReason.SHOW_SOFT_INPUT;
        final boolean fromUser = false;

        synchronized (mService.mLock) {
            for (int id = 0; id < History.ACTIVE_CAPACITY; id++) {
                final var tag = "tag#" + id;
                token = new ImeTracker.Token(id, tag);
                mService.onStart(token, uid, type, origin, reason, fromUser,
                        System.currentTimeMillis());
                assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull();
            }

            assertWithMessage("Active entries should be full")
                    .that(mHistory.isActiveFull()).isTrue();
        }

        final var otherId = -1;
        final var otherTag = "B";
        final var otherToken = new ImeTracker.Token(otherId, otherTag);
        final int otherType = ImeTracker.TYPE_HIDE;

        mService.onStart(otherToken, uid, otherType, origin, reason, fromUser,
                System.currentTimeMillis());
        synchronized (mService.mLock) {
            assertWithMessage(
                    "Other entry should not be created in onStart when active entries are full")
                    .that(mHistory.getActive(otherId)).isNull();
        }

        mService.onProgress(otherToken, ImeTracker.PHASE_SERVER_HAS_IME);
        synchronized (mService.mLock) {
            assertWithMessage(
                    "Other entry should not be created in onProgress when active entries are full")
                    .that(mHistory.getActive(otherId)).isNull();
        }

        mService.onHidden(otherToken);
        synchronized (mService.mLock) {
            assertWithMessage(
                    "Other entry should not be created in onHidden when active entries are full")
                    .that(mHistory.getActive(otherId)).isNull();
        }

        mService.onShown(token);
        synchronized (mService.mLock) {
            assertWithMessage("Last created entry was completed")
                    .that(mHistory.getActive(token.getId())).isNull();
            assertWithMessage("Active entries should no longer be full")
                    .that(mHistory.isActiveFull()).isFalse();
        }

        mService.onStart(otherToken, uid, otherType, origin, reason, fromUser,
                System.currentTimeMillis());
        synchronized (mService.mLock) {
            assertWithMessage(
                    "Other entry should be created in onStart when active entries are not full")
                    .that(mHistory.getActive(otherId)).isNotNull();
        }
    }

    /**
     * Advances the time on the test handler by the specified amount.
     *