diff --git a/api/current.xml b/api/current.xml index b9fb85a482c08..397e25dbe89f3 100644 --- a/api/current.xml +++ b/api/current.xml @@ -26818,6 +26818,19 @@ + + + + + + - - 0 ? -(int)(availw*xOffset+.5f) : 0; + final int availh = mReqHeight-mEngine.mCurHeight; + final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0; + mEngine.onOffsetsChanged(xOffset, yOffset, xPixels, yPixels); + } break; default : Log.w(TAG, "Unknown message type " + message.what); } diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 99d5c0caee36f..ec2036e57bc32 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -56,4 +56,9 @@ oneway interface IWindow { * to date on the current state showing navigational focus (touch mode) too. */ void windowFocusChanged(boolean hasFocus, boolean inTouchMode); + + /** + * Called for wallpaper windows when their offsets change. + */ + void dispatchWallpaperOffsets(float x, float y); } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 45465728d54d7..92e813f2ad063 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -16,6 +16,8 @@ package android.view; +import com.android.internal.view.BaseIWindow; + import android.content.Context; import android.content.res.Resources; import android.content.res.CompatibilityInfo.Translator; @@ -435,7 +437,7 @@ public class SurfaceView extends View { updateWindow(false); } - private static class MyWindow extends IWindow.Stub { + private static class MyWindow extends BaseIWindow { private final WeakReference mSurfaceView; public MyWindow(SurfaceView surfaceView) { diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 216fc5e76e40c..4623bb56a9865 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -2858,6 +2858,9 @@ public final class ViewRoot extends Handler implements ViewParent, } } } + + public void dispatchWallpaperOffsets(float x, float y) { + } } /** diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index 2ab9e09e8466c..e4c473d41059b 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -93,6 +93,10 @@ public class HandlerCaller { mH.sendMessage(msg); } + public boolean hasMessages(int what) { + return mH.hasMessages(what); + } + public void sendMessage(Message msg) { mH.sendMessage(msg); } diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 6d5084009639c..e1bf5cae23e61 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -21,6 +21,7 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.service.wallpaper.WallpaperService; +import android.util.Log; import android.view.SurfaceHolder; import android.content.Context; import android.content.IntentFilter; @@ -63,12 +64,23 @@ public class ImageWallpaper extends WallpaperService { class DrawableEngine extends Engine { private final Object mLock = new Object(); + private final Rect mBounds = new Rect(); Drawable mBackground; + int mXOffset; + int mYOffset; @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); mBackground = mWallpaperManager.getDrawable(); + mBounds.left = mBounds.top = 0; + mBounds.right = mBackground.getIntrinsicWidth(); + mBounds.bottom = mBackground.getIntrinsicHeight(); + int offx = (getDesiredMinimumWidth() - mBounds.right) / 2; + int offy = (getDesiredMinimumHeight() - mBounds.bottom) / 2; + mBounds.offset(offx, offy); + mBackground.setBounds(mBounds); + surfaceHolder.setSizeFromLayout(); } @Override @@ -76,6 +88,14 @@ public class ImageWallpaper extends WallpaperService { drawFrame(); } + @Override + public void onOffsetsChanged(float xOffset, float yOffset, + int xPixels, int yPixels) { + mXOffset = xPixels; + mYOffset = yPixels; + drawFrame(); + } + @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { super.onSurfaceChanged(holder, format, width, height); @@ -94,19 +114,16 @@ public class ImageWallpaper extends WallpaperService { void drawFrame() { SurfaceHolder sh = getSurfaceHolder(); - Canvas c = null; - try { - c = sh.lockCanvas(); - if (c != null) { - final Rect frame = sh.getSurfaceFrame(); - synchronized (mLock) { - final Drawable background = mBackground; - background.setBounds(frame); - background.draw(c); - } + Canvas c = sh.lockCanvas(); + if (c != null) { + //final Rect frame = sh.getSurfaceFrame(); + synchronized (mLock) { + final Drawable background = mBackground; + //background.setBounds(frame); + c.translate(mXOffset, mYOffset); + background.draw(c); } - } finally { - if (c != null) sh.unlockCanvasAndPost(c); + sh.unlockCanvasAndPost(c); } } diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index 744906780a4e0..a030db76e010d 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -65,4 +65,7 @@ public class BaseIWindow extends IWindow.Stub { public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { } + + public void dispatchWallpaperOffsets(float x, float y) { + } } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 641f251da5eb7..b0f049eceb637 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -1237,6 +1237,10 @@ public class WindowManagerService extends IWindowManager.Stub curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); + if (visible) { + updateWallpaperOffsetLocked(mWallpaperTarget, wallpaper, dw, dh); + } + // First, make sure the client has the current visibility // state. if (wallpaper.mWallpaperVisible != visible) { @@ -1250,10 +1254,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (visible) { - updateWallpaperOffsetLocked(mWallpaperTarget, wallpaper, dw, dh); - } - wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment; if (DEBUG_LAYERS) Log.v(TAG, "Wallpaper win " + wallpaper + " anim layer: " + wallpaper.mAnimLayer); @@ -1306,18 +1306,35 @@ public class WindowManagerService extends IWindowManager.Stub boolean updateWallpaperOffsetLocked(WindowState target, WindowState wallpaperWin, int dw, int dh) { - int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw; - int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0; - boolean changed = wallpaperWin.mXOffset != offset; - if (changed) { - wallpaperWin.mXOffset = offset; + boolean changed = false; + if (target.mWallpaperX >= 0) { + int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw; + int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0; + changed = wallpaperWin.mXOffset != offset; + if (changed) { + wallpaperWin.mXOffset = offset; + } } - int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh; - offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0; - if (wallpaperWin.mYOffset != offset) { - changed = true; - wallpaperWin.mYOffset = offset; + if (target.mWallpaperY >= 0) { + int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh; + int offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0; + if (wallpaperWin.mYOffset != offset) { + changed = true; + wallpaperWin.mYOffset = offset; + } } + + if (wallpaperWin.mWallpaperX != target.mWallpaperX + || wallpaperWin.mWallpaperY != target.mWallpaperY) { + wallpaperWin.mWallpaperX = target.mWallpaperX; + wallpaperWin.mWallpaperY = target.mWallpaperY; + try { + wallpaperWin.mClient.dispatchWallpaperOffsets( + wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY); + } catch (RemoteException e) { + } + } + return changed; } @@ -5975,8 +5992,6 @@ public class WindowManagerService extends IWindowManager.Stub int mRequestedHeight; int mLastRequestedWidth; int mLastRequestedHeight; - int mXOffset; - int mYOffset; int mLayer; int mAnimLayer; int mLastLayer; @@ -6061,8 +6076,14 @@ public class WindowManagerService extends IWindowManager.Stub boolean mHasLocalTransformation; final Transformation mTransformation = new Transformation(); - float mWallpaperX = 0; - float mWallpaperY = 0; + // If a window showing a wallpaper: the requested offset for the + // wallpaper; if a wallpaper window: the currently applied offset. + float mWallpaperX = -1; + float mWallpaperY = -1; + + // Wallpaper windows: pixels offset based on above variables. + int mXOffset; + int mYOffset; // This is set after IWindowSession.relayout() has been called at // least once for the window. It allows us to detect the situation @@ -7181,7 +7202,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); pw.print(" mVScale="); pw.println(mVScale); } - if (mWallpaperX != 0 || mWallpaperY != 0) { + if (mWallpaperX != -1 || mWallpaperY != -1) { pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); pw.print(" mWallpaperY="); pw.println(mWallpaperY); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index 8e7d48f78d967..8d44ac08558ea 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -1047,6 +1047,11 @@ public final class Bridge implements ILayoutBridge { // pass for now. } + @SuppressWarnings("unused") + public void dispatchWallpaperOffsets(float x, float y) { + // pass for now. + } + public IBinder asBinder() { // pass for now. return null;