Loading core/java/android/app/WallpaperManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -220,6 +220,20 @@ public class WallpaperManager { */ public static final String COMMAND_REAPPLY = "android.wallpaper.reapply"; /** * Command for {@link #sendWallpaperCommand}: reported when the live wallpaper needs to be * frozen. * @hide */ public static final String COMMAND_FREEZE = "android.wallpaper.freeze"; /** * Command for {@link #sendWallpaperCommand}: reported when the live wallapper doesn't need * to be frozen anymore. * @hide */ public static final String COMMAND_UNFREEZE = "android.wallpaper.unfreeze"; /** * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID. * @hide Loading core/java/android/service/wallpaper/WallpaperService.java +179 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.service.wallpaper; import static android.app.WallpaperManager.COMMAND_FREEZE; import static android.app.WallpaperManager.COMMAND_UNFREEZE; import static android.graphics.Matrix.MSCALE_X; import static android.graphics.Matrix.MSCALE_Y; import static android.graphics.Matrix.MSKEW_X; Loading @@ -42,12 +44,14 @@ import android.content.res.TypedArray; import android.graphics.BLASTBufferQueue; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.GraphicBuffer; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Build; Loading @@ -56,6 +60,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; Loading Loading @@ -200,6 +205,12 @@ public abstract class WallpaperService extends Service { boolean mVisible; boolean mReportedVisible; boolean mDestroyed; // Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false // after receiving WallpaperManager#COMMAND_UNFREEZE. COMMAND_FREEZE is fully applied once // mScreenshotSurfaceControl isn't null. When this happens, then Engine is notified through // doVisibilityChanged that main wallpaper surface is no longer visible and the wallpaper // host receives onVisibilityChanged(false) callback. private boolean mFrozenRequested = false; // Current window state. boolean mCreated; Loading Loading @@ -264,6 +275,8 @@ public abstract class WallpaperService extends Service { SurfaceControl mSurfaceControl = new SurfaceControl(); SurfaceControl mBbqSurfaceControl; BLASTBufferQueue mBlastBufferQueue; private SurfaceControl mScreenshotSurfaceControl; private Point mScreenshotSize = new Point(); final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { { Loading Loading @@ -1349,11 +1362,15 @@ public abstract class WallpaperService extends Service { if (!mDestroyed) { mVisible = visible; reportVisibility(); if (visible) processLocalColors(mPendingXOffset, mPendingXOffsetStep); if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep); } } void reportVisibility() { if (mScreenshotSurfaceControl != null && mVisible) { if (DEBUG) Log.v(TAG, "Frozen so don't report visibility change"); return; } if (!mDestroyed) { mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState(); boolean visible = mVisible && mDisplayState != Display.STATE_OFF; Loading @@ -1370,6 +1387,10 @@ public abstract class WallpaperService extends Service { updateSurface(true, false, false); } onVisibilityChanged(visible); if (mReportedVisible && mFrozenRequested) { if (DEBUG) Log.v(TAG, "Freezing wallpaper after visibility update"); freeze(); } } } } Loading Loading @@ -1830,6 +1851,9 @@ public abstract class WallpaperService extends Service { void doCommand(WallpaperCommand cmd) { Bundle result; if (!mDestroyed) { if (COMMAND_FREEZE.equals(cmd.action) || COMMAND_UNFREEZE.equals(cmd.action)) { updateFrozenState(/* frozenRequested= */ !COMMAND_UNFREEZE.equals(cmd.action)); } result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z, cmd.extras, cmd.sync); } else { Loading @@ -1844,6 +1868,159 @@ public abstract class WallpaperService extends Service { } } private void updateFrozenState(boolean frozenRequested) { if (mIWallpaperEngine.mWallpaperManager.getWallpaperInfo() == null // Procees the unfreeze command in case the wallaper became static while // being paused. && frozenRequested) { if (DEBUG) Log.v(TAG, "Ignoring the freeze command for static wallpapers"); return; } mFrozenRequested = frozenRequested; boolean isFrozen = mScreenshotSurfaceControl != null; if (mFrozenRequested == isFrozen) { return; } if (mFrozenRequested) { freeze(); } else { unfreeze(); } } private void freeze() { if (!mReportedVisible || mDestroyed) { // Screenshot can't be taken until visibility is reported to the wallpaper host. return; } if (!showScreenshotOfWallpaper()) { return; } // Prevent a wallpaper host from rendering wallpaper behind a screeshot. doVisibilityChanged(false); // Remember that visibility is requested since it's not guaranteed that // mWindow#dispatchAppVisibility will be called when letterboxed application with // wallpaper background transitions to the Home screen. mVisible = true; } private void unfreeze() { cleanUpScreenshotSurfaceControl(); if (mVisible) { doVisibilityChanged(true); } } private void cleanUpScreenshotSurfaceControl() { // TODO(b/194399558): Add crossfade transition. if (mScreenshotSurfaceControl != null) { new SurfaceControl.Transaction() .remove(mScreenshotSurfaceControl) .show(mBbqSurfaceControl) .apply(); mScreenshotSurfaceControl = null; } } void scaleAndCropScreenshot() { if (mScreenshotSurfaceControl == null) { return; } if (mScreenshotSize.x <= 0 || mScreenshotSize.y <= 0) { Log.w(TAG, "Unexpected screenshot size: " + mScreenshotSize); return; } // Don't scale down and using the same scaling factor for both dimensions to // avoid stretching wallpaper image. float scaleFactor = Math.max(1, Math.max( ((float) mSurfaceSize.x) / mScreenshotSize.x, ((float) mSurfaceSize.y) / mScreenshotSize.y)); int diffX = ((int) (mScreenshotSize.x * scaleFactor)) - mSurfaceSize.x; int diffY = ((int) (mScreenshotSize.y * scaleFactor)) - mSurfaceSize.y; if (DEBUG) { Log.v(TAG, "Adjusting screenshot: scaleFactor=" + scaleFactor + " diffX=" + diffX + " diffY=" + diffY + " mSurfaceSize=" + mSurfaceSize + " mScreenshotSize=" + mScreenshotSize); } new SurfaceControl.Transaction() .setMatrix( mScreenshotSurfaceControl, /* dsdx= */ scaleFactor, /* dtdx= */ 0, /* dtdy= */ 0, /* dsdy= */ scaleFactor) .setWindowCrop( mScreenshotSurfaceControl, new Rect( /* left= */ diffX / 2, /* top= */ diffY / 2, /* right= */ diffX / 2 + mScreenshotSize.x, /* bottom= */ diffY / 2 + mScreenshotSize.y)) .setPosition(mScreenshotSurfaceControl, -diffX / 2, -diffY / 2) .apply(); } private boolean showScreenshotOfWallpaper() { if (mDestroyed || mSurfaceControl == null || !mSurfaceControl.isValid()) { if (DEBUG) Log.v(TAG, "Failed to screenshot wallpaper: surface isn't valid"); return false; } final Rect bounds = new Rect(0, 0, mSurfaceSize.x, mSurfaceSize.y); if (bounds.isEmpty()) { Log.w(TAG, "Failed to screenshot wallpaper: surface bounds are empty"); return false; } if (mScreenshotSurfaceControl != null) { Log.e(TAG, "Screenshot is unexpectedly not null"); // Destroying previous screenshot since it can have different size. cleanUpScreenshotSurfaceControl(); } SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = SurfaceControl.captureLayers( new SurfaceControl.LayerCaptureArgs.Builder(mSurfaceControl) // Needed because SurfaceFlinger#validateScreenshotPermissions // uses this parameter to check whether a caller only attempts // to screenshot itself when call doesn't come from the system. .setUid(Process.myUid()) .setChildrenOnly(false) .setSourceCrop(bounds) .build()); if (screenshotBuffer == null) { Log.w(TAG, "Failed to screenshot wallpaper: screenshotBuffer is null"); return false; } final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); SurfaceControl.Transaction t = new SurfaceControl.Transaction(); // TODO(b/194399558): Add crossfade transition. mScreenshotSurfaceControl = new SurfaceControl.Builder() .setName("Wallpaper snapshot for engine " + this) .setFormat(hardwareBuffer.getFormat()) .setParent(mSurfaceControl) .setSecure(screenshotBuffer.containsSecureLayers()) .setCallsite("WallpaperService.Engine.showScreenshotOfWallpaper") .setBLASTLayer() .build(); mScreenshotSize.set(mSurfaceSize.x, mSurfaceSize.y); GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(hardwareBuffer); t.setBuffer(mScreenshotSurfaceControl, graphicBuffer); t.setColorSpace(mScreenshotSurfaceControl, screenshotBuffer.getColorSpace()); // Place on top everything else. t.setLayer(mScreenshotSurfaceControl, Integer.MAX_VALUE); t.show(mScreenshotSurfaceControl); t.hide(mBbqSurfaceControl); t.apply(); return true; } void reportSurfaceDestroyed() { if (mSurfaceCreated) { mSurfaceCreated = false; Loading Loading @@ -2166,6 +2343,7 @@ public abstract class WallpaperService extends Service { final boolean reportDraw = message.arg1 != 0; mEngine.updateSurface(true, false, reportDraw); mEngine.doOffsetsChanged(true); mEngine.scaleAndCropScreenshot(); } break; case MSG_WINDOW_MOVED: { // Do nothing. What does it mean for a Wallpaper to move? Loading services/core/java/com/android/server/wm/WallpaperController.java +32 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.wm; import static android.app.WallpaperManager.COMMAND_FREEZE; import static android.app.WallpaperManager.COMMAND_UNFREEZE; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; Loading Loading @@ -79,6 +81,8 @@ class WallpaperController { private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE; private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE; private final float mMaxWallpaperScale; // Whether COMMAND_FREEZE was dispatched. private boolean mLastFrozen = false; // This is set when we are waiting for a wallpaper to tell us it is done // changing its scroll position. Loading Loading @@ -194,6 +198,7 @@ class WallpaperController { if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": token animating, looking behind."); } mFindResults.setIsWallpaperTargetForLetterbox(w.hasWallpaperForLetterboxBackground()); // Found a target! End search. return true; } Loading Loading @@ -424,6 +429,14 @@ class WallpaperController { Bundle sendWindowWallpaperCommand( WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) { if (window == mWallpaperTarget || window == mPrevWallpaperTarget) { sendWindowWallpaperCommand(action, x, y, z, extras, sync); } return null; } private void sendWindowWallpaperCommand( String action, int x, int y, int z, Bundle extras, boolean sync) { boolean doWait = sync; for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); Loading @@ -435,9 +448,6 @@ class WallpaperController { } } return null; } private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { WindowState target = mWallpaperTarget; if (target != null) { Loading Loading @@ -641,6 +651,13 @@ class WallpaperController { updateWallpaperTokens(visible); if (visible && mLastFrozen != mFindResults.isWallpaperTargetForLetterbox) { mLastFrozen = mFindResults.isWallpaperTargetForLetterbox; sendWindowWallpaperCommand( mFindResults.isWallpaperTargetForLetterbox ? COMMAND_FREEZE : COMMAND_UNFREEZE, /* x= */ 0, /* y= */ 0, /* z= */ 0, /* extras= */ null, /* sync= */ false); } if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget + " prev=" + mPrevWallpaperTarget); } Loading Loading @@ -838,6 +855,7 @@ class WallpaperController { boolean useTopWallpaperAsTarget = false; WindowState wallpaperTarget = null; boolean resetTopWallpaper = false; boolean isWallpaperTargetForLetterbox = false; void setTopWallpaper(WindowState win) { topWallpaper = win; Loading @@ -851,11 +869,16 @@ class WallpaperController { useTopWallpaperAsTarget = topWallpaperAsTarget; } void setIsWallpaperTargetForLetterbox(boolean isWallpaperTargetForLetterbox) { this.isWallpaperTargetForLetterbox = isWallpaperTargetForLetterbox; } void reset() { topWallpaper = null; wallpaperTarget = null; useTopWallpaperAsTarget = false; resetTopWallpaper = false; isWallpaperTargetForLetterbox = false; } } } services/core/java/com/android/server/wm/WindowState.java +5 −2 Original line number Diff line number Diff line Loading @@ -6043,8 +6043,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean hasWallpaper() { return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 || (mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox()); return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 || hasWallpaperForLetterboxBackground(); } boolean hasWallpaperForLetterboxBackground() { return mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox(); } /** Loading Loading
core/java/android/app/WallpaperManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -220,6 +220,20 @@ public class WallpaperManager { */ public static final String COMMAND_REAPPLY = "android.wallpaper.reapply"; /** * Command for {@link #sendWallpaperCommand}: reported when the live wallpaper needs to be * frozen. * @hide */ public static final String COMMAND_FREEZE = "android.wallpaper.freeze"; /** * Command for {@link #sendWallpaperCommand}: reported when the live wallapper doesn't need * to be frozen anymore. * @hide */ public static final String COMMAND_UNFREEZE = "android.wallpaper.unfreeze"; /** * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID. * @hide Loading
core/java/android/service/wallpaper/WallpaperService.java +179 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.service.wallpaper; import static android.app.WallpaperManager.COMMAND_FREEZE; import static android.app.WallpaperManager.COMMAND_UNFREEZE; import static android.graphics.Matrix.MSCALE_X; import static android.graphics.Matrix.MSCALE_Y; import static android.graphics.Matrix.MSKEW_X; Loading @@ -42,12 +44,14 @@ import android.content.res.TypedArray; import android.graphics.BLASTBufferQueue; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.GraphicBuffer; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Build; Loading @@ -56,6 +60,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; Loading Loading @@ -200,6 +205,12 @@ public abstract class WallpaperService extends Service { boolean mVisible; boolean mReportedVisible; boolean mDestroyed; // Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false // after receiving WallpaperManager#COMMAND_UNFREEZE. COMMAND_FREEZE is fully applied once // mScreenshotSurfaceControl isn't null. When this happens, then Engine is notified through // doVisibilityChanged that main wallpaper surface is no longer visible and the wallpaper // host receives onVisibilityChanged(false) callback. private boolean mFrozenRequested = false; // Current window state. boolean mCreated; Loading Loading @@ -264,6 +275,8 @@ public abstract class WallpaperService extends Service { SurfaceControl mSurfaceControl = new SurfaceControl(); SurfaceControl mBbqSurfaceControl; BLASTBufferQueue mBlastBufferQueue; private SurfaceControl mScreenshotSurfaceControl; private Point mScreenshotSize = new Point(); final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { { Loading Loading @@ -1349,11 +1362,15 @@ public abstract class WallpaperService extends Service { if (!mDestroyed) { mVisible = visible; reportVisibility(); if (visible) processLocalColors(mPendingXOffset, mPendingXOffsetStep); if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep); } } void reportVisibility() { if (mScreenshotSurfaceControl != null && mVisible) { if (DEBUG) Log.v(TAG, "Frozen so don't report visibility change"); return; } if (!mDestroyed) { mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState(); boolean visible = mVisible && mDisplayState != Display.STATE_OFF; Loading @@ -1370,6 +1387,10 @@ public abstract class WallpaperService extends Service { updateSurface(true, false, false); } onVisibilityChanged(visible); if (mReportedVisible && mFrozenRequested) { if (DEBUG) Log.v(TAG, "Freezing wallpaper after visibility update"); freeze(); } } } } Loading Loading @@ -1830,6 +1851,9 @@ public abstract class WallpaperService extends Service { void doCommand(WallpaperCommand cmd) { Bundle result; if (!mDestroyed) { if (COMMAND_FREEZE.equals(cmd.action) || COMMAND_UNFREEZE.equals(cmd.action)) { updateFrozenState(/* frozenRequested= */ !COMMAND_UNFREEZE.equals(cmd.action)); } result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z, cmd.extras, cmd.sync); } else { Loading @@ -1844,6 +1868,159 @@ public abstract class WallpaperService extends Service { } } private void updateFrozenState(boolean frozenRequested) { if (mIWallpaperEngine.mWallpaperManager.getWallpaperInfo() == null // Procees the unfreeze command in case the wallaper became static while // being paused. && frozenRequested) { if (DEBUG) Log.v(TAG, "Ignoring the freeze command for static wallpapers"); return; } mFrozenRequested = frozenRequested; boolean isFrozen = mScreenshotSurfaceControl != null; if (mFrozenRequested == isFrozen) { return; } if (mFrozenRequested) { freeze(); } else { unfreeze(); } } private void freeze() { if (!mReportedVisible || mDestroyed) { // Screenshot can't be taken until visibility is reported to the wallpaper host. return; } if (!showScreenshotOfWallpaper()) { return; } // Prevent a wallpaper host from rendering wallpaper behind a screeshot. doVisibilityChanged(false); // Remember that visibility is requested since it's not guaranteed that // mWindow#dispatchAppVisibility will be called when letterboxed application with // wallpaper background transitions to the Home screen. mVisible = true; } private void unfreeze() { cleanUpScreenshotSurfaceControl(); if (mVisible) { doVisibilityChanged(true); } } private void cleanUpScreenshotSurfaceControl() { // TODO(b/194399558): Add crossfade transition. if (mScreenshotSurfaceControl != null) { new SurfaceControl.Transaction() .remove(mScreenshotSurfaceControl) .show(mBbqSurfaceControl) .apply(); mScreenshotSurfaceControl = null; } } void scaleAndCropScreenshot() { if (mScreenshotSurfaceControl == null) { return; } if (mScreenshotSize.x <= 0 || mScreenshotSize.y <= 0) { Log.w(TAG, "Unexpected screenshot size: " + mScreenshotSize); return; } // Don't scale down and using the same scaling factor for both dimensions to // avoid stretching wallpaper image. float scaleFactor = Math.max(1, Math.max( ((float) mSurfaceSize.x) / mScreenshotSize.x, ((float) mSurfaceSize.y) / mScreenshotSize.y)); int diffX = ((int) (mScreenshotSize.x * scaleFactor)) - mSurfaceSize.x; int diffY = ((int) (mScreenshotSize.y * scaleFactor)) - mSurfaceSize.y; if (DEBUG) { Log.v(TAG, "Adjusting screenshot: scaleFactor=" + scaleFactor + " diffX=" + diffX + " diffY=" + diffY + " mSurfaceSize=" + mSurfaceSize + " mScreenshotSize=" + mScreenshotSize); } new SurfaceControl.Transaction() .setMatrix( mScreenshotSurfaceControl, /* dsdx= */ scaleFactor, /* dtdx= */ 0, /* dtdy= */ 0, /* dsdy= */ scaleFactor) .setWindowCrop( mScreenshotSurfaceControl, new Rect( /* left= */ diffX / 2, /* top= */ diffY / 2, /* right= */ diffX / 2 + mScreenshotSize.x, /* bottom= */ diffY / 2 + mScreenshotSize.y)) .setPosition(mScreenshotSurfaceControl, -diffX / 2, -diffY / 2) .apply(); } private boolean showScreenshotOfWallpaper() { if (mDestroyed || mSurfaceControl == null || !mSurfaceControl.isValid()) { if (DEBUG) Log.v(TAG, "Failed to screenshot wallpaper: surface isn't valid"); return false; } final Rect bounds = new Rect(0, 0, mSurfaceSize.x, mSurfaceSize.y); if (bounds.isEmpty()) { Log.w(TAG, "Failed to screenshot wallpaper: surface bounds are empty"); return false; } if (mScreenshotSurfaceControl != null) { Log.e(TAG, "Screenshot is unexpectedly not null"); // Destroying previous screenshot since it can have different size. cleanUpScreenshotSurfaceControl(); } SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = SurfaceControl.captureLayers( new SurfaceControl.LayerCaptureArgs.Builder(mSurfaceControl) // Needed because SurfaceFlinger#validateScreenshotPermissions // uses this parameter to check whether a caller only attempts // to screenshot itself when call doesn't come from the system. .setUid(Process.myUid()) .setChildrenOnly(false) .setSourceCrop(bounds) .build()); if (screenshotBuffer == null) { Log.w(TAG, "Failed to screenshot wallpaper: screenshotBuffer is null"); return false; } final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); SurfaceControl.Transaction t = new SurfaceControl.Transaction(); // TODO(b/194399558): Add crossfade transition. mScreenshotSurfaceControl = new SurfaceControl.Builder() .setName("Wallpaper snapshot for engine " + this) .setFormat(hardwareBuffer.getFormat()) .setParent(mSurfaceControl) .setSecure(screenshotBuffer.containsSecureLayers()) .setCallsite("WallpaperService.Engine.showScreenshotOfWallpaper") .setBLASTLayer() .build(); mScreenshotSize.set(mSurfaceSize.x, mSurfaceSize.y); GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(hardwareBuffer); t.setBuffer(mScreenshotSurfaceControl, graphicBuffer); t.setColorSpace(mScreenshotSurfaceControl, screenshotBuffer.getColorSpace()); // Place on top everything else. t.setLayer(mScreenshotSurfaceControl, Integer.MAX_VALUE); t.show(mScreenshotSurfaceControl); t.hide(mBbqSurfaceControl); t.apply(); return true; } void reportSurfaceDestroyed() { if (mSurfaceCreated) { mSurfaceCreated = false; Loading Loading @@ -2166,6 +2343,7 @@ public abstract class WallpaperService extends Service { final boolean reportDraw = message.arg1 != 0; mEngine.updateSurface(true, false, reportDraw); mEngine.doOffsetsChanged(true); mEngine.scaleAndCropScreenshot(); } break; case MSG_WINDOW_MOVED: { // Do nothing. What does it mean for a Wallpaper to move? Loading
services/core/java/com/android/server/wm/WallpaperController.java +32 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.wm; import static android.app.WallpaperManager.COMMAND_FREEZE; import static android.app.WallpaperManager.COMMAND_UNFREEZE; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; Loading Loading @@ -79,6 +81,8 @@ class WallpaperController { private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE; private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE; private final float mMaxWallpaperScale; // Whether COMMAND_FREEZE was dispatched. private boolean mLastFrozen = false; // This is set when we are waiting for a wallpaper to tell us it is done // changing its scroll position. Loading Loading @@ -194,6 +198,7 @@ class WallpaperController { if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": token animating, looking behind."); } mFindResults.setIsWallpaperTargetForLetterbox(w.hasWallpaperForLetterboxBackground()); // Found a target! End search. return true; } Loading Loading @@ -424,6 +429,14 @@ class WallpaperController { Bundle sendWindowWallpaperCommand( WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) { if (window == mWallpaperTarget || window == mPrevWallpaperTarget) { sendWindowWallpaperCommand(action, x, y, z, extras, sync); } return null; } private void sendWindowWallpaperCommand( String action, int x, int y, int z, Bundle extras, boolean sync) { boolean doWait = sync; for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); Loading @@ -435,9 +448,6 @@ class WallpaperController { } } return null; } private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { WindowState target = mWallpaperTarget; if (target != null) { Loading Loading @@ -641,6 +651,13 @@ class WallpaperController { updateWallpaperTokens(visible); if (visible && mLastFrozen != mFindResults.isWallpaperTargetForLetterbox) { mLastFrozen = mFindResults.isWallpaperTargetForLetterbox; sendWindowWallpaperCommand( mFindResults.isWallpaperTargetForLetterbox ? COMMAND_FREEZE : COMMAND_UNFREEZE, /* x= */ 0, /* y= */ 0, /* z= */ 0, /* extras= */ null, /* sync= */ false); } if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget + " prev=" + mPrevWallpaperTarget); } Loading Loading @@ -838,6 +855,7 @@ class WallpaperController { boolean useTopWallpaperAsTarget = false; WindowState wallpaperTarget = null; boolean resetTopWallpaper = false; boolean isWallpaperTargetForLetterbox = false; void setTopWallpaper(WindowState win) { topWallpaper = win; Loading @@ -851,11 +869,16 @@ class WallpaperController { useTopWallpaperAsTarget = topWallpaperAsTarget; } void setIsWallpaperTargetForLetterbox(boolean isWallpaperTargetForLetterbox) { this.isWallpaperTargetForLetterbox = isWallpaperTargetForLetterbox; } void reset() { topWallpaper = null; wallpaperTarget = null; useTopWallpaperAsTarget = false; resetTopWallpaper = false; isWallpaperTargetForLetterbox = false; } } }
services/core/java/com/android/server/wm/WindowState.java +5 −2 Original line number Diff line number Diff line Loading @@ -6043,8 +6043,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean hasWallpaper() { return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 || (mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox()); return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 || hasWallpaperForLetterboxBackground(); } boolean hasWallpaperForLetterboxBackground() { return mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox(); } /** Loading