Merge "Fix problem with AOD when secondary power groups are awake" into udc-dev am: 6fbe5c119f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22923176 Change-Id: Ic1cad699190fe1c2f552dda6a864017c53086766 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -55,6 +55,7 @@ interface IPowerManager
|
|||||||
float getBrightnessConstraint(int constraint);
|
float getBrightnessConstraint(int constraint);
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
boolean isInteractive();
|
boolean isInteractive();
|
||||||
|
boolean isDisplayInteractive(int displayId);
|
||||||
boolean areAutoPowerSaveModesEnabled();
|
boolean areAutoPowerSaveModesEnabled();
|
||||||
boolean isPowerSaveMode();
|
boolean isPowerSaveMode();
|
||||||
PowerSaveState getPowerSaveState(int serviceType);
|
PowerSaveState getPowerSaveState(int serviceType);
|
||||||
|
|||||||
@@ -1150,13 +1150,17 @@ public final class PowerManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final PropertyInvalidatedCache<Void, Boolean> mInteractiveCache =
|
private final PropertyInvalidatedCache<Integer, Boolean> mInteractiveCache =
|
||||||
new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES,
|
new PropertyInvalidatedCache<Integer, Boolean>(MAX_CACHE_ENTRIES,
|
||||||
CACHE_KEY_IS_INTERACTIVE_PROPERTY) {
|
CACHE_KEY_IS_INTERACTIVE_PROPERTY) {
|
||||||
@Override
|
@Override
|
||||||
public Boolean recompute(Void query) {
|
public Boolean recompute(Integer displayId) {
|
||||||
try {
|
try {
|
||||||
|
if (displayId == null) {
|
||||||
return mService.isInteractive();
|
return mService.isInteractive();
|
||||||
|
} else {
|
||||||
|
return mService.isDisplayInteractive(displayId);
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -1802,6 +1806,18 @@ public final class PowerManager {
|
|||||||
return mInteractiveCache.query(null);
|
return mInteractiveCache.query(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the interactive state for a specific display, which may not be the same as the
|
||||||
|
* global wakefulness (which is true when any display is awake).
|
||||||
|
*
|
||||||
|
* @param displayId
|
||||||
|
* @return whether the given display is present and interactive, or false
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isInteractive(int displayId) {
|
||||||
|
return mInteractiveCache.query(displayId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if this device supports rebooting userspace.
|
* Returns {@code true} if this device supports rebooting userspace.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.database.ContentObserver
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.view.Display
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager.fixScale
|
import android.view.WindowManager.fixScale
|
||||||
@@ -272,7 +273,7 @@ class UnlockedScreenOffAnimationController @Inject constructor(
|
|||||||
// dispatched, a race condition could make it possible for this callback to be run
|
// dispatched, a race condition could make it possible for this callback to be run
|
||||||
// as the device is waking up. That results in the AOD UI being shown while we wake
|
// as the device is waking up. That results in the AOD UI being shown while we wake
|
||||||
// up, with unpredictable consequences.
|
// up, with unpredictable consequences.
|
||||||
if (!powerManager.isInteractive) {
|
if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY)) {
|
||||||
aodUiAnimationPlaying = true
|
aodUiAnimationPlaying = true
|
||||||
|
|
||||||
// Show AOD. That'll cause the KeyguardVisibilityHelper to call
|
// Show AOD. That'll cause the KeyguardVisibilityHelper to call
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.os.Handler
|
|||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
|
import android.view.Display
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.jank.InteractionJankMonitor
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
@@ -29,6 +30,7 @@ import com.android.systemui.shade.ShadeViewController
|
|||||||
import com.android.systemui.statusbar.LightRevealScrim
|
import com.android.systemui.statusbar.LightRevealScrim
|
||||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl
|
import com.android.systemui.statusbar.StatusBarStateControllerImpl
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.settings.GlobalSettings
|
import com.android.systemui.util.settings.GlobalSettings
|
||||||
import junit.framework.Assert.assertFalse
|
import junit.framework.Assert.assertFalse
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@@ -141,7 +143,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testAodUiNotShownIfInteractive() {
|
fun testAodUiNotShownIfInteractive() {
|
||||||
`when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
|
`when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
|
||||||
`when`(powerManager.isInteractive).thenReturn(true)
|
`when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(true)
|
||||||
|
|
||||||
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
|
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
|
||||||
controller.startAnimation()
|
controller.startAnimation()
|
||||||
@@ -152,6 +154,21 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
|
|||||||
verify(shadeViewController, never()).showAodUi()
|
verify(shadeViewController, never()).showAodUi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAodUiShownIfGloballyInteractiveButDefaultDisplayNotInteractive() {
|
||||||
|
`when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
|
||||||
|
`when`(powerManager.isInteractive()).thenReturn(false)
|
||||||
|
`when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(false)
|
||||||
|
|
||||||
|
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
|
||||||
|
controller.startAnimation()
|
||||||
|
|
||||||
|
verify(handler).postDelayed(callbackCaptor.capture(), anyLong())
|
||||||
|
callbackCaptor.value.run()
|
||||||
|
|
||||||
|
verify(shadeViewController).showAodUi()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNoAnimationPlaying_dozeParamsCanNotControlScreenOff() {
|
fun testNoAnimationPlaying_dozeParamsCanNotControlScreenOff() {
|
||||||
`when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(false)
|
`when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(false)
|
||||||
|
|||||||
@@ -2079,6 +2079,7 @@ public final class PowerManagerService extends SystemService
|
|||||||
int opUid, String opPackageName, String details) {
|
int opUid, String opPackageName, String details) {
|
||||||
mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid,
|
mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid,
|
||||||
opPackageName, details);
|
opPackageName, details);
|
||||||
|
mInjector.invalidateIsInteractiveCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@@ -3743,12 +3744,32 @@ public final class PowerManagerService extends SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInteractiveInternal() {
|
private boolean isGloballyInteractiveInternal() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked());
|
return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInteractiveInternal(int displayId, int uid) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
|
||||||
|
if (displayInfo == null) {
|
||||||
|
Slog.w(TAG, "Did not find DisplayInfo for displayId " + displayId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!displayInfo.hasAccess(uid)) {
|
||||||
|
throw new SecurityException(
|
||||||
|
"uid " + uid + " does not have access to display " + displayId);
|
||||||
|
}
|
||||||
|
PowerGroup powerGroup = mPowerGroups.get(displayInfo.displayGroupId);
|
||||||
|
if (powerGroup == null) {
|
||||||
|
Slog.w(TAG, "Did not find PowerGroup for displayId " + displayId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return PowerManagerInternal.isInteractive(powerGroup.getWakefulnessLocked());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean setLowPowerModeInternal(boolean enabled) {
|
private boolean setLowPowerModeInternal(boolean enabled) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -5805,7 +5826,18 @@ public final class PowerManagerService extends SystemService
|
|||||||
public boolean isInteractive() {
|
public boolean isInteractive() {
|
||||||
final long ident = Binder.clearCallingIdentity();
|
final long ident = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
return isInteractiveInternal();
|
return isGloballyInteractiveInternal();
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public boolean isDisplayInteractive(int displayId) {
|
||||||
|
int uid = Binder.getCallingUid();
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
return isInteractiveInternal(displayId, uid);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import android.os.IBinder;
|
|||||||
import android.os.IWakeLockCallback;
|
import android.os.IWakeLockCallback;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
import android.os.PowerManagerInternal;
|
||||||
import android.os.PowerSaveState;
|
import android.os.PowerSaveState;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
@@ -117,6 +118,7 @@ import org.mockito.stubbing.Answer;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@@ -150,6 +152,7 @@ public class PowerManagerServiceTest {
|
|||||||
@Mock private SystemPropertiesWrapper mSystemPropertiesMock;
|
@Mock private SystemPropertiesWrapper mSystemPropertiesMock;
|
||||||
@Mock private AppOpsManager mAppOpsManagerMock;
|
@Mock private AppOpsManager mAppOpsManagerMock;
|
||||||
@Mock private LowPowerStandbyController mLowPowerStandbyControllerMock;
|
@Mock private LowPowerStandbyController mLowPowerStandbyControllerMock;
|
||||||
|
@Mock private Callable<Void> mInvalidateInteractiveCachesMock;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
|
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
|
||||||
@@ -310,7 +313,11 @@ public class PowerManagerServiceTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void invalidateIsInteractiveCaches() {
|
void invalidateIsInteractiveCaches() {
|
||||||
// Avoids an SELinux failure.
|
try {
|
||||||
|
mInvalidateInteractiveCachesMock.call();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2317,6 +2324,140 @@ public class PowerManagerServiceTest {
|
|||||||
eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), eq(eventTime));
|
eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), eq(eventTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_isInteractive_nonExistentGroup() {
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
|
||||||
|
int nonExistentDisplayGroup = 999;
|
||||||
|
BinderService binderService = mService.getBinderServiceInstance();
|
||||||
|
assertThat(binderService.isDisplayInteractive(nonExistentDisplayGroup)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testMultiDisplay_isInteractive_returnsCorrectValue(
|
||||||
|
boolean defaultDisplayAwake, boolean secondGroupDisplayAwake) {
|
||||||
|
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||||
|
// We use a display id that does not match the group id, to make sure we aren't accidentally
|
||||||
|
// confusing display id's and display group id's in the implementation.
|
||||||
|
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 17;
|
||||||
|
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||||
|
new AtomicReference<>();
|
||||||
|
doAnswer((Answer<Void>) invocation -> {
|
||||||
|
listener.set(invocation.getArgument(0));
|
||||||
|
return null;
|
||||||
|
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||||
|
|
||||||
|
final DisplayInfo defaultDisplayInfo = new DisplayInfo();
|
||||||
|
defaultDisplayInfo.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
|
||||||
|
when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(
|
||||||
|
defaultDisplayInfo);
|
||||||
|
|
||||||
|
final DisplayInfo secondDisplayInfo = new DisplayInfo();
|
||||||
|
secondDisplayInfo.displayGroupId = nonDefaultDisplayGroupId;
|
||||||
|
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(
|
||||||
|
secondDisplayInfo);
|
||||||
|
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||||
|
|
||||||
|
if (!defaultDisplayAwake) {
|
||||||
|
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP,
|
||||||
|
mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
|
||||||
|
}
|
||||||
|
if (!secondGroupDisplayAwake) {
|
||||||
|
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP,
|
||||||
|
mClock.now(), 0,
|
||||||
|
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
|
||||||
|
}
|
||||||
|
assertThat(PowerManagerInternal.isInteractive(
|
||||||
|
mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP))).isEqualTo(
|
||||||
|
defaultDisplayAwake);
|
||||||
|
assertThat(PowerManagerInternal.isInteractive(
|
||||||
|
mService.getWakefulnessLocked(nonDefaultDisplayGroupId))).isEqualTo(
|
||||||
|
secondGroupDisplayAwake);
|
||||||
|
|
||||||
|
BinderService binderService = mService.getBinderServiceInstance();
|
||||||
|
assertThat(binderService.isInteractive()).isEqualTo(
|
||||||
|
defaultDisplayAwake || secondGroupDisplayAwake);
|
||||||
|
assertThat(binderService.isDisplayInteractive(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||||
|
defaultDisplayAwake);
|
||||||
|
assertThat(binderService.isDisplayInteractive(nonDefaultDisplay)).isEqualTo(
|
||||||
|
secondGroupDisplayAwake);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_isInteractive_defaultGroupIsAwakeSecondGroupIsAwake() {
|
||||||
|
testMultiDisplay_isInteractive_returnsCorrectValue(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_isInteractive_defaultGroupIsAwakeSecondGroupIsAsleep() {
|
||||||
|
testMultiDisplay_isInteractive_returnsCorrectValue(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_isInteractive_defaultGroupIsAsleepSecondGroupIsAwake() {
|
||||||
|
testMultiDisplay_isInteractive_returnsCorrectValue(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_isInteractive_bothGroupsAreAsleep() {
|
||||||
|
testMultiDisplay_isInteractive_returnsCorrectValue(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_defaultGroupWakefulnessChange_causesIsInteractiveInvalidate()
|
||||||
|
throws Exception {
|
||||||
|
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||||
|
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
|
||||||
|
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||||
|
new AtomicReference<>();
|
||||||
|
doAnswer((Answer<Void>) invocation -> {
|
||||||
|
listener.set(invocation.getArgument(0));
|
||||||
|
return null;
|
||||||
|
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||||
|
final DisplayInfo info = new DisplayInfo();
|
||||||
|
info.displayGroupId = nonDefaultDisplayGroupId;
|
||||||
|
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||||
|
|
||||||
|
verify(mInvalidateInteractiveCachesMock).call();
|
||||||
|
|
||||||
|
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP,
|
||||||
|
mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
|
||||||
|
|
||||||
|
verify(mInvalidateInteractiveCachesMock, times(2)).call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiDisplay_secondGroupWakefulness_causesIsInteractiveInvalidate()
|
||||||
|
throws Exception {
|
||||||
|
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||||
|
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
|
||||||
|
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||||
|
new AtomicReference<>();
|
||||||
|
doAnswer((Answer<Void>) invocation -> {
|
||||||
|
listener.set(invocation.getArgument(0));
|
||||||
|
return null;
|
||||||
|
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||||
|
final DisplayInfo info = new DisplayInfo();
|
||||||
|
info.displayGroupId = nonDefaultDisplayGroupId;
|
||||||
|
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||||
|
|
||||||
|
verify(mInvalidateInteractiveCachesMock).call();
|
||||||
|
|
||||||
|
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, mClock.now(),
|
||||||
|
0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
|
||||||
|
|
||||||
|
verify(mInvalidateInteractiveCachesMock, times(2)).call();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFullPowerSavePolicy_returnsStateMachineResult() {
|
public void testGetFullPowerSavePolicy_returnsStateMachineResult() {
|
||||||
createService();
|
createService();
|
||||||
|
|||||||
Reference in New Issue
Block a user