diff options
-rw-r--r-- | core/java/android/app/IWallpaperManager.aidl | 4 | ||||
-rw-r--r-- | core/java/android/app/WallpaperManager.java | 92 | ||||
-rw-r--r-- | core/java/android/service/wallpaper/IWallpaperEngine.aidl | 2 | ||||
-rw-r--r-- | core/java/android/service/wallpaper/WallpaperService.java | 162 | ||||
-rw-r--r-- | core/java/com/android/internal/service/wallpaper/ImageWallpaper.java | 38 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_activity_close_enter.xml | 2 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_activity_close_exit.xml | 2 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_activity_open_enter.xml | 2 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_activity_open_exit.xml | 2 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_enter.xml | 29 | ||||
-rw-r--r-- | core/res/res/anim/wallpaper_exit.xml | 29 | ||||
-rw-r--r-- | core/res/res/values/styles.xml | 6 | ||||
-rw-r--r-- | services/java/com/android/server/WallpaperManagerService.java | 18 | ||||
-rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 70 |
15 files changed, 375 insertions, 85 deletions
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 7741668..4d1e254 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -16,6 +16,7 @@ package android.app; +import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.app.IWallpaperManagerCallback; import android.content.ComponentName; @@ -36,7 +37,8 @@ interface IWallpaperManager { /** * Get the wallpaper. */ - ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb); + ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, + out Bundle outParams); /** * Clear the wallpaper. diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index c5ca0a3..7669306 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -21,13 +21,18 @@ import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; +import android.util.DisplayMetrics; import android.util.Log; import android.view.ViewRoot; @@ -51,7 +56,7 @@ public class WallpaperManager { static class Globals extends IWallpaperManagerCallback.Stub { private IWallpaperManager mService; - private Drawable mWallpaper; + private Bitmap mWallpaper; Globals() { IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE); @@ -69,7 +74,7 @@ public class WallpaperManager { } } - public Drawable peekWallpaper(Context context) { + public Bitmap peekWallpaperBitmap(Context context) { synchronized (this) { if (mWallpaper != null) { return mWallpaper; @@ -79,18 +84,82 @@ public class WallpaperManager { } } - private Drawable getCurrentWallpaperLocked(Context context) { + private Bitmap getCurrentWallpaperLocked(Context context) { try { - ParcelFileDescriptor fd = mService.getWallpaper(this); + Bundle params = new Bundle(); + ParcelFileDescriptor fd = mService.getWallpaper(this, params); if (fd != null) { + int width = params.getInt("width", 0); + int height = params.getInt("height", 0); + + if (width <= 0 || height <= 0) { + // Degenerate case: no size requested, just load + // bitmap as-is. + Bitmap bm = BitmapFactory.decodeFileDescriptor( + fd.getFileDescriptor(), null, null); + try { + fd.close(); + } catch (IOException e) { + } + if (bm != null) { + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + } + return bm; + } + + // Load the bitmap with full color depth, to preserve + // quality for later processing. + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inDither = false; + options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap bm = BitmapFactory.decodeFileDescriptor( - fd.getFileDescriptor(), null, null); - if (bm != null) { - // For now clear the density until we figure out how - // to deal with it for wallpapers. - bm.setDensity(0); - return new BitmapDrawable(context.getResources(), bm); + fd.getFileDescriptor(), null, options); + try { + fd.close(); + } catch (IOException e) { + } + if (bm == null) { + return bm; + } + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + + // This is the final bitmap we want to return. + Bitmap newbm = Bitmap.createBitmap(width, height, + bm.getConfig()); + newbm.setDensity(DisplayMetrics.DENSITY_DEVICE); + Canvas c = new Canvas(newbm); + c.setDensity(DisplayMetrics.DENSITY_DEVICE); + Rect targetRect = new Rect(); + targetRect.left = targetRect.top = 0; + targetRect.right = bm.getWidth(); + targetRect.bottom = bm.getHeight(); + + int deltaw = width - targetRect.right; + int deltah = height - targetRect.bottom; + + if (deltaw > 0 || deltah > 0) { + // We need to scale up so it covers the entire + // area. + float scale = 1.0f; + if (deltaw > deltah) { + scale = width / (float)targetRect.right; + } else { + scale = height / (float)targetRect.bottom; + } + targetRect.right = (int)(targetRect.right*scale); + targetRect.bottom = (int)(targetRect.bottom*scale); + deltaw = width - targetRect.right; + deltah = height - targetRect.bottom; } + + targetRect.offset(deltaw/2, deltah/2); + Paint paint = new Paint(); + paint.setFilterBitmap(true); + paint.setDither(true); + c.drawBitmap(bm, null, targetRect, paint); + + bm.recycle(); + return newbm; } } catch (RemoteException e) { } @@ -149,7 +218,8 @@ public class WallpaperManager { * null pointer if these is none. */ public Drawable peekDrawable() { - return getGlobals().peekWallpaper(mContext); + Bitmap bm = getGlobals().peekWallpaperBitmap(mContext); + return bm != null ? new BitmapDrawable(mContext.getResources(), bm) : null; } /** diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl index 9586e34..bbd9dde 100644 --- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl +++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl @@ -20,5 +20,7 @@ package android.service.wallpaper; * @hide */ oneway interface IWallpaperEngine { + void setDesiredSize(int width, int height); + void setVisibility(boolean visible); void destroy(); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 629e97e..2cdfc66 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -55,6 +55,7 @@ public abstract class WallpaperService extends Service { private static final int DO_ATTACH = 10; private static final int DO_DETACH = 20; + private static final int DO_SET_DESIRED_SIZE = 30; private static final int MSG_UPDATE_SURFACE = 10000; private static final int MSG_VISIBILITY_CHANGED = 10010; @@ -78,6 +79,8 @@ public abstract class WallpaperService extends Service { IBinder mWindowToken; boolean mInitializing = true; + boolean mVisible; + boolean mDestroyed; // Current window state. boolean mCreated; @@ -129,8 +132,15 @@ public abstract class WallpaperService extends Service { return mIsCreating; } + @Override + public void setFixedSize(int width, int height) { + throw new UnsupportedOperationException( + "Wallpapers currently only support sizing from layout"); + } + public void setKeepScreenOn(boolean screenOn) { - // Ignore. + throw new UnsupportedOperationException( + "Wallpapers do not support keep screen on"); } }; @@ -166,9 +176,13 @@ public abstract class WallpaperService extends Service { @Override public void dispatchAppVisibility(boolean visible) { - Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED, - visible ? 1 : 0); - mCaller.sendMessage(msg); + // We don't do this in preview mode; we'll let the preview + // activity tell us when to run. + if (!mIWallpaperEngine.mIsPreview) { + Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED, + visible ? 1 : 0); + mCaller.sendMessage(msg); + } } @Override @@ -212,6 +226,15 @@ public abstract class WallpaperService extends Service { } /** + * Return whether the wallpaper is currently visible to the user, + * this is the last value supplied to + * {@link #onVisibilityChanged(boolean)}. + */ + public boolean isVisible() { + return mVisible; + } + + /** * Returns true if this engine is running in preview mode -- that is, * it is being shown to the user before they select it as the actual * wallpaper. @@ -280,6 +303,13 @@ public abstract class WallpaperService extends Service { } /** + * Called when an application has changed the desired virtual size of + * the wallpaper. + */ + public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { + } + + /** * Convenience for {@link SurfaceHolder.Callback#surfaceChanged * SurfaceHolder.Callback.surfaceChanged()}. */ @@ -301,6 +331,10 @@ public abstract class WallpaperService extends Service { } void updateSurface(boolean forceRelayout, boolean forceReport) { + if (mDestroyed) { + Log.w(TAG, "Ignoring updateSurface: destroyed"); + } + int myWidth = mSurfaceHolder.getRequestedWidth(); if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.FILL_PARENT; int myHeight = mSurfaceHolder.getRequestedHeight(); @@ -314,7 +348,7 @@ public abstract class WallpaperService extends Service { if (forceRelayout || creating || formatChanged || sizeChanged || typeChanged || flagsChanged) { - if (DEBUG) Log.i(TAG, "Changes: creating=" + creating + if (DEBUG) Log.v(TAG, "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged); try { @@ -343,6 +377,8 @@ public abstract class WallpaperService extends Service { if (!mCreated) { mLayout.type = mIWallpaperEngine.mWindowType; mLayout.gravity = Gravity.LEFT|Gravity.TOP; + mLayout.windowAnimations = + com.android.internal.R.style.Animation_Wallpaper; mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets); } @@ -354,7 +390,7 @@ public abstract class WallpaperService extends Service { View.VISIBLE, false, mWinFrame, mContentInsets, mVisibleInsets, mSurfaceHolder.mSurface); - if (DEBUG) Log.i(TAG, "New surface: " + mSurfaceHolder.mSurface + if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface + ", frame=" + mWinFrame); int w = mWinFrame.width(); @@ -384,6 +420,8 @@ public abstract class WallpaperService extends Service { if (!mCreated) { mIsCreating = true; + if (DEBUG) Log.v(TAG, "onSurfaceCreated(" + + mSurfaceHolder + "): " + this); onSurfaceCreated(mSurfaceHolder); if (callbacks != null) { for (SurfaceHolder.Callback c : callbacks) { @@ -399,6 +437,10 @@ public abstract class WallpaperService extends Service { + " formatChanged=" + formatChanged + " sizeChanged=" + sizeChanged, e); } + if (DEBUG) Log.v(TAG, "onSurfaceChanged(" + + mSurfaceHolder + ", " + mFormat + + ", " + mCurWidth + ", " + mCurHeight + + "): " + this); onSurfaceChanged(mSurfaceHolder, mFormat, mCurWidth, mCurHeight); if (callbacks != null) { @@ -425,26 +467,73 @@ public abstract class WallpaperService extends Service { void attach(IWallpaperEngineWrapper wrapper) { if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper); + if (mDestroyed) { + return; + } + mIWallpaperEngine = wrapper; mCaller = wrapper.mCaller; mConnection = wrapper.mConnection; mWindowToken = wrapper.mWindowToken; - // XXX temp -- should run in size from layout (screen) mode. - mSurfaceHolder.setFixedSize(mIWallpaperEngine.mReqWidth, - mIWallpaperEngine.mReqHeight); - //mSurfaceHolder.setSizeFromLayout(); + mSurfaceHolder.setSizeFromLayout(); mInitializing = true; mSession = ViewRoot.getWindowSession(getMainLooper()); mWindow.setSession(mSession); + if (DEBUG) Log.v(TAG, "onCreate(): " + this); onCreate(mSurfaceHolder); mInitializing = false; updateSurface(false, false); } + void doDesiredSizeChanged(int desiredWidth, int desiredHeight) { + if (!mDestroyed) { + if (DEBUG) Log.v(TAG, "onDesiredSizeChanged(" + + desiredWidth + "," + desiredHeight + "): " + this); + onDesiredSizeChanged(desiredWidth, desiredHeight); + } + } + + void doVisibilityChanged(boolean visible) { + if (!mDestroyed) { + mVisible = visible; + if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible + + "): " + this); + onVisibilityChanged(visible); + } + } + + void doOffsetsChanged() { + if (mDestroyed) { + return; + } + + float xOffset; + float yOffset; + synchronized (mLock) { + xOffset = mPendingXOffset; + yOffset = mPendingYOffset; + mOffsetMessageEnqueued = false; + } + if (DEBUG) Log.v(TAG, "Offsets change in " + this + + ": " + xOffset + "," + yOffset); + final int availw = mIWallpaperEngine.mReqWidth-mCurWidth; + final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0; + final int availh = mIWallpaperEngine.mReqHeight-mCurHeight; + final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0; + onOffsetsChanged(xOffset, yOffset, xPixels, yPixels); + } + void detach() { - onDestroy(); + mDestroyed = true; + + if (mVisible) { + mVisible = false; + if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this); + onVisibilityChanged(false); + } + if (mDestroyReportNeeded) { mDestroyReportNeeded = false; SurfaceHolder.Callback callbacks[]; @@ -456,7 +545,14 @@ public abstract class WallpaperService extends Service { for (SurfaceHolder.Callback c : callbacks) { c.surfaceDestroyed(mSurfaceHolder); } + if (DEBUG) Log.v(TAG, "onSurfaceDestroyed(" + + mSurfaceHolder + "): " + this); + onSurfaceDestroyed(mSurfaceHolder); } + + if (DEBUG) Log.v(TAG, "onDestroy(): " + this); + onDestroy(); + if (mCreated) { try { mSession.remove(mWindow); @@ -492,16 +588,21 @@ public abstract class WallpaperService extends Service { mReqWidth = reqWidth; mReqHeight = reqHeight; - try { - conn.attachEngine(this); - } catch (RemoteException e) { - destroy(); - } - Message msg = mCaller.obtainMessage(DO_ATTACH); mCaller.sendMessage(msg); } + public void setDesiredSize(int width, int height) { + Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height); + mCaller.sendMessage(msg); + } + + public void setVisibility(boolean visible) { + Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED, + visible ? 1 : 0); + mCaller.sendMessage(msg); + } + public void destroy() { Message msg = mCaller.obtainMessage(DO_DETACH); mCaller.sendMessage(msg); @@ -510,6 +611,12 @@ public abstract class WallpaperService extends Service { public void executeMessage(Message message) { switch (message.what) { case DO_ATTACH: { + try { + mConnection.attachEngine(this); + } catch (RemoteException e) { + Log.w(TAG, "Wallpaper host disappeared", e); + return; + } Engine engine = onCreateEngine(); mEngine = engine; engine.attach(this); @@ -519,29 +626,20 @@ public abstract class WallpaperService extends Service { mEngine.detach(); return; } + case DO_SET_DESIRED_SIZE: { + mEngine.doDesiredSizeChanged(message.arg1, message.arg2); + return; + } case MSG_UPDATE_SURFACE: mEngine.updateSurface(true, false); break; case MSG_VISIBILITY_CHANGED: if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine + ": " + message.arg1); - mEngine.onVisibilityChanged(message.arg1 != 0); + mEngine.doVisibilityChanged(message.arg1 != 0); break; case MSG_WALLPAPER_OFFSETS: { - float xOffset; - float yOffset; - synchronized (mEngine.mLock) { - xOffset = mEngine.mPendingXOffset; - yOffset = mEngine.mPendingYOffset; - mEngine.mOffsetMessageEnqueued = false; - } - if (DEBUG) Log.v(TAG, "Offsets change in " + mEngine - + ": " + xOffset + "," + yOffset); - final int availw = mReqWidth-mEngine.mCurWidth; - final int xPixels = availw > 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); + mEngine.doOffsetsChanged(); } break; case MSG_WINDOW_RESIZED: { final boolean reportDraw = message.arg1 != 0; diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index c4eb31f..5357469 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -33,52 +33,50 @@ import android.content.BroadcastReceiver; */ public class ImageWallpaper extends WallpaperService { WallpaperManager mWallpaperManager; - ImageWallpaper.DrawableEngine mEngine; - private WallpaperObserver mReceiver; @Override public void onCreate() { super.onCreate(); mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); - IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); - mReceiver = new WallpaperObserver(); - registerReceiver(mReceiver, filter); - } - - @Override - public void onDestroy() { - super.onDestroy(); - unregisterReceiver(mReceiver); } public Engine onCreateEngine() { - mEngine = new DrawableEngine(); - return mEngine; - } - - class WallpaperObserver extends BroadcastReceiver { - public void onReceive(Context context, Intent intent) { - mEngine.updateWallpaper(); - mEngine.drawFrame(); - } + return new DrawableEngine(); } class DrawableEngine extends Engine { private final Object mLock = new Object(); private final Rect mBounds = new Rect(); + private WallpaperObserver mReceiver; Drawable mBackground; float mXOffset; float mYOffset; + class WallpaperObserver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + updateWallpaper(); + drawFrame(); + } + } + @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); + IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); + mReceiver = new WallpaperObserver(); + registerReceiver(mReceiver, filter); updateWallpaper(); surfaceHolder.setSizeFromLayout(); //setTouchEventsEnabled(true); } @Override + public void onDestroy() { + super.onDestroy(); + unregisterReceiver(mReceiver); + } + + @Override public void onVisibilityChanged(boolean visible) { drawFrame(); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4f789dd..1ea5fa3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -898,7 +898,7 @@ <permission android:name="android.permission.BIND_WALLPAPER" android:label="@string/permlab_bindWallpaper" android:description="@string/permdesc_bindWallpaper" - android:protectionLevel="signature" /> + android:protectionLevel="signatureOrSystem" /> <!-- Allows low-level access to setting the orientation (actually rotation) of the screen. Not for use by normal applications. --> diff --git a/core/res/res/anim/wallpaper_activity_close_enter.xml b/core/res/res/anim/wallpaper_activity_close_enter.xml index fc6e332..9e9bd80 100644 --- a/core/res/res/anim/wallpaper_activity_close_enter.xml +++ b/core/res/res/anim/wallpaper_activity_close_enter.xml @@ -27,4 +27,6 @@ android:duration="@android:integer/config_mediumAnimTime" /> <translate android:fromXDelta="-150%" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/wallpaper_activity_close_exit.xml b/core/res/res/anim/wallpaper_activity_close_exit.xml index edd00fd..badbbf0 100644 --- a/core/res/res/anim/wallpaper_activity_close_exit.xml +++ b/core/res/res/anim/wallpaper_activity_close_exit.xml @@ -26,4 +26,6 @@ android:duration="@android:integer/config_mediumAnimTime" /> <translate android:fromXDelta="0%" android:toXDelta="100%" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:duration="@android:integer/config_mediumAnimTime"/> </set> diff --git a/core/res/res/anim/wallpaper_activity_open_enter.xml b/core/res/res/anim/wallpaper_activity_open_enter.xml index 5b44d97..e60bac2 100644 --- a/core/res/res/anim/wallpaper_activity_open_enter.xml +++ b/core/res/res/anim/wallpaper_activity_open_enter.xml @@ -26,4 +26,6 @@ android:duration="@android:integer/config_mediumAnimTime" /> <translate android:fromXDelta="100%" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/wallpaper_activity_open_exit.xml b/core/res/res/anim/wallpaper_activity_open_exit.xml index fa39bee..01abbb7 100644 --- a/core/res/res/anim/wallpaper_activity_open_exit.xml +++ b/core/res/res/anim/wallpaper_activity_open_exit.xml @@ -27,4 +27,6 @@ android:duration="@android:integer/config_mediumAnimTime" /> <translate android:fromXDelta="0" android:toXDelta="-150%" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:duration="@android:integer/config_mediumAnimTime"/> </set> diff --git a/core/res/res/anim/wallpaper_enter.xml b/core/res/res/anim/wallpaper_enter.xml new file mode 100644 index 0000000..981f5f6 --- /dev/null +++ b/core/res/res/anim/wallpaper_enter.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/anim/options_panel_exit.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@anim/decelerate_interpolator"> + <scale android:fromXScale="3.0" android:toXScale="1.0" + android:fromYScale="3.0" android:toYScale="1.0" + android:pivotX="50%" android:pivotY="50%" + android:duration="@android:integer/config_longAnimTime" /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" /> +</set> diff --git a/core/res/res/anim/wallpaper_exit.xml b/core/res/res/anim/wallpaper_exit.xml new file mode 100644 index 0000000..2306071 --- /dev/null +++ b/core/res/res/anim/wallpaper_exit.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/anim/options_panel_exit.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@anim/accelerate_interpolator"> + <scale android:fromXScale="1.0" android:toXScale="3.0" + android:fromYScale="1.0" android:toYScale="3.0" + android:pivotX="50%" android:pivotY="50%" + android:duration="@android:integer/config_longAnimTime" /> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:duration="@android:integer/config_longAnimTime"/> +</set> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 3950cb1..55f8167 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -160,6 +160,12 @@ <item name="windowExitAnimation">@anim/fade_out</item> </style> + <!-- Standard animations for wallpapers. --> + <style name="Animation.Wallpaper"> + <item name="windowEnterAnimation">@anim/wallpaper_enter</item> + <item name="windowExitAnimation">@anim/wallpaper_exit</item> + </style> + <!-- Status Bar Styles --> <style name="TextAppearance.StatusBarTitle"> diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index 3c62aa0..c101463 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -32,6 +32,7 @@ import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.FileObserver; @@ -232,6 +233,16 @@ class WallpaperManagerService extends IWallpaperManager.Stub { mWidth = width; mHeight = height; saveSettingsLocked(); + if (mWallpaperConnection != null) { + if (mWallpaperConnection.mEngine != null) { + try { + mWallpaperConnection.mEngine.setDesiredSize( + width, height); + } catch (RemoteException e) { + } + notifyCallbacksLocked(); + } + } } } } @@ -248,9 +259,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } } - public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb) { + public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, + Bundle outParams) { synchronized (mLock) { try { + if (outParams != null) { + outParams.putInt("width", mWidth); + outParams.putInt("height", mHeight); + } mCallbacks.register(cb); File f = WALLPAPER_FILE; if (!f.exists()) { diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 4321b0d..81e0136 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -412,6 +412,8 @@ public class WindowManagerService extends IWindowManager.Stub // to another, and this is the higher one in Z-order. WindowState mUpperWallpaperTarget = null; int mWallpaperAnimLayerAdjustment; + float mLastWallpaperX; + float mLastWallpaperY; AppWindowToken mFocusedApp = null; @@ -1371,6 +1373,11 @@ public class WindowManagerService extends IWindowManager.Stub // what is below it for later. foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null; + if (visible) { + mLastWallpaperX = mWallpaperTarget.mWallpaperX; + mLastWallpaperY = mWallpaperTarget.mWallpaperY; + } + // Start stepping backwards from here, ensuring that our wallpaper windows // are correctly placed. int curTokenIndex = mWallpaperTokens.size(); @@ -1383,8 +1390,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(mWallpaperTarget, - wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh); } // First, make sure the client has the current visibility @@ -1455,36 +1461,35 @@ public class WindowManagerService extends IWindowManager.Stub } } - boolean updateWallpaperOffsetLocked(WindowState target, - WindowState wallpaperWin, int dw, int dh) { + boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh) { boolean changed = false; boolean rawChanged = false; - if (target.mWallpaperX >= 0) { + if (mLastWallpaperX >= 0) { int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw; - int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0; + int offset = availw > 0 ? -(int)(availw*mLastWallpaperX+.5f) : 0; changed = wallpaperWin.mXOffset != offset; if (changed) { if (DEBUG_WALLPAPER) Log.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset); wallpaperWin.mXOffset = offset; } - if (wallpaperWin.mWallpaperX != target.mWallpaperX) { - wallpaperWin.mWallpaperX = target.mWallpaperX; + if (wallpaperWin.mWallpaperX != mLastWallpaperX) { + wallpaperWin.mWallpaperX = mLastWallpaperX; rawChanged = true; } } - if (target.mWallpaperY >= 0) { + if (mLastWallpaperY >= 0) { int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh; - int offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0; + int offset = availh > 0 ? -(int)(availh*mLastWallpaperY+.5f) : 0; if (wallpaperWin.mYOffset != offset) { if (DEBUG_WALLPAPER) Log.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset); changed = true; wallpaperWin.mYOffset = offset; } - if (wallpaperWin.mWallpaperY != target.mWallpaperY) { - wallpaperWin.mWallpaperY = target.mWallpaperY; + if (wallpaperWin.mWallpaperY != mLastWallpaperY) { + wallpaperWin.mWallpaperY = mLastWallpaperY; rawChanged = true; } } @@ -1511,6 +1516,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowState target = mWallpaperTarget; if (target != null) { + mLastWallpaperX = target.mWallpaperX; + mLastWallpaperY = target.mWallpaperY; int curTokenIndex = mWallpaperTokens.size(); while (curTokenIndex > 0) { curTokenIndex--; @@ -1519,7 +1526,7 @@ public class WindowManagerService extends IWindowManager.Stub while (curWallpaperIndex > 0) { curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); - if (updateWallpaperOffsetLocked(target, wallpaper, dw, dh)) { + if (updateWallpaperOffsetLocked(wallpaper, dw, dh)) { wallpaper.computeShownFrameLocked(); changed = true; } @@ -1545,8 +1552,7 @@ public class WindowManagerService extends IWindowManager.Stub curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(mWallpaperTarget, - wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh); } if (wallpaper.mWallpaperVisible != visible) { @@ -2188,6 +2194,10 @@ public class WindowManagerService extends IWindowManager.Stub } newConfig = updateOrientationFromAppTokensLocked(null, null); performLayoutAndPlaceSurfacesLocked(); + if (displayed && win.mIsWallpaper) { + updateWallpaperOffsetLocked(win, mDisplay.getWidth(), + mDisplay.getHeight()); + } if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); } @@ -3010,6 +3020,23 @@ public class WindowManagerService extends IWindowManager.Stub return; } + // If this is a translucent or wallpaper window, then don't + // show a starting window -- the current effect (a full-screen + // opaque starting window that fades away to the real contents + // when it is ready) does not work for this. + if (theme != 0) { + AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme, + com.android.internal.R.styleable.Window); + if (ent.array.getBoolean( + com.android.internal.R.styleable.Window_windowIsTranslucent, false)) { + return; + } + if (ent.array.getBoolean( + com.android.internal.R.styleable.Window_windowShowWallpaper, false)) { + return; + } + } + mStartingIconInTransition = true; wtoken.startingData = new StartingData( pkg, theme, nonLocalizedLabel, @@ -6544,10 +6571,9 @@ public class WindowManagerService extends IWindowManager.Stub visibleInsets.right = frame.right-visible.right; visibleInsets.bottom = frame.bottom-visible.bottom; - if (mIsWallpaper && (fw != frame.width() || fh != frame.height()) - && mWallpaperTarget != null) { - updateWallpaperOffsetLocked(mWallpaperTarget, this, - mDisplay.getWidth(), mDisplay.getHeight()); + if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { + updateWallpaperOffsetLocked(this, mDisplay.getWidth(), + mDisplay.getHeight()); } if (localLOGV) { @@ -9851,6 +9877,10 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget); pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow); pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget); + if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) { + pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget); + pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget); + } pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mSystemBooted="); pw.print(mSystemBooted); pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled); @@ -9865,6 +9895,8 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(mInputMethodAnimLayerAdjustment); pw.print(" mWallpaperAnimLayerAdjustment="); pw.println(mWallpaperAnimLayerAdjustment); + pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX); + pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY); pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen); pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen); pw.print(" mAppsFreezingScreen="); pw.println(mAppsFreezingScreen); |