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

Commit aca60579 authored by dshivangi's avatar dshivangi Committed by Shivangi Dubey
Browse files

Add logging for missed auto-rotate issue scenarios

The current implementation failed to capture a specific scenario: device state change -> >1500ms -> setting change -> device state change.
This sequence is valid and should be logged.

Ensure only the first change's timestamp is reset.
This allows subsequent changes to be accurately assessed for potential issues, as their timestamps are retained.

Bug: 402764691
Test: atest DeviceStateAutoRotateSettingIssueLoggerTests
Flag: com.android.window.flags.enable_device_state_auto_rotate_setting_logging
Change-Id: I32f8a53c0ab80cc96b29a65cfa18e34b0e2d87dc
parent 36c32d2a
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -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.
@@ -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;
@@ -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;
            }
        }

    }
}
+43 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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));
    }
}