summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java66
-rw-r--r--services/tests/mockingservicestests/Android.mk1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java248
3 files changed, 281 insertions, 34 deletions
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 26421a2acb66..0b30ff5cc398 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -242,11 +242,9 @@ public class DeviceIdleController extends SystemService
private ActivityTaskManagerInternal mLocalActivityTaskManager;
private PowerManagerInternal mLocalPowerManager;
private PowerManager mPowerManager;
- private ConnectivityService mConnectivityService;
private INetworkPolicyManager mNetworkPolicyManager;
private SensorManager mSensorManager;
private Sensor mMotionSensor;
- private LocationManager mLocationManager;
private LocationRequest mLocationRequest;
private Intent mIdleIntent;
private Intent mLightIdleIntent;
@@ -1508,6 +1506,8 @@ public class DeviceIdleController extends SystemService
static class Injector {
private final Context mContext;
+ private ConnectivityService mConnectivityService;
+ private LocationManager mLocationManager;
Injector(Context ctx) {
mContext = ctx;
@@ -1527,7 +1527,11 @@ public class DeviceIdleController extends SystemService
}
ConnectivityService getConnectivityService() {
- return (ConnectivityService) ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ if (mConnectivityService == null) {
+ mConnectivityService = (ConnectivityService) ServiceManager.getService(
+ Context.CONNECTIVITY_SERVICE);
+ }
+ return mConnectivityService;
}
Constants getConstants(DeviceIdleController controller, Handler handler,
@@ -1536,7 +1540,10 @@ public class DeviceIdleController extends SystemService
}
LocationManager getLocationManager() {
- return mContext.getSystemService(LocationManager.class);
+ if (mLocationManager == null) {
+ mLocationManager = mContext.getSystemService(LocationManager.class);
+ }
+ return mLocationManager;
}
MyHandler getHandler(DeviceIdleController controller) {
@@ -1666,7 +1673,6 @@ public class DeviceIdleController extends SystemService
mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"deviceidle_going_idle");
mGoingIdleWakeLock.setReferenceCounted(true);
- mConnectivityService = mInjector.getConnectivityService();
mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
@@ -1689,7 +1695,6 @@ public class DeviceIdleController extends SystemService
if (getContext().getResources().getBoolean(
com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
- mLocationManager = mInjector.getLocationManager();
mLocationRequest = new LocationRequest()
.setQuality(LocationRequest.ACCURACY_FINE)
.setInterval(0)
@@ -2160,10 +2165,17 @@ public class DeviceIdleController extends SystemService
}
}
+ @VisibleForTesting
+ boolean isNetworkConnected() {
+ synchronized (this) {
+ return mNetworkConnected;
+ }
+ }
+
void updateConnectivityState(Intent connIntent) {
ConnectivityService cm;
synchronized (this) {
- cm = mConnectivityService;
+ cm = mInjector.getConnectivityService();
}
if (cm == null) {
return;
@@ -2276,13 +2288,17 @@ public class DeviceIdleController extends SystemService
/** Must only be used in tests. */
@VisibleForTesting
void setDeepEnabledForTest(boolean enabled) {
- mDeepEnabled = enabled;
+ synchronized (this) {
+ mDeepEnabled = enabled;
+ }
}
/** Must only be used in tests. */
@VisibleForTesting
void setLightEnabledForTest(boolean enabled) {
- mLightEnabled = enabled;
+ synchronized (this) {
+ mLightEnabled = enabled;
+ }
}
void becomeInactiveIfAppropriateLocked() {
@@ -2338,7 +2354,9 @@ public class DeviceIdleController extends SystemService
*/
@VisibleForTesting
void setLightStateForTest(int lightState) {
- mLightState = lightState;
+ synchronized (this) {
+ mLightState = lightState;
+ }
}
@VisibleForTesting
@@ -2429,12 +2447,6 @@ public class DeviceIdleController extends SystemService
}
}
- /** Must only be used in tests. */
- @VisibleForTesting
- void setLocationManagerForTest(LocationManager lm) {
- mLocationManager = lm;
- }
-
@VisibleForTesting
int getState() {
return mState;
@@ -2486,18 +2498,19 @@ public class DeviceIdleController extends SystemService
if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
EventLogTags.writeDeviceIdle(mState, reason);
scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
- if (mLocationManager != null
- && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
- mLocationManager.requestLocationUpdates(mLocationRequest,
+ LocationManager locationManager = mInjector.getLocationManager();
+ if (locationManager != null
+ && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+ locationManager.requestLocationUpdates(mLocationRequest,
mGenericLocationListener, mHandler.getLooper());
mLocating = true;
} else {
mHasNetworkLocation = false;
}
- if (mLocationManager != null
- && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+ if (locationManager != null
+ && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
mHasGps = true;
- mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
mGpsLocationListener, mHandler.getLooper());
mLocating = true;
} else {
@@ -2575,7 +2588,9 @@ public class DeviceIdleController extends SystemService
/** Must only be used in tests. */
@VisibleForTesting
void setActiveIdleOpsForTest(int count) {
- mActiveIdleOpCount = count;
+ synchronized (this) {
+ mActiveIdleOpCount = count;
+ }
}
void setJobsActive(boolean active) {
@@ -2751,8 +2766,9 @@ public class DeviceIdleController extends SystemService
void cancelLocatingLocked() {
if (mLocating) {
- mLocationManager.removeUpdates(mGenericLocationListener);
- mLocationManager.removeUpdates(mGpsLocationListener);
+ LocationManager locationManager = mInjector.getLocationManager();
+ locationManager.removeUpdates(mGenericLocationListener);
+ locationManager.removeUpdates(mGpsLocationListener);
mLocating = false;
}
}
diff --git a/services/tests/mockingservicestests/Android.mk b/services/tests/mockingservicestests/Android.mk
index 8c0283318419..b83a79fc232c 100644
--- a/services/tests/mockingservicestests/Android.mk
+++ b/services/tests/mockingservicestests/Android.mk
@@ -22,6 +22,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
frameworks-base-testutils \
services.core \
+ services.net \
androidx-test \
mockito-target-extended-minus-junit4 \
platform-test-annotations \
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 95ed00f3ad5b..7e7b1436a912 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -41,6 +41,9 @@ import static com.android.server.DeviceIdleController.lightStateToString;
import static com.android.server.DeviceIdleController.stateToString;
import static org.junit.Assert.assertEquals;
+
+import android.net.NetworkInfo;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -50,6 +53,8 @@ import static org.mockito.ArgumentMatchers.anyString;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
+import android.net.ConnectivityManager;
+import android.content.Intent;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -83,11 +88,14 @@ public class DeviceIdleControllerTest {
private DeviceIdleController mDeviceIdleController;
private AnyMotionDetectorForTest mAnyMotionDetector;
private AppStateTrackerForTest mAppStateTracker;
+ private InjectorForTest mInjector;
private MockitoSession mMockingSession;
@Mock
private AlarmManager mAlarmManager;
@Mock
+ private ConnectivityService mConnectivityService;
+ @Mock
private DeviceIdleController.Constants mConstants;
@Mock
private IActivityManager mIActivityManager;
@@ -99,6 +107,8 @@ public class DeviceIdleControllerTest {
private PowerManager.WakeLock mWakeLock;
class InjectorForTest extends DeviceIdleController.Injector {
+ ConnectivityService connectivityService;
+ LocationManager locationManager;
InjectorForTest(Context ctx) {
super(ctx);
@@ -122,18 +132,19 @@ public class DeviceIdleControllerTest {
@Override
ConnectivityService getConnectivityService() {
- return null;
+ return connectivityService;
}
@Override
- DeviceIdleController.Constants getConstants(DeviceIdleController controller, Handler handler,
+ DeviceIdleController.Constants getConstants(DeviceIdleController controller,
+ Handler handler,
ContentResolver resolver) {
return mConstants;
}
@Override
LocationManager getLocationManager() {
- return mLocationManager;
+ return locationManager;
}
@Override
@@ -201,8 +212,8 @@ public class DeviceIdleControllerTest {
doNothing().when(mWakeLock).acquire();
mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
mAnyMotionDetector = new AnyMotionDetectorForTest();
- mDeviceIdleController = new DeviceIdleController(getContext(),
- new InjectorForTest(getContext()));
+ mInjector = new InjectorForTest(getContext());
+ mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
spyOn(mDeviceIdleController);
doNothing().when(mDeviceIdleController).publishBinderService(any(), any());
mDeviceIdleController.onStart();
@@ -271,6 +282,60 @@ public class DeviceIdleControllerTest {
}
@Test
+ public void testUpdateConnectivityState() {
+ // No connectivity service
+ final boolean isConnected = mDeviceIdleController.isNetworkConnected();
+ mInjector.connectivityService = null;
+ mDeviceIdleController.updateConnectivityState(null);
+ assertEquals(isConnected, mDeviceIdleController.isNetworkConnected());
+
+ // No active network info
+ mInjector.connectivityService = mConnectivityService;
+ doReturn(null).when(mConnectivityService).getActiveNetworkInfo();
+ mDeviceIdleController.updateConnectivityState(null);
+ assertFalse(mDeviceIdleController.isNetworkConnected());
+
+ // Active network info says connected.
+ final NetworkInfo ani = mock(NetworkInfo.class);
+ doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+ doReturn(true).when(ani).isConnected();
+ mDeviceIdleController.updateConnectivityState(null);
+ assertTrue(mDeviceIdleController.isNetworkConnected());
+
+ // Active network info says not connected.
+ doReturn(false).when(ani).isConnected();
+ mDeviceIdleController.updateConnectivityState(null);
+ assertFalse(mDeviceIdleController.isNetworkConnected());
+
+ // Wrong intent passed (false).
+ Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
+ doReturn(true).when(ani).isConnected();
+ doReturn(1).when(ani).getType();
+ mDeviceIdleController.updateConnectivityState(intent);
+ // Wrong intent means we shouldn't update the connected state.
+ assertFalse(mDeviceIdleController.isNetworkConnected());
+
+ // Intent says connected.
+ doReturn(1).when(ani).getType();
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
+ intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+ mDeviceIdleController.updateConnectivityState(intent);
+ assertTrue(mDeviceIdleController.isNetworkConnected());
+
+ // Wrong intent passed (true).
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
+ // Wrong intent means we shouldn't update the connected state.
+ assertTrue(mDeviceIdleController.isNetworkConnected());
+
+ // Intent says not connected.
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
+ intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
+ mDeviceIdleController.updateConnectivityState(intent);
+ assertFalse(mDeviceIdleController.isNetworkConnected());
+ }
+
+ @Test
public void testStateActiveToStateInactive_ConditionsNotMet() {
mDeviceIdleController.becomeActiveLocked("testing", 0);
verifyStateConditions(STATE_ACTIVE);
@@ -361,7 +426,7 @@ public class DeviceIdleControllerTest {
@Test
public void testStepIdleStateLocked_ValidStates_NoLocationManager() {
- mDeviceIdleController.setLocationManagerForTest(null);
+ mInjector.locationManager = null;
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
// Set state to INACTIVE.
@@ -427,6 +492,7 @@ public class DeviceIdleControllerTest {
@Test
public void testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders() {
+ mInjector.locationManager = mLocationManager;
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
// TODO: add tests for when there's a wake-from-idle alarm coming soon.
@@ -463,6 +529,160 @@ public class DeviceIdleControllerTest {
}
@Test
+ public void testLightStepIdleStateLocked_InvalidStates() {
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ // stepLightIdleStateLocked doesn't handle the ACTIVE case, so the state
+ // should stay as ACTIVE.
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ }
+
+ /**
+ * Make sure stepLightIdleStateLocked doesn't change state when the state is
+ * LIGHT_STATE_OVERRIDE.
+ */
+ @Test
+ public void testLightStepIdleStateLocked_Overriden() {
+ enterLightState(LIGHT_STATE_OVERRIDE);
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+ }
+
+ @Test
+ public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NetworkConnected() {
+ setNetworkConnected(true);
+ mDeviceIdleController.setJobsActive(false);
+ mDeviceIdleController.setAlarmsActive(false);
+ mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+ // Set state to INACTIVE.
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+ // No active ops means INACTIVE should go straight to IDLE.
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+ }
+
+ @Test
+ public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NetworkConnected() {
+ setNetworkConnected(true);
+ // Set state to INACTIVE.
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+ // Active ops means INACTIVE should go to PRE_IDLE to wait.
+ mDeviceIdleController.setJobsActive(true);
+ mDeviceIdleController.setAlarmsActive(true);
+ mDeviceIdleController.setActiveIdleOpsForTest(1);
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+ // Even with active ops, PRE_IDLE should go to IDLE.
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+ }
+
+ @Test
+ public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NoNetworkConnected() {
+ setNetworkConnected(false);
+ mDeviceIdleController.setJobsActive(false);
+ mDeviceIdleController.setAlarmsActive(false);
+ mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+ // Set state to INACTIVE.
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+ // No active ops means INACTIVE should go straight to IDLE.
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+ }
+
+ @Test
+ public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NoNetworkConnected() {
+ setNetworkConnected(false);
+ // Set state to INACTIVE.
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+ // Active ops means INACTIVE should go to PRE_IDLE to wait.
+ mDeviceIdleController.setJobsActive(true);
+ mDeviceIdleController.setAlarmsActive(true);
+ mDeviceIdleController.setActiveIdleOpsForTest(1);
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+ // Even with active ops, PRE_IDLE should go to IDLE.
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+ mDeviceIdleController.stepLightIdleStateLocked("testing");
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+ }
+
+ @Test
public void testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps() {
mDeviceIdleController.setJobsActive(false);
mDeviceIdleController.setAlarmsActive(false);
@@ -903,6 +1123,7 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.becomeActiveLocked("testing", 0);
break;
case STATE_LOCATING:
+ mInjector.locationManager = mLocationManager;
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(
anyString());
// Fallthrough to step loop.
@@ -917,7 +1138,6 @@ public class DeviceIdleControllerTest {
setScreenOn(false);
setChargingOn(false);
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
- //fail(stateToString(mDeviceIdleController.getState()));
int count = 0;
while (mDeviceIdleController.getState() != state) {
// Stepping through each state ensures that the proper features are turned
@@ -925,7 +1145,8 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.stepIdleStateLocked("testing");
count++;
if (count > 10) {
- fail(stateToString(mDeviceIdleController.getState()));
+ fail("Infinite loop. Check test configuration. Currently at " +
+ stateToString(mDeviceIdleController.getState()));
}
}
break;
@@ -954,7 +1175,8 @@ public class DeviceIdleControllerTest {
count++;
if (count > 10) {
- fail(lightStateToString(mDeviceIdleController.getLightState()));
+ fail("Infinite loop. Check test configuration. Currently at " +
+ lightStateToString(mDeviceIdleController.getLightState()));
}
}
break;
@@ -979,6 +1201,14 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.updateInteractivityLocked();
}
+ private void setNetworkConnected(boolean connected) {
+ mInjector.connectivityService = mConnectivityService;
+ final NetworkInfo ani = mock(NetworkInfo.class);
+ doReturn(connected).when(ani).isConnected();
+ doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+ mDeviceIdleController.updateConnectivityState(null);
+ }
+
private void verifyStateConditions(int expectedState) {
int curState = mDeviceIdleController.getState();
assertEquals(