Let wallpaper know when to animate AoD transition
Sometimes the screen will blank, and sometime the
wallpaper has the opportunity to animate the
transition.
Bug: 64155983
Test: atest tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
Test: atest packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
Change-Id: Ia92c00edb98eeeba42da33bdc7bec3feb961a658
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 80782e3..4ba0ff2 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -159,5 +159,5 @@
/**
* Called from SystemUI when it shows the AoD UI.
*/
- void setInAmbientMode(boolean inAmbienMode);
+ void setInAmbientMode(boolean inAmbientMode, boolean animated);
}
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index b8f2191..dccce40 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -27,7 +27,7 @@
void setDesiredSize(int width, int height);
void setDisplayPadding(in Rect padding);
void setVisibility(boolean visible);
- void setInAmbientMode(boolean inAmbientDisplay);
+ void setInAmbientMode(boolean inAmbientDisplay, boolean animated);
void dispatchPointer(in MotionEvent event);
void dispatchWallpaperCommand(String action, int x, int y,
int z, in Bundle extras);
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 595bfb7..8588df7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -563,9 +563,12 @@
* Called when the device enters or exits ambient mode.
*
* @param inAmbientMode {@code true} if in ambient mode.
+ * @param animated {@code true} if you'll have te opportunity of animating your transition
+ * {@code false} when the screen will blank and the wallpaper should be
+ * set to ambient mode immediately.
* @hide
*/
- public void onAmbientModeChanged(boolean inAmbientMode) {
+ public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) {
}
/**
@@ -1021,18 +1024,20 @@
* Executes life cycle event and updates internal ambient mode state based on
* message sent from handler.
*
- * @param inAmbientMode True if in ambient mode.
+ * @param inAmbientMode {@code true} if in ambient mode.
+ * @param animated {@code true} if the transition will be animated.
* @hide
*/
@VisibleForTesting
- public void doAmbientModeChanged(boolean inAmbientMode) {
+ public void doAmbientModeChanged(boolean inAmbientMode, boolean animated) {
if (!mDestroyed) {
if (DEBUG) {
- Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + "): " + this);
+ Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + ", "
+ + animated + "): " + this);
}
mIsInAmbientMode = inAmbientMode;
if (mCreated) {
- onAmbientModeChanged(inAmbientMode);
+ onAmbientModeChanged(inAmbientMode, animated);
}
}
}
@@ -1278,8 +1283,10 @@
}
@Override
- public void setInAmbientMode(boolean inAmbientDisplay) throws RemoteException {
- Message msg = mCaller.obtainMessageI(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0);
+ public void setInAmbientMode(boolean inAmbientDisplay, boolean animated)
+ throws RemoteException {
+ Message msg = mCaller.obtainMessageII(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0,
+ animated ? 1 : 0);
mCaller.sendMessage(msg);
}
@@ -1350,7 +1357,7 @@
return;
}
case DO_IN_AMBIENT_MODE: {
- mEngine.doAmbientModeChanged(message.arg1 != 0);
+ mEngine.doAmbientModeChanged(message.arg1 != 0, message.arg2 != 0);
return;
}
case MSG_UPDATE_SURFACE:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 0f0402d..bfb3a6e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -66,7 +66,7 @@
createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params),
new DozeScreenState(wrappedService, handler),
createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
- new DozeWallpaperState()
+ new DozeWallpaperState(context)
});
return machine;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index 50c1ede..543a5e5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -23,6 +23,10 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import java.io.PrintWriter;
@@ -34,18 +38,28 @@
private static final String TAG = "DozeWallpaperState";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- @VisibleForTesting
- final IWallpaperManager mWallpaperManagerService;
+ private final IWallpaperManager mWallpaperManagerService;
+ private boolean mKeyguardVisible;
private boolean mIsAmbientMode;
+ private final DozeParameters mDozeParameters;
- public DozeWallpaperState() {
+ public DozeWallpaperState(Context context) {
this(IWallpaperManager.Stub.asInterface(
- ServiceManager.getService(Context.WALLPAPER_SERVICE)));
+ ServiceManager.getService(Context.WALLPAPER_SERVICE)),
+ new DozeParameters(context), KeyguardUpdateMonitor.getInstance(context));
}
@VisibleForTesting
- DozeWallpaperState(IWallpaperManager wallpaperManagerService) {
+ DozeWallpaperState(IWallpaperManager wallpaperManagerService, DozeParameters parameters,
+ KeyguardUpdateMonitor keyguardUpdateMonitor) {
mWallpaperManagerService = wallpaperManagerService;
+ mDozeParameters = parameters;
+ keyguardUpdateMonitor.registerCallback(new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ mKeyguardVisible = showing;
+ }
+ });
}
@Override
@@ -56,17 +70,25 @@
case DOZE_REQUEST_PULSE:
case DOZE_PULSING:
case DOZE_PULSE_DONE:
- isAmbientMode = true;
+ isAmbientMode = mDozeParameters.getAlwaysOn();
break;
default:
isAmbientMode = false;
}
+ final boolean animated;
+ if (isAmbientMode) {
+ animated = mDozeParameters.getCanControlScreenOffAnimation() && !mKeyguardVisible;
+ } else {
+ animated = !mDozeParameters.getDisplayNeedsBlanking();
+ }
+
if (isAmbientMode != mIsAmbientMode) {
mIsAmbientMode = isAmbientMode;
try {
- Log.i(TAG, "AoD wallpaper state changed to: " + mIsAmbientMode);
- mWallpaperManagerService.setInAmbientMode(mIsAmbientMode);
+ Log.i(TAG, "AoD wallpaper state changed to: " + mIsAmbientMode
+ + ", animated: " + animated);
+ mWallpaperManagerService.setInAmbientMode(mIsAmbientMode, animated);
} catch (RemoteException e) {
// Cannot notify wallpaper manager service, but it's fine, let's just skip it.
Log.w(TAG, "Cannot notify state to WallpaperManagerService: " + mIsAmbientMode);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index 8e7f83d..2705bca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -16,33 +16,90 @@
package com.android.systemui.doze;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.IWallpaperManager;
import android.os.Handler;
import android.os.RemoteException;
import android.support.test.filters.SmallTest;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
@RunWith(JUnit4.class)
@SmallTest
public class DozeWallpaperStateTest extends SysuiTestCase {
+ private DozeWallpaperState mDozeWallpaperState;
+ @Mock IWallpaperManager mIWallpaperManager;
+ @Mock DozeParameters mDozeParameters;
+ @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters,
+ mKeyguardUpdateMonitor);
+ }
+
@Test
public void testDreamNotification() throws RemoteException {
- IWallpaperManager wallpaperManagerService = mock(IWallpaperManager.class);
- DozeWallpaperState dozeWallpaperState = new DozeWallpaperState(wallpaperManagerService);
- dozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+ // Pre-condition
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
DozeMachine.State.DOZE_AOD);
- verify(wallpaperManagerService).setInAmbientMode(eq(true));
- dozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
- verify(wallpaperManagerService).setInAmbientMode(eq(false));
+ verify(mIWallpaperManager).setInAmbientMode(eq(true), anyBoolean());
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), anyBoolean());
+
+ // Make sure we're sending false when AoD is off
+ reset(mDozeParameters);
+ mDozeWallpaperState.transitionTo(DozeMachine.State.FINISH, DozeMachine.State.DOZE_AOD);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), anyBoolean());
+ }
+
+ @Test
+ public void testAnimates_whenSupported() throws RemoteException {
+ // Pre-conditions
+ when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
+ when(mDozeParameters.getCanControlScreenOffAnimation()).thenReturn(true);
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+ DozeMachine.State.DOZE_AOD);
+ verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(true));
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(true));
+ }
+
+ @Test
+ public void testDoesNotAnimate_whenNotSupported() throws RemoteException {
+ // Pre-conditions
+ when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
+ when(mDozeParameters.getCanControlScreenOffAnimation()).thenReturn(false);
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+ DozeMachine.State.DOZE_AOD);
+ verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(false));
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(false));
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 8e916ad..844aafb 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -956,7 +956,7 @@
}
if (mInfo != null && mInfo.getSupportsAmbientMode()) {
try {
- mEngine.setInAmbientMode(mInAmbientMode);
+ mEngine.setInAmbientMode(mInAmbientMode, false /* animated */);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to set ambient mode state", e);
}
@@ -1751,7 +1751,7 @@
}
}
- public void setInAmbientMode(boolean inAmbienMode) {
+ public void setInAmbientMode(boolean inAmbienMode, boolean animated) {
final IWallpaperEngine engine;
synchronized (mLock) {
mInAmbientMode = inAmbienMode;
@@ -1766,7 +1766,7 @@
if (engine != null) {
try {
- engine.setInAmbientMode(inAmbienMode);
+ engine.setInAmbientMode(inAmbienMode, animated);
} catch (RemoteException e) {
// Cannot talk to wallpaper engine.
}
diff --git a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
index f7ce2c7..8d8fc84 100644
--- a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
+++ b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
@@ -38,7 +38,7 @@
public Engine onCreateEngine() {
return new Engine() {
@Override
- public void onAmbientModeChanged(boolean inAmbientMode) {
+ public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) {
ambientModeChangedCount[0]++;
}
};
@@ -47,12 +47,12 @@
WallpaperService.Engine engine = service.onCreateEngine();
engine.setCreated(true);
- engine.doAmbientModeChanged(false);
+ engine.doAmbientModeChanged(false, false);
assertFalse("ambient mode should be false", engine.isInAmbientMode());
assertEquals("onAmbientModeChanged should have been called",
ambientModeChangedCount[0], 1);
- engine.doAmbientModeChanged(true);
+ engine.doAmbientModeChanged(true, false);
assertTrue("ambient mode should be false", engine.isInAmbientMode());
assertEquals("onAmbientModeChanged should have been called",
ambientModeChangedCount[0], 2);