Properly handle disabled location prefetch.

The controller was still registering for location updates when location
prefetch was disabled. Now, it skips requesting location updates
altogether when location prefetch is disabled.

Bug: 279725615
Test: atest DeviceIdleTest
Test: atest FrameworksMockingServicesTests:DeviceIdleControllerTest
Change-Id: If303d5448acbc4e97132f3713a7795e46eacc5ab
This commit is contained in:
Kweku Adams
2023-04-26 18:05:17 +00:00
parent 545899f8a9
commit b6a891913a
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;