Loading core/java/android/util/SequenceUtils.java +15 −8 Original line number Diff line number Diff line Loading @@ -25,8 +25,8 @@ package android.util; * {@link #getInitSeq}. * 2. Whenever a newer info needs to be sent to the client side, the system server should first * update its seq with {@link #getNextSeq}, then send the new info with the new seq to the client. * 3. On the client side, when receiving a new info, it should only consume it if it is newer than * the last received info seq by checking {@link #isIncomingSeqNewer}. * 3. On the client side, when receiving a new info, it should only consume it if it is not stale by * checking {@link #isIncomingSeqStale}. * * @hide */ Loading @@ -36,15 +36,22 @@ public final class SequenceUtils { } /** * Returns {@code true} if the incomingSeq is newer than the curSeq. * Returns {@code true} if the incomingSeq is stale, which means the client should not consume * it. */ public static boolean isIncomingSeqNewer(int curSeq, int incomingSeq) { public static boolean isIncomingSeqStale(int curSeq, int incomingSeq) { if (curSeq == getInitSeq()) { // curSeq can be set to the initial seq in the following cases: // 1. The client process/field is newly created/recreated. // 2. The field is not managed by the system server, such as WindowlessWindowManager. // The client should always consume the incoming in these cases. return false; } // Convert to long for comparison. final long diff = (long) incomingSeq - curSeq; // If there has been a sufficiently large jump, assume the sequence has wrapped around. // For example, when the last seq is MAX_VALUE, the incoming seq will be MIN_VALUE + 1. // diff = MIN_VALUE + 1 - MAX_VALUE. It is smaller than 0, but should be treated as newer. return diff > 0 || diff < Integer.MIN_VALUE; // When diff is 0, allow client to consume. // When there has been a sufficiently large jump, assume the sequence has wrapped around. return (diff < 0 && diff > Integer.MIN_VALUE) || diff > Integer.MAX_VALUE; } /** Returns the initial seq. */ Loading core/java/android/view/ViewRootImpl.java +13 −13 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUN import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID; import static android.os.Trace.TRACE_TAG_VIEW; import static android.util.SequenceUtils.getInitSeq; import static android.util.SequenceUtils.isIncomingSeqNewer; import static android.util.SequenceUtils.isIncomingSeqStale; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.DragEvent.ACTION_DRAG_LOCATION; Loading Loading @@ -2329,23 +2329,23 @@ public final class ViewRootImpl implements ViewParent, if (mLastReportedFrames == null) { return; } if (isIncomingSeqNewer(mLastReportedFrames.seq, inOutFrames.seq)) { if (isIncomingSeqStale(mLastReportedFrames.seq, inOutFrames.seq)) { // If the incoming is stale, use the last reported instead. inOutFrames.setTo(mLastReportedFrames); } else { // Keep track of the latest. mLastReportedFrames.setTo(inOutFrames); } else { // If the last reported frames is newer, use the last reported instead. inOutFrames.setTo(mLastReportedFrames); } } private void onInsetsStateChanged(@NonNull InsetsState insetsState) { if (insetsControlSeq()) { if (isIncomingSeqNewer(mLastReportedInsetsStateSeq, insetsState.getSeq())) { mLastReportedInsetsStateSeq = insetsState.getSeq(); } else { // The last reported InsetsState is newer. Skip. if (isIncomingSeqStale(mLastReportedInsetsStateSeq, insetsState.getSeq())) { // The incoming is stale. Skip. return; } // Keep track of the latest. mLastReportedInsetsStateSeq = insetsState.getSeq(); } if (mTranslator != null) { Loading @@ -2362,13 +2362,13 @@ public final class ViewRootImpl implements ViewParent, } if (insetsControlSeq()) { if (isIncomingSeqNewer(mLastReportedActiveControlsSeq, activeControls.getSeq())) { mLastReportedActiveControlsSeq = activeControls.getSeq(); } else { // The last reported controls is newer. Skip. if (isIncomingSeqStale(mLastReportedActiveControlsSeq, activeControls.getSeq())) { // The incoming is stale. Skip. activeControls.release(); return; } // Keep track of the latest. mLastReportedActiveControlsSeq = activeControls.getSeq(); } final InsetsSourceControl[] controls = activeControls.get(); Loading core/tests/coretests/src/android/util/SequenceUtilsTest.java +26 −21 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package android.util; import static android.util.SequenceUtils.getInitSeq; import static android.util.SequenceUtils.getNextSeq; import static android.util.SequenceUtils.isIncomingSeqNewer; import static android.util.SequenceUtils.isIncomingSeqStale; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -60,30 +60,35 @@ public class SequenceUtilsTest { } @Test public void testIsIncomingSeqNewer() { assertTrue(isIncomingSeqNewer(getInitSeq() + 1, getInitSeq() + 10)); assertFalse(isIncomingSeqNewer(getInitSeq() + 10, getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(-100, 100)); assertFalse(isIncomingSeqNewer(100, -100)); assertTrue(isIncomingSeqNewer(1, 2)); assertFalse(isIncomingSeqNewer(2, 1)); public void testIsIncomingSeqStale() { assertFalse(isIncomingSeqStale(getInitSeq() + 1, getInitSeq() + 10)); assertTrue(isIncomingSeqStale(getInitSeq() + 10, getInitSeq() + 1)); assertFalse(isIncomingSeqStale(-100, 100)); assertTrue(isIncomingSeqStale(100, -100)); assertFalse(isIncomingSeqStale(1, 2)); assertTrue(isIncomingSeqStale(2, 1)); // Possible incoming seq are all newer than the initial seq. assertTrue(isIncomingSeqNewer(getInitSeq(), getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(getInitSeq(), -100)); assertTrue(isIncomingSeqNewer(getInitSeq(), 0)); assertTrue(isIncomingSeqNewer(getInitSeq(), 100)); assertTrue(isIncomingSeqNewer(getInitSeq(), Integer.MAX_VALUE)); assertTrue(isIncomingSeqNewer(getInitSeq(), getNextSeq(Integer.MAX_VALUE))); assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq())); assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq() + 1)); assertFalse(isIncomingSeqStale(getInitSeq(), -100)); assertFalse(isIncomingSeqStale(getInitSeq(), 0)); assertFalse(isIncomingSeqStale(getInitSeq(), 100)); assertFalse(isIncomingSeqStale(getInitSeq(), Integer.MAX_VALUE)); assertFalse(isIncomingSeqStale(getInitSeq(), getNextSeq(Integer.MAX_VALUE))); // False for the same seq. assertFalse(isIncomingSeqNewer(getInitSeq(), getInitSeq())); assertFalse(isIncomingSeqNewer(100, 100)); assertFalse(isIncomingSeqNewer(Integer.MAX_VALUE, Integer.MAX_VALUE)); assertFalse(isIncomingSeqStale(100, 100)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, Integer.MAX_VALUE)); // True when there is a large jump (overflow). assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 100)); assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE))); // False when there is a large jump (overflow). assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 1)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 100)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE))); // True when the large jump is opposite (curSeq is newer). assertTrue(isIncomingSeqStale(getInitSeq() + 1, Integer.MAX_VALUE)); assertTrue(isIncomingSeqStale(getInitSeq() + 100, Integer.MAX_VALUE)); assertTrue(isIncomingSeqStale(getNextSeq(Integer.MAX_VALUE), Integer.MAX_VALUE)); } } core/tests/coretests/src/android/view/ViewRootImplTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import static android.util.SequenceUtils.getInitSeq; import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; Loading Loading @@ -1555,9 +1556,9 @@ public class ViewRootImplTest { final InsetsState state0 = new InsetsState(); final InsetsState state1 = new InsetsState(); state0.setDisplayFrame(new Rect(0, 0, 500, 1000)); state0.setSeq(10000); state0.setSeq(getInitSeq() + 10000); state1.setDisplayFrame(new Rect(0, 0, 1500, 2000)); state1.setSeq(10001); state1.setSeq(getInitSeq() + 10001); final InsetsSourceControl.Array array = new InsetsSourceControl.Array(); sInstrumentation.runOnMainSync(() -> { Loading Loading
core/java/android/util/SequenceUtils.java +15 −8 Original line number Diff line number Diff line Loading @@ -25,8 +25,8 @@ package android.util; * {@link #getInitSeq}. * 2. Whenever a newer info needs to be sent to the client side, the system server should first * update its seq with {@link #getNextSeq}, then send the new info with the new seq to the client. * 3. On the client side, when receiving a new info, it should only consume it if it is newer than * the last received info seq by checking {@link #isIncomingSeqNewer}. * 3. On the client side, when receiving a new info, it should only consume it if it is not stale by * checking {@link #isIncomingSeqStale}. * * @hide */ Loading @@ -36,15 +36,22 @@ public final class SequenceUtils { } /** * Returns {@code true} if the incomingSeq is newer than the curSeq. * Returns {@code true} if the incomingSeq is stale, which means the client should not consume * it. */ public static boolean isIncomingSeqNewer(int curSeq, int incomingSeq) { public static boolean isIncomingSeqStale(int curSeq, int incomingSeq) { if (curSeq == getInitSeq()) { // curSeq can be set to the initial seq in the following cases: // 1. The client process/field is newly created/recreated. // 2. The field is not managed by the system server, such as WindowlessWindowManager. // The client should always consume the incoming in these cases. return false; } // Convert to long for comparison. final long diff = (long) incomingSeq - curSeq; // If there has been a sufficiently large jump, assume the sequence has wrapped around. // For example, when the last seq is MAX_VALUE, the incoming seq will be MIN_VALUE + 1. // diff = MIN_VALUE + 1 - MAX_VALUE. It is smaller than 0, but should be treated as newer. return diff > 0 || diff < Integer.MIN_VALUE; // When diff is 0, allow client to consume. // When there has been a sufficiently large jump, assume the sequence has wrapped around. return (diff < 0 && diff > Integer.MIN_VALUE) || diff > Integer.MAX_VALUE; } /** Returns the initial seq. */ Loading
core/java/android/view/ViewRootImpl.java +13 −13 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUN import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID; import static android.os.Trace.TRACE_TAG_VIEW; import static android.util.SequenceUtils.getInitSeq; import static android.util.SequenceUtils.isIncomingSeqNewer; import static android.util.SequenceUtils.isIncomingSeqStale; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.DragEvent.ACTION_DRAG_LOCATION; Loading Loading @@ -2329,23 +2329,23 @@ public final class ViewRootImpl implements ViewParent, if (mLastReportedFrames == null) { return; } if (isIncomingSeqNewer(mLastReportedFrames.seq, inOutFrames.seq)) { if (isIncomingSeqStale(mLastReportedFrames.seq, inOutFrames.seq)) { // If the incoming is stale, use the last reported instead. inOutFrames.setTo(mLastReportedFrames); } else { // Keep track of the latest. mLastReportedFrames.setTo(inOutFrames); } else { // If the last reported frames is newer, use the last reported instead. inOutFrames.setTo(mLastReportedFrames); } } private void onInsetsStateChanged(@NonNull InsetsState insetsState) { if (insetsControlSeq()) { if (isIncomingSeqNewer(mLastReportedInsetsStateSeq, insetsState.getSeq())) { mLastReportedInsetsStateSeq = insetsState.getSeq(); } else { // The last reported InsetsState is newer. Skip. if (isIncomingSeqStale(mLastReportedInsetsStateSeq, insetsState.getSeq())) { // The incoming is stale. Skip. return; } // Keep track of the latest. mLastReportedInsetsStateSeq = insetsState.getSeq(); } if (mTranslator != null) { Loading @@ -2362,13 +2362,13 @@ public final class ViewRootImpl implements ViewParent, } if (insetsControlSeq()) { if (isIncomingSeqNewer(mLastReportedActiveControlsSeq, activeControls.getSeq())) { mLastReportedActiveControlsSeq = activeControls.getSeq(); } else { // The last reported controls is newer. Skip. if (isIncomingSeqStale(mLastReportedActiveControlsSeq, activeControls.getSeq())) { // The incoming is stale. Skip. activeControls.release(); return; } // Keep track of the latest. mLastReportedActiveControlsSeq = activeControls.getSeq(); } final InsetsSourceControl[] controls = activeControls.get(); Loading
core/tests/coretests/src/android/util/SequenceUtilsTest.java +26 −21 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package android.util; import static android.util.SequenceUtils.getInitSeq; import static android.util.SequenceUtils.getNextSeq; import static android.util.SequenceUtils.isIncomingSeqNewer; import static android.util.SequenceUtils.isIncomingSeqStale; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -60,30 +60,35 @@ public class SequenceUtilsTest { } @Test public void testIsIncomingSeqNewer() { assertTrue(isIncomingSeqNewer(getInitSeq() + 1, getInitSeq() + 10)); assertFalse(isIncomingSeqNewer(getInitSeq() + 10, getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(-100, 100)); assertFalse(isIncomingSeqNewer(100, -100)); assertTrue(isIncomingSeqNewer(1, 2)); assertFalse(isIncomingSeqNewer(2, 1)); public void testIsIncomingSeqStale() { assertFalse(isIncomingSeqStale(getInitSeq() + 1, getInitSeq() + 10)); assertTrue(isIncomingSeqStale(getInitSeq() + 10, getInitSeq() + 1)); assertFalse(isIncomingSeqStale(-100, 100)); assertTrue(isIncomingSeqStale(100, -100)); assertFalse(isIncomingSeqStale(1, 2)); assertTrue(isIncomingSeqStale(2, 1)); // Possible incoming seq are all newer than the initial seq. assertTrue(isIncomingSeqNewer(getInitSeq(), getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(getInitSeq(), -100)); assertTrue(isIncomingSeqNewer(getInitSeq(), 0)); assertTrue(isIncomingSeqNewer(getInitSeq(), 100)); assertTrue(isIncomingSeqNewer(getInitSeq(), Integer.MAX_VALUE)); assertTrue(isIncomingSeqNewer(getInitSeq(), getNextSeq(Integer.MAX_VALUE))); assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq())); assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq() + 1)); assertFalse(isIncomingSeqStale(getInitSeq(), -100)); assertFalse(isIncomingSeqStale(getInitSeq(), 0)); assertFalse(isIncomingSeqStale(getInitSeq(), 100)); assertFalse(isIncomingSeqStale(getInitSeq(), Integer.MAX_VALUE)); assertFalse(isIncomingSeqStale(getInitSeq(), getNextSeq(Integer.MAX_VALUE))); // False for the same seq. assertFalse(isIncomingSeqNewer(getInitSeq(), getInitSeq())); assertFalse(isIncomingSeqNewer(100, 100)); assertFalse(isIncomingSeqNewer(Integer.MAX_VALUE, Integer.MAX_VALUE)); assertFalse(isIncomingSeqStale(100, 100)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, Integer.MAX_VALUE)); // True when there is a large jump (overflow). assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 1)); assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 100)); assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE))); // False when there is a large jump (overflow). assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 1)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 100)); assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE))); // True when the large jump is opposite (curSeq is newer). assertTrue(isIncomingSeqStale(getInitSeq() + 1, Integer.MAX_VALUE)); assertTrue(isIncomingSeqStale(getInitSeq() + 100, Integer.MAX_VALUE)); assertTrue(isIncomingSeqStale(getNextSeq(Integer.MAX_VALUE), Integer.MAX_VALUE)); } }
core/tests/coretests/src/android/view/ViewRootImplTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import static android.util.SequenceUtils.getInitSeq; import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; Loading Loading @@ -1555,9 +1556,9 @@ public class ViewRootImplTest { final InsetsState state0 = new InsetsState(); final InsetsState state1 = new InsetsState(); state0.setDisplayFrame(new Rect(0, 0, 500, 1000)); state0.setSeq(10000); state0.setSeq(getInitSeq() + 10000); state1.setDisplayFrame(new Rect(0, 0, 1500, 2000)); state1.setSeq(10001); state1.setSeq(getInitSeq() + 10001); final InsetsSourceControl.Array array = new InsetsSourceControl.Array(); sInstrumentation.runOnMainSync(() -> { Loading