Merge "Properly handle disabled location prefetch." into udc-dev

This commit is contained in:
Kweku Adams
2023-04-27 21:00:43 +00:00
committed by Android (Google) Code Review
2 changed files with 136 additions and 36 deletions

View File

@@ -319,6 +319,8 @@ public class DeviceIdleController extends SystemService
private SensorManager mSensorManager;
private final boolean mUseMotionSensor;
private Sensor mMotionSensor;
private final boolean mIsLocationPrefetchEnabled;
@Nullable
private LocationRequest mLocationRequest;
private Intent mIdleIntent;
private Bundle mIdleIntentOptions;
@@ -2460,6 +2462,11 @@ public class DeviceIdleController extends SystemService
return null;
}
boolean isLocationPrefetchEnabled() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_autoPowerModePrefetchLocation);
}
boolean useMotionSensor() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
@@ -2489,6 +2496,7 @@ public class DeviceIdleController extends SystemService
mAppStateTracker = mInjector.getAppStateTracker(context,
AppSchedulingModuleThread.get().getLooper());
LocalServices.addService(AppStateTracker.class, mAppStateTracker);
mIsLocationPrefetchEnabled = mInjector.isLocationPrefetchEnabled();
mUseMotionSensor = mInjector.useMotionSensor();
}
@@ -2602,8 +2610,7 @@ public class DeviceIdleController extends SystemService
mMotionSensor = mInjector.getMotionSensor();
}
if (getContext().getResources().getBoolean(
com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
if (mIsLocationPrefetchEnabled) {
mLocationRequest = new LocationRequest.Builder(/*intervalMillis=*/ 0)
.setQuality(LocationRequest.QUALITY_HIGH_ACCURACY)
.setMaxUpdates(1)
@@ -3779,34 +3786,40 @@ public class DeviceIdleController extends SystemService
case STATE_SENSING:
cancelSensingTimeoutAlarmLocked();
moveToStateLocked(STATE_LOCATING, reason);
scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT);
LocationManager locationManager = mInjector.getLocationManager();
if (locationManager != null
&& locationManager.getProvider(LocationManager.FUSED_PROVIDER) != null) {
locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER,
mLocationRequest,
AppSchedulingModuleThread.getExecutor(),
mGenericLocationListener);
mLocating = true;
if (mIsLocationPrefetchEnabled) {
scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT);
LocationManager locationManager = mInjector.getLocationManager();
if (locationManager != null
&& locationManager.getProvider(LocationManager.FUSED_PROVIDER)
!= null) {
locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER,
mLocationRequest,
AppSchedulingModuleThread.getExecutor(),
mGenericLocationListener);
mLocating = true;
} else {
mHasFusedLocation = false;
}
if (locationManager != null
&& locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
mHasGps = true;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
1000, 5, mGpsLocationListener, mHandler.getLooper());
mLocating = true;
} else {
mHasGps = false;
}
// If we have a location provider, we're all set, the listeners will move state
// forward.
if (mLocating) {
break;
}
// Otherwise, we have to move from locating into idle maintenance.
} else {
mHasFusedLocation = false;
}
if (locationManager != null
&& locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
mHasGps = true;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
mGpsLocationListener, mHandler.getLooper());
mLocating = true;
} else {
mHasGps = false;
}
// If we have a location provider, we're all set, the listeners will move state
// forward.
if (mLocating) {
break;
mLocating = false;
}
// Otherwise, we have to move from locating into idle maintenance.
// We're not doing any locating work, so move on to the next state.
case STATE_LOCATING:
cancelAlarmLocked();
cancelLocatingLocked();
@@ -5303,15 +5316,19 @@ public class DeviceIdleController extends SystemService
pw.print(" "); pw.print(mStationaryListeners.size());
pw.println(" stationary listeners registered");
}
pw.print(" mLocating="); pw.print(mLocating);
pw.print(" mHasGps="); pw.print(mHasGps);
pw.print(" mHasFused="); pw.print(mHasFusedLocation);
pw.print(" mLocated="); pw.println(mLocated);
if (mLastGenericLocation != null) {
pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
}
if (mLastGpsLocation != null) {
pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
if (mIsLocationPrefetchEnabled) {
pw.print(" mLocating="); pw.print(mLocating);
pw.print(" mHasGps="); pw.print(mHasGps);
pw.print(" mHasFused="); pw.print(mHasFusedLocation);
pw.print(" mLocated="); pw.println(mLocated);
if (mLastGenericLocation != null) {
pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
}
if (mLastGpsLocation != null) {
pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
}
} else {
pw.println(" Location prefetching disabled");
}
pw.print(" mState="); pw.print(stateToString(mState));
pw.print(" mLightState=");

View File

@@ -154,6 +154,7 @@ public class DeviceIdleControllerTest {
// Freeze time for testing.
long nowElapsed;
boolean useMotionSensor = true;
boolean isLocationPrefetchEnabled = true;
InjectorForTest(Context ctx) {
super(ctx);
@@ -222,6 +223,11 @@ public class DeviceIdleControllerTest {
return mMotionSensor;
}
@Override
boolean isLocationPrefetchEnabled() {
return isLocationPrefetchEnabled;
}
@Override
PowerManager getPowerManager() {
return mPowerManager;
@@ -990,6 +996,43 @@ public class DeviceIdleControllerTest {
verifyStateConditions(STATE_IDLE_MAINTENANCE);
}
@Test
public void testStepIdleStateLocked_ValidStates_LocationPrefetchDisabled() {
mInjector.locationManager = mLocationManager;
mInjector.isLocationPrefetchEnabled = false;
cleanupDeviceIdleController();
setupDeviceIdleController();
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
setAlarmSoon(false);
// Set state to INACTIVE.
mDeviceIdleController.becomeActiveLocked("testing", 0);
setChargingOn(false);
setScreenOn(false);
verifyStateConditions(STATE_INACTIVE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_PENDING);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_SENSING);
mDeviceIdleController.stepIdleStateLocked("testing");
// Prefetch location is off, so SENSING should go straight through to IDLE.
verifyStateConditions(STATE_IDLE);
// Should just alternate between IDLE and IDLE_MAINTENANCE now.
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_MAINTENANCE);
}
@Test
public void testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders() {
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
@@ -1023,6 +1066,46 @@ public class DeviceIdleControllerTest {
verifyStateConditions(STATE_IDLE_MAINTENANCE);
}
@Test
public void testStepIdleStateLocked_ValidStates_WithLocationManager_MissingProviders() {
mInjector.locationManager = mLocationManager;
doReturn(null).when(mLocationManager)
.getProvider(eq(LocationManager.FUSED_PROVIDER));
doReturn(null).when(mLocationManager)
.getProvider(eq(LocationManager.GPS_PROVIDER));
doReturn(mock(LocationProvider.class)).when(mLocationManager)
.getProvider(eq(LocationManager.NETWORK_PROVIDER));
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
setAlarmSoon(false);
// Set state to INACTIVE.
mDeviceIdleController.becomeActiveLocked("testing", 0);
setChargingOn(false);
setScreenOn(false);
verifyStateConditions(STATE_INACTIVE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_PENDING);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_SENSING);
mDeviceIdleController.stepIdleStateLocked("testing");
// Location manager exists, but the required providers don't exist,
// so SENSING should go straight through to IDLE.
verifyStateConditions(STATE_IDLE);
// Should just alternate between IDLE and IDLE_MAINTENANCE now.
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE_MAINTENANCE);
}
@Test
public void testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders() {
mInjector.locationManager = mLocationManager;