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

Commit 1837d3d0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix locking in DeviceIdleController."

parents fe29c848 58186562
Loading
Loading
Loading
Loading
+107 −33
Original line number Diff line number Diff line
@@ -298,27 +298,45 @@ public class DeviceIdleController extends SystemService
    private Intent mLightIdleIntent;
    private AnyMotionDetector mAnyMotionDetector;
    private final AppStateTrackerImpl mAppStateTracker;
    @GuardedBy("this")
    private boolean mLightEnabled;
    @GuardedBy("this")
    private boolean mDeepEnabled;
    @GuardedBy("this")
    private boolean mQuickDozeActivated;
    @GuardedBy("this")
    private boolean mQuickDozeActivatedWhileIdling;
    @GuardedBy("this")
    private boolean mForceIdle;
    @GuardedBy("this")
    private boolean mNetworkConnected;
    @GuardedBy("this")
    private boolean mScreenOn;
    @GuardedBy("this")
    private boolean mCharging;
    @GuardedBy("this")
    private boolean mNotMoving;
    @GuardedBy("this")
    private boolean mLocating;
    @GuardedBy("this")
    private boolean mLocated;
    @GuardedBy("this")
    private boolean mHasGps;
    @GuardedBy("this")
    private boolean mHasNetworkLocation;
    @GuardedBy("this")
    private Location mLastGenericLocation;
    @GuardedBy("this")
    private Location mLastGpsLocation;

    /** Time in the elapsed realtime timebase when this listener last received a motion event. */
    @GuardedBy("this")
    private long mLastMotionEventElapsed;

    // Current locked state of the screen
    @GuardedBy("this")
    private boolean mScreenLocked;
    @GuardedBy("this")
    private int mNumBlockingConstraints = 0;

    /**
@@ -434,19 +452,30 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    private int mState;
    @GuardedBy("this")
    private int mLightState;

    @GuardedBy("this")
    private long mInactiveTimeout;
    @GuardedBy("this")
    private long mNextAlarmTime;
    @GuardedBy("this")
    private long mNextIdlePendingDelay;
    @GuardedBy("this")
    private long mNextIdleDelay;
    @GuardedBy("this")
    private long mNextLightIdleDelay;
    @GuardedBy("this")
    private long mNextLightIdleDelayFlex;
    @GuardedBy("this")
    private long mNextLightAlarmTime;
    @GuardedBy("this")
    private long mNextSensingTimeoutAlarmTime;

    /** How long a light idle maintenance window should last. */
    @GuardedBy("this")
    private long mCurLightIdleBudget;

    /**
@@ -454,15 +483,20 @@ public class DeviceIdleController extends SystemService
     * only if {@link #mState} == {@link #STATE_IDLE_MAINTENANCE} or
     * {@link #mLightState} == {@link #LIGHT_STATE_IDLE_MAINTENANCE}.
     */
    @GuardedBy("this")
    private long mMaintenanceStartTime;
    @GuardedBy("this")
    private long mIdleStartTime;

    @GuardedBy("this")
    private int mActiveIdleOpCount;
    private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress
    private PowerManager.WakeLock mGoingIdleWakeLock;  // held when we are going idle so hardware
                                                       // (especially NetworkPolicyManager) can shut
                                                       // down.
    @GuardedBy("this")
    private boolean mJobsActive;
    @GuardedBy("this")
    private boolean mAlarmsActive;

    /* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter
@@ -472,8 +506,11 @@ public class DeviceIdleController extends SystemService
     * Also don't apply the factor if the device is in motion because device motion provides a
     * stronger signal than a prediction algorithm.
     */
    @GuardedBy("this")
    private float mPreIdleFactor;
    @GuardedBy("this")
    private float mLastPreIdleFactor;
    @GuardedBy("this")
    private int mActiveReason;

    public final AtomicFile mConfigFile;
@@ -659,8 +696,8 @@ public class DeviceIdleController extends SystemService
            = new AlarmManager.OnAlarmListener() {
        @Override
        public void onAlarm() {
            if (mState == STATE_SENSING) {
            synchronized (DeviceIdleController.this) {
                if (mState == STATE_SENSING) {
                    // Restart the device idle progression in case the device moved but the screen
                    // didn't turn on.
                    becomeInactiveIfAppropriateLocked();
@@ -714,6 +751,7 @@ public class DeviceIdleController extends SystemService
        mHandler.sendEmptyMessage(MSG_REPORT_STATIONARY_STATUS);
    }

    @GuardedBy("this")
    private boolean isStationaryLocked() {
        final long now = mInjector.getElapsedRealtime();
        return mMotionListener.active
@@ -1592,27 +1630,21 @@ public class DeviceIdleController extends SystemService
    @Override
    public void onAnyMotionResult(int result) {
        if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
        if (result != AnyMotionDetector.RESULT_UNKNOWN) {
        synchronized (this) {
            if (result != AnyMotionDetector.RESULT_UNKNOWN) {
                cancelSensingTimeoutAlarmLocked();
            }
        }
        if ((result == AnyMotionDetector.RESULT_MOVED) ||
            (result == AnyMotionDetector.RESULT_UNKNOWN)) {
            synchronized (this) {
            if ((result == AnyMotionDetector.RESULT_MOVED)
                    || (result == AnyMotionDetector.RESULT_UNKNOWN)) {
                handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
            }
            } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
                if (mState == STATE_SENSING) {
                    // If we are currently sensing, it is time to move to locating.
                synchronized (this) {
                    mNotMoving = true;
                    stepIdleStateLocked("s:stationary");
                }
                } else if (mState == STATE_LOCATING) {
                    // If we are currently locating, note that we are not moving and step
                    // if we have located the position.
                synchronized (this) {
                    mNotMoving = true;
                    if (mLocated) {
                        stepIdleStateLocked("s:stationary");
@@ -3062,6 +3094,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void updateInteractivityLocked() {
        // The interactivity state from the power manager tells us whether the display is
        // in a state that we need to keep things running so they will update at a normal
@@ -3089,6 +3122,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void updateChargingLocked(boolean charging) {
        if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
        if (!charging && mCharging) {
@@ -3114,6 +3148,7 @@ public class DeviceIdleController extends SystemService

    /** Updates the quick doze flag and enters deep doze if appropriate. */
    @VisibleForTesting
    @GuardedBy("this")
    void updateQuickDozeFlagLocked(boolean enabled) {
        if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
        mQuickDozeActivated = enabled;
@@ -3138,6 +3173,7 @@ public class DeviceIdleController extends SystemService
    }

    @VisibleForTesting
    @GuardedBy("this")
    void keyguardShowingLocked(boolean showing) {
        if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
        if (mScreenLocked != showing) {
@@ -3150,15 +3186,18 @@ public class DeviceIdleController extends SystemService
    }

    @VisibleForTesting
    @GuardedBy("this")
    void scheduleReportActiveLocked(String activeReason, int activeUid) {
        Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
        mHandler.sendMessage(msg);
    }

    @GuardedBy("this")
    void becomeActiveLocked(String activeReason, int activeUid) {
        becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true);
    }

    @GuardedBy("this")
    private void becomeActiveLocked(String activeReason, int activeUid,
            long newInactiveTimeout, boolean changeLightIdle) {
        if (DEBUG) {
@@ -3204,6 +3243,7 @@ public class DeviceIdleController extends SystemService
    }

    /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */
    @GuardedBy("this")
    private void verifyAlarmStateLocked() {
        if (mState == STATE_ACTIVE && mNextAlarmTime != 0) {
            Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime);
@@ -3221,6 +3261,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void becomeInactiveIfAppropriateLocked() {
        verifyAlarmStateLocked();

@@ -3300,6 +3341,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    private void resetIdleManagementLocked() {
        mNextIdlePendingDelay = 0;
        mNextIdleDelay = 0;
@@ -3313,6 +3355,7 @@ public class DeviceIdleController extends SystemService
        updateActiveConstraintsLocked();
    }

    @GuardedBy("this")
    private void resetLightIdleManagementLocked() {
        mNextLightIdleDelay = 0;
        mNextLightIdleDelayFlex = 0;
@@ -3320,6 +3363,7 @@ public class DeviceIdleController extends SystemService
        cancelLightAlarmLocked();
    }

    @GuardedBy("this")
    void exitForceIdleLocked() {
        if (mForceIdle) {
            mForceIdle = false;
@@ -3344,9 +3388,12 @@ public class DeviceIdleController extends SystemService

    @VisibleForTesting
    int getLightState() {
        synchronized (this) {
            return mLightState;
        }
    }

    @GuardedBy("this")
    void stepLightIdleStateLocked(String reason) {
        if (mLightState == LIGHT_STATE_OVERRIDE) {
            // If we are already in deep device idle mode, then
@@ -3435,8 +3482,10 @@ public class DeviceIdleController extends SystemService

    @VisibleForTesting
    int getState() {
        synchronized (this) {
            return mState;
        }
    }

    /**
     * Returns true if there's an upcoming AlarmClock alarm that is soon enough to prevent the
@@ -3448,6 +3497,7 @@ public class DeviceIdleController extends SystemService
    }

    @VisibleForTesting
    @GuardedBy("this")
    void stepIdleStateLocked(String reason) {
        if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
        EventLogTags.writeDeviceIdleStep();
@@ -3588,6 +3638,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    private void moveToStateLocked(int state, String reason) {
        final int oldState = mState;
        mState = state;
@@ -3667,11 +3718,14 @@ public class DeviceIdleController extends SystemService

    @VisibleForTesting
    float getPreIdleTimeoutFactor() {
        synchronized (this) {
            return mPreIdleFactor;
        }
    }

    @VisibleForTesting
    int setPreIdleTimeoutFactor(float ratio) {
        synchronized (this) {
            if (!mDeepEnabled) {
                if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable");
                return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT;
@@ -3679,10 +3733,11 @@ public class DeviceIdleController extends SystemService
                if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Invalid input");
                return SET_IDLE_FACTOR_RESULT_INVALID;
            } else if (Math.abs(ratio - mPreIdleFactor) < MIN_PRE_IDLE_FACTOR_CHANGE) {
            if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor");
                if (DEBUG) {
                    Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor");
                }
                return SET_IDLE_FACTOR_RESULT_IGNORED;
            }
        synchronized (this) {
            mLastPreIdleFactor = mPreIdleFactor;
            mPreIdleFactor = ratio;
        }
@@ -3744,6 +3799,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    private boolean shouldUseIdleTimeoutFactorLocked() {
        // exclude ACTIVE_REASON_MOTION, for exclude device in pocket case
        if (mActiveReason == ACTIVE_REASON_MOTION) {
@@ -3763,13 +3819,17 @@ public class DeviceIdleController extends SystemService

    @VisibleForTesting
    long getNextAlarmTime() {
        synchronized (this) {
            return mNextAlarmTime;
        }
    }

    @GuardedBy("this")
    boolean isOpsInactiveLocked() {
        return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive;
    }

    @GuardedBy("this")
    void exitMaintenanceEarlyIfNeededLocked() {
        if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
                || mLightState == LIGHT_STATE_PRE_IDLE) {
@@ -3794,12 +3854,14 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void motionLocked() {
        if (DEBUG) Slog.d(TAG, "motionLocked()");
        mLastMotionEventElapsed = mInjector.getElapsedRealtime();
        handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
    }

    @GuardedBy("this")
    void handleMotionDetectedLocked(long timeout, String type) {
        if (mStationaryListeners.size() > 0) {
            postStationaryStatusUpdated();
@@ -3829,6 +3891,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void receivedGenericLocationLocked(Location location) {
        if (mState != STATE_LOCATING) {
            cancelLocatingLocked();
@@ -3845,6 +3908,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void receivedGpsLocationLocked(Location location) {
        if (mState != STATE_LOCATING) {
            cancelLocatingLocked();
@@ -3883,6 +3947,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void cancelAlarmLocked() {
        if (mNextAlarmTime != 0) {
            mNextAlarmTime = 0;
@@ -3890,6 +3955,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void cancelLightAlarmLocked() {
        if (mNextLightAlarmTime != 0) {
            mNextLightAlarmTime = 0;
@@ -3897,6 +3963,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void cancelLocatingLocked() {
        if (mLocating) {
            LocationManager locationManager = mInjector.getLocationManager();
@@ -3914,6 +3981,7 @@ public class DeviceIdleController extends SystemService
        mAlarmManager.cancel(mMotionRegistrationAlarmListener);
    }

    @GuardedBy("this")
    void cancelSensingTimeoutAlarmLocked() {
        if (mNextSensingTimeoutAlarmTime != 0) {
            mNextSensingTimeoutAlarmTime = 0;
@@ -3921,6 +3989,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void scheduleAlarmLocked(long delay, boolean idleUntil) {
        if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");

@@ -3957,6 +4026,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void scheduleLightAlarmLocked(long delay, long flex) {
        if (DEBUG) {
            Slog.d(TAG, "scheduleLightAlarmLocked(" + delay
@@ -4003,6 +4073,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    void scheduleSensingTimeoutAlarmLocked(long delay) {
        if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
        mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
@@ -4071,6 +4142,7 @@ public class DeviceIdleController extends SystemService
     * @param callingUid the callingUid that setup this temp-allowlist, only valid when param adding
     *                   is true.
     */
    @GuardedBy("this")
    private void updateTempWhitelistAppIdsLocked(int uid, boolean adding, long durationMs,
            @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason,
            int callingUid) {
@@ -4120,6 +4192,7 @@ public class DeviceIdleController extends SystemService
                mTempWhitelistAppIdArray);
    }

    @GuardedBy("this")
    void readConfigFileLocked() {
        if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
        mPowerSaveWhitelistUserApps.clear();
@@ -4142,6 +4215,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    @GuardedBy("this")
    private void readConfigFileLocked(XmlPullParser parser) {
        final PackageManager pm = getContext().getPackageManager();

@@ -4987,7 +5061,7 @@ public class DeviceIdleController extends SystemService
                pw.println();
            }
            if (mNextLightIdleDelay != 0) {
                pw.print("  mNextIdleDelay=");
                pw.print("  mNextLightIdleDelay=");
                TimeUtils.formatDuration(mNextLightIdleDelay, pw);
                if (mConstants.USE_WINDOW_ALARMS) {
                    pw.print(" (flex=");