diff options
24 files changed, 435 insertions, 115 deletions
@@ -358,6 +358,8 @@ web_docs_sample_code_flags := \ guide/samples/LunarLander "Lunar Lander" \ -samplecode $(sample_dir)/NotePad \ guide/samples/NotePad "Note Pad" \ + -samplecode $(sample_dir)/SearchableDictionary \ + guide/samples/SearchableDictionary "Searchable Dictionary" \ -samplecode $(sample_dir)/Snake \ guide/samples/Snake "Snake" \ -samplecode $(sample_dir)/SoftKeyboard \ 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/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index d4a4c11..0d51b93 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1042,6 +1042,7 @@ public final class ContactsContract { public static final int TYPE_HOME = 1; public static final int TYPE_WORK = 2; public static final int TYPE_OTHER = 3; + public static final int TYPE_MOBILE = 4; /** * The display name for the email address 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/config.xml b/core/res/res/values/config.xml index 86e6139..abb575c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -64,4 +64,21 @@ the slider is open. This can be set or unset depending how easily the slider can be opened (for example, in a pocket or purse). --> <bool name="config_bypass_keyguard_if_slider_open">true</bool> + + <!-- Vibrator pattern for feedback about a long screen/key press --> + <integer-array name="config_longPressVibePattern"> + <item>0</item> + <item>1</item> + <item>20</item> + <item>21</item> + </integer-array> + + <!-- Vibrator pattern for feedback about touching a virtual key --> + <integer-array name="config_virtualKeyVibePattern"> + <item>0</item> + <item>10</item> + <item>20</item> + <item>30</item> + </integer-array> + </resources> 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/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 459ad37..ef1a1ea 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -399,6 +399,9 @@ <li><a href="<?cs var:toroot ?>guide/samples/NotePad/index.html"> <span class="en">Note Pad</span> </a></li> + <li><a href="<?cs var:toroot ?>guide/samples/SearchableDictionary/index.html"> + <span class="en">Searchable Dictionary</span> + </a></li> <li><a href="<?cs var:toroot ?>guide/samples/Snake/index.html"> <span class="en">Snake</span> </a></li> diff --git a/docs/html/guide/samples/images/SearchableDictionary1.png b/docs/html/guide/samples/images/SearchableDictionary1.png Binary files differnew file mode 100644 index 0000000..ebb4604 --- /dev/null +++ b/docs/html/guide/samples/images/SearchableDictionary1.png diff --git a/docs/html/guide/samples/images/SearchableDictionary2.png b/docs/html/guide/samples/images/SearchableDictionary2.png Binary files differnew file mode 100644 index 0000000..34746cd --- /dev/null +++ b/docs/html/guide/samples/images/SearchableDictionary2.png diff --git a/docs/html/guide/samples/index.jd b/docs/html/guide/samples/index.jd index d8bbc41..6e79d50 100644 --- a/docs/html/guide/samples/index.jd +++ b/docs/html/guide/samples/index.jd @@ -33,6 +33,10 @@ can modify them and watch them execute. </p> <dd>An application for saving notes. Similar (but not identical) to the <a href="{@docRoot}guide/tutorials/notepad/index.html">Notepad tutorial</a>.</dd> + <dt><a href="SearchableDictionary/index.html">Searchable Dictionary</a></dt> + <dd>A sample application that demonstrates Android's search framework, + including how to provide search suggestions for Quick Search Box.</dd> + <dt><a href="Snake/index.html">Snake</a></dt> <dd>An implementation of the classic game "Snake."</dd> diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index 2bd039f..7385359 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -36,17 +36,15 @@ class DockObserver extends UEventObserver { private static final String DOCK_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/dock"; private static final String DOCK_STATE_PATH = "/sys/class/switch/dock/state"; - private int mDockState; - private boolean mPendingIntent; + private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + private boolean mSystemReady; private final Context mContext; public DockObserver(Context context) { mContext = context; - - startObserving(DOCK_UEVENT_MATCH); - init(); // set initial status + startObserving(DOCK_UEVENT_MATCH); } @Override @@ -55,55 +53,59 @@ class DockObserver extends UEventObserver { Log.v(TAG, "Dock UEVENT: " + event.toString()); } - try { - update(Integer.parseInt(event.get("SWITCH_STATE"))); - } catch (NumberFormatException e) { - Log.e(TAG, "Could not parse switch state from event " + event); + synchronized (this) { + try { + int newState = Integer.parseInt(event.get("SWITCH_STATE")); + if (newState != mDockState) { + mDockState = newState; + if (mSystemReady) { + update(); + } + } + } catch (NumberFormatException e) { + Log.e(TAG, "Could not parse switch state from event " + event); + } } } - private synchronized final void init() { + private final void init() { char[] buffer = new char[1024]; - int newState = mDockState; try { FileReader file = new FileReader(DOCK_STATE_PATH); int len = file.read(buffer, 0, 1024); - newState = Integer.valueOf((new String(buffer, 0, len)).trim()); + mDockState = Integer.valueOf((new String(buffer, 0, len)).trim()); } catch (FileNotFoundException e) { Log.w(TAG, "This kernel does not have dock station support"); } catch (Exception e) { Log.e(TAG, "" , e); } - - update(newState); } - private synchronized final void update(int newState) { - if (newState != mDockState) { - mDockState = newState; - - mPendingIntent = true; - mHandler.sendEmptyMessage(0); + void systemReady() { + synchronized (this) { + // don't bother broadcasting undocked here + if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) { + update(); + } + mSystemReady = true; } } - private synchronized final void sendIntent() { - Log.d(TAG, "Broadcasting dock state " + mDockState); - - // Pack up the values and broadcast them to everyone - Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); - intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); - mContext.sendStickyBroadcast(intent); + private final void update() { + mHandler.sendEmptyMessage(0); } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { - if (mPendingIntent) { - sendIntent(); - mPendingIntent = false; + synchronized (this) { + Log.d(TAG, "Broadcasting dock state " + mDockState); + // Pack up the values and broadcast them to everyone + Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); + intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); + mContext.sendStickyBroadcast(intent); } } }; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 95edbeb..df01c61 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -392,6 +392,7 @@ class ServerThread extends Thread { if (wallpaper != null) wallpaper.systemReady(); if (battery != null) battery.systemReady(); if (connectivity != null) connectivity.systemReady(); + if (dock != null) dock.systemReady(); Watchdog.getInstance().start(); Looper.loop(); 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); |
