Merge "Adding more PowerManager tests."

This commit is contained in:
TreeHugger Robot
2019-02-28 23:33:44 +00:00
committed by Android (Google) Code Review
3 changed files with 303 additions and 41 deletions

View File

@@ -715,6 +715,15 @@ public final class PowerManagerService extends SystemService
NativeWrapper createNativeWrapper() {
return new NativeWrapper();
}
WirelessChargerDetector createWirelessChargerDetector(
SensorManager sensorManager, SuspendBlocker suspendBlocker, Handler handler) {
return new WirelessChargerDetector(sensorManager, suspendBlocker, handler);
}
AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) {
return new AmbientDisplayConfiguration(context);
}
}
final Constants mConstants;
@@ -747,7 +756,7 @@ public final class PowerManagerService extends SystemService
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
mConstants = new Constants(mHandler);
mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
mBatterySavingStats = new BatterySavingStats(mLock);
@@ -833,7 +842,7 @@ public final class PowerManagerService extends SystemService
mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
mPolicy);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
mInjector.createSuspendBlocker(
this, "PowerManagerService.WirelessChargerDetector"),
mHandler);
@@ -932,7 +941,8 @@ public final class PowerManagerService extends SystemService
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
}
private void readConfigurationLocked() {
@VisibleForTesting
void readConfigurationLocked() {
final Resources resources = mContext.getResources();
mDecoupleHalAutoSuspendModeFromDisplayConfig = resources.getBoolean(
@@ -3865,7 +3875,8 @@ public final class PowerManagerService extends SystemService
return workSource != null ? new WorkSource(workSource) : null;
}
private final class BatteryReceiver extends BroadcastReceiver {
@VisibleForTesting
final class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
@@ -3883,7 +3894,8 @@ public final class PowerManagerService extends SystemService
}
}
private final class UserSwitchedReceiver extends BroadcastReceiver {
@VisibleForTesting
final class UserSwitchedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {

View File

@@ -28,6 +28,8 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
/**
@@ -70,7 +72,8 @@ import java.io.PrintWriter;
* sensor to detect this case.
* </p>
*/
final class WirelessChargerDetector {
@VisibleForTesting
public class WirelessChargerDetector {
private static final String TAG = "WirelessChargerDetector";
private static final boolean DEBUG = false;

View File

@@ -18,44 +18,67 @@ package com.android.server.power;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManagerInternal;
import android.attention.AttentionManagerInternal;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.hardware.SensorManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerSaveState;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.test.InstrumentationRegistry;
import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.PowerManagerService.BatteryReceiver;
import com.android.server.power.PowerManagerService.Injector;
import com.android.server.power.PowerManagerService.NativeWrapper;
import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
import com.android.server.power.batterysaver.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySavingStats;
import org.junit.Rule;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -65,29 +88,54 @@ import java.util.Map;
/**
* Tests for {@link com.android.server.power.PowerManagerService}
*/
public class PowerManagerServiceTest extends AndroidTestCase {
public class PowerManagerServiceTest {
private static final float PRECISION = 0.001f;
private static final float BRIGHTNESS_FACTOR = 0.7f;
private static final boolean BATTERY_SAVER_ENABLED = true;
private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
private @Mock BatterySaverPolicy mBatterySaverPolicyMock;
private @Mock LightsManager mLightsManagerMock;
private @Mock DisplayManagerInternal mDisplayManagerInternalMock;
private @Mock BatteryManagerInternal mBatteryManagerInternalMock;
private @Mock ActivityManagerInternal mActivityManagerInternalMock;
private @Mock AttentionManagerInternal mAttentionManagerInternalMock;
private @Mock PowerManagerService.NativeWrapper mNativeWrapperMock;
private @Mock Notifier mNotifierMock;
@Mock private BatterySaverPolicy mBatterySaverPolicyMock;
@Mock private LightsManager mLightsManagerMock;
@Mock private DisplayManagerInternal mDisplayManagerInternalMock;
@Mock private BatteryManagerInternal mBatteryManagerInternalMock;
@Mock private ActivityManagerInternal mActivityManagerInternalMock;
@Mock private AttentionManagerInternal mAttentionManagerInternalMock;
@Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
@Mock private Notifier mNotifierMock;
@Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock;
private PowerManagerService mService;
private PowerSaveState mPowerSaveState;
private DisplayPowerRequest mDisplayPowerRequest;
private ContextWrapper mContextSpy;
private BatteryReceiver mBatteryReceiver;
private UserSwitchedReceiver mUserSwitchedReceiver;
private Resources mResourcesSpy;
private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
private final IntentFilter mFilter;
IntentFilterMatcher(IntentFilter filter) {
mFilter = filter;
}
@Rule
@Override
public boolean matches(IntentFilter other) {
if (other.countActions() != mFilter.countActions()) {
return false;
}
for (int i = 0; i < mFilter.countActions(); i++) {
if (!mFilter.getAction(i).equals(other.getAction(i))) {
return false;
}
}
return true;
}
}
@Before
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
mPowerSaveState = new PowerSaveState.Builder()
@@ -105,33 +153,54 @@ public class PowerManagerServiceTest extends AndroidTestCase {
addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock);
mService = new PowerManagerService(getContext(), new Injector() {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
mResourcesSpy = spy(mContextSpy.getResources());
when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
mService = new PowerManagerService(mContextSpy, new Injector() {
@Override
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
return mNotifierMock;
}
@Override
SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
return mock(SuspendBlocker.class);
}
@Override
BatterySaverPolicy createBatterySaverPolicy(
Object lock, Context context, BatterySavingStats batterySavingStats) {
return mBatterySaverPolicyMock;
}
@Override
NativeWrapper createNativeWrapper() {
return mNativeWrapperMock;
}
@Override
WirelessChargerDetector createWirelessChargerDetector(
SensorManager sensorManager, SuspendBlocker suspendBlocker, Handler handler) {
return mWirelessChargerDetectorMock;
}
@Override
AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) {
return mAmbientDisplayConfigurationMock;
}
});
}
@Override
@After
public void tearDown() throws Exception {
LocalServices.removeServiceForTest(LightsManager.class);
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.removeServiceForTest(BatteryManagerInternal.class);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
Settings.Global.putInt(
mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
}
/**
@@ -142,7 +211,56 @@ public class PowerManagerServiceTest extends AndroidTestCase {
LocalServices.addService(clazz, mock);
}
@SmallTest
private void startSystem() throws Exception {
mService.systemReady(null);
// Grab the BatteryReceiver
ArgumentCaptor<BatteryReceiver> batCaptor = ArgumentCaptor.forClass(BatteryReceiver.class);
IntentFilter batFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
batFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
verify(mContextSpy).registerReceiver(batCaptor.capture(),
argThat(new IntentFilterMatcher(batFilter)), isNull(), isA(Handler.class));
mBatteryReceiver = batCaptor.getValue();
// Grab the UserSwitchedReceiver
ArgumentCaptor<UserSwitchedReceiver> userSwitchedCaptor =
ArgumentCaptor.forClass(UserSwitchedReceiver.class);
IntentFilter usFilter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
verify(mContextSpy).registerReceiver(userSwitchedCaptor.capture(),
argThat(new IntentFilterMatcher(usFilter)), isNull(), isA(Handler.class));
mUserSwitchedReceiver = userSwitchedCaptor.getValue();
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
}
private void forceSleep() {
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
}
private void forceDream() {
mService.getBinderServiceInstance().nap(SystemClock.uptimeMillis());
}
private void forceAwake() {
mService.getBinderServiceInstance().wakeUp(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
}
private void forceDozing() {
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
}
private void setPluggedIn(boolean isPluggedIn) {
// Set the callback to return the new state
when(mBatteryManagerInternalMock.isPowered(BatteryManager.BATTERY_PLUGGED_ANY))
.thenReturn(isPluggedIn);
// Trigger PowerManager to reread the plug-in state
mBatteryReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_BATTERY_CHANGED));
}
@Test
public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() {
mService.updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
assertThat(mDisplayPowerRequest.lowPowerMode).isEqualTo(BATTERY_SAVER_ENABLED);
@@ -150,7 +268,7 @@ public class PowerManagerServiceTest extends AndroidTestCase {
.isWithin(PRECISION).of(BRIGHTNESS_FACTOR);
}
@SmallTest
@Test
public void testGetLastShutdownReasonInternal() {
SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "shutdown,thermal");
int reason = mService.getLastShutdownReasonInternal(TEST_LAST_REBOOT_PROPERTY);
@@ -158,7 +276,7 @@ public class PowerManagerServiceTest extends AndroidTestCase {
assertThat(reason).isEqualTo(PowerManager.SHUTDOWN_REASON_THERMAL_SHUTDOWN);
}
@SmallTest
@Test
public void testGetDesiredScreenPolicy_WithVR() throws Exception {
// Brighten up the screen
mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
@@ -187,42 +305,171 @@ public class PowerManagerServiceTest extends AndroidTestCase {
DisplayPowerRequest.POLICY_BRIGHT);
}
@SmallTest
@Test
public void testWakefulnessAwake_InitialValue() throws Exception {
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
}
@SmallTest
@Test
public void testWakefulnessSleep_NoDozeSleepFlag() throws Exception {
// Start with AWAKE state
startSystem();
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
mService.systemReady(null);
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
// Take a nap with a flag.
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@MediumTest
@Test
public void testWakefulnessAwake_AcquireCausesWakeup() throws Exception {
startSystem();
forceSleep();
IBinder token = new Binder();
String tag = "acq_causes_wakeup";
String packageName = "pkg.name";
// First, ensure that a normal full wake lock does not cause a wakeup
int flags = PowerManager.FULL_WAKE_LOCK;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Ensure that the flag does *NOT* work with a partial wake lock.
flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK
flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
}
@Test
public void testWakefulnessAwake_IPowerManagerWakeUp() throws Exception {
startSystem();
forceSleep();
mService.getBinderServiceInstance().wakeUp(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
}
/**
* Tests a series of variants that control whether a device wakes-up when it is plugged in
* or docked.
*/
@Test
public void testWakefulnessAwake_ShouldWakeUpWhenPluggedIn() throws Exception {
boolean powerState;
startSystem();
forceSleep();
// Test 1:
// Set config to prevent it wake up, test, verify, reset config value.
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(false);
mService.readConfigurationLocked();
setPluggedIn(true);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true);
mService.readConfigurationLocked();
// Test 2:
// Turn the power off, sleep, then plug into a wireless charger.
// Verify that we do not wake up if the phone is being plugged into a wireless charger.
setPluggedIn(false);
forceSleep();
when(mBatteryManagerInternalMock.getPlugType())
.thenReturn(BatteryManager.BATTERY_PLUGGED_WIRELESS);
when(mWirelessChargerDetectorMock.update(true /* isPowered */,
BatteryManager.BATTERY_PLUGGED_WIRELESS)).thenReturn(false);
setPluggedIn(true);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 3:
// Do not wake up if the phone is being REMOVED from a wireless charger
when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
setPluggedIn(false);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 4:
// Do not wake if we are dreaming.
forceAwake(); // Needs to be awake first before it can dream.
forceDream();
setPluggedIn(true);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DREAMING);
forceSleep();
// Test 5:
// Don't wake if the device is configured not to wake up in theater mode (and theater
// mode is enabled).
Settings.Global.putInt(
mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 1);
mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
when(mResourcesSpy.getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug))
.thenReturn(false);
setPluggedIn(false);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
Settings.Global.putInt(
mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
// Test 6:
// Don't wake up if we are Dozing away and always-on is enabled.
when(mAmbientDisplayConfigurationMock.alwaysOnEnabled(UserHandle.USER_CURRENT))
.thenReturn(true);
mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
forceAwake();
forceDozing();
setPluggedIn(true);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
// Test 7:
// Finally, take away all the factors above and ensure the device wakes up!
forceAwake();
forceSleep();
setPluggedIn(false);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
public void testWakefulnessDoze_goToSleep() throws Exception {
// Start with AWAKE state
startSystem();
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
}
@Test
public void testWasDeviceIdleFor_true() {
int interval = 1000;
mService.onUserActivity();
SystemClock.sleep(interval);
SystemClock.sleep(interval + 1 /* just a little more */);
assertThat(mService.wasDeviceIdleForInternal(interval)).isTrue();
}
@SmallTest
@Test
public void testWasDeviceIdleFor_false() {
int interval = 1000;
mService.onUserActivity();
assertThat(mService.wasDeviceIdleForInternal(interval)).isFalse();
}
@SmallTest
@Test
public void testForceSuspend_putsDeviceToSleep() {
mService.systemReady(null);
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
@@ -244,11 +491,11 @@ public class PowerManagerServiceTest extends AndroidTestCase {
assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@SmallTest
@Test
public void testForceSuspend_pakeLocksDisabled() {
final String tag = "TestWakelockTag_098213";
final int flags = PowerManager.PARTIAL_WAKE_LOCK;
final String pkg = getContext().getOpPackageName();
final String pkg = mContextSpy.getOpPackageName();
// Set up the Notification mock to keep track of the wakelocks that are currently
// active or disabled. We'll use this to verify that wakelocks are disabled when
@@ -292,7 +539,7 @@ public class PowerManagerServiceTest extends AndroidTestCase {
}
@SmallTest
@Test
public void testForceSuspend_forceSuspendFailurePropogated() {
when(mNativeWrapperMock.nativeForceSuspend()).thenReturn(false);
assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();