Report visibility only when display is fully on in WallpaperService
This is needed as some custom wallpaper interactions need to start when the screen turns on (which is not the same as "wallpaper visibility" or "wake" status). Previously, only the power state was taken into consideration. However, brightness is turned on after all windows are drawn (brightness is separated from power state). This was causing some wallpapers to trigger animations while the screen was not yet visible. Bug: 275057152 Test: Recorded perfetto trace and made sure visibility callback is invoked at the correct moment (after display brightness is turned on) Change-Id: I8c8c59ad0e3f19880ec543686285a89b0b864739
This commit is contained in:
@@ -219,6 +219,20 @@ interface IWallpaperManager {
|
||||
*/
|
||||
void notifyGoingToSleep(int x, int y, in Bundle extras);
|
||||
|
||||
/**
|
||||
* Called when the screen has been fully turned on and is visible.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void notifyScreenTurnedOn(int displayId);
|
||||
|
||||
/**
|
||||
* Called when the screen starts turning on.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void notifyScreenTurningOn(int displayId);
|
||||
|
||||
/**
|
||||
* Sets the wallpaper dim amount between [0f, 1f] which would be blended with the system default
|
||||
* dimming. 0f doesn't add any additional dimming and 1f makes the wallpaper fully black.
|
||||
|
||||
@@ -32,6 +32,8 @@ interface IWallpaperEngine {
|
||||
oneway void setDisplayPadding(in Rect padding);
|
||||
@UnsupportedAppUsage
|
||||
oneway void setVisibility(boolean visible);
|
||||
oneway void onScreenTurningOn();
|
||||
oneway void onScreenTurnedOn();
|
||||
oneway void setInAmbientMode(boolean inAmbientDisplay, long animationDuration);
|
||||
@UnsupportedAppUsage
|
||||
oneway void dispatchPointer(in MotionEvent event);
|
||||
|
||||
@@ -168,6 +168,7 @@ public abstract class WallpaperService extends Service {
|
||||
private static final int MSG_ZOOM = 10100;
|
||||
private static final int MSG_RESIZE_PREVIEW = 10110;
|
||||
private static final int MSG_REPORT_SHOWN = 10150;
|
||||
private static final int MSG_UPDATE_SCREEN_TURNING_ON = 10170;
|
||||
private static final int MSG_UPDATE_DIMMING = 10200;
|
||||
private static final int MSG_WALLPAPER_FLAGS_CHANGED = 10210;
|
||||
|
||||
@@ -213,6 +214,16 @@ public abstract class WallpaperService extends Service {
|
||||
|
||||
boolean mInitializing = true;
|
||||
boolean mVisible;
|
||||
/**
|
||||
* Whether the screen is turning on.
|
||||
* After the display is powered on, brightness is initially off. It is turned on only after
|
||||
* all windows have been drawn, and sysui notifies that it's ready (See
|
||||
* {@link com.android.internal.policy.IKeyguardDrawnCallback}).
|
||||
* As some wallpapers use visibility as a signal to start animations, this makes sure
|
||||
* {@link Engine#onVisibilityChanged} is invoked only when the display is both on and
|
||||
* visible (with brightness on).
|
||||
*/
|
||||
private boolean mIsScreenTurningOn;
|
||||
boolean mReportedVisible;
|
||||
boolean mDestroyed;
|
||||
// Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false
|
||||
@@ -1018,6 +1029,7 @@ public abstract class WallpaperService extends Service {
|
||||
out.print(" mDestroyed="); out.println(mDestroyed);
|
||||
out.print(prefix); out.print("mVisible="); out.print(mVisible);
|
||||
out.print(" mReportedVisible="); out.println(mReportedVisible);
|
||||
out.print(" mIsScreenTurningOn="); out.println(mIsScreenTurningOn);
|
||||
out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
|
||||
out.print(prefix); out.print("mCreated="); out.print(mCreated);
|
||||
out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
|
||||
@@ -1549,6 +1561,13 @@ public abstract class WallpaperService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
void onScreenTurningOnChanged(boolean isScreenTurningOn) {
|
||||
if (!mDestroyed) {
|
||||
mIsScreenTurningOn = isScreenTurningOn;
|
||||
reportVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
void doVisibilityChanged(boolean visible) {
|
||||
if (!mDestroyed) {
|
||||
mVisible = visible;
|
||||
@@ -1565,9 +1584,10 @@ public abstract class WallpaperService extends Service {
|
||||
return;
|
||||
}
|
||||
if (!mDestroyed) {
|
||||
mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN :
|
||||
mDisplay.getCommittedState();
|
||||
boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
|
||||
mDisplayState =
|
||||
mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getCommittedState();
|
||||
boolean displayVisible = Display.isOnState(mDisplayState) && !mIsScreenTurningOn;
|
||||
boolean visible = mVisible && displayVisible;
|
||||
if (DEBUG) {
|
||||
Log.v(
|
||||
TAG,
|
||||
@@ -2486,6 +2506,20 @@ public abstract class WallpaperService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScreenTurningOn(boolean isScreenTurningOn) {
|
||||
Message msg = mCaller.obtainMessageBO(MSG_UPDATE_SCREEN_TURNING_ON, isScreenTurningOn,
|
||||
null);
|
||||
mCaller.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void onScreenTurningOn() throws RemoteException {
|
||||
updateScreenTurningOn(true);
|
||||
}
|
||||
|
||||
public void onScreenTurnedOn() throws RemoteException {
|
||||
updateScreenTurningOn(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeMessage(Message message) {
|
||||
switch (message.what) {
|
||||
@@ -2530,6 +2564,13 @@ public abstract class WallpaperService extends Service {
|
||||
+ ": " + message.arg1);
|
||||
mEngine.doVisibilityChanged(message.arg1 != 0);
|
||||
break;
|
||||
case MSG_UPDATE_SCREEN_TURNING_ON:
|
||||
if (DEBUG) {
|
||||
Log.v(TAG,
|
||||
message.arg1 != 0 ? "Screen turning on" : "Screen turned on");
|
||||
}
|
||||
mEngine.onScreenTurningOnChanged(/* isScreenTurningOn= */ message.arg1 != 0);
|
||||
break;
|
||||
case MSG_WALLPAPER_OFFSETS: {
|
||||
mEngine.doOffsetsChanged(true);
|
||||
} break;
|
||||
|
||||
@@ -222,6 +222,7 @@ import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
|
||||
import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
|
||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||
import com.android.server.vr.VrManagerInternal;
|
||||
import com.android.server.wallpaper.WallpaperManagerInternal;
|
||||
import com.android.server.wm.ActivityTaskManagerInternal;
|
||||
import com.android.server.wm.DisplayPolicy;
|
||||
import com.android.server.wm.DisplayRotation;
|
||||
@@ -412,6 +413,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
SensorPrivacyManager mSensorPrivacyManager;
|
||||
DisplayManager mDisplayManager;
|
||||
DisplayManagerInternal mDisplayManagerInternal;
|
||||
|
||||
private WallpaperManagerInternal mWallpaperManagerInternal;
|
||||
|
||||
boolean mPreloadedRecentApps;
|
||||
final Object mServiceAcquireLock = new Object();
|
||||
Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
|
||||
@@ -5016,11 +5020,34 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
return bootCompleted ? mKeyguardDrawnTimeout : 5000;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private WallpaperManagerInternal getWallpaperManagerInternal() {
|
||||
if (mWallpaperManagerInternal == null) {
|
||||
mWallpaperManagerInternal = LocalServices.getService(WallpaperManagerInternal.class);
|
||||
}
|
||||
return mWallpaperManagerInternal;
|
||||
}
|
||||
|
||||
private void reportScreenTurningOnToWallpaper(int displayId) {
|
||||
WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
|
||||
if (wallpaperManagerInternal != null) {
|
||||
wallpaperManagerInternal.onScreenTurningOn(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportScreenTurnedOnToWallpaper(int displayId) {
|
||||
WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
|
||||
if (wallpaperManagerInternal != null) {
|
||||
wallpaperManagerInternal.onScreenTurnedOn(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
// Called on the DisplayManager's DisplayPowerController thread.
|
||||
@Override
|
||||
public void screenTurningOn(int displayId, final ScreenOnListener screenOnListener) {
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turning on...");
|
||||
|
||||
reportScreenTurningOnToWallpaper(displayId);
|
||||
if (displayId == DEFAULT_DISPLAY) {
|
||||
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
|
||||
0 /* cookie */);
|
||||
@@ -5061,6 +5088,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
public void screenTurnedOn(int displayId) {
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turned on...");
|
||||
|
||||
reportScreenTurnedOnToWallpaper(displayId);
|
||||
|
||||
if (displayId != DEFAULT_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,4 +27,10 @@ public abstract class WallpaperManagerInternal {
|
||||
* Notifies the display is ready for adding wallpaper on it.
|
||||
*/
|
||||
public abstract void onDisplayReady(int displayId);
|
||||
|
||||
/** Notifies when the screen finished turning on and is visible to the user. */
|
||||
public abstract void onScreenTurnedOn(int displayId);
|
||||
|
||||
/** Notifies when the screen starts turning on and is not yet visible to the user. */
|
||||
public abstract void onScreenTurningOn(int displayId);
|
||||
}
|
||||
|
||||
@@ -1613,6 +1613,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
public void onDisplayReady(int displayId) {
|
||||
onDisplayReadyInternal(displayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenTurnedOn(int displayId) {
|
||||
notifyScreenTurnedOn(displayId);
|
||||
}
|
||||
@Override
|
||||
public void onScreenTurningOn(int displayId) {
|
||||
notifyScreenTurningOn(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
@@ -2442,6 +2451,54 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates screen turned on event to wallpaper engine.
|
||||
*/
|
||||
@Override
|
||||
public void notifyScreenTurnedOn(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
|
||||
if (data != null
|
||||
&& data.connection != null
|
||||
&& data.connection.containsDisplay(displayId)) {
|
||||
final IWallpaperEngine engine = data.connection
|
||||
.getDisplayConnectorOrCreate(displayId).mEngine;
|
||||
if (engine != null) {
|
||||
try {
|
||||
engine.onScreenTurnedOn();
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Propagate screen turning on event to wallpaper engine.
|
||||
*/
|
||||
@Override
|
||||
public void notifyScreenTurningOn(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
|
||||
if (data != null
|
||||
&& data.connection != null
|
||||
&& data.connection.containsDisplay(displayId)) {
|
||||
final IWallpaperEngine engine = data.connection
|
||||
.getDisplayConnectorOrCreate(displayId).mEngine;
|
||||
if (engine != null) {
|
||||
try {
|
||||
engine.onScreenTurningOn();
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
|
||||
checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
|
||||
|
||||
Reference in New Issue
Block a user