Merge change 24921 into eclair
* changes:
add system properties for experimenting with sync timeouts.
diff --git a/api/current.xml b/api/current.xml
index f8cf61f..04823e5 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"
@@ -101558,6 +101580,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/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 8cfb758..6abed93 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1398,9 +1398,8 @@
}
if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "wiping all passwords and authtokens");
- }
+ Log.w(TAG, "wiping all passwords and authtokens because IMSI changed ("
+ + "stored=" + storedImsi + ", current=" + imsi + ")");
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
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/res/Resources.java b/core/java/android/content/res/Resources.java
index ba5c9ed..9d370fc 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;
@@ -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);
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/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 6ce0f5f..78e2c27 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -399,7 +399,7 @@
// Electronics, Flaircomm Electronics, Jatty Electronics, Delphi,
// Clarion, Novero, Denso (Lexus, Toyota), Johnson Controls (Acura),
// Continental Automotive, Harman/Becker
- private final ArrayList<String> mAutoPairingBlacklisted =
+ private final ArrayList<String> mAutoPairingAddressBlacklist =
new ArrayList<String>(Arrays.asList(
"00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", "00:21:4F",
"00:23:06", "00:24:33", "00:A0:79", "00:0E:6D", "00:13:E0", "00:21:E8",
@@ -408,6 +408,12 @@
"00:0A:30", "00:1E:AE", "00:1C:D7"
));
+ // List of names of Bluetooth devices for which auto pairing should be
+ // disabled.
+ private final ArrayList<String> mAutoPairingNameBlacklist =
+ new ArrayList<String>(Arrays.asList(
+ "Motorola IHF1000", "i.TechBlueBAND", "X5 Stereo v1.3"));
+
public synchronized void loadBondState() {
if (mBluetoothState != BluetoothAdapter.STATE_TURNING_ON) {
return;
@@ -460,9 +466,16 @@
}
public boolean isAutoPairingBlacklisted(String address) {
- for (String blacklistAddress : mAutoPairingBlacklisted) {
+ for (String blacklistAddress : mAutoPairingAddressBlacklist) {
if (address.startsWith(blacklistAddress)) return true;
}
+
+ String name = getRemoteName(address);
+ if (name != null) {
+ for (String blacklistName : mAutoPairingNameBlacklist) {
+ if (name.equals(blacklistName)) return true;
+ }
+ }
return false;
}
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/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index d61e888..ce25c47 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -208,7 +208,7 @@
if ((mask & WEB_URLS) != 0) {
gatherLinks(links, text, Regex.WEB_URL_PATTERN,
- new String[] { "http://", "https://" },
+ new String[] { "http://", "https://", "rtsp://" },
sUrlMatchFilter, null);
}
diff --git a/core/java/android/text/util/Regex.java b/core/java/android/text/util/Regex.java
index a349b82..a6844a4 100644
--- a/core/java/android/text/util/Regex.java
+++ b/core/java/android/text/util/Regex.java
@@ -65,7 +65,7 @@
*/
public static final Pattern WEB_URL_PATTERN
= Pattern.compile(
- "((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+" // named host
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index ebc5f7b..b7953af 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 c93df74..2329e21 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -458,8 +458,7 @@
private static final int SWITCH_TO_LONGPRESS = 4;
private static final int RELEASE_SINGLE_TAP = 5;
private static final int REQUEST_FORM_DATA = 6;
- private static final int SWITCH_TO_CLICK = 7;
- private static final int RESUME_WEBCORE_UPDATE = 8;
+ private static final int RESUME_WEBCORE_UPDATE = 7;
//! arg1=x, arg2=y
static final int SCROLL_TO_MSG_ID = 10;
@@ -1395,6 +1394,7 @@
* Reload the current url.
*/
public void reload() {
+ clearTextEntry();
switchOutDrawHistory();
mWebViewCore.sendMessage(EventHub.RELOAD);
}
@@ -3664,16 +3664,27 @@
if (mShiftIsPressed) {
return false;
}
- if (getSettings().supportZoom()
- && mTouchMode == TOUCH_DOUBLECLICK_MODE) {
- zoomScrollOut();
- } else {
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(SWITCH_TO_CLICK), TAP_TIMEOUT);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "TOUCH_DOUBLECLICK_MODE");
- }
- mTouchMode = TOUCH_DOUBLECLICK_MODE;
+
+ // perform the single click
+ Rect visibleRect = sendOurVisibleRect();
+ // Note that sendOurVisibleRect calls viewToContent, so the
+ // coordinates should be in content coordinates.
+ if (!nativeCursorIntersects(visibleRect)) {
+ return false;
+ }
+ nativeSetFollowedLink(true);
+ nativeUpdatePluginReceivesEvents();
+ WebViewCore.CursorData data = cursorData();
+ mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data);
+ playSoundEffect(SoundEffectConstants.CLICK);
+ boolean isTextInput = nativeCursorIsTextInput();
+ if (isTextInput || !mCallbackProxy.uiOverrideUrlLoading(
+ nativeCursorText())) {
+ mWebViewCore.sendMessage(EventHub.CLICK, data.mFrame,
+ nativeCursorNodePointer());
+ }
+ if (isTextInput) {
+ rebuildWebTextView();
}
return true;
}
@@ -4321,7 +4332,6 @@
return true;
}
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mPrivateHandler.removeMessages(SWITCH_TO_CLICK);
mTrackballDown = true;
if (mNativeClass == 0) {
return false;
@@ -4570,7 +4580,7 @@
private int computeMaxScrollY() {
int maxContentH = computeVerticalScrollRange() + getTitleHeight();
- return Math.max(maxContentH - getHeight(), 0);
+ return Math.max(maxContentH - getHeight(), getTitleHeight());
}
public void flingScroll(int vx, int vy) {
@@ -4876,6 +4886,9 @@
}
int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
+ // In case the soft keyboard has been dismissed, bring it back up.
+ InputMethodManager.getInstance(getContext()).showSoftInput(mWebTextView,
+ 0);
nativeTextInputMotionUp(x, y);
}
@@ -5184,32 +5197,6 @@
}
break;
}
- case SWITCH_TO_CLICK:
- // The user clicked with the trackball, and did not click a
- // second time, so perform the action of a trackball single
- // click
- mTouchMode = TOUCH_DONE_MODE;
- Rect visibleRect = sendOurVisibleRect();
- // Note that sendOurVisibleRect calls viewToContent, so the
- // coordinates should be in content coordinates.
- if (!nativeCursorIntersects(visibleRect)) {
- break;
- }
- nativeSetFollowedLink(true);
- nativeUpdatePluginReceivesEvents();
- WebViewCore.CursorData data = cursorData();
- mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data);
- playSoundEffect(SoundEffectConstants.CLICK);
- boolean isTextInput = nativeCursorIsTextInput();
- if (isTextInput || !mCallbackProxy.uiOverrideUrlLoading(
- nativeCursorText())) {
- mWebViewCore.sendMessage(EventHub.CLICK, data.mFrame,
- nativeCursorNodePointer());
- }
- if (isTextInput) {
- rebuildWebTextView();
- }
- break;
case SCROLL_BY_MSG_ID:
setContentScrollBy(msg.arg1, msg.arg2, (Boolean) msg.obj);
break;
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/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/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/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 38df47b..ba65f01 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -63,7 +63,7 @@
import java.util.Observer;
class PowerManagerService extends IPowerManager.Stub
- implements LocalPowerManager,Watchdog.Monitor, SensorEventListener {
+ implements LocalPowerManager, Watchdog.Monitor, SensorEventListener {
private static final String TAG = "PowerManagerService";
static final String PARTIAL_NAME = "PowerManagerService";
@@ -1848,7 +1848,17 @@
}
public void setKeyboardVisibility(boolean visible) {
- mKeyboardVisible = visible;
+ synchronized (mLocks) {
+ if (mSpew) {
+ Log.d(TAG, "setKeyboardVisibility: " + visible);
+ }
+ mKeyboardVisible = visible;
+ // don't signal user activity when closing keyboard if the screen is off.
+ // otherwise, we want to make sure the backlights are adjusted.
+ if (visible || (mPowerState & SCREEN_ON_BIT) != 0) {
+ userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
+ }
+ }
}
/**
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/api/src/com/android/layoutlib/api/ILayoutBridge.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
index c562650..4dbcfdc 100644
--- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
+++ b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
@@ -88,7 +88,7 @@
* @param projectCallback The {@link IProjectCallback} object to get information from
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
- * @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @return a new {@link ILayoutResult} object that contains the result of the layout.
* @since 4
*/
ILayoutResult computeLayout(IXmlPullParser layoutDescription,
@@ -123,7 +123,7 @@
* @param projectCallback The {@link IProjectCallback} object to get information from
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
- * @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @return a new {@link ILayoutResult} object that contains the result of the layout.
* @since 3
*/
@Deprecated
@@ -155,7 +155,7 @@
* @param projectCallback The {@link IProjectCallback} object to get information from
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
- * @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @return a new {@link ILayoutResult} object that contains the result of the layout.
* @deprecated Use {@link #computeLayout(IXmlPullParser, Object, int, int, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}
* @since 2
*/
@@ -187,7 +187,7 @@
* @param projectCallback The {@link IProjectCallback} object to get information from
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
- * @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @return a new {@link ILayoutResult} object that contains the result of the layout.
* @deprecated Use {@link #computeLayout(IXmlPullParser, Object, int, int, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}
* @since 1
*/
@@ -205,7 +205,7 @@
* until this method is called.
* <p/>The cache is not configuration dependent and should only be cleared when a
* resource changes (at this time only bitmaps and 9 patches go into the cache).
- * @param objectKey the key for the project.
+ * @param projectKey the key for the project.
* @since 1
*/
void clearCaches(Object projectKey);
diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java
index 5a06349..2d8a210 100644
--- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java
+++ b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java
@@ -23,13 +23,17 @@
* {@link ILayoutLibBridge#computeLayout(IXmlPullParser, int, int, String, java.util.Map, java.util.Map, java.util.Map, IFontLoader, ILayoutLibLog, ICustomViewLoader)}
*/
public interface ILayoutResult {
- /** Sucess return code */
+ /**
+ * Success return code
+ */
final static int SUCCESS = 0;
- /** Error return code.
- * <p/>See {@link #getErrorMessage()}
- */
+
+ /**
+ * Error return code, in which case an error message is guaranteed to be defined.
+ * @See {@link #getErrorMessage()}
+ */
final static int ERROR = 1;
-
+
/**
* Returns the result code.
* @see #SUCCESS
@@ -62,18 +66,18 @@
* Returns the list of children views.
*/
ILayoutViewInfo[] getChildren();
-
+
/**
* Returns the key associated with the node.
* @see IXmlPullParser#getViewKey()
*/
Object getViewKey();
-
+
/**
* Returns the name of the view.
*/
String getName();
-
+
/**
* Returns the left of the view bounds.
*/
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.
}