diff options
31 files changed, 604 insertions, 230 deletions
diff --git a/api/current.xml b/api/current.xml index f8cf61fdf160..04823e577ff6 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 8cfb75830728..6abed93e284e 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -1398,9 +1398,8 @@ public class AccountManagerService extends IAccountManager.Stub { } 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 da40c8a2fa5a..38cac87bcb53 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -22,7 +22,9 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; +import android.graphics.ColorFilter; import android.graphics.Paint; +import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -56,9 +58,96 @@ public class WallpaperManager { private final Context mContext; + /** + * Special drawable that draws a wallpaper as fast as possible. Assumes + * no scaling or placement off (0,0) of the wallpaper (this should be done + * at the time the bitmap is loaded). + */ + static class FastBitmapDrawable extends Drawable { + private final Bitmap mBitmap; + private final int mWidth; + private final int mHeight; + private int mDrawLeft; + private int mDrawTop; + + private FastBitmapDrawable(Bitmap bitmap) { + mBitmap = bitmap; + mWidth = bitmap.getWidth(); + mHeight = bitmap.getHeight(); + setBounds(0, 0, mWidth, mHeight); + } + + @Override + public void draw(Canvas canvas) { + canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, null); + } + + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + @Override + public void setBounds(int left, int top, int right, int bottom) { + mDrawLeft = left + (right-left - mWidth) / 2; + mDrawTop = top + (bottom-top - mHeight) / 2; + } + + @Override + public void setBounds(Rect bounds) { + // TODO Auto-generated method stub + super.setBounds(bounds); + } + + @Override + public void setAlpha(int alpha) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setColorFilter(ColorFilter cf) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setDither(boolean dither) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public void setFilterBitmap(boolean filter) { + throw new UnsupportedOperationException( + "Not supported with this drawable"); + } + + @Override + public int getIntrinsicWidth() { + return mWidth; + } + + @Override + public int getIntrinsicHeight() { + return mHeight; + } + + @Override + public int getMinimumWidth() { + return mWidth; + } + + @Override + public int getMinimumHeight() { + return mHeight; + } + } + static class Globals extends IWallpaperManagerCallback.Stub { private IWallpaperManager mService; private Bitmap mWallpaper; + private Bitmap mDefaultWallpaper; private static final int MSG_CLEAR_WALLPAPER = 1; @@ -74,6 +163,7 @@ public class WallpaperManager { case MSG_CLEAR_WALLPAPER: synchronized (this) { mWallpaper = null; + mDefaultWallpaper = null; } break; } @@ -90,12 +180,19 @@ public class WallpaperManager { mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER); } - public Bitmap peekWallpaperBitmap(Context context) { + public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) { synchronized (this) { if (mWallpaper != null) { return mWallpaper; } + if (mDefaultWallpaper != null) { + return mDefaultWallpaper; + } mWallpaper = getCurrentWallpaperLocked(context); + if (mWallpaper == null && returnDefault) { + mDefaultWallpaper = getDefaultWallpaperLocked(context); + return mDefaultWallpaper; + } return mWallpaper; } } @@ -134,48 +231,48 @@ public class WallpaperManager { fd.close(); } catch (IOException e) { } - if (bm == null) { - return bm; - } - bm.setDensity(DisplayMetrics.DENSITY_DEVICE); - - // This is the final bitmap we want to return. - Bitmap newbm = Bitmap.createBitmap(width, height, - bm.getConfig()); - newbm.setDensity(DisplayMetrics.DENSITY_DEVICE); - Canvas c = new Canvas(newbm); - c.setDensity(DisplayMetrics.DENSITY_DEVICE); - Rect targetRect = new Rect(); - targetRect.left = targetRect.top = 0; - targetRect.right = bm.getWidth(); - targetRect.bottom = bm.getHeight(); - int deltaw = width - targetRect.right; - int deltah = height - targetRect.bottom; + return generateBitmap(context, bm, width, height); + } + } catch (RemoteException e) { + } + return null; + } + + private Bitmap getDefaultWallpaperLocked(Context context) { + try { + InputStream is = context.getResources().openRawResource( + com.android.internal.R.drawable.default_wallpaper); + if (is != null) { + int width = mService.getWidthHint(); + int height = mService.getHeightHint(); - if (deltaw > 0 || deltah > 0) { - // We need to scale up so it covers the entire - // area. - float scale = 1.0f; - if (deltaw > deltah) { - scale = width / (float)targetRect.right; - } else { - scale = height / (float)targetRect.bottom; + if (width <= 0 || height <= 0) { + // Degenerate case: no size requested, just load + // bitmap as-is. + Bitmap bm = BitmapFactory.decodeStream(is, null, null); + try { + is.close(); + } catch (IOException e) { } - targetRect.right = (int)(targetRect.right*scale); - targetRect.bottom = (int)(targetRect.bottom*scale); - deltaw = width - targetRect.right; - deltah = height - targetRect.bottom; + if (bm != null) { + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + } + return bm; } - targetRect.offset(deltaw/2, deltah/2); - Paint paint = new Paint(); - paint.setFilterBitmap(true); - paint.setDither(true); - c.drawBitmap(bm, null, targetRect, paint); + // Load the bitmap with full color depth, to preserve + // quality for later processing. + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inDither = false; + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + Bitmap bm = BitmapFactory.decodeStream(is, null, options); + try { + is.close(); + } catch (IOException e) { + } - bm.recycle(); - return newbm; + return generateBitmap(context, bm, width, height); } } catch (RemoteException e) { } @@ -219,9 +316,13 @@ public class WallpaperManager { * @return Returns a Drawable object that will draw the wallpaper. */ public Drawable getDrawable() { - Drawable dr = peekDrawable(); - return dr != null ? dr : Resources.getSystem().getDrawable( - com.android.internal.R.drawable.default_wallpaper); + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true); + if (bm != null) { + Drawable dr = new BitmapDrawable(mContext.getResources(), bm); + dr.setDither(false); + return dr; + } + return null; } /** @@ -234,8 +335,51 @@ public class WallpaperManager { * null pointer if these is none. */ public Drawable peekDrawable() { - Bitmap bm = sGlobals.peekWallpaperBitmap(mContext); - return bm != null ? new BitmapDrawable(mContext.getResources(), bm) : null; + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false); + if (bm != null) { + Drawable dr = new BitmapDrawable(mContext.getResources(), bm); + dr.setDither(false); + return dr; + } + return null; + } + + /** + * Like {@link #peekFastDrawable}, but always returns a valid Drawable. If + * no wallpaper is set, the system default wallpaper is returned. + * + * @return Returns a Drawable object that will draw the wallpaper. + */ + public Drawable getFastDrawable() { + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true); + if (bm != null) { + Drawable dr = new FastBitmapDrawable(bm); + return dr; + } + return null; + } + + /** + * Like {@link #peekDrawable()}, but the returned Drawable has a number + * of limitations to reduce its overhead as much as possible: it will + * never scale the wallpaper (only centering it if the requested bounds + * do match the bitmap bounds, which should not be typical), doesn't + * allow setting an alpha, color filter, or other attributes, etc. The + * bounds of the returned drawable will be initialized to the same bounds + * as the wallpaper, so normally you will not need to touch it. The + * drawable also assumes that it will be used in a context running in + * the same density as the screen (not in density compatibility mode). + * + * @return Returns an optimized Drawable object that will draw the + * wallpaper or a null pointer if these is none. + */ + public Drawable peekFastDrawable() { + Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false); + if (bm != null) { + Drawable dr = new FastBitmapDrawable(bm); + return dr; + } + return null; } /** @@ -429,8 +573,10 @@ public class WallpaperManager { */ public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) { try { + //Log.v(TAG, "Sending new wallpaper offsets from app..."); ViewRoot.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, xOffset, yOffset); + //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { // Ignore. } @@ -466,4 +612,51 @@ public class WallpaperManager { public void clear() throws IOException { setResource(com.android.internal.R.drawable.default_wallpaper); } + + static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) { + if (bm == null) { + return bm; + } + bm.setDensity(DisplayMetrics.DENSITY_DEVICE); + + // This is the final bitmap we want to return. + // XXX We should get the pixel depth from the system (to match the + // physical display depth), when there is a way. + Bitmap newbm = Bitmap.createBitmap(width, height, + Bitmap.Config.RGB_565); + newbm.setDensity(DisplayMetrics.DENSITY_DEVICE); + Canvas c = new Canvas(newbm); + c.setDensity(DisplayMetrics.DENSITY_DEVICE); + Rect targetRect = new Rect(); + targetRect.left = targetRect.top = 0; + targetRect.right = bm.getWidth(); + targetRect.bottom = bm.getHeight(); + + int deltaw = width - targetRect.right; + int deltah = height - targetRect.bottom; + + if (deltaw > 0 || deltah > 0) { + // We need to scale up so it covers the entire + // area. + float scale = 1.0f; + if (deltaw > deltah) { + scale = width / (float)targetRect.right; + } else { + scale = height / (float)targetRect.bottom; + } + targetRect.right = (int)(targetRect.right*scale); + targetRect.bottom = (int)(targetRect.bottom*scale); + deltaw = width - targetRect.right; + deltah = height - targetRect.bottom; + } + + targetRect.offset(deltaw/2, deltah/2); + Paint paint = new Paint(); + paint.setFilterBitmap(true); + paint.setDither(true); + c.drawBitmap(bm, null, targetRect, paint); + + bm.recycle(); + return newbm; + } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index ba5c9ed18a43..9d370fc4610e 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -22,8 +22,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import android.content.pm.ApplicationInfo; -import android.graphics.BitmapFactory; import android.graphics.Movie; import android.graphics.drawable.Drawable; import android.graphics.drawable.ColorDrawable; @@ -1699,7 +1697,7 @@ public class Resources { } else { try { InputStream is = mAssets.openNonAsset( - value.assetCookie, file, AssetManager.ACCESS_BUFFER); + value.assetCookie, file, AssetManager.ACCESS_STREAMING); // System.out.println("Opened file " + file + ": " + is); dr = Drawable.createFromResourceStream(this, value, is, file, null); diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java index 0ce86db972c3..65301e41bb7f 100644 --- a/core/java/android/os/HandlerThread.java +++ b/core/java/android/os/HandlerThread.java @@ -64,7 +64,7 @@ public class HandlerThread extends Thread { /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread - * has been started, this method will blocked until the looper has been initialized. + * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { @@ -85,6 +85,21 @@ public class HandlerThread extends Thread { } /** + * Ask the currently running looper to quit. If the thread has not + * been started or has finished (that is if {@link #getLooper} returns + * null), then false is returned. Otherwise the looper is asked to + * quit and true is returned. + */ + public boolean quit() { + Looper looper = getLooper(); + if (looper != null) { + looper.quit(); + return true; + } + return false; + } + + /** * Returns the identifier of this thread. See Process.myTid(). */ public int getThreadId() { diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index 6ce0f5f070ba..78e2c273e779 100644 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -399,7 +399,7 @@ public class BluetoothService extends IBluetooth.Stub { // 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 @@ public class BluetoothService extends IBluetooth.Stub { "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 class BluetoothService extends IBluetooth.Stub { } 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 e5659d57a0cb..cd5cf1027af4 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -28,9 +28,11 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.Rect; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; +import android.util.LogPrinter; import android.view.Gravity; import android.view.IWindowSession; import android.view.MotionEvent; @@ -74,6 +76,8 @@ public abstract class WallpaperService extends Service { private static final int MSG_WINDOW_RESIZED = 10030; private static final int MSG_TOUCH_EVENT = 10040; + private Looper mCallbackLooper; + /** * The actual implementation of a wallpaper. A wallpaper service may * have multiple instances running (for example as a real wallpaper @@ -120,6 +124,7 @@ public abstract class WallpaperService extends Service { boolean mOffsetMessageEnqueued; float mPendingXOffset; float mPendingYOffset; + boolean mPendingSync; MotionEvent mPendingMove; final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -212,10 +217,14 @@ public abstract class WallpaperService extends Service { } @Override - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { synchronized (mLock) { + if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y); mPendingXOffset = x; mPendingYOffset = y; + if (sync) { + mPendingSync = true; + } if (!mOffsetMessageEnqueued) { mOffsetMessageEnqueued = true; Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS); @@ -551,9 +560,12 @@ public abstract class WallpaperService extends Service { float xOffset; float yOffset; + boolean sync; synchronized (mLock) { xOffset = mPendingXOffset; yOffset = mPendingYOffset; + sync = mPendingSync; + mPendingSync = false; mOffsetMessageEnqueued = false; } if (DEBUG) Log.v(TAG, "Offsets change in " + this @@ -563,6 +575,14 @@ public abstract class WallpaperService extends Service { final int availh = mIWallpaperEngine.mReqHeight-mCurHeight; final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0; onOffsetsChanged(xOffset, yOffset, xPixels, yPixels); + + if (sync) { + try { + if (DEBUG) Log.v(TAG, "Reporting offsets change complete"); + mSession.wallpaperOffsetsComplete(mWindow.asBinder()); + } catch (RemoteException e) { + } + } } void detach() { @@ -622,7 +642,13 @@ public abstract class WallpaperService extends Service { IWallpaperEngineWrapper(WallpaperService context, IWallpaperConnection conn, IBinder windowToken, int windowType, boolean isPreview, int reqWidth, int reqHeight) { - mCaller = new HandlerCaller(context, this); + if (DEBUG && mCallbackLooper != null) { + mCallbackLooper.setMessageLogging(new LogPrinter(Log.VERBOSE, TAG)); + } + mCaller = new HandlerCaller(context, + mCallbackLooper != null + ? mCallbackLooper : context.getMainLooper(), + this); mConnection = conn; mWindowToken = windowToken; mWindowType = windowType; @@ -736,5 +762,18 @@ public abstract class WallpaperService extends Service { return new IWallpaperServiceWrapper(this); } + /** + * This allows subclasses to change the thread that most callbacks + * occur on. Currently hidden because it is mostly needed for the + * image wallpaper (which runs in the system process and doesn't want + * to get stuck running on that seriously in use main thread). Not + * exposed right now because the semantics of this are not totally + * well defined and some callbacks can still happen on the main thread). + * @hide + */ + public void setCallbackLooper(Looper looper) { + mCallbackLooper = looper; + } + public abstract Engine onCreateEngine(); } diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index d61e888e1815..ce25c47cfec2 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -208,7 +208,7 @@ public class Linkify { 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 a349b82dbad6..a6844a464ffc 100644 --- a/core/java/android/text/util/Regex.java +++ b/core/java/android/text/util/Regex.java @@ -65,7 +65,7 @@ public class Regex { */ 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 ebc5f7b383d1..b7953af28818 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -60,5 +60,5 @@ oneway interface IWindow { /** * Called for wallpaper windows when their offsets change. */ - void dispatchWallpaperOffsets(float x, float y); + void dispatchWallpaperOffsets(float x, float y, boolean sync); } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 4d662d252a7f..9b8b6d474af7 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -114,4 +114,6 @@ interface IWindowSession { * larger than the screen, set the offset within the screen. */ void setWallpaperPosition(IBinder windowToken, float x, float y); + + void wallpaperOffsetsComplete(IBinder window); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f63c2f1162e1..2cc243e84342 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6042,12 +6042,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility int height = mBottom - mTop; final AttachInfo attachInfo = mAttachInfo; - final float scale = attachInfo.mApplicationScale; + final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f; width = (int) ((width * scale) + 0.5f); height = (int) ((height * scale) + 0.5f); - Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, - height > 0 ? height : 1, quality); + Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, height > 0 ? height : 1, quality); if (bitmap == null) { throw new OutOfMemoryError(); } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index b61465a74bf3..6748ade40ce6 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -2868,7 +2868,13 @@ public final class ViewRoot extends Handler implements ViewParent, } } - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { + if (sync) { + try { + sWindowSession.wallpaperOffsetsComplete(asBinder()); + } catch (RemoteException e) { + } + } } } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index c93df742d3c6..2329e2194fe6 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -458,8 +458,7 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout * Reload the current url. */ public void reload() { + clearTextEntry(); switchOutDrawHistory(); mWebViewCore.sendMessage(EventHub.RELOAD); } @@ -3664,16 +3664,27 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout return true; } if (ev.getAction() == MotionEvent.ACTION_DOWN) { - mPrivateHandler.removeMessages(SWITCH_TO_CLICK); mTrackballDown = true; if (mNativeClass == 0) { return false; @@ -4570,7 +4580,7 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout } 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 @@ public class WebView extends AbsoluteLayout } 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 e7b303ada4d0..f34823cb484a 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Config; import android.util.Log; import android.view.GestureDetector; import android.view.Gravity; @@ -36,8 +35,6 @@ import android.view.ViewGroup; import android.view.SoundEffectConstants; import android.view.ContextMenu.ContextMenuInfo; import android.view.animation.Transformation; -import android.widget.AbsSpinner; -import android.widget.Scroller; /** * A view that shows items in a center-locked, horizontally scrolling list. @@ -59,7 +56,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList private static final String TAG = "Gallery"; - private static final boolean localLOGV = Config.LOGV; + private static final boolean localLOGV = false; /** * Duration in milliseconds from the start of a scroll during which we're @@ -514,6 +511,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList // We haven't been callbacking during the fling, so do it now super.selectionChanged(); } + invalidate(); } @Override @@ -534,12 +532,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList int galleryCenter = getCenterOfGallery(); - if (selView != null) { - - // Common case where the current selected position is correct - if (selView.getLeft() <= galleryCenter && selView.getRight() >= galleryCenter) { - return; - } + // Common case where the current selected position is correct + if (selView.getLeft() <= galleryCenter && selView.getRight() >= galleryCenter) { + return; } // TODO better search @@ -627,7 +622,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList View sel = makeAndAddView(mSelectedPosition, 0, 0, true); // Put the selected child in the center - Gallery.LayoutParams lp = (Gallery.LayoutParams) sel.getLayoutParams(); int selectedOffset = childrenLeft + (childrenWidth / 2) - (sel.getWidth() / 2); sel.offsetLeftAndRight(selectedOffset); @@ -733,9 +727,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList child = mRecycler.get(position); if (child != null) { // Can reuse an existing view - Gallery.LayoutParams lp = (Gallery.LayoutParams) - child.getLayoutParams(); - int childLeft = child.getLeft(); // Remember left and right edges of where views have been placed @@ -798,7 +789,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList int childRight; // Position vertically based on gravity setting - int childTop = calculateTop(child, lp, true); + int childTop = calculateTop(child, true); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); @@ -817,11 +808,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * Figure out vertical placement based on mGravity * * @param child Child to place - * @param lp LayoutParams for this view (just so we don't keep looking them - * up) * @return Where the top of the child should be */ - private int calculateTop(View child, Gallery.LayoutParams lp, boolean duringLayout) { + private int calculateTop(View child, boolean duringLayout) { int myHeight = duringLayout ? mMeasuredHeight : getHeight(); int childHeight = duringLayout ? child.getMeasuredHeight() : child.getHeight(); diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index 582502488bb4..35b9251338e6 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -57,6 +57,13 @@ public class HandlerCaller { mCallback = callback; } + public HandlerCaller(Context context, Looper looper, Callback callback) { + mContext = context; + mMainLooper = looper; + mH = new MyHandler(mMainLooper); + mCallback = callback; + } + public SomeArgs obtainArgs() { synchronized (mH) { SomeArgs args = mArgsPool; diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 5357469a2f36..0bc70def2aec 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -20,6 +20,8 @@ import android.app.WallpaperManager; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.HandlerThread; +import android.os.Process; import android.service.wallpaper.WallpaperService; import android.view.MotionEvent; import android.view.SurfaceHolder; @@ -33,20 +35,29 @@ import android.content.BroadcastReceiver; */ public class ImageWallpaper extends WallpaperService { WallpaperManager mWallpaperManager; + private HandlerThread mThread; @Override public void onCreate() { super.onCreate(); mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); + mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND); + mThread.start(); + setCallbackLooper(mThread.getLooper()); } public Engine onCreateEngine() { return new DrawableEngine(); } + @Override + public void onDestroy() { + super.onDestroy(); + mThread.quit(); + } + class DrawableEngine extends Engine { private final Object mLock = new Object(); - private final Rect mBounds = new Rect(); private WallpaperObserver mReceiver; Drawable mBackground; float mXOffset; @@ -56,6 +67,9 @@ public class ImageWallpaper extends WallpaperService { public void onReceive(Context context, Intent intent) { updateWallpaper(); drawFrame(); + // Assume we are the only one using the wallpaper in this + // process, and force a GC now to release the old wallpaper. + System.gc(); } } @@ -67,7 +81,6 @@ public class ImageWallpaper extends WallpaperService { registerReceiver(mReceiver, filter); updateWallpaper(); surfaceHolder.setSizeFromLayout(); - //setTouchEventsEnabled(true); } @Override @@ -137,11 +150,7 @@ public class ImageWallpaper extends WallpaperService { void updateWallpaper() { synchronized (mLock) { - mBackground = mWallpaperManager.getDrawable(); - mBounds.left = mBounds.top = 0; - mBounds.right = mBackground.getIntrinsicWidth(); - mBounds.bottom = mBackground.getIntrinsicHeight(); - mBackground.setBounds(mBounds); + mBackground = mWallpaperManager.getFastDrawable(); } } } diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index f4f629785386..b8d19aca64a7 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -90,6 +90,12 @@ public class BaseIWindow extends IWindow.Stub { public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { } - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { + if (sync) { + try { + mSession.wallpaperOffsetsComplete(asBinder()); + } catch (RemoteException e) { + } + } } } diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 7748aba25a52..5b6c7ea13e8a 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -32,6 +32,7 @@ #include <sys/errno.h> #include <sys/resource.h> #include <sys/types.h> +#include <cutils/sched_policy.h> #include <dirent.h> #include <fcntl.h> #include <grp.h> @@ -186,58 +187,6 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name) return -1; } -static int add_pid_to_cgroup(int pid, const char *grp_name) -{ - int fd; - char path[255]; - char text[64]; - - sprintf(path, "/dev/cpuctl/%s/tasks", grp_name); - - if ((fd = open(path, O_WRONLY)) < 0) - return -1; - - sprintf(text, "%d", pid); - if (write(fd, text, strlen(text)) < 0) { - close(fd); - return -1; - } - - close(fd); - return 0; -} - -void setSchedPolicy(JNIEnv* env, jobject clazz, int pid, SchedPolicy policy) -{ - static int __sys_supports_schedgroups = -1; - - if (__sys_supports_schedgroups < 0) { - if (!access("/dev/cpuctl/tasks", F_OK)) { - __sys_supports_schedgroups = 1; - } else { - __sys_supports_schedgroups = 0; - } - } - - if (__sys_supports_schedgroups) { - const char *grp = NULL; - - if (policy == SP_BACKGROUND) { - grp = "bg_non_interactive"; - } - - if (add_pid_to_cgroup(pid, grp)) { - if (errno != ESRCH && errno != ENOENT) - signalExceptionForGroupError(env, clazz, errno); - } - } else { - struct sched_param param; - - param.sched_priority = 0; - sched_setscheduler(pid, (policy == SP_BACKGROUND) ? 5 : 0, ¶m); - } -} - void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp) { if (grp > ANDROID_TGROUP_MAX || grp < 0) { @@ -245,9 +194,10 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint return; } - setSchedPolicy(env, clazz, pid, - (grp == ANDROID_TGROUP_BG_NONINTERACT) ? - SP_BACKGROUND : SP_FOREGROUND); + if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ? + SP_BACKGROUND : SP_FOREGROUND)) { + signalExceptionForGroupError(env, clazz, errno); + } } void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) @@ -291,9 +241,10 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin continue; } - setSchedPolicy(env, clazz, t_pid, - (grp == ANDROID_TGROUP_BG_NONINTERACT) ? - SP_BACKGROUND : SP_FOREGROUND); + if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ? + SP_BACKGROUND : SP_FOREGROUND)) { + signalExceptionForGroupError(env, clazz, errno); + } } closedir(d); } @@ -301,10 +252,16 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz, jint pid, jint pri) { + int rc = 0; + if (pri >= ANDROID_PRIORITY_BACKGROUND) { - setSchedPolicy(env, clazz, pid, SP_BACKGROUND); + rc = set_sched_policy(pid, SP_BACKGROUND); } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) { - setSchedPolicy(env, clazz, pid, SP_FOREGROUND); + rc = set_sched_policy(pid, SP_FOREGROUND); + } + + if (rc) { + signalExceptionForGroupError(env, clazz, errno); } if (setpriority(PRIO_PROCESS, pid, pri) < 0) { diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h index 6181f5576097..8b0f154f5c99 100644 --- a/include/private/ui/SharedBufferStack.h +++ b/include/private/ui/SharedBufferStack.h @@ -228,6 +228,8 @@ private: friend struct Condition; friend struct DequeueCondition; friend struct LockCondition; + + int32_t computeTail() const; struct QueueUpdate : public UpdateBase { inline QueueUpdate(SharedBufferBase* sbb); diff --git a/include/utils/threads.h b/include/utils/threads.h index f5304f72bd7e..0fc533f9551c 100644 --- a/include/utils/threads.h +++ b/include/utils/threads.h @@ -90,11 +90,6 @@ enum { ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST, }; -typedef enum { - SP_BACKGROUND = 0, - SP_FOREGROUND = 1, -} SchedPolicy; - // Create and run a new thread. extern int androidCreateThread(android_thread_func_t, void *); diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 8685f9951f92..a352431f810b 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1524,13 +1524,24 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) result.append( l->lcblk->dump(" ") ); sp<const Buffer> buf0(l->getBuffer(0)); sp<const Buffer> buf1(l->getBuffer(1)); + uint32_t w0=0, h0=0, s0=0; + uint32_t w1=0, h1=0, s1=0; + if (buf0 != 0) { + w0 = buf0->getWidth(); + h0 = buf0->getHeight(); + s0 = buf0->getStride(); + } + if (buf1 != 0) { + w1 = buf1->getWidth(); + h1 = buf1->getHeight(); + s1 = buf1->getStride(); + } snprintf(buffer, SIZE, " " "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," " freezeLock=%p\n", l->pixelFormat(), - buf0->getWidth(), buf0->getHeight(), buf0->getStride(), - buf1->getWidth(), buf1->getHeight(), buf1->getStride(), + w0, h0, s0, w1, h1, s1, l->getFreezeLock().get()); result.append(buffer); buffer[0] = 0; diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp index 436d79320e9c..7789a3f8646f 100644 --- a/libs/ui/SharedBufferStack.cpp +++ b/libs/ui/SharedBufferStack.cpp @@ -246,19 +246,26 @@ SharedBufferClient::SharedBufferClient(SharedClient* sharedClient, int surface, int num) : SharedBufferBase(sharedClient, surface, num), tail(0) { + tail = computeTail(); +} + +int32_t SharedBufferClient::computeTail() const +{ SharedBufferStack& stack( *mSharedStack ); - int32_t avail; - int32_t head; // we need to make sure we read available and head coherently, // w.r.t RetireUpdate. + int32_t newTail; + int32_t avail; + int32_t head; do { avail = stack.available; head = stack.head; } while (stack.available != avail); - tail = head - avail + 1; - if (tail < 0) { - tail += num; + newTail = head - avail + 1; + if (newTail < 0) { + newTail += mNumBuffers; } + return newTail; } ssize_t SharedBufferClient::dequeue() @@ -296,6 +303,9 @@ status_t SharedBufferClient::undoDequeue(int buf) { UndoDequeueUpdate update(this); status_t err = updateCondition( update ); + if (err == NO_ERROR) { + tail = computeTail(); + } return err; } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index d905619159aa..22c2f3987929 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1266,6 +1266,8 @@ status_t OMXCodec::freeBuffersOnPort( CHECK_EQ(info->mOwnedByComponent, false); + CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); + status_t err = mOMX->free_buffer(mNode, portIndex, info->mBuffer); diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 38df47b41895..ba65f01ef686 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -63,7 +63,7 @@ import java.util.Observable; 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 @@ class PowerManagerService extends IPowerManager.Stub } 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 b0e40380e62f..c844de224d3f 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -418,6 +418,17 @@ public class WindowManagerService extends IWindowManager.Stub int mWallpaperAnimLayerAdjustment; float mLastWallpaperX; float mLastWallpaperY; + // Lock for waiting for the wallpaper. + final Object mWaitingOnWallpaperLock = new Object(); + // This is set when we are waiting for a wallpaper to tell us it is done + // changing its scroll position. + WindowState mWaitingOnWallpaper; + // The last time we had a timeout when waiting for a wallpaper. + long mLastWallpaperTimeoutTime; + // We give a wallpaper up to 150ms to finish scrolling. + static final long WALLPAPER_TIMEOUT = 150; + // Time we wait after a timeout before trying to wait again. + static final long WALLPAPER_TIMEOUT_RECOVERY = 10000; AppWindowToken mFocusedApp = null; @@ -1427,7 +1438,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh, false); } // First, make sure the client has the current visibility @@ -1498,7 +1509,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh) { + boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh, + boolean sync) { boolean changed = false; boolean rawChanged = false; if (mLastWallpaperX >= 0) { @@ -1536,8 +1548,37 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WALLPAPER) Log.v(TAG, "Report new wp offset " + wallpaperWin + " x=" + wallpaperWin.mWallpaperX + " y=" + wallpaperWin.mWallpaperY); + if (sync) { + synchronized (mWaitingOnWallpaperLock) { + mWaitingOnWallpaper = wallpaperWin; + } + } wallpaperWin.mClient.dispatchWallpaperOffsets( - wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY); + wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY, sync); + if (sync) { + synchronized (mWaitingOnWallpaperLock) { + if (mWaitingOnWallpaper != null) { + long start = SystemClock.uptimeMillis(); + if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY) + < start) { + try { + if (DEBUG_WALLPAPER) Log.v(TAG, + "Waiting for offset complete..."); + mWaitingOnWallpaperLock.wait(WALLPAPER_TIMEOUT); + } catch (InterruptedException e) { + } + if (DEBUG_WALLPAPER) Log.v(TAG, "Offset complete!"); + if ((start+WALLPAPER_TIMEOUT) + < SystemClock.uptimeMillis()) { + Log.i(TAG, "Timeout waiting for wallpaper to offset: " + + wallpaperWin); + mLastWallpaperTimeoutTime = start; + } + } + mWaitingOnWallpaper = null; + } + } + } } catch (RemoteException e) { } } @@ -1545,7 +1586,17 @@ public class WindowManagerService extends IWindowManager.Stub return changed; } - boolean updateWallpaperOffsetLocked() { + void wallpaperOffsetsComplete(IBinder window) { + synchronized (mWaitingOnWallpaperLock) { + if (mWaitingOnWallpaper != null && + mWaitingOnWallpaper.mClient.asBinder() == window) { + mWaitingOnWallpaper = null; + mWaitingOnWallpaperLock.notifyAll(); + } + } + } + + boolean updateWallpaperOffsetLocked(boolean sync) { final int dw = mDisplay.getWidth(); final int dh = mDisplay.getHeight(); @@ -1563,9 +1614,11 @@ public class WindowManagerService extends IWindowManager.Stub while (curWallpaperIndex > 0) { curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); - if (updateWallpaperOffsetLocked(wallpaper, dw, dh)) { + if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) { wallpaper.computeShownFrameLocked(); changed = true; + // We only want to be synchronous with one wallpaper. + sync = false; } } } @@ -1595,7 +1648,7 @@ public class WindowManagerService extends IWindowManager.Stub curWallpaperIndex--; WindowState wallpaper = token.windows.get(curWallpaperIndex); if (visible) { - updateWallpaperOffsetLocked(wallpaper, dw, dh); + updateWallpaperOffsetLocked(wallpaper, dw, dh, false); } if (wallpaper.mWallpaperVisible != visible) { @@ -1782,8 +1835,10 @@ public class WindowManagerService extends IWindowManager.Stub imMayMove = false; } else { addWindowToListInOrderLocked(win, true); - if (attrs.type == TYPE_WALLPAPER || - (attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { + if (attrs.type == TYPE_WALLPAPER) { + mLastWallpaperTimeoutTime = 0; + adjustWallpaperWindowsLocked(); + } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { adjustWallpaperWindowsLocked(); } } @@ -1992,8 +2047,10 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (win.mAttrs.type == TYPE_WALLPAPER || - (win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) { + if (win.mAttrs.type == TYPE_WALLPAPER) { + mLastWallpaperTimeoutTime = 0; + adjustWallpaperWindowsLocked(); + } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) { adjustWallpaperWindowsLocked(); } @@ -2070,7 +2127,7 @@ public class WindowManagerService extends IWindowManager.Stub window.mWallpaperY = y; if (mWallpaperTarget == window) { - if (updateWallpaperOffsetLocked()) { + if (updateWallpaperOffsetLocked(true)) { performLayoutAndPlaceSurfacesLocked(); } } @@ -2258,7 +2315,7 @@ public class WindowManagerService extends IWindowManager.Stub performLayoutAndPlaceSurfacesLocked(); if (displayed && win.mIsWallpaper) { updateWallpaperOffsetLocked(win, mDisplay.getWidth(), - mDisplay.getHeight()); + mDisplay.getHeight(), false); } if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); @@ -6303,6 +6360,10 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void wallpaperOffsetsComplete(IBinder window) { + WindowManagerService.this.wallpaperOffsetsComplete(window); + } + void windowAddedLocked() { if (mSurfaceSession == null) { if (localLOGV) Log.v( @@ -6698,7 +6759,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { updateWallpaperOffsetLocked(this, mDisplay.getWidth(), - mDisplay.getHeight()); + mDisplay.getHeight(), false); } if (localLOGV) { diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py index c3e6b5b48fa0..c3627bbf8fae 100755 --- a/tests/DumpRenderTree/assets/run_layout_tests.py +++ b/tests/DumpRenderTree/assets/run_layout_tests.py @@ -197,7 +197,17 @@ def main(options, args): logging.error("DumpRenderTree crashed, output:\n" + adb_output) shell_cmd_str = adb_cmd + " shell cat /sdcard/android/running_test.txt" - crashed_test = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE).communicate()[0] + crashed_test = "" + while not crashed_test: + (crashed_test, err) = subprocess.Popen( + shell_cmd_str, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + crashed_test = crashed_test.strip() + if not crashed_test: + logging.error('Cannot get crashed test name, device offline?') + logging.error('stderr: ' + err) + logging.error('retrying in 10s...') + time.sleep(10) logging.info(crashed_test + " CRASHED"); crashed_tests.append(crashed_test); diff --git a/tests/DumpRenderTree/assets/run_reliability_tests.py b/tests/DumpRenderTree/assets/run_reliability_tests.py index 23f93df8508e..59ac4a3344ef 100755 --- a/tests/DumpRenderTree/assets/run_reliability_tests.py +++ b/tests/DumpRenderTree/assets/run_reliability_tests.py @@ -195,8 +195,18 @@ def main(options, args): while not DumpRenderTreeFinished(adb_cmd): logging.error("DumpRenderTree exited before all URLs are visited.") shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE - crashed_test = subprocess.Popen(shell_cmd_str, shell=True, - stdout=subprocess.PIPE).communicate()[0] + crashed_test = "" + while not crashed_test: + (crashed_test, err) = subprocess.Popen( + shell_cmd_str, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + crashed_test = crashed_test.strip() + if not crashed_test: + logging.error('Cannot get crashed test name, device offline?') + logging.error('stderr: ' + err) + logging.error('retrying in 10s...') + time.sleep(10) + logging.info(crashed_test + " CRASHED") crashed_tests.append(crashed_test) Bugreport(crashed_test, bugreport_dir, adb_cmd) diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java index c562650f2a3d..4dbcfdc4a6ac 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 @@ public interface ILayoutBridge { * @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 @@ public interface ILayoutBridge { * @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 @@ public interface ILayoutBridge { * @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 @@ public interface ILayoutBridge { * @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 @@ public interface ILayoutBridge { * 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 5a06349ba9f2..2d8a210123fb 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 @@ import java.awt.image.BufferedImage; * {@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 @@ public interface ILayoutResult { * 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 55fe4ac84fa6..0888fd829f17 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -1051,15 +1051,22 @@ public final class Bridge implements ILayoutBridge { // pass for now. } + @SuppressWarnings("unused") public void setInsets(IWindow window, int touchable, Rect contentInsets, Rect visibleInsets) { // pass for now. } + @SuppressWarnings("unused") public void setWallpaperPosition(IBinder window, float x, float y) { // pass for now. } + @SuppressWarnings("unused") + public void wallpaperOffsetsComplete(IBinder window) { + // pass for now. + } + public IBinder asBinder() { // pass for now. return null; @@ -1114,7 +1121,7 @@ public final class Bridge implements ILayoutBridge { } @SuppressWarnings("unused") - public void dispatchWallpaperOffsets(float x, float y) { + public void dispatchWallpaperOffsets(float x, float y, boolean sync) { // pass for now. } |