Merge change 24968 into eclair
* changes:
Minor perf tweak for fountain.
diff --git a/api/current.xml b/api/current.xml
index f8cf61f..ee82e00 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,7 +63352,7 @@
type="android.graphics.drawable.BitmapDrawable"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="filepath" type="java.lang.String">
@@ -63343,6 +63365,30 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="res" type="android.content.res.Resources">
+</parameter>
+<parameter name="filepath" type="java.lang.String">
+</parameter>
+</constructor>
+<constructor name="BitmapDrawable"
+ 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 8730288..8f7e8ca 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -395,7 +395,7 @@
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 @@
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 @@
// 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 da40c8a..38cac87 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -22,7 +22,9 @@
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 @@
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 @@
case MSG_CLEAR_WALLPAPER:
synchronized (this) {
mWallpaper = null;
+ mDefaultWallpaper = null;
}
break;
}
@@ -90,12 +180,19 @@
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 @@
fd.close();
} catch (IOException e) {
}
- if (bm == null) {
+
+ 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 (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) {
+ }
+ if (bm != null) {
+ bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
+ }
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;
+ // 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) {
}
- 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;
+ return generateBitmap(context, bm, width, height);
}
} catch (RemoteException e) {
}
@@ -219,9 +316,13 @@
* @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 @@
* 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 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 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 6d27bc7..1e590f0 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -87,13 +87,37 @@
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 ba5c9ed..3796201 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -22,8 +22,6 @@
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 @@
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 @@
} 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 @@
//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 0ce86db..65301e4 100644
--- a/core/java/android/os/HandlerThread.java
+++ b/core/java/android/os/HandlerThread.java
@@ -64,7 +64,7 @@
/**
* 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 @@
}
/**
+ * 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 e5659d5..cd5cf10 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -28,9 +28,11 @@
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 @@
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 @@
boolean mOffsetMessageEnqueued;
float mPendingXOffset;
float mPendingYOffset;
+ boolean mPendingSync;
MotionEvent mPendingMove;
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -212,10 +217,14 @@
}
@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 @@
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 @@
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 @@
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 @@
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 ebc5f7b..b7953af2 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -60,5 +60,5 @@
/**
* 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 4d662d2..9b8b6d4 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -114,4 +114,6 @@
* 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 f63c2f1..2cc243e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6042,12 +6042,11 @@
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 b61465a..6748ade 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2868,7 +2868,13 @@
}
}
- 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 0f178e9..2329e21 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1394,6 +1394,7 @@
* 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 e7b303a..f34823c 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -23,7 +23,6 @@
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.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 @@
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 @@
// We haven't been callbacking during the fling, so do it now
super.selectionChanged();
}
+ invalidate();
}
@Override
@@ -534,12 +532,9 @@
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 @@
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 @@
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 @@
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 @@
* 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 5825024..35b9251 100644
--- a/core/java/com/android/internal/os/HandlerCaller.java
+++ b/core/java/com/android/internal/os/HandlerCaller.java
@@ -57,6 +57,13 @@
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 5357469..0bc70de 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.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 @@
*/
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 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 @@
registerReceiver(mReceiver, filter);
updateWallpaper();
surfaceHolder.setSizeFromLayout();
- //setTouchEventsEnabled(true);
}
@Override
@@ -137,11 +150,7 @@
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 f4f6297..b8d19ac 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -90,6 +90,12 @@
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 b81c2b3..bba2ee2 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 @@
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 7748aba..5b6c7ea 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 @@
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 @@
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 @@
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_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 ac96f20..58206d4 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -45,11 +45,11 @@
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 @@
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 @@
@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 68718c9..fdc4c92 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -77,7 +77,7 @@
private boolean mMutated;
public AnimationDrawable() {
- this(null);
+ this(null, null);
}
@Override
@@ -297,8 +297,9 @@
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 @@
@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 @@
}
}
- 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 30cef67..e82f297 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -60,15 +60,15 @@
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 BitmapDrawable(Resources res) {
mBitmapState = new BitmapState((Bitmap) null);
- if (res != null) {
- setTargetDensity(res.getDisplayMetrics());
- mBitmapState.mTargetDensity = mTargetDensity;
- }
+ mBitmapState.mTargetDensity = mTargetDensity;
}
/**
@@ -101,7 +98,7 @@
*/
@Deprecated
public BitmapDrawable(Bitmap bitmap) {
- this(new BitmapState(bitmap));
+ this(new BitmapState(bitmap), null);
}
/**
@@ -109,22 +106,51 @@
* 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 @@
@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 @@
}
}
- 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 95d4dd0..c387a9b 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -48,14 +48,14 @@
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 @@
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 @@
@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 @@
}
}
- 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 226cc04..604c602 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -146,6 +146,11 @@
}
@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 21b5e39..6a7b2d1 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -822,7 +822,26 @@
}
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 af1a289..3266f1e 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 @@
boolean mPaddingChecked = false;
- DrawableContainerState(DrawableContainerState orig, DrawableContainer owner) {
+ DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
+ Resources res) {
mOwner = owner;
if (orig != null) {
@@ -299,7 +301,11 @@
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 a7a8708..ddbbaf1 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -917,6 +917,11 @@
}
@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 6047726..4fa9d44 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -49,7 +49,7 @@
private boolean mMutated;
/*package*/ InsetDrawable() {
- this(null);
+ this(null, null);
}
public InsetDrawable(Drawable drawable, int inset) {
@@ -58,7 +58,7 @@
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 @@
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 @@
@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 @@
}
}
- 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 c777205..389fd40 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -70,7 +70,7 @@
* @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 @@
}
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 @@
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 @@
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 @@
@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 7ae649f..ae8f224 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -57,7 +57,7 @@
private boolean mMutated;
public LevelListDrawable() {
- this(null);
+ this(null, null);
}
public void addLevel(int low, int high, Drawable drawable) {
@@ -154,8 +154,8 @@
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 @@
@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 @@
}
}
- 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 997efb8..803e7b1 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -61,7 +61,7 @@
*/
@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 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 @@
*/
@Deprecated
public NinePatchDrawable(NinePatch patch) {
- this(new NinePatchState(patch, null));
+ this(new NinePatchState(patch, null), null);
}
/**
@@ -92,18 +89,16 @@
* 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 @@
}
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 @@
@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 @@
}
}
- 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 cb16cb7..c4a7822 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -54,7 +54,7 @@
* <p>Create a new rotating drawable with an empty state.</p>
*/
public RotateDrawable() {
- this(null);
+ this(null, null);
}
/**
@@ -64,8 +64,8 @@
*
* @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 @@
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 @@
@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 7125ab1..275e36f 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -47,11 +47,11 @@
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 @@
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 @@
@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 @@
}
}
- 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 6677a35..c699a82 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -396,6 +396,11 @@
}
@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 59cb226..b1d588e 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -65,7 +65,7 @@
private boolean mMutated;
public StateListDrawable() {
- this(null);
+ this(null, null);
}
/**
@@ -248,8 +248,8 @@
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 @@
@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 @@
}
}
- 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 358f889..97b45d8 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 @@
* 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 @@
* @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 @@
}
@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 @@
}
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 6181f55..8b0f154 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -228,6 +228,8 @@
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 f5304f7..0fc533f 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -90,11 +90,6 @@
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 8685f99..a352431 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1524,13 +1524,24 @@
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 436d793..7789a3f 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -246,19 +246,26 @@
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 @@
{
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 d905619..22c2f39 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1266,6 +1266,8 @@
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 b0e4038..c844de2 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -418,6 +418,17 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
window.mWallpaperY = y;
if (mWallpaperTarget == window) {
- if (updateWallpaperOffsetLocked()) {
+ if (updateWallpaperOffsetLocked(true)) {
performLayoutAndPlaceSurfacesLocked();
}
}
@@ -2258,7 +2315,7 @@
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 void wallpaperOffsetsComplete(IBinder window) {
+ WindowManagerService.this.wallpaperOffsetsComplete(window);
+ }
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
@@ -6698,7 +6759,7 @@
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 c3e6b5b..c3627bb 100755
--- a/tests/DumpRenderTree/assets/run_layout_tests.py
+++ b/tests/DumpRenderTree/assets/run_layout_tests.py
@@ -197,7 +197,17 @@
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 23f93df..59ac4a3 100755
--- a/tests/DumpRenderTree/assets/run_reliability_tests.py
+++ b/tests/DumpRenderTree/assets/run_reliability_tests.py
@@ -195,8 +195,18 @@
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 55fe4ac..0888fd8 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 @@
// 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 @@
}
@SuppressWarnings("unused")
- public void dispatchWallpaperOffsets(float x, float y) {
+ public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
// pass for now.
}