Loading core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java +2 −2 Original line number Diff line number Diff line Loading @@ -631,13 +631,13 @@ final class IInputMethodManagerGlobalInvoker { /** @see com.android.server.inputmethod.ImeTrackerService#onProgress */ @AnyThread static void onProgress(long id, @ImeTracker.Phase int phase) { static void onProgress(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) { final IImeTracker service = getImeTrackerService(); if (service == null) { return; } try { service.onProgress(id, phase); service.onProgress(statsToken, phase); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/view/inputmethod/ImeTracker.java +1 −1 Original line number Diff line number Diff line Loading @@ -646,7 +646,7 @@ public interface ImeTracker { @Override public void onProgress(@Nullable Token token, @Phase int phase) { if (token == null) return; IInputMethodManagerGlobalInvoker.onProgress(token.mId, phase); IInputMethodManagerGlobalInvoker.onProgress(token, phase); if (mLogProgress) { log("%s: onProgress at %s", token.mTag, Debug.phaseToString(phase)); Loading core/java/com/android/internal/inputmethod/IImeTracker.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ interface IImeTracker { * @param statsToken the token tracking the request. * @param phase the new phase the request reached. */ oneway void onProgress(long id, int phase); oneway void onProgress(in ImeTracker.Token statsToken, int phase); /** * Called when the IME request fails. Loading services/core/java/com/android/server/inputmethod/ImeTrackerService.java +20 −1 Original line number Diff line number Diff line Loading @@ -112,6 +112,11 @@ public final class ImeTrackerService extends IImeTracker.Stub { final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. Log.i(TAG, tag + ": onStart on previously finished token"); return; } if (entry.mStarted) { Log.i(TAG, tag + ": onStart on previously started and not finished token: " + entry.mTag); Loading @@ -136,10 +141,16 @@ public final class ImeTrackerService extends IImeTracker.Stub { } @Override public void onProgress(long id, @ImeTracker.Phase int phase) { public void onProgress(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) { synchronized (mLock) { final long id = statsToken.getId(); final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. return; } if (entry.mFinished) { return; } Loading @@ -151,6 +162,7 @@ public final class ImeTrackerService extends IImeTracker.Stub { } final var newEntry = new History.Entry(); newEntry.mTag = tag; newEntry.onProgress(phase); mHistory.putActive(id, newEntry); Loading @@ -174,6 +186,13 @@ public final class ImeTrackerService extends IImeTracker.Stub { final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. Log.i(TAG, tag + ": onFinished on previously finished token at " + ImeTracker.Debug.phaseToString(phase) + " with " + ImeTracker.Debug.statusToString(status)); return; } if (entry.mFinished) { Log.i(TAG, tag + ": onFinished on previously finished but active token at " + ImeTracker.Debug.phaseToString(phase) Loading services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeTrackerServiceTest.java +173 −13 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onShown(token); synchronized (mService.mLock) { Loading Loading @@ -112,7 +112,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); mService.onProgress(token, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); mService.onHidden(token); synchronized (mService.mLock) { Loading Loading @@ -144,7 +144,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); mService.onProgress(token, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); mService.onCancelled(token, ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL); synchronized (mService.mLock) { Loading Loading @@ -176,7 +176,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_IME_SHOW_WINDOW); mService.onProgress(token, ImeTracker.PHASE_IME_SHOW_WINDOW); mService.onFailed(token, ImeTracker.PHASE_CLIENT_SHOW_INSETS); synchronized (mService.mLock) { Loading Loading @@ -208,7 +208,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); mService.onProgress(token, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); mService.onDispatched(token); synchronized (mService.mLock) { Loading Loading @@ -247,7 +247,7 @@ public class ImeTrackerServiceTest { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onProgress(id, ImeTracker.PHASE_SERVER_SYSTEM_READY); mService.onProgress(token, ImeTracker.PHASE_SERVER_SYSTEM_READY); mService.onShown(token); synchronized (mService.mLock) { Loading Loading @@ -309,6 +309,53 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_CLIENT_VIEW_SERVED, fromUser); } /** * Check that a start from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testStartOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Emulate start on token of completed entry. Completing an entry with the id will allow // re-using the id for token creation only in onStart, but that scenario is already // checked in testStartTwice. This emulated scenario can happen if the completed entry is // old, and the history is flushed due to many new entries. mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("One recorded").that(mRecordedEntries).hasSize(1); verifyEntry(mRecordedEntries.getFirst(), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** * Check that an entry that is first progressed, then started and then finished will be * completed normally, and contain the given data. Loading @@ -324,7 +371,7 @@ public class ImeTrackerServiceTest { final int reason = SoftInputShowHideReason.SHOW_SOFT_INPUT; final boolean fromUser = false; mService.onProgress(id, ImeTracker.PHASE_SERVER_HAS_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_HAS_IME); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } Loading Loading @@ -364,7 +411,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onProgress(token, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { Loading Loading @@ -399,7 +446,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onShown(token); synchronized (mService.mLock) { Loading @@ -407,7 +454,7 @@ public class ImeTrackerServiceTest { .isEmpty(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onProgress(token, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); synchronized (mService.mLock) { assertWithMessage("No entry created for progress after complete") .that(mHistory.getActive(id)).isNull(); Loading @@ -420,6 +467,62 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_CLIENT_VIEW_SERVED, fromUser); } /** * Check that a progress from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testProgressOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onShown(token); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Progress on token of completed entry. mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("Two entries recorded").that(mRecordedEntries).hasSize(2); verifyEntry(mRecordedEntries.get(0), tag, uid, type, ImeTracker.STATUS_SUCCESS, origin, reason, ImeTracker.PHASE_NOT_SET, fromUser); verifyEntry(mRecordedEntries.get(1), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** * Check that an entry that is first finished, then started and will be completed normally, * and contain the given data. Loading Loading @@ -528,6 +631,62 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_NOT_SET, fromUser); } /** * Check that a finish from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testFinishOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onShown(token); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Finish on token of completed entry. mService.onFailed(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that( mHistory.activeEntries()).isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("Two entries recorded").that(mRecordedEntries).hasSize(2); verifyEntry(mRecordedEntries.get(0), tag, uid, type, ImeTracker.STATUS_SUCCESS, origin, reason, ImeTracker.PHASE_NOT_SET, fromUser); verifyEntry(mRecordedEntries.get(1), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** Check that a started entry that is not completed will time out. */ @Test public void testTimeoutFromStart() { Loading @@ -545,7 +704,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_WAIT_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_WAIT_IME); advanceTime(TIMEOUT_MS); Loading @@ -562,14 +721,15 @@ public class ImeTrackerServiceTest { @Test public void testTimeoutFromProgress() { final int id = 0; final var tag = "not set"; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); final int uid = -1; final int type = ImeTracker.TYPE_NOT_SET; final int origin = ImeTracker.ORIGIN_NOT_SET; final int reason = SoftInputShowHideReason.NOT_SET; final boolean fromUser = false; mService.onProgress(id, ImeTracker.PHASE_SERVER_HAS_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_HAS_IME); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } Loading Loading
core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java +2 −2 Original line number Diff line number Diff line Loading @@ -631,13 +631,13 @@ final class IInputMethodManagerGlobalInvoker { /** @see com.android.server.inputmethod.ImeTrackerService#onProgress */ @AnyThread static void onProgress(long id, @ImeTracker.Phase int phase) { static void onProgress(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) { final IImeTracker service = getImeTrackerService(); if (service == null) { return; } try { service.onProgress(id, phase); service.onProgress(statsToken, phase); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/view/inputmethod/ImeTracker.java +1 −1 Original line number Diff line number Diff line Loading @@ -646,7 +646,7 @@ public interface ImeTracker { @Override public void onProgress(@Nullable Token token, @Phase int phase) { if (token == null) return; IInputMethodManagerGlobalInvoker.onProgress(token.mId, phase); IInputMethodManagerGlobalInvoker.onProgress(token, phase); if (mLogProgress) { log("%s: onProgress at %s", token.mTag, Debug.phaseToString(phase)); Loading
core/java/com/android/internal/inputmethod/IImeTracker.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ interface IImeTracker { * @param statsToken the token tracking the request. * @param phase the new phase the request reached. */ oneway void onProgress(long id, int phase); oneway void onProgress(in ImeTracker.Token statsToken, int phase); /** * Called when the IME request fails. Loading
services/core/java/com/android/server/inputmethod/ImeTrackerService.java +20 −1 Original line number Diff line number Diff line Loading @@ -112,6 +112,11 @@ public final class ImeTrackerService extends IImeTracker.Stub { final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. Log.i(TAG, tag + ": onStart on previously finished token"); return; } if (entry.mStarted) { Log.i(TAG, tag + ": onStart on previously started and not finished token: " + entry.mTag); Loading @@ -136,10 +141,16 @@ public final class ImeTrackerService extends IImeTracker.Stub { } @Override public void onProgress(long id, @ImeTracker.Phase int phase) { public void onProgress(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) { synchronized (mLock) { final long id = statsToken.getId(); final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. return; } if (entry.mFinished) { return; } Loading @@ -151,6 +162,7 @@ public final class ImeTrackerService extends IImeTracker.Stub { } final var newEntry = new History.Entry(); newEntry.mTag = tag; newEntry.onProgress(phase); mHistory.putActive(id, newEntry); Loading @@ -174,6 +186,13 @@ public final class ImeTrackerService extends IImeTracker.Stub { final String tag = statsToken.getTag(); final var entry = mHistory.getActive(id); if (entry != null) { if (!entry.mTag.equals(tag)) { // Tags don't match as the ID is being reused after the initial entry completed. Log.i(TAG, tag + ": onFinished on previously finished token at " + ImeTracker.Debug.phaseToString(phase) + " with " + ImeTracker.Debug.statusToString(status)); return; } if (entry.mFinished) { Log.i(TAG, tag + ": onFinished on previously finished but active token at " + ImeTracker.Debug.phaseToString(phase) Loading
services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeTrackerServiceTest.java +173 −13 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onShown(token); synchronized (mService.mLock) { Loading Loading @@ -112,7 +112,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); mService.onProgress(token, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); mService.onHidden(token); synchronized (mService.mLock) { Loading Loading @@ -144,7 +144,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); mService.onProgress(token, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); mService.onCancelled(token, ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL); synchronized (mService.mLock) { Loading Loading @@ -176,7 +176,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_IME_SHOW_WINDOW); mService.onProgress(token, ImeTracker.PHASE_IME_SHOW_WINDOW); mService.onFailed(token, ImeTracker.PHASE_CLIENT_SHOW_INSETS); synchronized (mService.mLock) { Loading Loading @@ -208,7 +208,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); mService.onProgress(token, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); mService.onDispatched(token); synchronized (mService.mLock) { Loading Loading @@ -247,7 +247,7 @@ public class ImeTrackerServiceTest { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onProgress(id, ImeTracker.PHASE_SERVER_SYSTEM_READY); mService.onProgress(token, ImeTracker.PHASE_SERVER_SYSTEM_READY); mService.onShown(token); synchronized (mService.mLock) { Loading Loading @@ -309,6 +309,53 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_CLIENT_VIEW_SERVED, fromUser); } /** * Check that a start from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testStartOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Emulate start on token of completed entry. Completing an entry with the id will allow // re-using the id for token creation only in onStart, but that scenario is already // checked in testStartTwice. This emulated scenario can happen if the completed entry is // old, and the history is flushed due to many new entries. mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("One recorded").that(mRecordedEntries).hasSize(1); verifyEntry(mRecordedEntries.getFirst(), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** * Check that an entry that is first progressed, then started and then finished will be * completed normally, and contain the given data. Loading @@ -324,7 +371,7 @@ public class ImeTrackerServiceTest { final int reason = SoftInputShowHideReason.SHOW_SOFT_INPUT; final boolean fromUser = false; mService.onProgress(id, ImeTracker.PHASE_SERVER_HAS_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_HAS_IME); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } Loading Loading @@ -364,7 +411,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onProgress(token, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { Loading Loading @@ -399,7 +446,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); mService.onShown(token); synchronized (mService.mLock) { Loading @@ -407,7 +454,7 @@ public class ImeTrackerServiceTest { .isEmpty(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); mService.onProgress(token, ImeTracker.PHASE_SERVER_CLIENT_KNOWN); synchronized (mService.mLock) { assertWithMessage("No entry created for progress after complete") .that(mHistory.getActive(id)).isNull(); Loading @@ -420,6 +467,62 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_CLIENT_VIEW_SERVED, fromUser); } /** * Check that a progress from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testProgressOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onShown(token); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Progress on token of completed entry. mService.onProgress(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("Two entries recorded").that(mRecordedEntries).hasSize(2); verifyEntry(mRecordedEntries.get(0), tag, uid, type, ImeTracker.STATUS_SUCCESS, origin, reason, ImeTracker.PHASE_NOT_SET, fromUser); verifyEntry(mRecordedEntries.get(1), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** * Check that an entry that is first finished, then started and will be completed normally, * and contain the given data. Loading Loading @@ -528,6 +631,62 @@ public class ImeTrackerServiceTest { reason, ImeTracker.PHASE_NOT_SET, fromUser); } /** * Check that a finish from a completed entry won't affect a new entry that is * re-using the id. */ @Test public void testFinishOnReusedId() { final int id = 0; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); 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; mService.onStart(token, uid, type, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onShown(token); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that(mHistory.activeEntries()) .isEmpty(); } final var secondTag = "B"; final var secondToken = new ImeTracker.Token(id, secondTag); final int secondType = ImeTracker.TYPE_HIDE; mService.onStart(secondToken, uid, secondType, origin, reason, fromUser, System.currentTimeMillis()); synchronized (mService.mLock) { assertWithMessage("Second created entry").that(mHistory.getActive(id)).isNotNull(); } // Finish on token of completed entry. mService.onFailed(token, ImeTracker.PHASE_CLIENT_VIEW_SERVED); synchronized (mService.mLock) { assertWithMessage("One active entry").that(mHistory.activeEntries()).hasSize(1); } mService.onCancelled(secondToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); synchronized (mService.mLock) { assertWithMessage("No active entries remaining").that( mHistory.activeEntries()).isEmpty(); } advanceTime(TIMEOUT_MS); assertWithMessage("Two entries recorded").that(mRecordedEntries).hasSize(2); verifyEntry(mRecordedEntries.get(0), tag, uid, type, ImeTracker.STATUS_SUCCESS, origin, reason, ImeTracker.PHASE_NOT_SET, fromUser); verifyEntry(mRecordedEntries.get(1), secondTag, uid, secondType, ImeTracker.STATUS_CANCEL, origin, reason, ImeTracker.PHASE_SERVER_SHOULD_HIDE, fromUser); } /** Check that a started entry that is not completed will time out. */ @Test public void testTimeoutFromStart() { Loading @@ -545,7 +704,7 @@ public class ImeTrackerServiceTest { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } mService.onProgress(id, ImeTracker.PHASE_SERVER_WAIT_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_WAIT_IME); advanceTime(TIMEOUT_MS); Loading @@ -562,14 +721,15 @@ public class ImeTrackerServiceTest { @Test public void testTimeoutFromProgress() { final int id = 0; final var tag = "not set"; final var tag = "A"; final var token = new ImeTracker.Token(id, tag); final int uid = -1; final int type = ImeTracker.TYPE_NOT_SET; final int origin = ImeTracker.ORIGIN_NOT_SET; final int reason = SoftInputShowHideReason.NOT_SET; final boolean fromUser = false; mService.onProgress(id, ImeTracker.PHASE_SERVER_HAS_IME); mService.onProgress(token, ImeTracker.PHASE_SERVER_HAS_IME); synchronized (mService.mLock) { assertWithMessage("Created entry").that(mHistory.getActive(id)).isNotNull(); } Loading