Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbfbc3cc authored by Robin Lee's avatar Robin Lee
Browse files

Rewire WallpaperManager keyguard callback

- keyguardGoingAway is not changed (but happens outside WM lock).

- keyguardAppearing is sent if the flag is enabled.

- When the flag is enabled, both commands are only sent if the recipient
  has proper permissions to subscribe to keyguard events.

Test: atest WallpaperManagerServiceTests
Bug: 395897130
Flag: android.app.notify_keyguard_events
Change-Id: I328a1d602be691dd57d10eb41c1679f2b5321d97
parent c396ff18
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -248,13 +248,27 @@ public class WallpaperManager {
    /**
     * Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
     * starts going away.
     * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}.
     * <p>
     * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}
     * or by {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
     *
     * @hide
     */
    public static final String COMMAND_KEYGUARD_GOING_AWAY =
            "android.wallpaper.keyguardgoingaway";

    /**
     * Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
     * starts going away.
     *
     * <p>This command is triggered by
     * {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
     *
     * @hide
     */
    public static final String COMMAND_KEYGUARD_APPEARING =
            "android.wallpaper.keyguardappearing";

    /**
     * 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
+10 −0
Original line number Diff line number Diff line
@@ -23,6 +23,16 @@ flag {
  is_exported: true
}

flag {
  name: "notify_keyguard_events"
  namespace: "systemui"
  description: "Send keyguard showing/hiding/going-away events to wallpaper as wallpaper commands (guarded by permission)"
  bug: "395897130"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "accurate_wallpaper_downsampling"
  namespace: "systemui"
+0 −3
Original line number Diff line number Diff line
@@ -36,7 +36,4 @@ public abstract class WallpaperManagerInternal {

    /** Notifies when the screen starts turning on and is not yet visible to the user. */
    public abstract void onScreenTurningOn(int displayId);

    /** Notifies when the keyguard is going away. Sent right after the bouncer is gone. */
    public abstract void onKeyguardGoingAway();
}
+61 −8
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.Flags.fixWallpaperChanged;
import static android.app.Flags.liveWallpaperContentHandling;
import static android.app.Flags.notifyKeyguardEvents;
import static android.app.Flags.removeNextWallpaperComponent;
import static android.app.WallpaperManager.COMMAND_REAPPLY;
import static android.app.WallpaperManager.FLAG_LOCK;
@@ -1705,8 +1706,32 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper,
                mWallpaperCropper);
        LocalServices.addService(WallpaperManagerInternal.class, new LocalService());

        LocalServices.getService(ActivityTaskManagerInternal.class)
                .registerScreenObserver(mKeyguardObserver);

    }

    private final ActivityTaskManagerInternal.ScreenObserver mKeyguardObserver =
            new ActivityTaskManagerInternal.ScreenObserver() {
                @Override
                public void onKeyguardStateChanged(boolean isShowing) {
                    if (!notifyKeyguardEvents()) {
                        return;
                    }
                    if (isShowing) {
                        notifyKeyguardAppearing();
                    } else {
                        notifyKeyguardGoingAway();
                    }
                }

                @Override
                public void onKeyguardGoingAway() {
                    notifyKeyguardGoingAway();
                }
            };

    private final class LocalService extends WallpaperManagerInternal {
        @Override
        public void onDisplayAddSystemDecorations(int displayId) {
@@ -1729,11 +1754,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        public void onScreenTurningOn(int displayId) {
            notifyScreenTurningOn(displayId);
        }

        @Override
        public void onKeyguardGoingAway() {
            notifyKeyguardGoingAway();
        }
    }

    void initialize() {
@@ -2562,6 +2582,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
    }

    private boolean hasPermission(WallpaperData data, String permission) {
        try {
            return PackageManager.PERMISSION_GRANTED == mIPackageManager.checkPermission(
                    permission,
                    data.getComponent().getPackageName(),
                    data.userId);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to check wallpaper service permission", e);
            return false;
        }
    }

    private boolean hasAppOpPermission(String permission, int callingUid, String callingPackage,
            String attributionTag, String message) {
        final String op = AppOpsManager.permissionToOp(permission);
@@ -2864,16 +2896,37 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
     * Propagate a keyguard going away event to the wallpaper engine.
     */
    private void notifyKeyguardGoingAway() {
        dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY);
    }

    /**
     * Propagate a keyguard appearing event to the wallpaper engine.
     */
    private void notifyKeyguardAppearing() {
        dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_APPEARING);
    }

    /**
     * Propagate a keyguard-related event to the wallpaper engine.
     *
     * When the flag below is enabled, the event will only be dispatched in case the recipient
     * has {@link android.Manifest.pertmission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} permission.
     */
    private void dispatchKeyguardCommand(String command) {
        synchronized (mLock) {
            for (WallpaperData data : getActiveWallpapers()) {
                if (notifyKeyguardEvents() && !hasPermission(
                        data, android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)) {
                    continue;
                }

                data.connection.forEachDisplayConnector(displayConnector -> {
                    if (displayConnector.mEngine != null) {
                        try {
                            displayConnector.mEngine.dispatchWallpaperCommand(
                                    WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY,
                                    -1, -1, -1, new Bundle());
                                    command, -1, -1, -1, new Bundle());
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Failed to notify that the keyguard is going away", e);
                            Slog.w(TAG, "Failed to dispatch wallpaper command: " + command, e);
                        }
                    }
                });
+3 −2
Original line number Diff line number Diff line
@@ -124,8 +124,9 @@ public abstract class ActivityTaskManagerInternal {
    public static final String ASSIST_KEY_RECEIVER_EXTRAS = "receiverExtras";

    public interface ScreenObserver {
        void onAwakeStateChanged(boolean isAwake);
        void onKeyguardStateChanged(boolean isShowing);
        default void onAwakeStateChanged(boolean isAwake) {}
        default void onKeyguardStateChanged(boolean isShowing) {}
        default void onKeyguardGoingAway() {}
    }

    /**
Loading