Loading services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java +26 −16 Original line number Diff line number Diff line Loading @@ -29,13 +29,13 @@ import java.util.function.LongSupplier; /** * Logs potential race conditions that lead to incorrect auto-rotate setting. * * Before go/auto-rotate-refactor, there is a race condition that happen during device state * <p>Before go/auto-rotate-refactor, there is a race condition that happen during device state * changes, as a result, incorrect auto-rotate setting are written for a device state in * DEVICE_STATE_ROTATION_LOCK. Realistically, users shouldn’t be able to change * DEVICE_STATE_ROTATION_LOCK while the device folds/unfolds. * * This class monitors the time between a device state change and a subsequent change to the device * state based auto-rotate setting. If the duration is less than a threshold * <p>This class monitors the time between a device state change and a subsequent change to the * device state based auto-rotate setting. If the duration is less than a threshold * (DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD), a potential issue is logged. The logging of * the atom is not expected to occur often, realistically estimated once a month on few devices. * But the number could be bigger, as that's what this metric is set to reveal. Loading Loading @@ -72,9 +72,11 @@ public class DeviceStateAutoRotateSettingIssueLogger { } private void onStateChange() { // Only move forward if both of the events have occurred already if (mLastDeviceStateChangeTime != TIME_NOT_SET && mLastDeviceStateAutoRotateSettingChangeTime != TIME_NOT_SET) { // Only move forward if both of the events have occurred already. if (mLastDeviceStateChangeTime == TIME_NOT_SET || mLastDeviceStateAutoRotateSettingChangeTime == TIME_NOT_SET) { return; } final long duration = mLastDeviceStateAutoRotateSettingChangeTime - mLastDeviceStateChangeTime; boolean isDeviceStateChangeFirst = duration > 0; Loading @@ -85,10 +87,18 @@ public class DeviceStateAutoRotateSettingIssueLogger { FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED, (int) abs(duration), isDeviceStateChangeFirst); } // This pair is logged, reset both timestamps. mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; mLastDeviceStateChangeTime = TIME_NOT_SET; } else { // This pair was not logged, reset the earlier timestamp. if (isDeviceStateChangeFirst) { mLastDeviceStateChangeTime = TIME_NOT_SET; } else { mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; } } } } services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java +43 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.platform.test.annotations.Presubmit; Loading Loading @@ -143,4 +144,46 @@ public class DeviceStateAutoRotateSettingIssueLoggerTests { anyInt(), anyBoolean()), never()); } @Test public void onStateChange_issueOccurredSettingChangedTwice_reportOnlyOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), anyInt(), anyBoolean()), times(1)); } @Test public void onStateChange_issueOccurredDeviceStateChangedTwice_reportOnlyOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), anyInt(), anyBoolean()), times(1)); } @Test public void onStateChange_issueOccurredAfterDelay_reportOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mTestTimeSupplier.delay( DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD_MILLIS + DELAY); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mTestTimeSupplier.delay(DELAY); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), eq(DELAY), anyBoolean()), times(1)); } } Loading
services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java +26 −16 Original line number Diff line number Diff line Loading @@ -29,13 +29,13 @@ import java.util.function.LongSupplier; /** * Logs potential race conditions that lead to incorrect auto-rotate setting. * * Before go/auto-rotate-refactor, there is a race condition that happen during device state * <p>Before go/auto-rotate-refactor, there is a race condition that happen during device state * changes, as a result, incorrect auto-rotate setting are written for a device state in * DEVICE_STATE_ROTATION_LOCK. Realistically, users shouldn’t be able to change * DEVICE_STATE_ROTATION_LOCK while the device folds/unfolds. * * This class monitors the time between a device state change and a subsequent change to the device * state based auto-rotate setting. If the duration is less than a threshold * <p>This class monitors the time between a device state change and a subsequent change to the * device state based auto-rotate setting. If the duration is less than a threshold * (DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD), a potential issue is logged. The logging of * the atom is not expected to occur often, realistically estimated once a month on few devices. * But the number could be bigger, as that's what this metric is set to reveal. Loading Loading @@ -72,9 +72,11 @@ public class DeviceStateAutoRotateSettingIssueLogger { } private void onStateChange() { // Only move forward if both of the events have occurred already if (mLastDeviceStateChangeTime != TIME_NOT_SET && mLastDeviceStateAutoRotateSettingChangeTime != TIME_NOT_SET) { // Only move forward if both of the events have occurred already. if (mLastDeviceStateChangeTime == TIME_NOT_SET || mLastDeviceStateAutoRotateSettingChangeTime == TIME_NOT_SET) { return; } final long duration = mLastDeviceStateAutoRotateSettingChangeTime - mLastDeviceStateChangeTime; boolean isDeviceStateChangeFirst = duration > 0; Loading @@ -85,10 +87,18 @@ public class DeviceStateAutoRotateSettingIssueLogger { FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED, (int) abs(duration), isDeviceStateChangeFirst); } // This pair is logged, reset both timestamps. mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; mLastDeviceStateChangeTime = TIME_NOT_SET; } else { // This pair was not logged, reset the earlier timestamp. if (isDeviceStateChangeFirst) { mLastDeviceStateChangeTime = TIME_NOT_SET; } else { mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; } } } }
services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java +43 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.platform.test.annotations.Presubmit; Loading Loading @@ -143,4 +144,46 @@ public class DeviceStateAutoRotateSettingIssueLoggerTests { anyInt(), anyBoolean()), never()); } @Test public void onStateChange_issueOccurredSettingChangedTwice_reportOnlyOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), anyInt(), anyBoolean()), times(1)); } @Test public void onStateChange_issueOccurredDeviceStateChangedTwice_reportOnlyOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), anyInt(), anyBoolean()), times(1)); } @Test public void onStateChange_issueOccurredAfterDelay_reportOnce() { mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); mTestTimeSupplier.delay( DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD_MILLIS + DELAY); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); mTestTimeSupplier.delay(DELAY); mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); verify(() -> FrameworkStatsLog.write( eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), eq(DELAY), anyBoolean()), times(1)); } }