From 72c82ab9923025a91bbabb32e56bfea27bfd083b Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 11 Aug 2009 21:13:54 -0700 Subject: [PATCH] Report wallpaper offset to the wallpaper, use this in the image wallpaper. Wallpapers can now be just the size of the screen, and get told when their scroll position should change to do the updating on their own. --- api/current.xml | 17 ++++- core/java/android/app/WallpaperManager.java | 19 +++++ .../service/wallpaper/WallpaperService.java | 70 +++++++++++++++++-- core/java/android/view/IWindow.aidl | 5 ++ core/java/android/view/SurfaceView.java | 4 +- core/java/android/view/ViewRoot.java | 3 + .../android/internal/os/HandlerCaller.java | 4 ++ .../service/wallpaper/ImageWallpaper.java | 41 +++++++---- .../android/internal/view/BaseIWindow.java | 3 + .../android/server/WindowManagerService.java | 59 +++++++++++----- .../com/android/layoutlib/bridge/Bridge.java | 5 ++ 11 files changed, 189 insertions(+), 41 deletions(-) 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;