diff options
44 files changed, 864 insertions, 284 deletions
diff --git a/api/current.xml b/api/current.xml index f8cf61fdf160..ee82e008a091 100644 --- a/api/current.xml +++ b/api/current.xml @@ -24714,6 +24714,17 @@ visibility="public" > </method> +<method name="getFastDrawable" + return="android.graphics.drawable.Drawable" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getInstance" return="android.app.WallpaperManager" abstract="false" @@ -24738,6 +24749,17 @@ visibility="public" > </method> +<method name="peekFastDrawable" + return="android.graphics.drawable.Drawable" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="setBitmap" return="void" abstract="false" @@ -63330,9 +63352,21 @@ type="android.graphics.drawable.BitmapDrawable" static="false" final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="filepath" type="java.lang.String"> +</parameter> +</constructor> +<constructor name="BitmapDrawable" + type="android.graphics.drawable.BitmapDrawable" + static="false" + final="false" deprecated="not deprecated" visibility="public" > +<parameter name="res" type="android.content.res.Resources"> +</parameter> <parameter name="filepath" type="java.lang.String"> </parameter> </constructor> @@ -63340,9 +63374,21 @@ type="android.graphics.drawable.BitmapDrawable" static="false" final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="is" type="java.io.InputStream"> +</parameter> +</constructor> +<constructor name="BitmapDrawable" + type="android.graphics.drawable.BitmapDrawable" + static="false" + final="false" deprecated="not deprecated" visibility="public" > +<parameter name="res" type="android.content.res.Resources"> +</parameter> <parameter name="is" type="java.io.InputStream"> </parameter> </constructor> @@ -64521,6 +64567,19 @@ visibility="public" > </method> +<method name="newDrawable" + return="android.graphics.drawable.Drawable" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="res" type="android.content.res.Resources"> +</parameter> +</method> </class> <class name="DrawableContainer" extends="android.graphics.drawable.Drawable" @@ -101558,6 +101617,17 @@ visibility="protected" > </method> +<method name="quit" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> </class> <interface name="IBinder" abstract="true" diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index 8730288b97a4..8f7e8ca55c11 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -395,7 +395,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { Drawable.ConstantState cachedBg = mBackgroundsCache.get(backgroundColor); if (cachedBg != null) { if (DBG) Log.d(LOG_TAG, "Background cache hit for color " + backgroundColor); - return cachedBg.newDrawable(); + return cachedBg.newDrawable(mProviderContext.getResources()); } if (DBG) Log.d(LOG_TAG, "Creating new background for color " + backgroundColor); ColorDrawable transparent = new ColorDrawable(0); @@ -572,7 +572,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { Drawable.ConstantState cached = mOutsideDrawablesCache.get(drawableId); if (cached != null) { if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + drawableId); - return cached.newDrawable(); + return cached.newDrawable(mProviderContext.getResources()); } Drawable drawable = null; @@ -663,7 +663,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { // Using containsKey() since we also store null values. if (mOutsideDrawablesCache.containsKey(componentIconKey)) { Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey); - return cached == null ? null : cached.newDrawable(); + return cached == null ? null : cached.newDrawable(mProviderContext.getResources()); } // Then try the activity or application icon Drawable drawable = getActivityIcon(component); diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index da40c8a2fa5a..38cac87bcb53 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -22,7 +22,9 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; +import android.graphics.ColorFilter; import android.graphics.Paint; +import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -56,9 +58,96 @@ public class WallpaperManager { private final Context mContext; + /** + * Special drawable that draws a wallpaper as fast as possible. Assumes + * no scaling or placement off (0,0) of the wallpaper (this should be done + * at the time the bitmap is loaded). + */ + static class FastBitmapDrawable extends Drawable { + private final Bitmap mBitmap; + private final int mWidth; + private final int mHeight; + private int mDrawLeft; + private int mDrawTop; + + private FastBitmapDrawable(Bitmap bitmap) { + mBitmap = bitmap; + mWidth = bitmap.getWidth(); + mHeight = bitmap.getHeight(); + setBounds(0, 0, mWidth, mHeight); + } + + @Override + public void draw(Canvas canvas) { + canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, null); + } + + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + @Override + public void setBounds(int left, int top, int right, int bottom) { + mDrawLeft = left + (right-left - mWidth) / 2; + mDrawTop = top + (bottom-top - mHeight) / 2; + } + + @Override + public void setBounds(Rect bounds) { + // TODO Auto-generated method stub + super.setBounds(bounds); + } + + @Override + public void setAlpha(int alpha) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setColorFilter(ColorFilter cf) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setDither(boolean dither) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setFilterBitmap(boolean filter) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public int getIntrinsicWidth() { + return mWidth; + } + + @Override + public int getIntrinsicHeight() { + return mHeight; + } + + @Override + public int getMinimumWidth() { + return mWidth; + } + + @Override + public int getMinimumHeight() { + return mHeight; + } + } + static class Globals extends IWallpaperManagerCallback.Stub { private IWallpaperManager mService; private Bitmap mWallpaper; + private Bitmap mDefaultWallpaper; private static final int MSG_CLEAR_WALLPAPER = 1; @@ -74,6 +163,7 @@ public class WallpaperManager { case MSG_CLEAR_WALLPAPER: synchronized (this) { mWallpaper = null; + mDefaultWallpaper = null; } break; } @@ -90,12 +180,19 @@ public class WallpaperManager { mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER); } - public Bitmap peekWallpaperBitmap(Context context) { + public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) { synchronized (this) { if (mWallpaper != null) { return mWallpaper; } + if (mDefaultWallpaper != null) { + return mDefaultWallpaper; + } mWallpaper = getCurrentWallpaperLocked(context); + if (mWallpaper == null && returnDefault) { + mDefaultWallpaper = getDefaultWallpaperLocked(context); + return mDefaultWallpaper; + } return mWallpaper; } } @@ -134,48 +231,48 @@ public class WallpaperManager { 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; + return generateBitmap(context, bm, width, height); + } + } catch (RemoteException e) { + } + return null; + } + + private Bitmap getDefaultWallpaperLocked(Context context) { + try { + InputStream is = context.getResources().openRawResource( + com.android.internal.R.drawable.default_wallpaper); + if (is != null) { + int width = mService.getWidthHint(); + int height = mService.getHeightHint(); - 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; + if (width <= 0 || height <= 0) { + // Degenerate case: no size requested, just load + // bitmap as-is. + Bitmap bm = BitmapFactory.decodeStream(is, null, null); + try { + is.close(); + } catch (IOException e) { } - targetRect.right = (int)(targetRect.right*scale); - targetRect.bottom = (int)(targetRect.bottom*scale); - deltaw = width - targetRect.right; - deltah = height - targetRect.bottom; + if (bm != null) { + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + } + return bm; } - targetRect.offset(deltaw/2, deltah/2); - Paint paint = new Paint(); - paint.setFilterBitmap(true); - paint.setDither(true); - c.drawBitmap(bm, null, targetRect, paint); + // 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.decodeStream(is, null, options); + try { + is.close(); + } catch (IOException e) { + } - bm.recycle(); - return newbm; + return generateBitmap(context, bm, width, height); } } catch (RemoteException e) { } @@ -219,9 +316,13 @@ public class WallpaperManager { * @return Returns a Drawable object that will draw the wallpaper. */ public Drawable getDrawable() { - Drawable dr = peekDrawable(); - return dr != null ? dr : Resources.getSystem().getDrawable( - com.android.internal.R.drawable.default_wallpaper); + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true); + if (bm != null) { + Drawable dr = new BitmapDrawable(mContext.getResources(), bm); + dr.setDither(false); + return dr; + } + return null; } /** @@ -234,8 +335,51 @@ public class WallpaperManager { * null pointer if these is none. */ public Drawable peekDrawable() { - Bitmap bm = sGlobals.peekWallpaperBitmap(mContext); - return bm != null ? new BitmapDrawable(mContext.getResources(), bm) : null; + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false); + if (bm != null) { + Drawable dr = new BitmapDrawable(mContext.getResources(), bm); + dr.setDither(false); + return dr; + } + return null; + } + + /** + * Like {@link #peekFastDrawable}, but always returns a valid Drawable. If + * no wallpaper is set, the system default wallpaper is returned. + * + * @return Returns a Drawable object that will draw the wallpaper. + */ + public Drawable getFastDrawable() { + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true); + if (bm != null) { + Drawable dr = new FastBitmapDrawable(bm); + return dr; + } + return null; + } + + /** + * Like {@link #peekDrawable()}, but the returned Drawable has a number + * of limitations to reduce its overhead as much as possible: it will + * never scale the wallpaper (only centering it if the requested bounds + * do match the bitmap bounds, which should not be typical), doesn't + * allow setting an alpha, color filter, or other attributes, etc. The + * bounds of the returned drawable will be initialized to the same bounds + * as the wallpaper, so normally you will not need to touch it. The + * drawable also assumes that it will be used in a context running in + * the same density as the screen (not in density compatibility mode). + * + * @return Returns an optimized Drawable object that will draw the + * wallpaper or a null pointer if these is none. + */ + public Drawable peekFastDrawable() { + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false); + if (bm != null) { + Drawable dr = new FastBitmapDrawable(bm); + return dr; + } + return null; } /** @@ -429,8 +573,10 @@ public class WallpaperManager { */ public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) { try { + //Log.v(TAG, "Sending new wallpaper offsets from app..."); ViewRoot.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, xOffset, yOffset); + //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { // Ignore. } @@ -466,4 +612,51 @@ public class WallpaperManager { public void clear() throws IOException { setResource(com.android.internal.R.drawable.default_wallpaper); } + + static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) { + if (bm == null) { + return bm; + } + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + + // This is the final bitmap we want to return. + // XXX We should get the pixel depth from the system (to match the + // physical display depth), when there is a way. + Bitmap newbm = Bitmap.createBitmap(width, height, + Bitmap.Config.RGB_565); + 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; + } } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 6d27bc78bbd2..1e590f0f9e8b 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -87,13 +87,37 @@ class SyncManager implements OnAccountsUpdatedListener { private static final long MILLIS_IN_4WEEKS = MILLIS_IN_WEEK * 4; /** Delay a sync due to local changes this long. In milliseconds */ - private static final long LOCAL_SYNC_DELAY = 30 * 1000; // 30 seconds + private static final long LOCAL_SYNC_DELAY; /** * If a sync takes longer than this and the sync queue is not empty then we will * cancel it and add it back to the end of the sync queue. In milliseconds. */ - private static final long MAX_TIME_PER_SYNC = 5 * 60 * 1000; // 5 minutes + private static final long MAX_TIME_PER_SYNC; + + static { + String localSyncDelayString = SystemProperties.get("sync.local_sync_delay"); + long localSyncDelay = 30 * 1000; // 30 seconds + if (localSyncDelayString != null) { + try { + localSyncDelay = Long.parseLong(localSyncDelayString); + } catch (NumberFormatException nfe) { + // ignore, use default + } + } + LOCAL_SYNC_DELAY = localSyncDelay; + + String maxTimePerSyncString = SystemProperties.get("sync.max_time_per_sync"); + long maxTimePerSync = 5 * 60 * 1000; // 5 minutes + if (maxTimePerSyncString != null) { + try { + maxTimePerSync = Long.parseLong(maxTimePerSyncString); + } catch (NumberFormatException nfe) { + // ignore, use default + } + } + MAX_TIME_PER_SYNC = maxTimePerSync; + } private static final long SYNC_NOTIFICATION_DELAY = 30 * 1000; // 30 seconds diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index ba5c9ed18a43..379620111179 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -22,8 +22,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import android.content.pm.ApplicationInfo; -import android.graphics.BitmapFactory; import android.graphics.Movie; import android.graphics.drawable.Drawable; import android.graphics.drawable.ColorDrawable; @@ -1664,7 +1662,7 @@ public class Resources { Drawable.ConstantState cs = sPreloadedDrawables.get(key); if (cs != null) { - dr = cs.newDrawable(); + dr = cs.newDrawable(this); } else { if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) { @@ -1699,7 +1697,7 @@ public class Resources { } else { try { InputStream is = mAssets.openNonAsset( - value.assetCookie, file, AssetManager.ACCESS_BUFFER); + value.assetCookie, file, AssetManager.ACCESS_STREAMING); // System.out.println("Opened file " + file + ": " + is); dr = Drawable.createFromResourceStream(this, value, is, file, null); @@ -1745,7 +1743,7 @@ public class Resources { //Log.i(TAG, "Returning cached drawable @ #" + // Integer.toHexString(((Integer)key).intValue()) // + " in " + this + ": " + entry); - return entry.newDrawable(); + return entry.newDrawable(this); } else { // our entry has been purged mDrawableCache.delete(key); diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java index 0ce86db972c3..65301e41bb7f 100644 --- a/core/java/android/os/HandlerThread.java +++ b/core/java/android/os/HandlerThread.java @@ -64,7 +64,7 @@ public class HandlerThread extends Thread { /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread - * has been started, this method will blocked until the looper has been initialized. + * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { @@ -85,6 +85,21 @@ public class HandlerThread extends Thread { } /** + * Ask the currently running looper to quit. If the thread has not + * been started or has finished (that is if {@link #getLooper} returns + * null), then false is returned. Otherwise the looper is asked to + * quit and true is returned. + */ + public boolean quit() { + Looper looper = getLooper(); + if (looper != null) { + looper.quit(); + return true; + } + return false; + } + + /** * Returns the identifier of this thread. See Process.myTid(). */ public int getThreadId() { diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index e5659d57a0cb..cd5cf1027af4 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -28,9 +28,11 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.Rect; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; +import android.util.LogPrinter; import android.view.Gravity; import android.view.IWindowSession; import android.view.MotionEvent; @@ -74,6 +76,8 @@ public abstract class WallpaperService extends Service { private static final int MSG_WINDOW_RESIZED = 10030; private static final int MSG_TOUCH_EVENT = 10040; + private Looper mCallbackLooper; + /** * The actual implementation of a wallpaper. A wallpaper service may * have multiple instances running (for example as a real wallpaper @@ -120,6 +124,7 @@ public abstract class WallpaperService extends Service { boolean mOffsetMessageEnqueued; float mPendingXOffset; float mPendingYOffset; + boolean mPendingSync; MotionEvent mPendingMove; final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -212,10 +217,14 @@ public abstract class WallpaperService extends Service { } @Override - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { synchronized (mLock) { + if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y); mPendingXOffset = x; mPendingYOffset = y; + if (sync) { + mPendingSync = true; + } if (!mOffsetMessageEnqueued) { mOffsetMessageEnqueued = true; Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS); @@ -551,9 +560,12 @@ public abstract class WallpaperService extends Service { float xOffset; float yOffset; + boolean sync; synchronized (mLock) { xOffset = mPendingXOffset; yOffset = mPendingYOffset; + sync = mPendingSync; + mPendingSync = false; mOffsetMessageEnqueued = false; } if (DEBUG) Log.v(TAG, "Offsets change in " + this @@ -563,6 +575,14 @@ public abstract class WallpaperService extends Service { final int availh = mIWallpaperEngine.mReqHeight-mCurHeight; final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0; onOffsetsChanged(xOffset, yOffset, xPixels, yPixels); + + if (sync) { + try { + if (DEBUG) Log.v(TAG, "Reporting offsets change complete"); + mSession.wallpaperOffsetsComplete(mWindow.asBinder()); + } catch (RemoteException e) { + } + } } void detach() { @@ -622,7 +642,13 @@ public abstract class WallpaperService extends Service { IWallpaperEngineWrapper(WallpaperService context, IWallpaperConnection conn, IBinder windowToken, int windowType, boolean isPreview, int reqWidth, int reqHeight) { - mCaller = new HandlerCaller(context, this); + if (DEBUG && mCallbackLooper != null) { + mCallbackLooper.setMessageLogging(new LogPrinter(Log.VERBOSE, TAG)); + } + mCaller = new HandlerCaller(context, + mCallbackLooper != null + ? mCallbackLooper : context.getMainLooper(), + this); mConnection = conn; mWindowToken = windowToken; mWindowType = windowType; @@ -736,5 +762,18 @@ public abstract class WallpaperService extends Service { return new IWallpaperServiceWrapper(this); } + /** + * This allows subclasses to change the thread that most callbacks + * occur on. Currently hidden because it is mostly needed for the + * image wallpaper (which runs in the system process and doesn't want + * to get stuck running on that seriously in use main thread). Not + * exposed right now because the semantics of this are not totally + * well defined and some callbacks can still happen on the main thread). + * @hide + */ + public void setCallbackLooper(Looper looper) { + mCallbackLooper = looper; + } + public abstract Engine onCreateEngine(); } diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index ebc5f7b383d1..b7953af28818 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -60,5 +60,5 @@ oneway interface IWindow { /** * Called for wallpaper windows when their offsets change. */ - void dispatchWallpaperOffsets(float x, float y); + void dispatchWallpaperOffsets(float x, float y, boolean sync); } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 4d662d252a7f..9b8b6d474af7 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -114,4 +114,6 @@ interface IWindowSession { * larger than the screen, set the offset within the screen. */ void setWallpaperPosition(IBinder windowToken, float x, float y); + + void wallpaperOffsetsComplete(IBinder window); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f63c2f1162e1..2cc243e84342 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6042,12 +6042,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility int height = mBottom - mTop; final AttachInfo attachInfo = mAttachInfo; - final float scale = attachInfo.mApplicationScale; + final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f; width = (int) ((width * scale) + 0.5f); height = (int) ((height * scale) + 0.5f); - Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, - height > 0 ? height : 1, quality); + Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, height > 0 ? height : 1, quality); if (bitmap == null) { throw new OutOfMemoryError(); } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index b61465a74bf3..6748ade40ce6 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -2868,7 +2868,13 @@ public final class ViewRoot extends Handler implements ViewParent, } } - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { + if (sync) { + try { + sWindowSession.wallpaperOffsetsComplete(asBinder()); + } catch (RemoteException e) { + } + } } } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 0f178e97a683..2329e2194fe6 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1394,6 +1394,7 @@ public class WebView extends AbsoluteLayout * Reload the current url. */ public void reload() { + clearTextEntry(); switchOutDrawHistory(); mWebViewCore.sendMessage(EventHub.RELOAD); } diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index e7b303ada4d0..f34823cb484a 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Config; import android.util.Log; import android.view.GestureDetector; import android.view.Gravity; @@ -36,8 +35,6 @@ import android.view.ViewGroup; import android.view.SoundEffectConstants; import android.view.ContextMenu.ContextMenuInfo; import android.view.animation.Transformation; -import android.widget.AbsSpinner; -import android.widget.Scroller; /** * A view that shows items in a center-locked, horizontally scrolling list. @@ -59,7 +56,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList private static final String TAG = "Gallery"; - private static final boolean localLOGV = Config.LOGV; + private static final boolean localLOGV = false; /** * Duration in milliseconds from the start of a scroll during which we're @@ -514,6 +511,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList // We haven't been callbacking during the fling, so do it now super.selectionChanged(); } + invalidate(); } @Override @@ -534,12 +532,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList int galleryCenter = getCenterOfGallery(); - if (selView != null) { - - // Common case where the current selected position is correct - if (selView.getLeft() <= galleryCenter && selView.getRight() >= galleryCenter) { - return; - } + // Common case where the current selected position is correct + if (selView.getLeft() <= galleryCenter && selView.getRight() >= galleryCenter) { + return; } // TODO better search @@ -627,7 +622,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList View sel = makeAndAddView(mSelectedPosition, 0, 0, true); // Put the selected child in the center - Gallery.LayoutParams lp = (Gallery.LayoutParams) sel.getLayoutParams(); int selectedOffset = childrenLeft + (childrenWidth / 2) - (sel.getWidth() / 2); sel.offsetLeftAndRight(selectedOffset); @@ -733,9 +727,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList child = mRecycler.get(position); if (child != null) { // Can reuse an existing view - Gallery.LayoutParams lp = (Gallery.LayoutParams) - child.getLayoutParams(); - int childLeft = child.getLeft(); // Remember left and right edges of where views have been placed @@ -798,7 +789,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList int childRight; // Position vertically based on gravity setting - int childTop = calculateTop(child, lp, true); + int childTop = calculateTop(child, true); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); @@ -817,11 +808,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * Figure out vertical placement based on mGravity * * @param child Child to place - * @param lp LayoutParams for this view (just so we don't keep looking them - * up) * @return Where the top of the child should be */ - private int calculateTop(View child, Gallery.LayoutParams lp, boolean duringLayout) { + private int calculateTop(View child, boolean duringLayout) { int myHeight = duringLayout ? mMeasuredHeight : getHeight(); int childHeight = duringLayout ? child.getMeasuredHeight() : child.getHeight(); diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index 582502488bb4..35b9251338e6 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -57,6 +57,13 @@ public class HandlerCaller { mCallback = callback; } + public HandlerCaller(Context context, Looper looper, Callback callback) { + mContext = context; + mMainLooper = looper; + mH = new MyHandler(mMainLooper); + mCallback = callback; + } + public SomeArgs obtainArgs() { synchronized (mH) { SomeArgs args = mArgsPool; diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 5357469a2f36..0bc70def2aec 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -20,6 +20,8 @@ import android.app.WallpaperManager; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.HandlerThread; +import android.os.Process; import android.service.wallpaper.WallpaperService; import android.view.MotionEvent; import android.view.SurfaceHolder; @@ -33,20 +35,29 @@ import android.content.BroadcastReceiver; */ public class ImageWallpaper extends WallpaperService { WallpaperManager mWallpaperManager; + private HandlerThread mThread; @Override public void onCreate() { super.onCreate(); mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); + mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND); + mThread.start(); + setCallbackLooper(mThread.getLooper()); } public Engine onCreateEngine() { return new DrawableEngine(); } + @Override + public void onDestroy() { + super.onDestroy(); + mThread.quit(); + } + class DrawableEngine extends Engine { private final Object mLock = new Object(); - private final Rect mBounds = new Rect(); private WallpaperObserver mReceiver; Drawable mBackground; float mXOffset; @@ -56,6 +67,9 @@ public class ImageWallpaper extends WallpaperService { public void onReceive(Context context, Intent intent) { updateWallpaper(); drawFrame(); + // Assume we are the only one using the wallpaper in this + // process, and force a GC now to release the old wallpaper. + System.gc(); } } @@ -67,7 +81,6 @@ public class ImageWallpaper extends WallpaperService { registerReceiver(mReceiver, filter); updateWallpaper(); surfaceHolder.setSizeFromLayout(); - //setTouchEventsEnabled(true); } @Override @@ -137,11 +150,7 @@ public class ImageWallpaper extends WallpaperService { void updateWallpaper() { synchronized (mLock) { - mBackground = mWallpaperManager.getDrawable(); - mBounds.left = mBounds.top = 0; - mBounds.right = mBackground.getIntrinsicWidth(); - mBounds.bottom = mBackground.getIntrinsicHeight(); - mBackground.setBounds(mBounds); + mBackground = mWallpaperManager.getFastDrawable(); } } } diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index f4f629785386..b8d19aca64a7 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -90,6 +90,12 @@ public class BaseIWindow extends IWindow.Stub { public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { } - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { + if (sync) { + try { + mSession.wallpaperOffsetsComplete(asBinder()); + } catch (RemoteException e) { + } + } } } diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java index b81c2b3527d6..bba2ee275562 100644 --- a/core/java/com/android/internal/view/menu/IconMenuView.java +++ b/core/java/com/android/internal/view/menu/IconMenuView.java @@ -282,7 +282,9 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi itemView.setIconMenuView(this); // Apply the background to the item view - itemView.setBackgroundDrawable(mItemBackground.getConstantState().newDrawable()); + itemView.setBackgroundDrawable( + mItemBackground.getConstantState().newDrawable( + getContext().getResources())); // This class is the invoker for all its item views itemView.setItemInvoker(this); diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 7748aba25a52..5b6c7ea13e8a 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -32,6 +32,7 @@ #include <sys/errno.h> #include <sys/resource.h> #include <sys/types.h> +#include <cutils/sched_policy.h> #include <dirent.h> #include <fcntl.h> #include <grp.h> @@ -186,58 +187,6 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name) return -1; } -static int add_pid_to_cgroup(int pid, const char *grp_name) -{ - int fd; - char path[255]; - char text[64]; - - sprintf(path, "/dev/cpuctl/%s/tasks", grp_name); - - if ((fd = open(path, O_WRONLY)) < 0) - return -1; - - sprintf(text, "%d", pid); - if (write(fd, text, strlen(text)) < 0) { - close(fd); - return -1; - } - - close(fd); - return 0; -} - -void setSchedPolicy(JNIEnv* env, jobject clazz, int pid, SchedPolicy policy) -{ - static int __sys_supports_schedgroups = -1; - - if (__sys_supports_schedgroups < 0) { - if (!access("/dev/cpuctl/tasks", F_OK)) { - __sys_supports_schedgroups = 1; - } else { - __sys_supports_schedgroups = 0; - } - } - - if (__sys_supports_schedgroups) { - const char *grp = NULL; - - if (policy == SP_BACKGROUND) { - grp = "bg_non_interactive"; - } - - if (add_pid_to_cgroup(pid, grp)) { - if (errno != ESRCH && errno != ENOENT) - signalExceptionForGroupError(env, clazz, errno); - } - } else { - struct sched_param param; - - param.sched_priority = 0; - sched_setscheduler(pid, (policy == SP_BACKGROUND) ? 5 : 0, ¶m); - } -} - void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp) { if (grp > ANDROID_TGROUP_MAX || grp < 0) { @@ -245,9 +194,10 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint return; } - setSchedPolicy(env, clazz, pid, - (grp == ANDROID_TGROUP_BG_NONINTERACT) ? - SP_BACKGROUND : SP_FOREGROUND); + if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ? + SP_BACKGROUND : SP_FOREGROUND)) { + signalExceptionForGroupError(env, clazz, errno); + } } void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) @@ -291,9 +241,10 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin continue; } - setSchedPolicy(env, clazz, t_pid, - (grp == ANDROID_TGROUP_BG_NONINTERACT) ? - SP_BACKGROUND : SP_FOREGROUND); + if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ? + SP_BACKGROUND : SP_FOREGROUND)) { + signalExceptionForGroupError(env, clazz, errno); + } } closedir(d); } @@ -301,10 +252,16 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz, jint pid, jint pri) { + int rc = 0; + if (pri >= ANDROID_PRIORITY_BACKGROUND) { - setSchedPolicy(env, clazz, pid, SP_BACKGROUND); + rc = set_sched_policy(pid, SP_BACKGROUND); } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) { - setSchedPolicy(env, clazz, pid, SP_FOREGROUND); + rc = set_sched_policy(pid, SP_FOREGROUND); + } + + if (rc) { + signalExceptionForGroupError(env, clazz, errno); } if (setpriority(PRIO_PROCESS, pid, pri) < 0) { diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index ac96f20bc527..58206d484fb6 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -45,11 +45,11 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac private boolean mRunning; public AnimatedRotateDrawable() { - this(null); + this(null, null); } - private AnimatedRotateDrawable(AnimatedRotateState rotateState) { - mState = new AnimatedRotateState(rotateState, this); + private AnimatedRotateDrawable(AnimatedRotateState rotateState, Resources res) { + mState = new AnimatedRotateState(rotateState, this, res); init(); } @@ -296,9 +296,14 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac private boolean mCanConstantState; private boolean mCheckedConstantState; - public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner) { + public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner, + Resources res) { if (source != null) { - mDrawable = source.mDrawable.getConstantState().newDrawable(); + if (res != null) { + mDrawable = source.mDrawable.getConstantState().newDrawable(res); + } else { + mDrawable = source.mDrawable.getConstantState().newDrawable(); + } mDrawable.setCallback(owner); mPivotXRel = source.mPivotXRel; mPivotX = source.mPivotX; @@ -312,7 +317,12 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac @Override public Drawable newDrawable() { - return new AnimatedRotateDrawable(this); + return new AnimatedRotateDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new AnimatedRotateDrawable(this, res); } @Override diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 68718c9763eb..fdc4c92e178d 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -77,7 +77,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An private boolean mMutated; public AnimationDrawable() { - this(null); + this(null, null); } @Override @@ -297,8 +297,9 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An private int[] mDurations; private boolean mOneShot; - AnimationState(AnimationState orig, AnimationDrawable owner) { - super(orig, owner); + AnimationState(AnimationState orig, AnimationDrawable owner, + Resources res) { + super(orig, owner, res); if (orig != null) { mDurations = orig.mDurations; @@ -311,7 +312,12 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An @Override public Drawable newDrawable() { - return new AnimationDrawable(this); + return new AnimationDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new AnimationDrawable(this, res); } public void addFrame(Drawable dr, int dur) { @@ -330,8 +336,8 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } } - private AnimationDrawable(AnimationState state) { - AnimationState as = new AnimationState(state, this); + private AnimationDrawable(AnimationState state, Resources res) { + AnimationState as = new AnimationState(state, this, res); mAnimationState = as; setConstantState(as); if (state != null) { diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 30cef670d90a..e82f297dfff2 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -60,15 +60,15 @@ public class BitmapDrawable extends Drawable { Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG; private BitmapState mBitmapState; private Bitmap mBitmap; + private int mTargetDensity; + private final Rect mDstRect = new Rect(); // Gravity.apply() sets this private boolean mApplyGravity; private boolean mRebuildShader; private boolean mMutated; - private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; - - // These are scaled to match the target density. + // These are scaled to match the target density. private int mBitmapWidth; private int mBitmapHeight; @@ -88,10 +88,7 @@ public class BitmapDrawable extends Drawable { */ public BitmapDrawable(Resources res) { mBitmapState = new BitmapState((Bitmap) null); - if (res != null) { - setTargetDensity(res.getDisplayMetrics()); - mBitmapState.mTargetDensity = mTargetDensity; - } + mBitmapState.mTargetDensity = mTargetDensity; } /** @@ -101,7 +98,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(Bitmap bitmap) { - this(new BitmapState(bitmap)); + this(new BitmapState(bitmap), null); } /** @@ -109,22 +106,51 @@ public class BitmapDrawable extends Drawable { * the display metrics of the resources. */ public BitmapDrawable(Resources res, Bitmap bitmap) { - this(new BitmapState(bitmap)); - if (res != null) { - setTargetDensity(res.getDisplayMetrics()); - mBitmapState.mTargetDensity = mTargetDensity; - } + this(new BitmapState(bitmap), res); + mBitmapState.mTargetDensity = mTargetDensity; } + /** + * Create a drawable by opening a given file path and decoding the bitmap. + * @deprecated Use {@link #BitmapDrawable(Resources, String)} to ensure + * that the drawable has correctly set its target density. + */ public BitmapDrawable(String filepath) { - this(new BitmapState(BitmapFactory.decodeFile(filepath))); + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); + if (mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); + } + } + + /** + * Create a drawable by opening a given file path and decoding the bitmap. + */ + public BitmapDrawable(Resources res, String filepath) { + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); + mBitmapState.mTargetDensity = mTargetDensity; if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); } } + /** + * Create a drawable by decoding a bitmap from the given input stream. + * @deprecated Use {@link #BitmapDrawable(Resources, java.io.InputStream)} to ensure + * that the drawable has correctly set its target density. + */ public BitmapDrawable(java.io.InputStream is) { - this(new BitmapState(BitmapFactory.decodeStream(is))); + this(new BitmapState(BitmapFactory.decodeStream(is)), null); + if (mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); + } + } + + /** + * Create a drawable by decoding a bitmap from the given input stream. + */ + public BitmapDrawable(Resources res, java.io.InputStream is) { + this(new BitmapState(BitmapFactory.decodeStream(is)), null); + mBitmapState.mTargetDensity = mTargetDensity; if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); } @@ -425,7 +451,12 @@ public class BitmapDrawable extends Drawable { @Override public Drawable newDrawable() { - return new BitmapDrawable(this); + return new BitmapDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new BitmapDrawable(this, res); } @Override @@ -434,9 +465,15 @@ public class BitmapDrawable extends Drawable { } } - private BitmapDrawable(BitmapState state) { + private BitmapDrawable(BitmapState state, Resources res) { mBitmapState = state; - mTargetDensity = state.mTargetDensity; + if (res != null) { + mTargetDensity = res.getDisplayMetrics().densityDpi; + } else if (state != null) { + mTargetDensity = state.mTargetDensity; + } else { + mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; + } setBitmap(state.mBitmap); } } diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java index 95d4dd096b9c..c387a9ba7d5f 100644 --- a/graphics/java/android/graphics/drawable/ClipDrawable.java +++ b/graphics/java/android/graphics/drawable/ClipDrawable.java @@ -48,14 +48,14 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { public static final int VERTICAL = 2; ClipDrawable() { - this(null); + this(null, null); } /** * @param orientation Bitwise-or of {@link #HORIZONTAL} and/or {@link #VERTICAL} */ public ClipDrawable(Drawable drawable, int gravity, int orientation) { - this(null); + this(null, null); mClipState.mDrawable = drawable; mClipState.mGravity = gravity; @@ -241,9 +241,13 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { private boolean mCheckedConstantState; private boolean mCanConstantState; - ClipState(ClipState orig, ClipDrawable owner) { + ClipState(ClipState orig, ClipDrawable owner, Resources res) { if (orig != null) { - mDrawable = orig.mDrawable.getConstantState().newDrawable(); + if (res != null) { + mDrawable = orig.mDrawable.getConstantState().newDrawable(res); + } else { + mDrawable = orig.mDrawable.getConstantState().newDrawable(); + } mDrawable.setCallback(owner); mOrientation = orig.mOrientation; mGravity = orig.mGravity; @@ -253,7 +257,12 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { @Override public Drawable newDrawable() { - return new ClipDrawable(this); + return new ClipDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new ClipDrawable(this, res); } @Override @@ -271,8 +280,8 @@ public class ClipDrawable extends Drawable implements Drawable.Callback { } } - private ClipDrawable(ClipState state) { - mClipState = new ClipState(state, this); + private ClipDrawable(ClipState state, Resources res) { + mClipState = new ClipState(state, this, res); } } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 226cc04129fb..604c602207bf 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -146,6 +146,11 @@ public class ColorDrawable extends Drawable { } @Override + public Drawable newDrawable(Resources res) { + return new ColorDrawable(this); + } + + @Override public int getChangingConfigurations() { return mChangingConfigurations; } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 21b5e3955209..6a7b2d1ae922 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -822,7 +822,26 @@ public abstract class Drawable { } public static abstract class ConstantState { + /** + * Create a new drawable without supplying resources the caller + * is running in. Note that using this means the density-dependent + * drawables (like bitmaps) will not be able to update their target + * density correctly. + */ public abstract Drawable newDrawable(); + /** + * Create a new Drawable instance from its constant state. This + * must be implemented for drawables that change based on the target + * density of their caller (that is depending on whether it is + * in compatibility mode). + */ + public Drawable newDrawable(Resources res) { + return newDrawable(); + } + /** + * Return a bit mask of configuration changes that will impact + * this drawable (and thus require completely reloading it). + */ public abstract int getChangingConfigurations(); } diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index af1a2892a8a5..3266f1e21102 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -16,6 +16,7 @@ package android.graphics.drawable; +import android.content.res.Resources; import android.graphics.*; public class DrawableContainer extends Drawable implements Drawable.Callback { @@ -285,7 +286,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { boolean mPaddingChecked = false; - DrawableContainerState(DrawableContainerState orig, DrawableContainer owner) { + DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, + Resources res) { mOwner = owner; if (orig != null) { @@ -299,7 +301,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { final int N = mNumChildren; for (int i=0; i<N; i++) { - mDrawables[i] = origDr[i].getConstantState().newDrawable(); + if (res != null) { + mDrawables[i] = origDr[i].getConstantState().newDrawable(res); + } else { + mDrawables[i] = origDr[i].getConstantState().newDrawable(); + } mDrawables[i].setCallback(owner); } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index a7a870881ea5..ddbbaf17f2a5 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -917,6 +917,11 @@ public class GradientDrawable extends Drawable { } @Override + public Drawable newDrawable(Resources res) { + return new GradientDrawable(this); + } + + @Override public int getChangingConfigurations() { return mChangingConfigurations; } diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index 604772602ae1..4fa9d44f1332 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -49,7 +49,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback private boolean mMutated; /*package*/ InsetDrawable() { - this(null); + this(null, null); } public InsetDrawable(Drawable drawable, int inset) { @@ -58,7 +58,7 @@ public class InsetDrawable extends Drawable implements Drawable.Callback public InsetDrawable(Drawable drawable, int insetLeft, int insetTop, int insetRight, int insetBottom) { - this(null); + this(null, null); mInsetState.mDrawable = drawable; mInsetState.mInsetLeft = insetLeft; @@ -263,9 +263,13 @@ public class InsetDrawable extends Drawable implements Drawable.Callback boolean mCheckedConstantState; boolean mCanConstantState; - InsetState(InsetState orig, InsetDrawable owner) { + InsetState(InsetState orig, InsetDrawable owner, Resources res) { if (orig != null) { - mDrawable = orig.mDrawable.getConstantState().newDrawable(); + if (res != null) { + mDrawable = orig.mDrawable.getConstantState().newDrawable(res); + } else { + mDrawable = orig.mDrawable.getConstantState().newDrawable(); + } mDrawable.setCallback(owner); mInsetLeft = orig.mInsetLeft; mInsetTop = orig.mInsetTop; @@ -277,7 +281,12 @@ public class InsetDrawable extends Drawable implements Drawable.Callback @Override public Drawable newDrawable() { - return new InsetDrawable(this); + return new InsetDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new InsetDrawable(this, res); } @Override @@ -295,8 +304,8 @@ public class InsetDrawable extends Drawable implements Drawable.Callback } } - private InsetDrawable(InsetState state) { - mInsetState = new InsetState(state, this); + private InsetDrawable(InsetState state, Resources res) { + mInsetState = new InsetState(state, this, res); } } diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index c7772053f98c..389fd4075b22 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -70,7 +70,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { * @param state The constant drawable state. */ LayerDrawable(Drawable[] layers, LayerState state) { - this(state); + this(state, null); int length = layers.length; ChildDrawable[] r = new ChildDrawable[length]; @@ -87,19 +87,19 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } LayerDrawable() { - this((LayerState) null); + this((LayerState) null, null); } - LayerDrawable(LayerState state) { - LayerState as = createConstantState(state); + LayerDrawable(LayerState state, Resources res) { + LayerState as = createConstantState(state, res); mLayerState = as; if (as.mNum > 0) { ensurePadding(); } } - LayerState createConstantState(LayerState state) { - return new LayerState(state, this); + LayerState createConstantState(LayerState state, Resources res) { + return new LayerState(state, this, res); } @Override @@ -563,7 +563,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { private boolean mCheckedConstantState; private boolean mCanConstantState; - LayerState(LayerState orig, LayerDrawable owner) { + LayerState(LayerState orig, LayerDrawable owner, Resources res) { if (orig != null) { final ChildDrawable[] origChildDrawable = orig.mChildren; final int N = orig.mNum; @@ -577,7 +577,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { for (int i = 0; i < N; i++) { final ChildDrawable r = mChildren[i] = new ChildDrawable(); final ChildDrawable or = origChildDrawable[i]; - r.mDrawable = or.mDrawable.getConstantState().newDrawable(); + if (res != null) { + r.mDrawable = or.mDrawable.getConstantState().newDrawable(res); + } else { + r.mDrawable = or.mDrawable.getConstantState().newDrawable(); + } r.mDrawable.setCallback(owner); r.mInsetL = or.mInsetL; r.mInsetT = or.mInsetT; @@ -599,7 +603,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { @Override public Drawable newDrawable() { - return new LayerDrawable(this); + return new LayerDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new LayerDrawable(this, res); } @Override diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java index 7ae649f91cad..ae8f224c80df 100644 --- a/graphics/java/android/graphics/drawable/LevelListDrawable.java +++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java @@ -57,7 +57,7 @@ public class LevelListDrawable extends DrawableContainer { private boolean mMutated; public LevelListDrawable() { - this(null); + this(null, null); } public void addLevel(int low, int high, Drawable drawable) { @@ -154,8 +154,8 @@ public class LevelListDrawable extends DrawableContainer { private int[] mLows; private int[] mHighs; - LevelListState(LevelListState orig, LevelListDrawable owner) { - super(orig, owner); + LevelListState(LevelListState orig, LevelListDrawable owner, Resources res) { + super(orig, owner, res); if (orig != null) { mLows = orig.mLows; @@ -186,7 +186,12 @@ public class LevelListDrawable extends DrawableContainer { @Override public Drawable newDrawable() { - return new LevelListDrawable(this); + return new LevelListDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new LevelListDrawable(this, res); } @Override @@ -201,8 +206,8 @@ public class LevelListDrawable extends DrawableContainer { } } - private LevelListDrawable(LevelListState state) { - LevelListState as = new LevelListState(state, this); + private LevelListDrawable(LevelListState state, Resources res) { + LevelListState as = new LevelListState(state, this, res); mLevelListState = as; setConstantState(as); onLevelChange(getLevel()); diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 997efb813a6d..803e7b113ba4 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -61,7 +61,7 @@ public class NinePatchDrawable extends Drawable { */ @Deprecated public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { - this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding)); + this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null); } /** @@ -70,11 +70,8 @@ public class NinePatchDrawable extends Drawable { */ public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { - this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding)); - if (res != null) { - setTargetDensity(res.getDisplayMetrics()); - mNinePatchState.mTargetDensity = mTargetDensity; - } + this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res); + mNinePatchState.mTargetDensity = mTargetDensity; } /** @@ -84,7 +81,7 @@ public class NinePatchDrawable extends Drawable { */ @Deprecated public NinePatchDrawable(NinePatch patch) { - this(new NinePatchState(patch, null)); + this(new NinePatchState(patch, null), null); } /** @@ -92,18 +89,16 @@ public class NinePatchDrawable extends Drawable { * based on the display metrics of the resources. */ public NinePatchDrawable(Resources res, NinePatch patch) { - this(new NinePatchState(patch, null)); - if (res != null) { - setTargetDensity(res.getDisplayMetrics()); - mNinePatchState.mTargetDensity = mTargetDensity; - } + this(new NinePatchState(patch, null), res); + mNinePatchState.mTargetDensity = mTargetDensity; } - private void setNinePatchState(NinePatchState state) { + private void setNinePatchState(NinePatchState state, Resources res) { mNinePatchState = state; mNinePatch = state.mNinePatch; mPadding = state.mPadding; - mTargetDensity = state.mTargetDensity; + mTargetDensity = res != null ? res.getDisplayMetrics().densityDpi + : state.mTargetDensity; if (DEFAULT_DITHER != state.mDither) { // avoid calling the setter unless we need to, since it does a // lazy allocation of a paint @@ -258,7 +253,8 @@ public class NinePatchDrawable extends Drawable { } setNinePatchState(new NinePatchState( - new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"), padding, dither)); + new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"), + padding, dither), r); mNinePatchState.mTargetDensity = mTargetDensity; a.recycle(); @@ -357,7 +353,12 @@ public class NinePatchDrawable extends Drawable { @Override public Drawable newDrawable() { - return new NinePatchDrawable(this); + return new NinePatchDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new NinePatchDrawable(this, res); } @Override @@ -366,8 +367,7 @@ public class NinePatchDrawable extends Drawable { } } - private NinePatchDrawable(NinePatchState state) { - setNinePatchState(state); + private NinePatchDrawable(NinePatchState state, Resources res) { + setNinePatchState(state, res); } } - diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index cb16cb711b42..c4a78223c98c 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -54,7 +54,7 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { * <p>Create a new rotating drawable with an empty state.</p> */ public RotateDrawable() { - this(null); + this(null, null); } /** @@ -64,8 +64,8 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { * * @param rotateState the state for this drawable */ - private RotateDrawable(RotateState rotateState) { - mState = new RotateState(rotateState, this); + private RotateDrawable(RotateState rotateState, Resources res) { + mState = new RotateState(rotateState, this, res); } public void draw(Canvas canvas) { @@ -291,9 +291,13 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { private boolean mCanConstantState; private boolean mCheckedConstantState; - public RotateState(RotateState source, RotateDrawable owner) { + public RotateState(RotateState source, RotateDrawable owner, Resources res) { if (source != null) { - mDrawable = source.mDrawable.getConstantState().newDrawable(); + if (res != null) { + mDrawable = source.mDrawable.getConstantState().newDrawable(res); + } else { + mDrawable = source.mDrawable.getConstantState().newDrawable(); + } mDrawable.setCallback(owner); mPivotXRel = source.mPivotXRel; mPivotX = source.mPivotX; @@ -307,7 +311,12 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { @Override public Drawable newDrawable() { - return new RotateDrawable(this); + return new RotateDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new RotateDrawable(this, res); } @Override diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index 7125ab1e689e..275e36f4730f 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -47,11 +47,11 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { private final Rect mTmpRect = new Rect(); ScaleDrawable() { - this(null); + this(null, null); } public ScaleDrawable(Drawable drawable, int gravity, float scaleWidth, float scaleHeight) { - this(null); + this(null, null); mScaleState.mDrawable = drawable; mScaleState.mGravity = gravity; @@ -260,9 +260,13 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { private boolean mCheckedConstantState; private boolean mCanConstantState; - ScaleState(ScaleState orig, ScaleDrawable owner) { + ScaleState(ScaleState orig, ScaleDrawable owner, Resources res) { if (orig != null) { - mDrawable = orig.mDrawable.getConstantState().newDrawable(); + if (res != null) { + mDrawable = orig.mDrawable.getConstantState().newDrawable(res); + } else { + mDrawable = orig.mDrawable.getConstantState().newDrawable(); + } mDrawable.setCallback(owner); mScaleWidth = orig.mScaleWidth; mScaleHeight = orig.mScaleHeight; @@ -273,7 +277,12 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { @Override public Drawable newDrawable() { - return new ScaleDrawable(this); + return new ScaleDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new ScaleDrawable(this, res); } @Override @@ -291,8 +300,8 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback { } } - private ScaleDrawable(ScaleState state) { - mScaleState = new ScaleState(state, this); + private ScaleDrawable(ScaleState state, Resources res) { + mScaleState = new ScaleState(state, this, res); } } diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 6677a3560de3..c699a82f0ccd 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -396,6 +396,11 @@ public class ShapeDrawable extends Drawable { } @Override + public Drawable newDrawable(Resources res) { + return new ShapeDrawable(this); + } + + @Override public int getChangingConfigurations() { return mChangingConfigurations; } diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index 59cb2268431f..b1d588e8e606 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -65,7 +65,7 @@ public class StateListDrawable extends DrawableContainer { private boolean mMutated; public StateListDrawable() { - this(null); + this(null, null); } /** @@ -248,8 +248,8 @@ public class StateListDrawable extends DrawableContainer { static final class StateListState extends DrawableContainerState { private int[][] mStateSets; - StateListState(StateListState orig, StateListDrawable owner) { - super(orig, owner); + StateListState(StateListState orig, StateListDrawable owner, Resources res) { + super(orig, owner, res); if (orig != null) { mStateSets = orig.mStateSets; @@ -277,7 +277,12 @@ public class StateListDrawable extends DrawableContainer { @Override public Drawable newDrawable() { - return new StateListDrawable(this); + return new StateListDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new StateListDrawable(this, res); } @Override @@ -289,8 +294,8 @@ public class StateListDrawable extends DrawableContainer { } } - private StateListDrawable(StateListState state) { - StateListState as = new StateListState(state, this); + private StateListDrawable(StateListState state, Resources res) { + StateListState as = new StateListState(state, this, res); mStateListState = as; setConstantState(as); onStateChange(getState()); diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index 358f889bc08f..97b45d8edae9 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; +import android.content.res.Resources; import android.graphics.Canvas; import android.os.SystemClock; @@ -72,7 +73,7 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba * 2 layers are required for this drawable to work properly. */ public TransitionDrawable(Drawable[] layers) { - this(new TransitionState(null, null), layers); + this(new TransitionState(null, null, null), layers); } /** @@ -82,11 +83,11 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba * @see #TransitionDrawable(Drawable[]) */ TransitionDrawable() { - this(new TransitionState(null, null)); + this(new TransitionState(null, null, null), (Resources)null); } - private TransitionDrawable(TransitionState state) { - super(state); + private TransitionDrawable(TransitionState state, Resources res) { + super(state, res); } private TransitionDrawable(TransitionState state, Drawable[] layers) { @@ -94,8 +95,8 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba } @Override - LayerState createConstantState(LayerState state) { - return new TransitionState((TransitionState) state, this); + LayerState createConstantState(LayerState state, Resources res) { + return new TransitionState((TransitionState) state, this, res); } /** @@ -229,13 +230,19 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba } static class TransitionState extends LayerState { - TransitionState(TransitionState orig, TransitionDrawable owner) { - super(orig, owner); + TransitionState(TransitionState orig, TransitionDrawable owner, + Resources res) { + super(orig, owner, res); } @Override public Drawable newDrawable() { - return new TransitionDrawable(this); + return new TransitionDrawable(this, (Resources)null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new TransitionDrawable(this, res); } @Override diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h index 6181f5576097..8b0f154f5c99 100644 --- a/include/private/ui/SharedBufferStack.h +++ b/include/private/ui/SharedBufferStack.h @@ -228,6 +228,8 @@ private: friend struct Condition; friend struct DequeueCondition; friend struct LockCondition; + + int32_t computeTail() const; struct QueueUpdate : public UpdateBase { inline QueueUpdate(SharedBufferBase* sbb); diff --git a/include/utils/threads.h b/include/utils/threads.h index f5304f72bd7e..0fc533f9551c 100644 --- a/include/utils/threads.h +++ b/include/utils/threads.h @@ -90,11 +90,6 @@ enum { ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST, }; -typedef enum { - SP_BACKGROUND = 0, - SP_FOREGROUND = 1, -} SchedPolicy; - // Create and run a new thread. extern int androidCreateThread(android_thread_func_t, void *); diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 8685f9951f92..a352431f810b 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1524,13 +1524,24 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) result.append( l->lcblk->dump(" ") ); sp<const Buffer> buf0(l->getBuffer(0)); sp<const Buffer> buf1(l->getBuffer(1)); + uint32_t w0=0, h0=0, s0=0; + uint32_t w1=0, h1=0, s1=0; + if (buf0 != 0) { + w0 = buf0->getWidth(); + h0 = buf0->getHeight(); + s0 = buf0->getStride(); + } + if (buf1 != 0) { + w1 = buf1->getWidth(); + h1 = buf1->getHeight(); + s1 = buf1->getStride(); + } snprintf(buffer, SIZE, " " "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," " freezeLock=%p\n", l->pixelFormat(), - buf0->getWidth(), buf0->getHeight(), buf0->getStride(), - buf1->getWidth(), buf1->getHeight(), buf1->getStride(), + w0, h0, s0, w1, h1, s1, l->getFreezeLock().get()); result.append(buffer); buffer[0] = 0; diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp index 436d79320e9c..7789a3f8646f 100644 --- a/libs/ui/SharedBufferStack.cpp +++ b/libs/ui/SharedBufferStack.cpp @@ -246,19 +246,26 @@ SharedBufferClient::SharedBufferClient(SharedClient* sharedClient, int surface, int num) : SharedBufferBase(sharedClient, surface, num), tail(0) { + tail = computeTail(); +} + +int32_t SharedBufferClient::computeTail() const +{ SharedBufferStack& stack( *mSharedStack ); - int32_t avail; - int32_t head; // we need to make sure we read available and head coherently, // w.r.t RetireUpdate. + int32_t newTail; + int32_t avail; + int32_t head; do { avail = stack.available; head = stack.head; } while (stack.available != avail); - tail = head - avail + 1; - if (tail < 0) { - tail += num; + newTail = head - avail + 1; + if (newTail < 0) { + newTail += mNumBuffers; } + return newTail; } ssize_t SharedBufferClient::dequeue() @@ -296,6 +303,9 @@ status_t SharedBufferClient::undoDequeue(int buf) { UndoDequeueUpdate update(this); status_t err = updateCondition( update ); + if (err == NO_ERROR) { + tail = computeTail(); + } return err; } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index d905619159aa..22c2f3987929 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1266,6 +1266,8 @@ status_t OMXCodec::freeBuffersOnPort( CHECK_EQ(info->mOwnedByComponent, false); + CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); + status_t err = mOMX->free_buffer(mNode, portIndex, info->mBuffer); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index b0e40380e62f..c844de224d3f 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -418,6 +418,17 @@ public class WindowManagerService extends IWindowManager.Stub int mWallpaperAnimLayerAdjustment; float mLastWallpaperX; float mLastWallpaperY; + // Lock for waiting for the wallpaper. + final Object mWaitingOnWallpaperLock = new Object(); + // This is set when we are waiting for a wallpaper to tell us it is done + // changing its scroll position. + WindowState mWaitingOnWallpaper; + // The last time we had a timeout when waiting for a wallpaper. + long mLastWallpaperTimeoutTime; + // We give a wallpaper up to 150ms to finish scrolling. + static final long WALLPAPER_TIMEOUT = 150; + // Time we wait after a timeout before trying to wait again. + static final long WALLPAPER_TIMEOUT_RECOVERY = 10000; AppWindowToken mFocusedApp = null; @@ -1427,7 +1438,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh, false); } // First, make sure the client has the current visibility @@ -1498,7 +1509,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh) { + boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh, + boolean sync) { boolean changed = false; boolean rawChanged = false; if (mLastWallpaperX >= 0) { @@ -1536,8 +1548,37 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WALLPAPER) Log.v(TAG, "Report new wp offset " + wallpaperWin + " x=" + wallpaperWin.mWallpaperX + " y=" + wallpaperWin.mWallpaperY); + if (sync) { + synchronized (mWaitingOnWallpaperLock) { + mWaitingOnWallpaper = wallpaperWin; + } + } wallpaperWin.mClient.dispatchWallpaperOffsets( - wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY); + wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY, sync); + if (sync) { + synchronized (mWaitingOnWallpaperLock) { + if (mWaitingOnWallpaper != null) { + long start = SystemClock.uptimeMillis(); + if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY) + < start) { + try { + if (DEBUG_WALLPAPER) Log.v(TAG, + "Waiting for offset complete..."); + mWaitingOnWallpaperLock.wait(WALLPAPER_TIMEOUT); + } catch (InterruptedException e) { + } + if (DEBUG_WALLPAPER) Log.v(TAG, "Offset complete!"); + if ((start+WALLPAPER_TIMEOUT) + < SystemClock.uptimeMillis()) { + Log.i(TAG, "Timeout waiting for wallpaper to offset: " + + wallpaperWin); + mLastWallpaperTimeoutTime = start; + } + } + mWaitingOnWallpaper = null; + } + } + } } catch (RemoteException e) { } } @@ -1545,7 +1586,17 @@ public class WindowManagerService extends IWindowManager.Stub return changed; } - boolean updateWallpaperOffsetLocked() { + void wallpaperOffsetsComplete(IBinder window) { + synchronized (mWaitingOnWallpaperLock) { + if (mWaitingOnWallpaper != null && + mWaitingOnWallpaper.mClient.asBinder() == window) { + mWaitingOnWallpaper = null; + mWaitingOnWallpaperLock.notifyAll(); + } + } + } + + boolean updateWallpaperOffsetLocked(boolean sync) { final int dw = mDisplay.getWidth(); final int dh = mDisplay.getHeight(); @@ -1563,9 +1614,11 @@ public class WindowManagerService extends IWindowManager.Stub while (curWallpaperIndex > 0) { curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); - if (updateWallpaperOffsetLocked(wallpaper, dw, dh)) { + if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) { wallpaper.computeShownFrameLocked(); changed = true; + // We only want to be synchronous with one wallpaper. + sync = false; } } } @@ -1595,7 +1648,7 @@ public class WindowManagerService extends IWindowManager.Stub curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh, false); } if (wallpaper.mWallpaperVisible != visible) { @@ -1782,8 +1835,10 @@ public class WindowManagerService extends IWindowManager.Stub imMayMove = false; } else { addWindowToListInOrderLocked(win, true); - if (attrs.type == TYPE_WALLPAPER || - (attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { + if (attrs.type == TYPE_WALLPAPER) { + mLastWallpaperTimeoutTime = 0; + adjustWallpaperWindowsLocked(); + } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { adjustWallpaperWindowsLocked(); } } @@ -1992,8 +2047,10 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (win.mAttrs.type == TYPE_WALLPAPER || - (win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) { + if (win.mAttrs.type == TYPE_WALLPAPER) { + mLastWallpaperTimeoutTime = 0; + adjustWallpaperWindowsLocked(); + } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) { adjustWallpaperWindowsLocked(); } @@ -2070,7 +2127,7 @@ public class WindowManagerService extends IWindowManager.Stub window.mWallpaperY = y; if (mWallpaperTarget == window) { - if (updateWallpaperOffsetLocked()) { + if (updateWallpaperOffsetLocked(true)) { performLayoutAndPlaceSurfacesLocked(); } } @@ -2258,7 +2315,7 @@ public class WindowManagerService extends IWindowManager.Stub performLayoutAndPlaceSurfacesLocked(); if (displayed && win.mIsWallpaper) { updateWallpaperOffsetLocked(win, mDisplay.getWidth(), - mDisplay.getHeight()); + mDisplay.getHeight(), false); } if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); @@ -6303,6 +6360,10 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void wallpaperOffsetsComplete(IBinder window) { + WindowManagerService.this.wallpaperOffsetsComplete(window); + } + void windowAddedLocked() { if (mSurfaceSession == null) { if (localLOGV) Log.v( @@ -6698,7 +6759,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { updateWallpaperOffsetLocked(this, mDisplay.getWidth(), - mDisplay.getHeight()); + mDisplay.getHeight(), false); } if (localLOGV) { diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py index c3e6b5b48fa0..c3627bbf8fae 100755 --- a/tests/DumpRenderTree/assets/run_layout_tests.py +++ b/tests/DumpRenderTree/assets/run_layout_tests.py @@ -197,7 +197,17 @@ def main(options, args): logging.error("DumpRenderTree crashed, output:\n" + adb_output) shell_cmd_str = adb_cmd + " shell cat /sdcard/android/running_test.txt" - crashed_test = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE).communicate()[0] + crashed_test = "" + while not crashed_test: + (crashed_test, err) = subprocess.Popen( + shell_cmd_str, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + crashed_test = crashed_test.strip() + if not crashed_test: + logging.error('Cannot get crashed test name, device offline?') + logging.error('stderr: ' + err) + logging.error('retrying in 10s...') + time.sleep(10) logging.info(crashed_test + " CRASHED"); crashed_tests.append(crashed_test); diff --git a/tests/DumpRenderTree/assets/run_reliability_tests.py b/tests/DumpRenderTree/assets/run_reliability_tests.py index 23f93df8508e..59ac4a3344ef 100755 --- a/tests/DumpRenderTree/assets/run_reliability_tests.py +++ b/tests/DumpRenderTree/assets/run_reliability_tests.py @@ -195,8 +195,18 @@ def main(options, args): while not DumpRenderTreeFinished(adb_cmd): logging.error("DumpRenderTree exited before all URLs are visited.") shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE - crashed_test = subprocess.Popen(shell_cmd_str, shell=True, - stdout=subprocess.PIPE).communicate()[0] + crashed_test = "" + while not crashed_test: + (crashed_test, err) = subprocess.Popen( + shell_cmd_str, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + crashed_test = crashed_test.strip() + if not crashed_test: + logging.error('Cannot get crashed test name, device offline?') + logging.error('stderr: ' + err) + logging.error('retrying in 10s...') + time.sleep(10) + logging.info(crashed_test + " CRASHED") crashed_tests.append(crashed_test) Bugreport(crashed_test, bugreport_dir, adb_cmd) 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 55fe4ac84fa6..0888fd829f17 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -1051,15 +1051,22 @@ public final class Bridge implements ILayoutBridge { // pass for now. } + @SuppressWarnings("unused") public void setInsets(IWindow window, int touchable, Rect contentInsets, Rect visibleInsets) { // pass for now. } + @SuppressWarnings("unused") public void setWallpaperPosition(IBinder window, float x, float y) { // pass for now. } + @SuppressWarnings("unused") + public void wallpaperOffsetsComplete(IBinder window) { + // pass for now. + } + public IBinder asBinder() { // pass for now. return null; @@ -1114,7 +1121,7 @@ public final class Bridge implements ILayoutBridge { } @SuppressWarnings("unused") - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { // pass for now. } |