Merge "Fix locking in DeviceIdleController."
This commit is contained in:
committed by
Android (Google) Code Review
commit
1837d3d0fb
@@ -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) {
|
||||
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) {
|
||||
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) {
|
||||
} else if (result == AnyMotionDetector.RESULT_STATIONARY) {
|
||||
if (mState == STATE_SENSING) {
|
||||
// If we are currently sensing, it is time to move to locating.
|
||||
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) {
|
||||
} else if (mState == STATE_LOCATING) {
|
||||
// If we are currently locating, note that we are not moving and step
|
||||
// if we have located the position.
|
||||
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() {
|
||||
return mLightState;
|
||||
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,7 +3482,9 @@ public class DeviceIdleController extends SystemService
|
||||
|
||||
@VisibleForTesting
|
||||
int getState() {
|
||||
return mState;
|
||||
synchronized (this) {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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,22 +3718,26 @@ public class DeviceIdleController extends SystemService
|
||||
|
||||
@VisibleForTesting
|
||||
float getPreIdleTimeoutFactor() {
|
||||
return mPreIdleFactor;
|
||||
synchronized (this) {
|
||||
return mPreIdleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int setPreIdleTimeoutFactor(float ratio) {
|
||||
if (!mDeepEnabled) {
|
||||
if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable");
|
||||
return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT;
|
||||
} else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) {
|
||||
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");
|
||||
return SET_IDLE_FACTOR_RESULT_IGNORED;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (!mDeepEnabled) {
|
||||
if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable");
|
||||
return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT;
|
||||
} else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) {
|
||||
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");
|
||||
}
|
||||
return SET_IDLE_FACTOR_RESULT_IGNORED;
|
||||
}
|
||||
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() {
|
||||
return mNextAlarmTime;
|
||||
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=");
|
||||
|
||||
Reference in New Issue
Block a user