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

Commit f4bef470 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add validation before logging ScreenInteractiveSessionReported" into main

parents ed43b148 51f86b52
Loading
Loading
Loading
Loading
+51 −52
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayAddress;
@@ -70,12 +71,11 @@ import java.lang.annotation.RetentionPolicy;
public class WakefulnessSessionObserver {
    private static final String TAG = "WakefulnessSessionObserver";

    private static final int OFF_REASON_UNKNOWN = FrameworkStatsLog
    static final int OFF_REASON_UNKNOWN = FrameworkStatsLog
            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__UNKNOWN;
    private static final int OFF_REASON_TIMEOUT = FrameworkStatsLog
    static final int OFF_REASON_TIMEOUT = FrameworkStatsLog
            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__TIMEOUT;
    @VisibleForTesting
    protected static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog
    static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog
            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__POWER_BUTTON;

    /**
@@ -90,25 +90,21 @@ public class WakefulnessSessionObserver {
    @Retention(RetentionPolicy.SOURCE)
    private @interface OffReason {}

    private static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__UNKNOWN;
    @VisibleForTesting
    protected static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_SUCCESS;
    @VisibleForTesting
    protected static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_USER_INITIATED_REVERT;
    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_API_CALL;
    @VisibleForTesting
    protected static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_USER_INTERACTION;
    @VisibleForTesting
    protected static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_POWER_BUTTON;
    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_DISCONNECTED;
    private static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog
    static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog
            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_OTHER;

    /**
@@ -128,19 +124,15 @@ public class WakefulnessSessionObserver {
    @Retention(RetentionPolicy.SOURCE)
    private @interface OverrideOutcome {}

    private static final int POLICY_REASON_UNKNOWN = FrameworkStatsLog
    static final int POLICY_REASON_UNKNOWN = FrameworkStatsLog
            .SCREEN_DIM_REPORTED__POLICY_REASON__UNKNOWN;
    @VisibleForTesting
    protected static final int POLICY_REASON_OFF_TIMEOUT = FrameworkStatsLog
    static final int POLICY_REASON_OFF_TIMEOUT = FrameworkStatsLog
            .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_TIMEOUT;
    @VisibleForTesting
    protected static final int POLICY_REASON_OFF_POWER_BUTTON = FrameworkStatsLog
    static final int POLICY_REASON_OFF_POWER_BUTTON = FrameworkStatsLog
            .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_POWER_BUTTON;
    @VisibleForTesting
    protected static final int POLICY_REASON_BRIGHT_UNDIM = FrameworkStatsLog
    static final int POLICY_REASON_BRIGHT_UNDIM = FrameworkStatsLog
            .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_UNDIM;
    @VisibleForTesting
    protected static final int POLICY_REASON_BRIGHT_INITIATED_REVERT = FrameworkStatsLog
    static final int POLICY_REASON_BRIGHT_INITIATED_REVERT = FrameworkStatsLog
            .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_INITIATED_REVERT;

    /**
@@ -157,21 +149,18 @@ public class WakefulnessSessionObserver {
    @Retention(RetentionPolicy.SOURCE)
    private @interface PolicyReason {}

    @VisibleForTesting protected static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
    private static final long USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
    private static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
    @VisibleForTesting
    protected static final long SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS = 500L;
    static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
    static final long USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
    static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
    static final long SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS = 500L;

    @VisibleForTesting protected static final Object HANDLER_TOKEN = new Object();
    static final Object HANDLER_TOKEN = new Object();

    private Context mContext;
    private int mScreenOffTimeoutMs;
    private int mOverrideTimeoutMs = 0;
    @VisibleForTesting
    protected final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>();
    @VisibleForTesting
    protected WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
    final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>();
    WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
    private final Clock mClock;
    private final Object mLock = new Object();
    private final Handler mHandler;
@@ -347,7 +336,8 @@ public class WakefulnessSessionObserver {
        writer.println();
    }

    private void updateSettingScreenOffTimeout(Context context) {
    @VisibleForTesting
    void updateSettingScreenOffTimeout(Context context) {
        synchronized (mLock) {
            mScreenOffTimeoutMs = Settings.System.getIntForUser(
                    context.getContentResolver(),
@@ -453,6 +443,7 @@ public class WakefulnessSessionObserver {
                return;
            }

            final int screenOffTimeoutMs = getScreenOffTimeout();
            mIsInteractive = isInteractive(wakefulness);
            if (mIsInteractive) {
                mInteractiveStateOnStartTimestamp = eventTime;
@@ -466,7 +457,7 @@ public class WakefulnessSessionObserver {
                                mPowerGroupId,
                                OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT,
                                mOverrideTimeoutMs,
                                getScreenOffTimeout());
                                screenOffTimeoutMs);
                        mSendOverrideTimeoutLogTimestamp = eventTime;
                    }
                    mTimeoutOffTimestamp = TIMEOUT_OFF_RESET_TIMESTAMP;
@@ -496,7 +487,7 @@ public class WakefulnessSessionObserver {
                                mPowerGroupId,
                                OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON,
                                mOverrideTimeoutMs,
                                getScreenOffTimeout());
                                screenOffTimeoutMs);
                        mSendOverrideTimeoutLogTimestamp = eventTime;
                        mTimeoutOverrideReleaseReason = RELEASE_REASON_UNKNOWN; // reset the reason
                    }
@@ -514,13 +505,12 @@ public class WakefulnessSessionObserver {
                    // timeout has been done successfully.
                    if (isInOverrideTimeout()) {
                        reducedInteractiveStateOnDurationMs =
                                getScreenOffTimeout() - mOverrideTimeoutMs;

                                screenOffTimeoutMs - mOverrideTimeoutMs;
                        mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
                                mPowerGroupId,
                                OVERRIDE_OUTCOME_TIMEOUT_SUCCESS,
                                mOverrideTimeoutMs,
                                getScreenOffTimeout());
                                screenOffTimeoutMs);
                        mSendOverrideTimeoutLogTimestamp = eventTime;

                        // Record a timestamp to track if the user initiates to revert from off
@@ -533,6 +523,9 @@ public class WakefulnessSessionObserver {

                long interactiveStateOnDurationMs =
                        eventTime - mInteractiveStateOnStartTimestamp;

                if (reducedInteractiveStateOnDurationMs < screenOffTimeoutMs
                        && reducedInteractiveStateOnDurationMs >= 0) {
                    mWakefulnessSessionFrameworkStatsLogger.logSessionEvent(
                            mPowerGroupId,
                            interactiveStateOffReason,
@@ -540,6 +533,11 @@ public class WakefulnessSessionObserver {
                            lastUserActivity,
                            lastUserActivityDurationMs,
                            reducedInteractiveStateOnDurationMs);
                } else {
                    Slog.w(TAG, "invalid reducedInteractiveStateOnDurationMs: "
                            + reducedInteractiveStateOnDurationMs);
                }

            }
        }

@@ -608,6 +606,7 @@ public class WakefulnessSessionObserver {
                return;
            }

            final int screenOffTimeoutMs = getScreenOffTimeout();
            int dimDurationMs = 0;
            int lastUserActivity = mCurrentUserActivityEvent;
            int lastUserActivityDurationMs = (int) (eventTime - mCurrentUserActivityTimestamp);
@@ -625,7 +624,7 @@ public class WakefulnessSessionObserver {
                            lastUserActivity,
                            lastUserActivityDurationMs,
                            dimDurationMs,
                            mScreenOffTimeoutMs);
                            screenOffTimeoutMs);
                    mPastDimDurationMs = dimDurationMs;
                    return;
                }
@@ -645,7 +644,7 @@ public class WakefulnessSessionObserver {
                                lastUserActivity,
                                lastUserActivityDurationMs,
                                dimDurationMs,
                                mScreenOffTimeoutMs);
                                screenOffTimeoutMs);
                        mHandler.removeCallbacksAndMessages(HANDLER_TOKEN);
                    }

@@ -674,7 +673,7 @@ public class WakefulnessSessionObserver {
                                    savedLastUserActivity,
                                    savedLastUserActivityDurationMs,
                                    savedDimDurationMs,
                                    mScreenOffTimeoutMs);
                                    screenOffTimeoutMs);
                            mPastDimDurationMs = savedDimDurationMs;
                        }, HANDLER_TOKEN, SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS);
                    }
@@ -692,7 +691,7 @@ public class WakefulnessSessionObserver {
                                lastUserActivity,
                                lastUserActivityDurationMs,
                                mPastDimDurationMs,
                                mScreenOffTimeoutMs);
                                screenOffTimeoutMs);
                    }
                    return;
                }
+115 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN;
import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH;
import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_POWER_BUTTON;
import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_TIMEOUT;
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON;
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION;
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_SUCCESS;
@@ -40,6 +41,7 @@ import static com.android.server.power.WakefulnessSessionObserver.POLICY_REASON_
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -90,6 +92,7 @@ public class WakefulnessSessionObserverTest {
            mWakefulnessSessionFrameworkStatsLogger;
    @Mock
    private DisplayManagerInternal mDisplayManagerInternal;
    private MockContentResolver mContentResolver = new MockContentResolver();

    private TestHandler mHandler;
    @Before
@@ -106,10 +109,9 @@ public class WakefulnessSessionObserverTest {
                R.integer.config_screenTimeoutOverride);
        when(mContext.getResources()).thenReturn(res);
        FakeSettingsProvider.clearSettingsProvider();
        MockContentResolver mockContentResolver = new MockContentResolver();
        mockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
        when(mContext.getContentResolver()).thenReturn(mockContentResolver);
        Settings.System.putIntForUser(mockContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);

        final DisplayInfo info = new DisplayInfo();
@@ -511,6 +513,115 @@ public class WakefulnessSessionObserverTest {
                        DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
    }

    @Test
    public void testScreenOffTimeout_normal_logSessionEventTriggered() {
        int powerGroupId = 1;
        int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
        triggerLogSessionEvent(powerGroupId, userActivity);
        verify(mWakefulnessSessionFrameworkStatsLogger)
                .logSessionEvent(
                        powerGroupId, // powerGroupId
                        OFF_REASON_TIMEOUT, // interactiveStateOffReason
                        0, // interactiveStateOnDurationMs
                        userActivity, // userActivity
                        0,  // lastUserActivityEventDurationMs
                        DEFAULT_SCREEN_OFF_TIMEOUT_MS - OVERRIDE_SCREEN_OFF_TIMEOUT_MS
                ); // reducedInteractiveStateOnDurationMs;
    }

    @Test
    public void testScreenOffTimeout_zero_noLogSessionEventTriggered() {
        // simulate adding an invalid screen_off_timeout value
        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                0, // invalid timeout value
                UserHandle.USER_CURRENT);
        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);

        try {
            triggerLogSessionEvent();
            verify(mWakefulnessSessionFrameworkStatsLogger, never())
                    .logSessionEvent(anyInt(), anyInt(), anyLong(), anyInt(), anyLong(), anyInt());
        } finally {
            // rollback the original data
            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
        }
    }

    @Test
    public void testScreenOffTimeout_negative_noLogSessionEventTriggered() {
        // simulate adding an invalid screen_off_timeout value
        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                -1, // invalid timeout value
                UserHandle.USER_CURRENT);
        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);

        try {
            triggerLogSessionEvent();
            verify(mWakefulnessSessionFrameworkStatsLogger, never())
                    .logSessionEvent(anyInt(), anyInt(), anyLong(), anyInt(), anyLong(), anyInt());
        } finally {
            // rollback the original data
            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
        }
    }

    @Test
    public void testScreenOffTimeout_max_logSessionEventTriggered() {
        // simulate adding the max screen_off_timeout value
        int defaultTimeoutMs = Integer.MAX_VALUE;
        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                defaultTimeoutMs,
                UserHandle.USER_CURRENT);
        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);

        try {
            int powerGroupId = 1;
            int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
            triggerLogSessionEvent(powerGroupId, userActivity);
            verify(mWakefulnessSessionFrameworkStatsLogger)
                    .logSessionEvent(
                            powerGroupId, // powerGroupId
                            OFF_REASON_TIMEOUT, // interactiveStateOffReason
                            0, // interactiveStateOnDurationMs
                            userActivity, // userActivity
                            0,  // lastUserActivityEventDurationMs
                            defaultTimeoutMs - OVERRIDE_SCREEN_OFF_TIMEOUT_MS
                    ); // reducedInteractiveStateOnDurationMs;
        } finally {
            // rollback the original data
            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
        }
    }

    private void triggerLogSessionEvent() {
        triggerLogSessionEvent(1, PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY);
    }

    private void triggerLogSessionEvent(int powerGroupId, int userActivity) {
        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
                powerGroupId,
                PowerManagerInternal.WAKEFULNESS_AWAKE,
                WAKE_REASON_POWER_BUTTON,
                mTestClock.now());
        mWakefulnessSessionObserver.onWakeLockAcquired(
                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);

        long userActivityTime = mTestClock.now();
        mWakefulnessSessionObserver.notifyUserActivity(
                userActivityTime, powerGroupId, userActivity);
        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
                powerGroupId,
                PowerManagerInternal.WAKEFULNESS_DOZING,
                GO_TO_SLEEP_REASON_TIMEOUT,
                mTestClock.now());
    }

    private void advanceTime(long timeMs) {
        mTestClock.fastForward(timeMs);
    }