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

Commit 01f655a0 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Avoid repeated/redundant work." into main

parents f6e3f562 40f71889
Loading
Loading
Loading
Loading
+29 −13
Original line number Diff line number Diff line
@@ -82,6 +82,10 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
     * be a negative value if the device is not in state to be considered idle.
     */
    private long mIdlenessCheckScheduledElapsed = -1;
    /**
     * Time (in the elapsed realtime timebase) when the device can be considered idle.
     */
    private long mIdleStartElapsed = Long.MAX_VALUE;

    private IdlenessListener mIdleListener;
    private final UiModeManager.OnProjectionStateChangedListener mOnProjectionStateChangedListener =
@@ -191,11 +195,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
        }
        mProjectionActive = projectionActive;
        if (mProjectionActive) {
            cancelIdlenessCheck();
            if (mIdle) {
                mIdle = false;
                mIdleListener.reportNewIdleState(mIdle);
            }
            exitIdle();
        } else {
            maybeScheduleIdlenessCheck("Projection ended");
        }
@@ -209,6 +209,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
        pw.print("  mDockIdle: "); pw.println(mDockIdle);
        pw.print("  mProjectionActive: "); pw.println(mProjectionActive);
        pw.print("  mIdlenessCheckScheduledElapsed: "); pw.println(mIdlenessCheckScheduledElapsed);
        pw.print("  mIdleStartElapsed: "); pw.println(mIdleStartElapsed);
    }

    @Override
@@ -270,11 +271,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
                if (DEBUG) {
                    Slog.v(TAG, "exiting idle");
                }
                cancelIdlenessCheck();
                if (mIdle) {
                    mIdle = false;
                    mIdleListener.reportNewIdleState(mIdle);
                }
                exitIdle();
                break;
            case Intent.ACTION_SCREEN_OFF:
            case Intent.ACTION_DREAMING_STARTED:
@@ -302,6 +299,12 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
    }

    private void maybeScheduleIdlenessCheck(String reason) {
        if (mIdle) {
            if (DEBUG) {
                Slog.w(TAG, "Already idle. Redundant reason=" + reason);
            }
            return;
        }
        if ((!mScreenOn || mDockIdle) && !mProjectionActive) {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final long inactivityThresholdMs = mIsStablePower
@@ -319,19 +322,32 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
                mIdlenessCheckScheduledElapsed = nowElapsed;
            }
            final long when = mIdlenessCheckScheduledElapsed + inactivityThresholdMs;
            if (when == mIdleStartElapsed) {
                if (DEBUG) {
                    Slog.i(TAG, "No change to idle start time");
                }
                return;
            }
            mIdleStartElapsed = when;
            if (DEBUG) {
                Slog.v(TAG, "Scheduling idle : " + reason + " now:" + nowElapsed
                        + " checkElapsed=" + mIdlenessCheckScheduledElapsed + " when=" + when);
                        + " checkElapsed=" + mIdlenessCheckScheduledElapsed
                        + " when=" + mIdleStartElapsed);
            }
            mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    when, mIdleWindowSlop, "JS idleness",
                    mIdleStartElapsed, mIdleWindowSlop, "JS idleness",
                    AppSchedulingModuleThread.getExecutor(), mIdleAlarmListener);
        }
    }

    private void cancelIdlenessCheck() {
    private void exitIdle() {
        mAlarm.cancel(mIdleAlarmListener);
        mIdlenessCheckScheduledElapsed = -1;
        mIdleStartElapsed = Long.MAX_VALUE;
        if (mIdle) {
            mIdle = false;
            mIdleListener.reportNewIdleState(false);
        }
    }

    private void handleIdleTrigger() {
+71 −0
Original line number Diff line number Diff line
@@ -162,6 +162,77 @@ public class DeviceIdlenessTrackerTest {
        mDeviceIdlenessTracker.processConstant(mDeviceConfigPropertiesBuilder.build(), key);
    }

    @Test
    public void testAlarmSkippedIfAlreadyIdle() {
        setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, MINUTE_IN_MILLIS);
        setDeviceConfigLong(KEY_INACTIVITY_STABLE_POWER_IDLE_THRESHOLD_MS, 5 * MINUTE_IN_MILLIS);
        setBatteryState(false, false);

        Intent dockIdleIntent = new Intent(Intent.ACTION_DOCK_IDLE);
        mBroadcastReceiver.onReceive(mContext, dockIdleIntent);

        final long nowElapsed = sElapsedRealtimeClock.millis();
        long expectedAlarmElapsed = nowElapsed + MINUTE_IN_MILLIS;

        ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerCaptor =
                ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);

        InOrder inOrder = inOrder(mAlarmManager);
        inOrder.verify(mAlarmManager)
                .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
                        eq(AppSchedulingModuleThread.getExecutor()),
                        onAlarmListenerCaptor.capture());

        AlarmManager.OnAlarmListener onAlarmListener = onAlarmListenerCaptor.getValue();

        advanceElapsedClock(MINUTE_IN_MILLIS);

        onAlarmListener.onAlarm();

        // Now in idle.

        // Trigger SCREEN_OFF. Make sure alarm isn't set again.
        Intent screenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
        mBroadcastReceiver.onReceive(mContext, screenOffIntent);

        inOrder.verify(mAlarmManager, never())
                .setWindow(anyInt(), anyLong(), anyLong(), anyString(),
                        eq(AppSchedulingModuleThread.getExecutor()), any());
    }

    @Test
    public void testAlarmSkippedIfNoThresholdChange() {
        setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);
        setDeviceConfigLong(KEY_INACTIVITY_STABLE_POWER_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);
        setBatteryState(false, false);

        Intent screenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
        mBroadcastReceiver.onReceive(mContext, screenOffIntent);

        final long nowElapsed = sElapsedRealtimeClock.millis();
        long expectedAlarmElapsed = nowElapsed + 10 * MINUTE_IN_MILLIS;

        InOrder inOrder = inOrder(mAlarmManager);
        inOrder.verify(mAlarmManager)
                .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
                        eq(AppSchedulingModuleThread.getExecutor()), any());

        // Advanced the clock a little to make sure the tracker continues to use the original time.
        advanceElapsedClock(MINUTE_IN_MILLIS);

        // Now on stable power. Thresholds are the same, so alarm doesn't need to be rescheduled.
        setBatteryState(true, true);
        inOrder.verify(mAlarmManager, never())
                .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
                        eq(AppSchedulingModuleThread.getExecutor()), any());

        // Not on stable power. Thresholds are the same, so alarm doesn't need to be rescheduled.
        setBatteryState(false, false);
        inOrder.verify(mAlarmManager, never())
                .setWindow(anyInt(), anyLong(), anyLong(), anyString(),
                        eq(AppSchedulingModuleThread.getExecutor()), any());
    }

    @Test
    public void testThresholdChangeWithStablePowerChange() {
        setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);