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

Commit 6594c021 authored by Nick Chameyev's avatar Nick Chameyev
Browse files

Expose transform surface control in wallpaper service

Expose a special surface control that could be used
to transform wallpaper in the wallpaper service.

This surface control is needed when sending buffers
directly to wallpaper's surface. Using this surface control
wallpapers can perform transformations without updating
the buffer.

Test: atest WallpaperTransformTest
Flag: android.app.enable_wallpaper_transform_surface_control_command
Bug: 399077623
Change-Id: I78b394ff5d199b6741907f5ff3a879796d6d20d1
parent e1062a79
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -321,6 +321,14 @@ public class WallpaperManager {
    public static final String COMMAND_LOCKSCREEN_TAP =
            "android.wallpaper.lockscreen_tap";

    /**
     * Command for {@link #sendWallpaperCommand}: reported when the surface control that could be
     * used to transform the wallpaper is available
     * @hide
     */
    public static final String COMMAND_TRANSFORM_SURFACE_CONTROL =
            "android.wallpaper.transform_surface_control";

    /**
     * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID.
     * @hide
+10 −0
Original line number Diff line number Diff line
@@ -33,6 +33,16 @@ flag {
  }
}

flag {
  name: "enable_wallpaper_transform_surface_control_command"
  namespace: "systemui"
  description: "Enables sending SurfaceControl to onCommand that could be used to transform the wallpaper"
  bug: "399077623"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "accurate_wallpaper_downsampling"
  namespace: "systemui"
+39 −4
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package android.service.wallpaper;

import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
import static android.app.Flags.liveWallpaperContentHandling;
import static android.app.Flags.enableWallpaperTransformSurfaceControlCommand;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_TRANSFORM_SURFACE_CONTROL;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WallpaperManager.SetWallpaperFlags;
import static android.graphics.Matrix.MSCALE_X;
@@ -374,11 +376,16 @@ public abstract class WallpaperService extends Service {
        private float mPreviousWallpaperDimAmount = mWallpaperDimAmount;
        private float mDefaultDimAmount = 0.05f;
        SurfaceControl mBbqSurfaceControl;
        // Surface control that could be used to apply transformation to the wallpaper
        // The hiearchy is the following:
        //   mSurfaceControl <- mTransformSurfaceControl <- mBbqSurfaceControl
        SurfaceControl mTransformSurfaceControl;
        BLASTBufferQueue mBlastBufferQueue;
        IBinder mBbqApplyToken = new Binder();
        private SurfaceControl mScreenshotSurfaceControl;
        private Point mScreenshotSize = new Point();

        private final boolean mEnableTransformSurfaceControlCommand;
        private final boolean mDisableDrawWakeLock;

        final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
@@ -568,6 +575,7 @@ public abstract class WallpaperService extends Service {
        public Engine(Supplier<Long> clockFunction, Handler handler) {
            mClockFunction = clockFunction;
            mHandler = handler;
            mEnableTransformSurfaceControlCommand = enableWallpaperTransformSurfaceControlCommand();
            mDisableDrawWakeLock = CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK_WALLPAPER)
                    && disableDrawWakeLock();
        }
@@ -1331,11 +1339,20 @@ public abstract class WallpaperService extends Service {
                            (mDisplay.getInstallOrientation() + mDisplay.getRotation()) % 4);
                        mSurfaceControl.setTransformHint(transformHint);
                        if (mBbqSurfaceControl == null) {
                            if (mEnableTransformSurfaceControlCommand) {
                                mTransformSurfaceControl = new SurfaceControl.Builder()
                                        .setName("Wallpaper Transform wrapper")
                                        .setHidden(false)
                                        .setParent(mSurfaceControl)
                                        .setCallsite("Wallpaper#relayout")
                                        .build();
                            }
                            mBbqSurfaceControl = new SurfaceControl.Builder()
                                    .setName("Wallpaper BBQ wrapper")
                                    .setHidden(false)
                                    .setBLASTLayer()
                                    .setParent(mSurfaceControl)
                                    .setParent(mEnableTransformSurfaceControlCommand
                                            ? mTransformSurfaceControl : mSurfaceControl)
                                    .setCallsite("Wallpaper#relayout")
                                    .build();
                            SurfaceControl.Transaction transaction =
@@ -1348,6 +1365,10 @@ public abstract class WallpaperService extends Service {
                            }
                            transaction.setDefaultFrameRateCompatibility(mBbqSurfaceControl,
                                    frameRateCompat).apply();
                            if (mEnableTransformSurfaceControlCommand) {
                                // TODO: b/406967924 - remove after creating public APIs
                                sendTransformSurfaceControl();
                            }
                        }
                        // Propagate transform hint from WM, so we can use the right hint for the
                        // first frame.
@@ -1551,6 +1572,12 @@ public abstract class WallpaperService extends Service {
            }
        }

        private void sendTransformSurfaceControl() {
            final Bundle extras = new Bundle();
            extras.putParcelable(COMMAND_TRANSFORM_SURFACE_CONTROL, mTransformSurfaceControl);
            onCommand(COMMAND_TRANSFORM_SURFACE_CONTROL, 0, 0, 0, extras, false);
        }

        private void resizePreview(Rect position) {
            if (position != null) {
                mSurfaceHolder.setFixedSize(position.width(), position.height());
@@ -2218,7 +2245,8 @@ public abstract class WallpaperService extends Service {
            if (mScreenshotSurfaceControl != null) {
                new SurfaceControl.Transaction()
                        .remove(mScreenshotSurfaceControl)
                        .show(mBbqSurfaceControl)
                        .show(mEnableTransformSurfaceControlCommand
                                ? mTransformSurfaceControl : mBbqSurfaceControl)
                        .apply();
                mScreenshotSurfaceControl = null;
            }
@@ -2315,7 +2343,8 @@ public abstract class WallpaperService extends Service {
            // Place on top everything else.
            t.setLayer(mScreenshotSurfaceControl, Integer.MAX_VALUE);
            t.show(mScreenshotSurfaceControl);
            t.hide(mBbqSurfaceControl);
            t.hide(mEnableTransformSurfaceControlCommand
                    ? mTransformSurfaceControl : mBbqSurfaceControl);
            t.apply();

            return true;
@@ -2388,10 +2417,16 @@ public abstract class WallpaperService extends Service {
                        mBlastBufferQueue.destroy();
                        mBlastBufferQueue = null;
                    }
                    final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
                    if (mBbqSurfaceControl != null) {
                        new SurfaceControl.Transaction().remove(mBbqSurfaceControl).apply();
                        t.remove(mBbqSurfaceControl);
                        mBbqSurfaceControl = null;
                    }
                    if (mTransformSurfaceControl != null) {
                        t.remove(mTransformSurfaceControl);
                        mTransformSurfaceControl = null;
                    }
                    t.apply();
                    mCreated = false;
                }