Use the existing wallpaper command API to send wake/sleep events to the wallpaper.

This is already used for similar events such as icon drops and user taps. Using it to indicate that the user has woken/slept the device (and passing along location information) makes sense!

This was previously rolled back since WallpaperManager can be null in Car environments. This CL now checks if WallpaperManager is null.

Bug: 169693662
Test: locally with modified wallpaper, it receives events
Change-Id: Ie9d21b4ff4a1edf871540481bc0c4216ed686b7f
This commit is contained in:
Josh Tsuji
2021-04-18 23:12:00 -04:00
parent 07d522f307
commit d5da89479e
6 changed files with 194 additions and 4 deletions

View File

@@ -190,4 +190,18 @@ interface IWallpaperManager {
* Called from SystemUI when it shows the AoD UI.
*/
oneway void setInAmbientMode(boolean inAmbientMode, long animationDuration);
/**
* Called from SystemUI when the device is waking up.
*
* @hide
*/
oneway void notifyWakingUp(int x, int y, in Bundle extras);
/**
* Called from SystemUI when the device is going to sleep.
*
* @hide
*/
void notifyGoingToSleep(int x, int y, in Bundle extras);
}

View File

@@ -189,6 +189,30 @@ public class WallpaperManager {
*/
public static final String COMMAND_DROP = "android.home.drop";
/**
* Command for {@link #sendWallpaperCommand}: reported by System UI when the device is waking
* up. The x and y arguments are a location (possibly very roughly) corresponding to the action
* that caused the device to wake up. For example, if the power button was pressed, this will be
* the location on the screen nearest the power button.
*
* If the location is unknown or not applicable, x and y will be -1.
*
* @hide
*/
public static final String COMMAND_WAKING_UP = "android.wallpaper.wakingup";
/**
* Command for {@link #sendWallpaperCommand}: reported by System UI when the device is going to
* sleep. The x and y arguments are a location (possibly very roughly) corresponding to the
* action that caused the device to go to sleep. For example, if the power button was pressed,
* this will be the location on the screen nearest the power button.
*
* If the location is unknown or not applicable, x and y will be -1.
*
* @hide
*/
public static final String COMMAND_GOING_TO_SLEEP = "android.wallpaper.goingtosleep";
/**
* Command for {@link #sendWallpaperCommand}: reported when the wallpaper that was already
* set is re-applied by the user.

View File

@@ -17,10 +17,20 @@
package com.android.systemui.keyguard;
import android.annotation.IntDef;
import android.app.IWallpaperManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.Trace;
import android.util.DisplayMetrics;
import androidx.annotation.Nullable;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import java.io.FileDescriptor;
@@ -31,7 +41,7 @@ import java.lang.annotation.RetentionPolicy;
import javax.inject.Inject;
/**
* Tracks the wakefulness lifecycle.
* Tracks the wakefulness lifecycle, including why we're waking or sleeping.
*/
@SysUISingleton
public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
@@ -51,13 +61,32 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe
public static final int WAKEFULNESS_AWAKE = 2;
public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
private final Context mContext;
private final DisplayMetrics mDisplayMetrics;
@Nullable
private final IWallpaperManager mWallpaperManagerService;
private int mWakefulness = WAKEFULNESS_ASLEEP;
private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
@Nullable
private Point mLastWakeOriginLocation = null;
private @PowerManager.GoToSleepReason int mLastSleepReason =
PowerManager.GO_TO_SLEEP_REASON_MIN;
@Nullable
private Point mLastSleepOriginLocation = null;
@Inject
public WakefulnessLifecycle() {
public WakefulnessLifecycle(
Context context,
@Nullable IWallpaperManager wallpaperManagerService) {
mContext = context;
mDisplayMetrics = context.getResources().getDisplayMetrics();
mWallpaperManagerService = wallpaperManagerService;
}
public @Wakefulness int getWakefulness() {
@@ -85,6 +114,17 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe
}
setWakefulness(WAKEFULNESS_WAKING);
mLastWakeReason = pmWakeReason;
updateLastWakeOriginLocation();
if (mWallpaperManagerService != null) {
try {
mWallpaperManagerService.notifyWakingUp(
mLastWakeOriginLocation.x, mLastWakeOriginLocation.y, new Bundle());
} catch (RemoteException e) {
e.printStackTrace();
}
}
dispatch(Observer::onStartedWakingUp);
}
@@ -102,6 +142,17 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe
}
setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
mLastSleepReason = pmSleepReason;
updateLastSleepOriginLocation();
if (mWallpaperManagerService != null) {
try {
mWallpaperManagerService.notifyGoingToSleep(
mLastSleepOriginLocation.x, mLastSleepOriginLocation.y, new Bundle());
} catch (RemoteException e) {
e.printStackTrace();
}
}
dispatch(Observer::onStartedGoingToSleep);
}
@@ -124,6 +175,60 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe
Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
}
private void updateLastWakeOriginLocation() {
mLastWakeOriginLocation = null;
switch (mLastWakeReason) {
case PowerManager.WAKE_REASON_POWER_BUTTON:
mLastWakeOriginLocation = getPowerButtonOrigin();
break;
default:
mLastWakeOriginLocation = getDefaultWakeSleepOrigin();
break;
}
}
private void updateLastSleepOriginLocation() {
mLastSleepOriginLocation = null;
switch (mLastSleepReason) {
case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
mLastSleepOriginLocation = getPowerButtonOrigin();
break;
default:
mLastSleepOriginLocation = getDefaultWakeSleepOrigin();
break;
}
}
/**
* Returns the point on the screen closest to the physical power button.
*/
private Point getPowerButtonOrigin() {
final boolean isPortrait = mContext.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT;
if (isPortrait) {
return new Point(
mDisplayMetrics.widthPixels,
mContext.getResources().getDimensionPixelSize(
R.dimen.physical_power_button_center_screen_location_y));
} else {
return new Point(
mContext.getResources().getDimensionPixelSize(
R.dimen.physical_power_button_center_screen_location_y),
mDisplayMetrics.heightPixels);
}
}
/**
* Returns the point on the screen used as the default origin for wake/sleep events. This is the
* middle-bottom of the screen.
*/
private Point getDefaultWakeSleepOrigin() {
return new Point(mDisplayMetrics.widthPixels / 2, mDisplayMetrics.heightPixels);
}
public interface Observer {
default void onStartedWakingUp() {}
default void onFinishedWakingUp() {}

View File

@@ -22,6 +22,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.app.IWallpaperManager;
import android.os.PowerManager;
import android.testing.AndroidTestingRunner;
@@ -43,9 +44,12 @@ public class WakefulnessLifecycleTest extends SysuiTestCase {
private WakefulnessLifecycle mWakefulness;
private WakefulnessLifecycle.Observer mWakefulnessObserver;
private IWallpaperManager mWallpaperManager;
@Before
public void setUp() throws Exception {
mWakefulness = new WakefulnessLifecycle();
mWallpaperManager = mock(IWallpaperManager.class);
mWakefulness = new WakefulnessLifecycle(mContext, mWallpaperManager);
mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
mWakefulness.addObserver(mWakefulnessObserver);
}

View File

@@ -38,6 +38,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.IWallpaperManager;
import android.app.Notification;
import android.app.StatusBarManager;
import android.app.trust.TrustManager;
@@ -269,6 +270,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private PrivacyDotViewController mDotViewController;
@Mock private TunerService mTunerService;
@Mock private FeatureFlags mFeatureFlags;
@Mock private IWallpaperManager mWallpaperManager;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -327,7 +329,8 @@ public class StatusBarTest extends SysuiTestCase {
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
WakefulnessLifecycle wakefulnessLifecycle =
new WakefulnessLifecycle(mContext, mWallpaperManager);
wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
wakefulnessLifecycle.dispatchFinishedWakingUp();

View File

@@ -2378,6 +2378,46 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
/**
* Propagate a wake event to the wallpaper engine.
*/
public void notifyWakingUp(int x, int y, @NonNull Bundle extras) {
synchronized (mLock) {
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
data.connection.forEachDisplayConnector(
displayConnector -> {
if (displayConnector.mEngine != null) {
try {
displayConnector.mEngine.dispatchWallpaperCommand(
WallpaperManager.COMMAND_WAKING_UP, x, y, -1, extras);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
/**
* Propagate a sleep event to the wallpaper engine.
*/
public void notifyGoingToSleep(int x, int y, @NonNull Bundle extras) {
synchronized (mLock) {
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
data.connection.forEachDisplayConnector(
displayConnector -> {
if (displayConnector.mEngine != null) {
try {
displayConnector.mEngine.dispatchWallpaperCommand(
WallpaperManager.COMMAND_GOING_TO_SLEEP, x, y, -1, extras);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);