Merge "For consistency with getAuthToken, pass UID/PID for add account. Needed for customizing the add account flow"
diff --git a/api/current.txt b/api/current.txt
index 804a524..c3f339f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23017,6 +23017,7 @@
     method public void scrollTo(int, int);
     method public void sendAccessibilityEvent(int);
     method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
+    method public void setAccessibilityDelegate(android.view.View.AccessibilityDelegate);
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
@@ -23193,6 +23194,17 @@
     field public static android.util.Property Y;
   }
 
+  public static class View.AccessibilityDelegate {
+    ctor public View.AccessibilityDelegate();
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, android.view.accessibility.AccessibilityNodeInfo);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
   public static class View.BaseSavedState extends android.view.AbsSavedState {
     ctor public View.BaseSavedState(android.os.Parcel);
     ctor public View.BaseSavedState(android.os.Parcelable);
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 0d4a067..be00aa5 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -915,6 +915,7 @@
                     com.android.internal.R.styleable.ActionBar_LayoutParams);
             gravity = a.getInt(
                     com.android.internal.R.styleable.ActionBar_LayoutParams_layout_gravity, -1);
+            a.recycle();
         }
 
         public LayoutParams(int width, int height) {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 9678d48..684c4fe 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -191,12 +191,6 @@
     private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds
     private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours
 
-    /**
-     * The amount of time (in milliseconds) to wait after attempting a bind
-     * before canceling a sync and disabling the sync adapter
-     */
-    public static final long BIND_TIMEOUT_MS = 5 * 60 * 1000;
-
     public void onAccountsUpdated(Account[] accounts) {
         // remember if this was the first time this was called after an update
         final boolean justBootedUp = mAccounts == INITIAL_ACCOUNTS_ARRAY;
@@ -1074,9 +1068,6 @@
             pw.print(" - ");
             pw.print(activeSyncContext.mSyncOperation.dump(false));
             pw.println();
-            if (activeSyncContext.mSyncAdapter == null) {
-                pw.println("   **** Waiting for onServiceConnected ****");
-            }
         }
 
         synchronized (mSyncQueue) {
@@ -1433,7 +1424,6 @@
         public void handleMessage(Message msg) {
             long earliestFuturePollTime = Long.MAX_VALUE;
             long nextPendingSyncTime = Long.MAX_VALUE;
-            long nextBindTimeoutTime = Long.MAX_VALUE;
 
             // Setting the value here instead of a method because we want the dumpsys logs
             // to have the most recent value used.
@@ -1441,7 +1431,6 @@
                 waitUntilReadyToRun();
                 mDataConnectionIsConnected = readDataConnectionState();
                 mSyncManagerWakeLock.acquire();
-                nextBindTimeoutTime = auditRunningSyncsForStuckBindsLocked();
                 // Always do this first so that we be sure that any periodic syncs that
                 // are ready to run have been converted into pending syncs. This allows the
                 // logic that considers the next steps to take based on the set of pending syncs
@@ -1543,7 +1532,6 @@
                         break;
                 }
             } finally {
-                nextPendingSyncTime = Math.min(nextBindTimeoutTime, nextPendingSyncTime);
                 manageSyncNotificationLocked();
                 manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime);
                 mSyncTimeTracker.update();
@@ -1552,36 +1540,6 @@
         }
 
         /**
-         * Looks to see if any of the active syncs have been waiting for a bind for too long,
-         * and if so the sync is canceled and the sync adapter is disabled for that account.
-         * @return the earliest time that an active sync can have waited too long to bind,
-         * relative to {@link android.os.SystemClock#elapsedRealtime()}.
-         */
-        private long auditRunningSyncsForStuckBindsLocked() {
-            final long now = SystemClock.elapsedRealtime();
-            long oldest = Long.MAX_VALUE;
-            for (ActiveSyncContext active : mActiveSyncContexts) {
-                if (active.mSyncAdapter == null) {
-                    final long timeoutTime = active.mStartTime + BIND_TIMEOUT_MS;
-                    if (timeoutTime < now) {
-                        Log.w(TAG, "canceling long-running bind and disabling sync for "
-                                + active.mSyncOperation.account + ", authority "
-                                + active.mSyncOperation.authority);
-                        runSyncFinishedOrCanceledLocked(null, active);
-                        ContentResolver.setIsSyncable(active.mSyncOperation.account,
-                                active.mSyncOperation.authority, 0);
-                    } else {
-                        if (oldest > timeoutTime) {
-                            oldest = timeoutTime;
-                        }
-                    }
-                }
-            }
-
-            return oldest;
-        }
-
-        /**
          * Turn any periodic sync operations that are ready to run into pending sync operations.
          * @return the desired start time of the earliest future  periodic sync operation,
          * in milliseconds since boot
@@ -1861,17 +1819,13 @@
                 synchronized (mSyncQueue){
                     mSyncQueue.remove(candidate);
                 }
-                ActiveSyncContext newSyncContext = dispatchSyncOperation(candidate);
-                if (newSyncContext != null) {
-                    nextReadyToRunTime = Math.min(nextReadyToRunTime,
-                            newSyncContext.mStartTime + BIND_TIMEOUT_MS);
-                }
+                dispatchSyncOperation(candidate);
             }
 
             return nextReadyToRunTime;
      }
 
-        private ActiveSyncContext dispatchSyncOperation(SyncOperation op) {
+        private boolean dispatchSyncOperation(SyncOperation op) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "dispatchSyncOperation: we are going to sync " + op);
                 Log.v(TAG, "num active syncs: " + mActiveSyncContexts.size());
@@ -1888,7 +1842,7 @@
                 Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                         + ", removing settings for it");
                 mSyncStorageEngine.removeAuthority(op.account, op.authority);
-                return null;
+                return false;
             }
 
             ActiveSyncContext activeSyncContext =
@@ -1901,10 +1855,10 @@
             if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo)) {
                 Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
                 closeActiveSyncContext(activeSyncContext);
-                return null;
+                return false;
             }
 
-            return activeSyncContext;
+            return true;
         }
 
         private void runBoundToSyncAdapter(final ActiveSyncContext activeSyncContext,
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c61e32f..e7b844c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -92,6 +92,7 @@
 
     private String mArchiveSourcePath;
     private String[] mSeparateProcesses;
+    private boolean mOnlyCoreApps;
     private static final int SDK_VERSION = Build.VERSION.SDK_INT;
     private static final String SDK_CODENAME = "REL".equals(Build.VERSION.CODENAME)
             ? null : Build.VERSION.CODENAME;
@@ -180,6 +181,10 @@
         mSeparateProcesses = procs;
     }
 
+    public void setOnlyCoreApps(boolean onlyCoreApps) {
+        mOnlyCoreApps = onlyCoreApps;
+    }
+
     private static final boolean isPackageFilename(String name) {
         return name.endsWith(".apk");
     }
@@ -433,18 +438,22 @@
 
 
         if (pkg == null) {
-            if (errorException != null) {
-                Slog.w(TAG, mArchiveSourcePath, errorException);
-            } else {
-                Slog.w(TAG, mArchiveSourcePath + " (at "
-                        + parser.getPositionDescription()
-                        + "): " + errorText[0]);
+            // If we are only parsing core apps, then a null with INSTALL_SUCCEEDED
+            // just means to skip this app so don't make a fuss about it.
+            if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) {
+                if (errorException != null) {
+                    Slog.w(TAG, mArchiveSourcePath, errorException);
+                } else {
+                    Slog.w(TAG, mArchiveSourcePath + " (at "
+                            + parser.getPositionDescription()
+                            + "): " + errorText[0]);
+                }
+                if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
+                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+                }
             }
             parser.close();
             assmgr.close();
-            if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
-                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            }
             return null;
         }
 
@@ -782,6 +791,14 @@
         }
         int type;
 
+        if (mOnlyCoreApps) {
+            boolean core = attrs.getAttributeBooleanValue(null, "coreApp", false);
+            if (!core) {
+                mParseError = PackageManager.INSTALL_SUCCEEDED;
+                return null;
+            }
+        }
+
         final Package pkg = new Package(pkgName);
         boolean foundApp = false;
         
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d7f901a..4f19010 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -72,6 +72,7 @@
     static final String TAG = "Resources";
     private static final boolean DEBUG_LOAD = false;
     private static final boolean DEBUG_CONFIG = false;
+    private static final boolean DEBUG_ATTRIBUTES_CACHE = false;
     private static final boolean TRACE_FOR_PRELOAD = false;
     private static final boolean TRACE_FOR_MISS_PRELOAD = false;
 
@@ -104,6 +105,7 @@
     private boolean mPreloading;
 
     /*package*/ TypedArray mCachedStyledAttributes = null;
+    RuntimeException mLastRetrievedAttrs = null;
 
     private int mLastCachedXmlBlockIndex = -1;
     private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 };
@@ -2167,6 +2169,10 @@
             TypedArray attrs = mCachedStyledAttributes;
             if (attrs != null) {
                 mCachedStyledAttributes = null;
+                if (DEBUG_ATTRIBUTES_CACHE) {
+                    mLastRetrievedAttrs = new RuntimeException("here");
+                    mLastRetrievedAttrs.fillInStackTrace();
+                }
 
                 attrs.mLength = len;
                 int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
@@ -2177,6 +2183,15 @@
                 attrs.mIndices = new int[1+len];
                 return attrs;
             }
+            if (DEBUG_ATTRIBUTES_CACHE) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                if (mLastRetrievedAttrs != null) {
+                    Log.i(TAG, "Allocated new TypedArray of " + len + " in " + this, here);
+                    Log.i(TAG, "Last retrieved attributes here", mLastRetrievedAttrs);
+                }
+                mLastRetrievedAttrs = here;
+            }
             return new TypedArray(this,
                     new int[len*AssetManager.STYLE_NUM_ENTRIES],
                     new int[1+len], len);
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index d07d899..d8ac31f 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -29,6 +29,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.MathUtils;
 
 import java.io.CharArrayWriter;
 import java.io.DataInputStream;
@@ -207,6 +208,34 @@
     }
 
     /**
+     * Return index of bucket that contains or is immediately before the
+     * requested time.
+     */
+    public int getIndexBefore(long time) {
+        int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
+        if (index < 0) {
+            index = (~index) - 1;
+        } else {
+            index -= 1;
+        }
+        return MathUtils.constrain(index, 0, bucketCount - 1);
+    }
+
+    /**
+     * Return index of bucket that contains or is immediately after the
+     * requested time.
+     */
+    public int getIndexAfter(long time) {
+        int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
+        if (index < 0) {
+            index = ~index;
+        } else {
+            index += 1;
+        }
+        return MathUtils.constrain(index, 0, bucketCount - 1);
+    }
+
+    /**
      * Return specific stats entry.
      */
     public Entry getValues(int i, Entry recycle) {
@@ -247,7 +276,8 @@
 
         // distribute data usage into buckets
         long duration = end - start;
-        for (int i = bucketCount - 1; i >= 0; i--) {
+        final int startIndex = getIndexAfter(end);
+        for (int i = startIndex; i >= 0; i--) {
             final long curStart = bucketStart[i];
             final long curEnd = curStart + bucketDuration;
 
@@ -406,7 +436,8 @@
         entry.txPackets = txPackets != null ? 0 : UNKNOWN;
         entry.operations = operations != null ? 0 : UNKNOWN;
 
-        for (int i = bucketCount - 1; i >= 0; i--) {
+        final int startIndex = getIndexAfter(end);
+        for (int i = startIndex; i >= 0; i--) {
             final long curStart = bucketStart[i];
             final long curEnd = curStart + bucketDuration;
 
@@ -417,8 +448,14 @@
 
             // include full value for active buckets, otherwise only fractional
             final boolean activeBucket = curStart < now && curEnd > now;
-            final long overlap = activeBucket ? bucketDuration
-                    : Math.min(curEnd, end) - Math.max(curStart, start);
+            final long overlap;
+            if (activeBucket) {
+                overlap = bucketDuration;
+            } else {
+                final long overlapEnd = curEnd < end ? curEnd : end;
+                final long overlapStart = curStart > start ? curStart : start;
+                overlap = overlapEnd - overlapStart;
+            }
             if (overlap <= 0) continue;
 
             // integer math each time is faster than floating point
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index eedf19f..1cc428b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -27,7 +27,6 @@
 import android.graphics.Interpolator;
 import android.graphics.LinearGradient;
 import android.graphics.Matrix;
-import android.graphics.Matrix.ScaleToFit;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -2272,8 +2271,6 @@
      */
     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
 
-    private Resources mResources = null;
-
     private Drawable mBGDrawable;
 
     private int mBackgroundResource;
@@ -2336,6 +2333,8 @@
      */
     protected Context mContext;
 
+    private final Resources mResources;
+
     private ScrollabilityCache mScrollCache;
 
     private int[] mDrawableState = null;
@@ -2552,6 +2551,11 @@
     private boolean mSendingHoverAccessibilityEvents;
 
     /**
+     * Delegate for injecting accessiblity functionality.
+     */
+    AccessibilityDelegate mAccessibilityDelegate;
+
+    /**
      * Text direction is inherited thru {@link ViewGroup}
      * @hide
      */
@@ -3012,6 +3016,8 @@
             }
         }
 
+        a.recycle();
+
         setOverScrollMode(overScrollMode);
 
         if (background != null) {
@@ -3069,14 +3075,13 @@
         }
 
         computeOpaqueFlags();
-
-        a.recycle();
     }
 
     /**
      * Non-public constructor for use in testing
      */
     View() {
+        mResources = null;
     }
 
     /**
@@ -3774,14 +3779,34 @@
      * and last calls
      * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
      * on its parent to resuest sending of the event to interested parties.
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is
+     * responsible for handling this call.
+     * </p>
      *
      * @param eventType The type of the event to send.
      *
      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
      * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)
+     * @see AccessibilityDelegate
      */
     public void sendAccessibilityEvent(int eventType) {
+        if (mAccessibilityDelegate != null) {
+            mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
+        } else {
+            sendAccessibilityEventInternal(eventType);
+        }
+    }
+
+    /**
+     * @see #sendAccessibilityEvent(int)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    void sendAccessibilityEventInternal(int eventType) {
         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
             sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
         }
@@ -3790,13 +3815,32 @@
     /**
      * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but
      * takes as an argument an empty {@link AccessibilityEvent} and does not
-     * perfrom a check whether accessibility is enabled.
+     * perform a check whether accessibility is enabled.
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)}
+     * is responsible for handling this call.
+     * </p>
      *
      * @param event The event to send.
      *
      * @see #sendAccessibilityEvent(int)
      */
     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
+        if (mAccessibilityDelegate != null) {
+           mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
+        } else {
+            sendAccessibilityEventUncheckedInternal(event);
+        }
+    }
+
+    /**
+     * @see #sendAccessibilityEventUnchecked(AccessibilityEvent)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
         if (!isShown()) {
             return;
         }
@@ -3811,18 +3855,36 @@
      * to its children for adding their text content to the event. Note that the
      * event text is populated in a separate dispatch path since we add to the
      * event not only the text of the source but also the text of all its descendants.
-     * </p>
      * A typical implementation will call
      * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
      * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
      * on each child. Override this method if custom population of the event text
      * content is required.
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
+     * is responsible for handling this call.
+     * </p>
      *
      * @param event The event.
      *
      * @return True if the event population was completed.
      */
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (mAccessibilityDelegate != null) {
+            return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event);
+        } else {
+            return dispatchPopulateAccessibilityEventInternal(event);
+        }
+    }
+
+    /**
+     * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
         onPopulateAccessibilityEvent(event);
         return false;
     }
@@ -3845,6 +3907,12 @@
      *     event.getText().add(selectedDateUtterance);
      * }
      * </code></pre></p>
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
+     * is responsible for handling this call.
+     * </p>
      *
      * @param event The accessibility event which to populate.
      *
@@ -3852,13 +3920,27 @@
      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
      */
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (mAccessibilityDelegate != null) {
+            mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event);
+        } else {
+            onPopulateAccessibilityEventInternal(event);
+        }
     }
 
     /**
-     * Initializes an {@link AccessibilityEvent} with information about the
-     * the type of the event and this View which is the event source. In other
-     * words, the source of an accessibility event is the view whose state
-     * change triggered firing the event.
+     * @see #onPopulateAccessibilityEvent(AccessibilityEvent)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
+
+    }
+
+    /**
+     * Initializes an {@link AccessibilityEvent} with information about
+     * this View which is the event source. In other words, the source of
+     * an accessibility event is the view whose state change triggered firing
+     * the event.
      * <p>
      * Example: Setting the password property of an event in addition
      *          to properties set by the super implementation.
@@ -3868,12 +3950,32 @@
      *    event.setPassword(true);
      * }
      * </code></pre></p>
-     * @param event The event to initialeze.
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
+     * is responsible for handling this call.
+     * </p>
+     *
+     * @param event The event to initialize.
      *
      * @see #sendAccessibilityEvent(int)
      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
      */
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        if (mAccessibilityDelegate != null) {
+            mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
+        } else {
+            onInitializeAccessibilityEventInternal(event);
+        }
+    }
+
+    /**
+     * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
         event.setSource(this);
         event.setClassName(getClass().getName());
         event.setPackageName(getContext().getPackageName());
@@ -3942,9 +4044,29 @@
      * Subclasses should override this method, call the super implementation,
      * and set additional attributes.
      * </p>
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)}
+     * is responsible for handling this call.
+     * </p>
+     *
      * @param info The instance to initialize.
      */
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        if (mAccessibilityDelegate != null) {
+            mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info);
+        } else {
+            onInitializeAccessibilityNodeInfoInternal(info);
+        }
+    }
+
+    /**
+     * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
+     *
+     * Note: Called from the default {@link AccessibilityDelegate}.
+     */
+    void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         Rect bounds = mAttachInfo.mTmpInvalRect;
         getDrawingRect(bounds);
         info.setBoundsInParent(bounds);
@@ -3988,6 +4110,19 @@
     }
 
     /**
+     * Sets a delegate for implementing accessibility support via compositon as
+     * opposed to inheritance. The delegate's primary use is for implementing
+     * backwards compatible widgets. For more details see {@link AccessibilityDelegate}.
+     *
+     * @param delegate The delegate instance.
+     *
+     * @see AccessibilityDelegate
+     */
+    public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
+        mAccessibilityDelegate = delegate;
+    }
+
+    /**
      * Gets the unique identifier of this view on the screen for accessibility purposes.
      * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
      *
@@ -10192,7 +10327,7 @@
 
     /**
      * Setting a solid background color for the drawing cache's bitmaps will improve
-     * perfromance and memory usage. Note, though that this should only be used if this
+     * performance and memory usage. Note, though that this should only be used if this
      * view will always be drawn on top of a solid color.
      *
      * @param color The background color to use for the drawing cache's bitmap
@@ -14417,4 +14552,205 @@
             mIsPending = false;
         }
     }
+
+    /**
+     * <p>
+     * This class represents a delegate that can be registered in a {@link View}
+     * to enhance accessibility support via composition rather via inheritance.
+     * It is specifically targeted to widget developers that extend basic View
+     * classes i.e. classes in package android.view, that would like their
+     * applications to be backwards compatible.
+     * </p>
+     * <p>
+     * A scenario in which a developer would like to use an accessibility delegate
+     * is overriding a method introduced in a later API version then the minimal API
+     * version supported by the application. For example, the method
+     * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
+     * in API version 4 when the accessibility APIs were first introduced. If a
+     * developer would like his application to run on API version 4 devices (assuming
+     * all other APIs used by the application are version 4 or lower) and take advantage
+     * of this method, instead of overriding the method which would break the application's
+     * backwards compatibility, he can override the corresponding method in this
+     * delegate and register the delegate in the target View if the API version of
+     * the system is high enough i.e. the API version is same or higher to the API
+     * version that introduced
+     * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}.
+     * </p>
+     * <p>
+     * Here is an example implementation:
+     * </p>
+     * <code><pre><p>
+     * if (Build.VERSION.SDK_INT >= 14) {
+     *     // If the API version is equal of higher than the version in
+     *     // which onInitializeAccessibilityNodeInfo was introduced we
+     *     // register a delegate with a customized implementation.
+     *     View view = findViewById(R.id.view_id);
+     *     view.setAccessibilityDelegate(new AccessibilityDelegate() {
+     *         public void onInitializeAccessibilityNodeInfo(View host,
+     *                 AccessibilityNodeInfo info) {
+     *             // Let the default implementation populate the info.
+     *             super.onInitializeAccessibilityNodeInfo(host, info);
+     *             // Set some other information.
+     *             info.setEnabled(host.isEnabled());
+     *         }
+     *     });
+     * }
+     * </code></pre></p>
+     * <p>
+     * This delegate contains methods that correspond to the accessibility methods
+     * in View. If a delegate has been specified the implementation in View hands
+     * off handling to the corresponding method in this delegate. The default
+     * implementation the delegate methods behaves exactly as the corresponding
+     * method in View for the case of no accessibility delegate been set. Hence,
+     * to customize the behavior of a View method, clients can override only the
+     * corresponding delegate method without altering the behavior of the rest
+     * accessibility related methods of the host view.
+     * </p>
+     */
+    public static class AccessibilityDelegate {
+
+        /**
+         * Sends an accessibility event of the given type. If accessibility is not
+         * enabled this method has no effect.
+         * <p>
+         * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
+         *  View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
+         * been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param eventType The type of the event to send.
+         *
+         * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
+         */
+        public void sendAccessibilityEvent(View host, int eventType) {
+            host.sendAccessibilityEventInternal(eventType);
+        }
+
+        /**
+         * Sends an accessibility event. This method behaves exactly as
+         * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
+         * empty {@link AccessibilityEvent} and does not perform a check whether
+         * accessibility is enabled.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
+         *  View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param event The event to send.
+         *
+         * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
+         *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
+         */
+        public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
+            host.sendAccessibilityEventUncheckedInternal(event);
+        }
+
+        /**
+         * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
+         * to its children for adding their text content to the event.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+         *  View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param event The event.
+         * @return True if the event population was completed.
+         *
+         * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+         *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+         */
+        public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+            return host.dispatchPopulateAccessibilityEventInternal(event);
+        }
+
+        /**
+         * Gives a chance to the host View to populate the accessibility event with its
+         * text content.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)
+         *  View#onPopulateAccessibilityEvent(AccessibilityEvent)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param event The accessibility event which to populate.
+         *
+         * @see View#onPopulateAccessibilityEvent(AccessibilityEvent)
+         *      View#onPopulateAccessibilityEvent(AccessibilityEvent)
+         */
+        public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+            host.onPopulateAccessibilityEventInternal(event);
+        }
+
+        /**
+         * Initializes an {@link AccessibilityEvent} with information about the
+         * the host View which is the event source.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)
+         *  View#onInitializeAccessibilityEvent(AccessibilityEvent)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param event The event to initialize.
+         *
+         * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
+         *      View#onInitializeAccessibilityEvent(AccessibilityEvent)
+         */
+        public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+            host.onInitializeAccessibilityEventInternal(event);
+        }
+
+        /**
+         * Initializes an {@link AccessibilityNodeInfo} with information about the host view.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
+         *  View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param info The instance to initialize.
+         *
+         * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
+         *      View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
+         */
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            host.onInitializeAccessibilityNodeInfoInternal(info);
+        }
+
+        /**
+         * Called when a child of the host View has requested sending an
+         * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
+         * to augment the event.
+         * <p>
+         * The default implementation behaves as
+         * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
+         *  ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         *
+         * @param host The View hosting the delegate.
+         * @param child The child which requests sending the event.
+         * @param event The event to be sent.
+         * @return True if the event should be sent
+         *
+         * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
+         *      ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
+         */
+        public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
+                AccessibilityEvent event) {
+            return host.onRequestSendAccessibilityEventInternal(child, event);
+        }
+    }
 }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0e420d6..1bd0782 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -34,6 +34,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.View.AccessibilityDelegate;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Animation;
@@ -606,6 +607,12 @@
     /**
      * Called when a child has requested sending an {@link AccessibilityEvent} and
      * gives an opportunity to its parent to augment the event.
+     * <p>
+     * If an {@link AccessibilityDelegate} has been specified via calling
+     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+     * {@link AccessibilityDelegate#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)}
+     * is responsible for handling this call.
+     * </p>
      *
      * @param child The child which requests sending the event.
      * @param event The event to be sent.
@@ -614,6 +621,19 @@
      * @see #requestSendAccessibilityEvent(View, AccessibilityEvent)
      */
     public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+        if (mAccessibilityDelegate != null) {
+            return mAccessibilityDelegate.onRequestSendAccessibilityEvent(this, child, event);
+        } else {
+            return onRequestSendAccessibilityEventInternal(child, event);
+        }
+    }
+
+    /**
+     * @see #onRequestSendAccessibilityEvent(View, AccessibilityEvent)
+     *
+     * Note: Called from the default {@link View.AccessibilityDelegate}.
+     */
+    boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
         return true;
     }
 
@@ -2142,9 +2162,9 @@
     }
 
     @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+    boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
         // We first get a chance to populate the event.
-        onPopulateAccessibilityEvent(event);
+        super.dispatchPopulateAccessibilityEventInternal(event);
         // Let our children have a shot in populating the event.
         for (int i = 0, count = getChildCount(); i < count; i++) {
             View child = getChildAt(i);
@@ -2159,8 +2179,8 @@
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
+    void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoInternal(info);
         // If the view is not the topmost one in the view hierarchy and it is
         // marked as the logical root of a view hierarchy, do not go any deeper.
         if ((!(getParent() instanceof ViewRootImpl)) && (mPrivateFlags & IS_ROOT_NAMESPACE) != 0) {
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index c1eec6f..0d57c9b 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -232,11 +232,6 @@
         setFillBefore(a.getBoolean(com.android.internal.R.styleable.Animation_fillBefore, mFillBefore));
         setFillAfter(a.getBoolean(com.android.internal.R.styleable.Animation_fillAfter, mFillAfter));
 
-        final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);
-        if (resID > 0) {
-            setInterpolator(context, resID);
-        }
-
         setRepeatCount(a.getInt(com.android.internal.R.styleable.Animation_repeatCount, mRepeatCount));
         setRepeatMode(a.getInt(com.android.internal.R.styleable.Animation_repeatMode, RESTART));
 
@@ -245,10 +240,16 @@
         setBackgroundColor(a.getInt(com.android.internal.R.styleable.Animation_background, 0));
 
         setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
-        
-        ensureInterpolator();
+
+        final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);
 
         a.recycle();
+
+        if (resID > 0) {
+            setInterpolator(context, resID);
+        }
+
+        ensureInterpolator();
     }
 
     @Override
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 77f6776..9c44138 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -643,10 +643,10 @@
 
     /**
      * Set whether the WebView will enable smooth transition while panning or
-     * zooming. If it is true, WebView will choose a solution to maximize the
-     * performance. e.g. the WebView's content may not be updated during the
-     * transition. If it is false, WebView will keep its fidelity. The default
-     * value is false.
+     * zooming or while the window hosting the WebView does not have focus.
+     * If it is true, WebView will choose a solution to maximize the performance.
+     * e.g. the WebView's content may not be updated during the transition.
+     * If it is false, WebView will keep its fidelity. The default value is false.
      */
     public void setEnableSmoothTransition(boolean enable) {
         mEnableSmoothTransition = enable;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 47abbc2..065beb1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -908,6 +908,9 @@
     // used for serializing asynchronously handled touch events.
     private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
 
+    // Used to track whether picture updating was paused due to a window focus change.
+    private boolean mPictureUpdatePausedForFocusChange = false;
+
     // Used to notify listeners of a new picture.
     private PictureListener mPictureListener;
     /**
@@ -5570,8 +5573,20 @@
         setActive(hasWindowFocus);
         if (hasWindowFocus) {
             JWebCoreJavaBridge.setActiveWebView(this);
+            if (mPictureUpdatePausedForFocusChange) {
+                WebViewCore.resumeUpdatePicture(mWebViewCore);
+                nativeSetIsScrolling(false);
+                mPictureUpdatePausedForFocusChange = false;
+            }
         } else {
             JWebCoreJavaBridge.removeActiveWebView(this);
+            final WebSettings settings = getSettings();
+            if (settings != null && settings.enableSmoothTransition() &&
+                    mWebViewCore != null && !WebViewCore.isUpdatePicturePaused(mWebViewCore)) {
+                WebViewCore.pauseUpdatePicture(mWebViewCore);
+                nativeSetIsScrolling(true);
+                mPictureUpdatePausedForFocusChange = true;
+            }
         }
         super.onWindowFocusChanged(hasWindowFocus);
     }
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c61bd48..843a624 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2107,6 +2107,10 @@
         }
     }
 
+    static boolean isUpdatePicturePaused(WebViewCore core) {
+        return core != null ? core.mDrawIsPaused : false;
+    }
+
     //////////////////////////////////////////////////////////////////////////
 
     private void restoreState(int index) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index d7fb7a0..353d83c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3774,6 +3774,10 @@
                 }
                 // Fall through
             case TOUCH_MODE_FLING: {
+                if (mDataChanged) {
+                    layoutChildren();
+                }
+
                 if (mItemCount == 0 || getChildCount() == 0) {
                     endFling();
                     return;
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 2d10bbe..72db8e8 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -896,6 +896,7 @@
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
         // We send selection events only from AdapterView to avoid
         // generation of such event for each child.
         getSelectedView().dispatchPopulateAccessibilityEvent(event);
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 7598e54..0a54743 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -26,6 +26,7 @@
 import android.view.Gravity;
 import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 
 /**
@@ -231,4 +232,10 @@
             event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
         }
     }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setChecked(mChecked);
+    }
 }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index b92130d..a5d6c9a 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -212,6 +212,7 @@
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
         CharSequence contentDescription = getContentDescription();
         if (!TextUtils.isEmpty(contentDescription)) {
             event.getText().add(contentDescription);
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 191c4ca..80bfe99 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -489,6 +489,7 @@
     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
         // this class fires events only when tabs are focused or selected
         if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && isFocused()) {
+            event.recycle();
             return;
         }
         super.sendAccessibilityEventUnchecked(event);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b948114..70d2bd7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -461,10 +461,6 @@
         mMovement = getDefaultMovementMethod();
         mTransformation = null;
 
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
-
         int textColorHighlight = 0;
         ColorStateList textColor = null;
         ColorStateList textColorHint = null;
@@ -474,18 +470,23 @@
         int styleIndex = -1;
         boolean allCaps = false;
 
+        final Resources.Theme theme = context.getTheme();
+
         /*
          * Look the appearance up without checking first if it exists because
          * almost every TextView has one and it greatly simplifies the logic
          * to be able to parse the appearance first and then let specific tags
          * for this View override it.
          */
+        TypedArray a = theme.obtainStyledAttributes(
+                    attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);
         TypedArray appearance = null;
-        int ap = a.getResourceId(com.android.internal.R.styleable.TextView_textAppearance, -1);
+        int ap = a.getResourceId(
+                com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
+        a.recycle();
         if (ap != -1) {
-            appearance = context.obtainStyledAttributes(ap,
-                                com.android.internal.R.styleable.
-                                TextAppearance);
+            appearance = theme.obtainStyledAttributes(
+                    ap, com.android.internal.R.styleable.TextAppearance);
         }
         if (appearance != null) {
             int n = appearance.getIndexCount();
@@ -552,6 +553,9 @@
         boolean password = false;
         int inputType = EditorInfo.TYPE_NULL;
 
+        a = theme.obtainStyledAttributes(
+                    attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
+
         int n = a.getIndexCount();
         for (int i = 0; i < n; i++) {
             int attr = a.getIndex(i);
@@ -3102,6 +3106,11 @@
             text = "";
         }
 
+        // If suggestions are not enabled, remove the suggestion spans from the text
+        if (!isSuggestionsEnabled()) {
+            text = removeSuggestionSpans(text);
+        }
+
         if (!mUserSetTextScaleX) mTextPaint.setTextScaleX(1.0f);
 
         if (text instanceof Spanned &&
@@ -3503,6 +3512,10 @@
             applySingleLine(singleLine, !isPassword, true);
         }
         
+        if (!isSuggestionsEnabled()) {
+            mText = removeSuggestionSpans(mText);
+        }
+
         InputMethodManager imm = InputMethodManager.peekInstance();
         if (imm != null) imm.restartInput(this);
     }
@@ -9923,9 +9936,28 @@
         }
     }
 
-    void showSuggestions() {
-        if (!isSuggestionsEnabled() || !isTextEditable()) return;
+    /**
+     * Removes the suggestion spans.
+     */
+    CharSequence removeSuggestionSpans(CharSequence text) {
+       if (text instanceof Spanned) {
+           Spannable spannable;
+           if (text instanceof Spannable) {
+               spannable = (Spannable) text;
+           } else {
+               spannable = new SpannableString(text);
+               text = spannable;
+           }
 
+           SuggestionSpan[] spans = spannable.getSpans(0, text.length(), SuggestionSpan.class);
+           for (int i = 0; i < spans.length; i++) {
+               spannable.removeSpan(spans[i]);
+           }
+       }
+       return text;
+    }
+
+    void showSuggestions() {
         if (mSuggestionsPopupWindow == null) {
             mSuggestionsPopupWindow = new SuggestionsPopupWindow();
         }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 7434df3a..bbecb6c 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -268,8 +268,10 @@
 
         if (mTabScrollView != null && mIncludeTabs) {
             ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
-            lp.width = LayoutParams.WRAP_CONTENT;
-            lp.height = LayoutParams.MATCH_PARENT;
+            if (lp != null) {
+                lp.width = LayoutParams.WRAP_CONTENT;
+                lp.height = LayoutParams.MATCH_PARENT;
+            }
             mTabScrollView.setAllowCollapse(true);
         }
     }
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 0335ce7..e8933fe 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -1562,8 +1562,8 @@
         LOG_AND_FREE_DBUS_ERROR(&err);
     }
 
-    LOGV("... Health Device Code = %d, result = %d", code, result);
     jint code = *(int *) user;
+    LOGV("... Health Device Code = %d, result = %d", code, result);
     env->CallVoidMethod(nat->me,
                         method_onHealthDeviceConnectionResult,
                         code,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 72863a2..9f2eef5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -18,7 +18,7 @@
 */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android" android:sharedUserId="android.uid.system"
+    package="android" coreApp="true" android:sharedUserId="android.uid.system"
     android:sharedUserLabel="@string/android_system_label">
 
     <!-- ================================================ -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fc84f53..c990125 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3177,6 +3177,10 @@
         <!-- Present the text in ALL CAPS. This may use a small-caps form when available. -->
         <attr name="textAllCaps" />
     </declare-styleable>
+    <declare-styleable name="TextViewAppearance">
+        <!-- Base text color, typeface, size, and style. -->
+        <attr name="textAppearance" />
+    </declare-styleable>
     <declare-styleable name="SuggestionSpan">
         <attr name="textUnderlineColor" />
         <attr name="textUnderlineThickness" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 051ed14..8fd2cd1 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -385,6 +385,9 @@
     <!-- Default value for LED on time when the battery is low on charge in miliseconds -->
     <integer name="config_notificationsBatteryLedOn">125</integer>
 
+    <!-- Is the notification LED intrusive? Used to decide if there should be a disable option -->
+    <bool name="config_intrusiveNotificationLed">false</bool>
+
     <!-- Default value for LED off time when the battery is low on charge in miliseconds -->
     <integer name="config_notificationsBatteryLedOff">2875</integer>
 
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
index b888d9a..e1db073 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
@@ -407,6 +407,54 @@
         assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40));
     }
 
+    public void testIndexBeforeAfter() throws Exception {
+        final long BUCKET_SIZE = HOUR_IN_MILLIS;
+        stats = new NetworkStatsHistory(BUCKET_SIZE);
+
+        final long FIRST_START = TEST_START;
+        final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS);
+        final long SECOND_START = TEST_START + WEEK_IN_MILLIS;
+        final long SECOND_END = SECOND_START + HOUR_IN_MILLIS;
+        final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS);
+        final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS);
+
+        stats.recordData(FIRST_START, FIRST_END,
+                new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
+        stats.recordData(SECOND_START, SECOND_END,
+                new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
+        stats.recordData(THIRD_START, THIRD_END,
+                new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
+
+        // should have buckets: 2+1+2
+        assertEquals(5, stats.size());
+
+        assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE);
+        assertIndexBeforeAfter(stats, 0, 1, FIRST_START);
+        assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 1, 2, FIRST_END);
+        assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 1, 3, SECOND_START);
+        assertIndexBeforeAfter(stats, 2, 3, SECOND_END);
+        assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 2, 4, THIRD_START);
+        assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 4, 4, THIRD_END);
+        assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS);
+        assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE);
+    }
+
+    private static void assertIndexBeforeAfter(
+            NetworkStatsHistory stats, int before, int after, long time) {
+        assertEquals("unexpected before", before, stats.getIndexBefore(time));
+        assertEquals("unexpected after", after, stats.getIndexAfter(time));
+    }
+
     private static long performVarLong(long before) throws Exception {
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
         writeVarLong(new DataOutputStream(out), before);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index ee65223..ce42612 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -20,7 +20,6 @@
 import android.text.SpannableString;
 import android.text.SpannedString;
 import android.text.TextUtils;
-import android.util.DisplayMetrics;
 
 /**
  * The Paint class holds the style and color information about how to draw
@@ -344,8 +343,10 @@
     public Paint(int flags) {
         mNativePaint = native_init();
         setFlags(flags | DEFAULT_PAINT_FLAGS);
-        setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
-                ? HINTING_OFF : HINTING_ON);
+        // TODO: Turning off hinting has undesirable side effects, we need to
+        //       revisit hinting once we add support for subpixel positioning
+        // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
+        //        ? HINTING_OFF : HINTING_ON);
         mCompatScaling = mInvCompatScaling = 1;
     }
 
@@ -365,8 +366,10 @@
     public void reset() {
         native_reset(mNativePaint);
         setFlags(DEFAULT_PAINT_FLAGS);
-        setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
-                ? HINTING_OFF : HINTING_ON);
+        // TODO: Turning off hinting has undesirable side effects, we need to
+        //       revisit hinting once we add support for subpixel positioning
+        // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
+        //        ? HINTING_OFF : HINTING_ON);
         mHasCompatScaling = false;
         mCompatScaling = mInvCompatScaling = 1;
         mBidiFlags = BIDI_DEFAULT_LTR;
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 7c4e147..34f9070 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -79,7 +79,7 @@
         float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
         float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
 
-        canvas.rotate(mCurrentDegrees, px, py);
+        canvas.rotate(mCurrentDegrees, px + bounds.left, py + bounds.top);
 
         drawable.draw(canvas);
 
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index e965f14..b7286e5 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -164,6 +164,8 @@
 
     void sendFormatChange();
 
+    void signalError(OMX_ERRORTYPE error = OMX_ErrorUndefined);
+
     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
 };
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 8f213da..bf83849 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -26,6 +26,9 @@
 
 namespace android {
 
+// static
+const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
+
 NuPlayer::Renderer::Renderer(
         const sp<MediaPlayerBase::AudioSink> &sink,
         const sp<AMessage> &notify)
@@ -43,7 +46,8 @@
       mHasAudio(false),
       mHasVideo(false),
       mSyncQueues(false),
-      mPaused(false) {
+      mPaused(false),
+      mLastPositionUpdateUs(-1ll) {
 }
 
 NuPlayer::Renderer::~Renderer() {
@@ -190,7 +194,7 @@
     mDrainAudioQueuePending = true;
     sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
     msg->setInt32("generation", mAudioQueueGeneration);
-    msg->post(10000);
+    msg->post();
 }
 
 void NuPlayer::Renderer::signalAudioSinkChanged() {
@@ -198,7 +202,6 @@
 }
 
 void NuPlayer::Renderer::onDrainAudioQueue() {
-
     for (;;) {
         if (mAudioQueue.empty()) {
             break;
@@ -562,6 +565,13 @@
     }
 
     int64_t nowUs = ALooper::GetNowUs();
+
+    if (mLastPositionUpdateUs >= 0
+            && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs) {
+        return;
+    }
+    mLastPositionUpdateUs = nowUs;
+
     int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs;
 
     sp<AMessage> notify = mNotify->dup();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 2713031..3a641a2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -74,6 +74,8 @@
         status_t mFinalResult;
     };
 
+    static const int64_t kMinPositionUpdateDelayUs;
+
     sp<MediaPlayerBase::AudioSink> mAudioSink;
     sp<AMessage> mNotify;
     List<QueueEntry> mAudioQueue;
@@ -98,6 +100,8 @@
 
     bool mPaused;
 
+    int64_t mLastPositionUpdateUs;
+
     void onDrainAudioQueue();
     void postDrainAudioQueue();
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e9dc61c..2ba2273 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1131,6 +1131,13 @@
     mSentFormat = true;
 }
 
+void ACodec::signalError(OMX_ERRORTYPE error) {
+    sp<AMessage> notify = mNotify->dup();
+    notify->setInt32("what", ACodec::kWhatError);
+    notify->setInt32("omx-error", error);
+    notify->post();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
@@ -1252,10 +1259,7 @@
 
     LOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
 
-    sp<AMessage> notify = mCodec->mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatError);
-    notify->setInt32("omx-error", data1);
-    notify->post();
+    mCodec->signalError((OMX_ERRORTYPE)data1);
 
     return true;
 }
@@ -1548,12 +1552,14 @@
             && msg->findInt32("render", &render) && render != 0) {
         // The client wants this buffer to be rendered.
 
-        CHECK_EQ(mCodec->mNativeWindow->queueBuffer(
+        if (mCodec->mNativeWindow->queueBuffer(
                     mCodec->mNativeWindow.get(),
-                    info->mGraphicBuffer.get()),
-                 0);
-
-        info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
+                    info->mGraphicBuffer.get()) == OK) {
+            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
+        } else {
+            mCodec->signalError();
+            info->mStatus = BufferInfo::OWNED_BY_US;
+        }
     } else {
         info->mStatus = BufferInfo::OWNED_BY_US;
     }
@@ -1692,11 +1698,7 @@
     if (node == NULL) {
         LOGE("Unable to instantiate a decoder for type '%s'.", mime.c_str());
 
-        sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatError);
-        notify->setInt32("omx-error", OMX_ErrorComponentNotFound);
-        notify->post();
-
+        mCodec->signalError(OMX_ErrorComponentNotFound);
         return;
     }
 
@@ -1744,10 +1746,7 @@
              "(error 0x%08x)",
              err);
 
-        sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatError);
-        notify->setInt32("omx-error", OMX_ErrorUndefined);
-        notify->post();
+        mCodec->signalError();
     }
 }
 
@@ -2063,10 +2062,7 @@
                          "port reconfiguration (error 0x%08x)",
                          err);
 
-                    sp<AMessage> notify = mCodec->mNotify->dup();
-                    notify->setInt32("what", ACodec::kWhatError);
-                    notify->setInt32("omx-error", OMX_ErrorUndefined);
-                    notify->post();
+                    mCodec->signalError();
                 }
 
                 return true;
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index 6313ca3..62d17da 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -911,7 +911,11 @@
 
     if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
         mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
-        *confidence = 0.2;
+
+        // Just a tad over the mp3 extractor's confidence, since
+        // these .avi files may contain .mp3 content that otherwise would
+        // mistakenly lead to us identifying the entire file as a .mp3 file.
+        *confidence = 0.21;
 
         return true;
     }
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index 0f47482..319eb8d 100755
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.defcontainer">
+        package="com.android.defcontainer" coreApp="true">
     <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
     <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS"/>
     <uses-permission android:name="android.permission.ASEC_ACCESS"/>
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index dd0d064..0719426 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.providers.settings"
+        coreApp="true"
         android:sharedUserId="android.uid.system">
 
     <application android:allowClearUserData="false"
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d10911f..a2452c4 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.systemui"
+        coreApp="true"
         android:sharedUserId="android.uid.system"
         android:process="system"
         >
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index eae3e52..167d362 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -42,6 +42,7 @@
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:visibility="invisible"
             />
         </FrameLayout>
 
@@ -71,6 +72,7 @@
             android:singleLine="true"
             android:ellipsize="marquee"
             android:visibility="invisible"
+            android:textColor="@color/status_bar_recents_app_label_color"
         />
 
         <TextView android:id="@+id/app_description"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index b14ef595..de80a51 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -40,6 +40,7 @@
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:visibility="invisible"
             />
         </FrameLayout>
 
@@ -67,6 +68,7 @@
             android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
             android:singleLine="true"
             android:ellipsize="marquee"
+            android:textColor="@color/status_bar_recents_app_label_color"
         />
 
         <View android:id="@+id/recents_callout_line"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index f4be651..07088d5 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -35,6 +35,7 @@
         <ImageView android:id="@+id/app_thumbnail_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:visibility="invisible"
         />
     </FrameLayout>
 
@@ -63,6 +64,7 @@
         android:layout_marginTop="32dip"
         android:singleLine="true"
         android:ellipsize="marquee"
+        android:textColor="@color/status_bar_recents_app_label_color"
     />
 
     <View android:id="@+id/recents_callout_line"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4c222f9..670ee54 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -23,5 +23,6 @@
     <drawable name="status_bar_background">#ff000000</drawable>
     <drawable name="status_bar_recents_background">#b3000000</drawable>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
+    <color name="status_bar_recents_app_label_color">#ffffffff</color>
     <drawable name="status_bar_notification_row_background_color">#ff000000</drawable>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 0354fd7..07281d4 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -41,9 +41,10 @@
     public static final int Y = 1;
 
     private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
-    private int MAX_ESCAPE_ANIMATION_DURATION = 500; // ms
-    private int MAX_DISMISS_VELOCITY = 1000; // dp/sec
-    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250; // ms
+    private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
+    private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
+    private int MAX_DISMISS_VELOCITY = 2000; // dp/sec
+    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
 
     public static float ALPHA_FADE_START = 0f; // fraction of thumbnail width
                                                  // where fade starts
@@ -126,7 +127,10 @@
         } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
             result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
         }
-        return result;
+        // Make .03 alpha the minimum so you always see the item a bit-- slightly below
+        // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
+        // a bit jarring
+        return Math.max(0.03f, result);
     }
 
     // invalidate the view's own bounds all the way up the view hierarchy
@@ -186,6 +190,7 @@
                 }
                 break;
             case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
                 mDragging = false;
                 mCurrView = null;
                 mCurrAnimView = null;
@@ -212,7 +217,10 @@
             duration = Math.min(duration,
                                 (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math
                                         .abs(velocity)));
+        } else {
+            duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
         }
+
         ObjectAnimator anim = createTranslationAnimation(animView, newPos);
         anim.setInterpolator(new LinearInterpolator());
         anim.setDuration(duration);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index fc03a27..1c9d80d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -44,15 +44,6 @@
     private SwipeHelper mSwipeHelper;
     private RecentsScrollViewPerformanceHelper mPerformanceHelper;
 
-    private OnLongClickListener mOnLongClick = new OnLongClickListener() {
-        public boolean onLongClick(View v) {
-            final View anchorView = v.findViewById(R.id.app_description);
-            final View thumbnailView = v.findViewById(R.id.app_thumbnail);
-            mCallback.handleLongPress(v, anchorView, thumbnailView);
-            return true;
-        }
-    };
-
     public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
         super(context, attrs, 0);
         float densityScale = getResources().getDisplayMetrics().density;
@@ -69,8 +60,6 @@
         mLinearLayout.removeAllViews();
         for (int i = 0; i < mAdapter.getCount(); i++) {
             final View view = mAdapter.getView(i, null, mLinearLayout);
-            view.setLongClickable(true);
-            view.setOnLongClickListener(mOnLongClick);
 
             if (mPerformanceHelper != null) {
                 mPerformanceHelper.addViewCallback(view);
@@ -81,18 +70,30 @@
                     mCallback.dismiss();
                 }
             });
+            // We don't want a click sound when we dimiss recents
+            view.setSoundEffectsEnabled(false);
 
             OnClickListener launchAppListener = new OnClickListener() {
                 public void onClick(View v) {
                     mCallback.handleOnClick(view);
                 }
             };
+            OnLongClickListener longClickListener = new OnLongClickListener() {
+                public boolean onLongClick(View v) {
+                    final View anchorView = view.findViewById(R.id.app_description);
+                    final View thumbnailView = view.findViewById(R.id.app_thumbnail);
+                    mCallback.handleLongPress(view, anchorView, thumbnailView);
+                    return true;
+                }
+            };
             final View thumbnail = view.findViewById(R.id.app_thumbnail);
             thumbnail.setClickable(true);
             thumbnail.setOnClickListener(launchAppListener);
+            thumbnail.setOnLongClickListener(longClickListener);
             final View appTitle = view.findViewById(R.id.app_label);
             appTitle.setClickable(true);
             appTitle.setOnClickListener(launchAppListener);
+            appTitle.setOnLongClickListener(longClickListener);
             mLinearLayout.addView(view);
         }
         // Scroll to end after layout.
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index f7afe3a..0621b22 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -186,12 +186,6 @@
                 holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
                 holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
 
-		/*                StateListDrawable thumbnailForegroundDrawable = new StateListDrawable();
-                thumbnailForegroundDrawable.addState(new int[] { android.R.attr.state_pressed },
-                        mPressedDrawable);
-                thumbnailForegroundDrawable.addState(new int[] { android.R.attr.state_selected },
-                        mPressedDrawable);
-			((FrameLayout)holder.thumbnailView).setForeground(thumbnailForegroundDrawable);*/
                 convertView.setTag(holder);
             } else {
                 holder = (ViewHolder) convertView.getTag();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index b12387a..213803c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -43,15 +43,6 @@
     private SwipeHelper mSwipeHelper;
     private RecentsScrollViewPerformanceHelper mPerformanceHelper;
 
-    private OnLongClickListener mOnLongClick = new OnLongClickListener() {
-        public boolean onLongClick(View v) {
-            final View anchorView = v.findViewById(R.id.app_description);
-            final View thumbnailView = v.findViewById(R.id.app_thumbnail);
-            mCallback.handleLongPress(v, anchorView, thumbnailView);
-            return true;
-        }
-    };
-
     public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
         super(context, attrs, 0);
         float densityScale = getResources().getDisplayMetrics().density;
@@ -83,28 +74,39 @@
             }
 
             if (old == null) {
-                view.setClickable(true);
-                view.setOnLongClickListener(mOnLongClick);
                 view.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
                         mCallback.dismiss();
                     }
                 });
+                // We don't want a click sound when we dimiss recents
+                view.setSoundEffectsEnabled(false);
 
                 OnClickListener launchAppListener = new OnClickListener() {
                     public void onClick(View v) {
                         mCallback.handleOnClick(view);
                     }
                 };
+                OnLongClickListener longClickListener = new OnLongClickListener() {
+                    public boolean onLongClick(View v) {
+                        final View anchorView = view.findViewById(R.id.app_description);
+                        final View thumbnailView = view.findViewById(R.id.app_thumbnail);
+                        mCallback.handleLongPress(view, anchorView, thumbnailView);
+                        return true;
+                    }
+                };
                 final View thumbnail = view.findViewById(R.id.app_thumbnail);
                 thumbnail.setClickable(true);
                 thumbnail.setOnClickListener(launchAppListener);
+                thumbnail.setOnLongClickListener(longClickListener);
                 final View appTitle = view.findViewById(R.id.app_label);
                 appTitle.setClickable(true);
                 appTitle.setOnClickListener(launchAppListener);
+                appTitle.setOnLongClickListener(longClickListener);
                 final View calloutLine = view.findViewById(R.id.recents_callout_line);
                 calloutLine.setClickable(true);
                 calloutLine.setOnClickListener(launchAppListener);
+                calloutLine.setOnLongClickListener(longClickListener);
                 mLinearLayout.addView(view);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 69e0752..b153613 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1458,9 +1458,10 @@
             Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
                 + mDisabled);
         } else if (CHATTY) {
-            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            if (event.getAction() != MotionEvent.ACTION_MOVE) {
                 Slog.d(TAG, String.format(
-                            "panel: ACTION_DOWN at (%f, %f) mDisabled=0x%08x",
+                            "panel: %s at (%f, %f) mDisabled=0x%08x",
+                            MotionEvent.actionToString(event.getAction()),
                             event.getRawX(), event.getRawY(), mDisabled));
             }
         }
@@ -1469,11 +1470,11 @@
             return false;
         }
 
+        final int action = event.getAction();
         final int statusBarSize = mStatusBarView.getHeight();
         final int hitSize = statusBarSize*2;
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            final int y = (int)event.getRawY();
-
+        final int y = (int)event.getRawY();
+        if (action == MotionEvent.ACTION_DOWN) {
             if (!mExpanded) {
                 mViewDelta = statusBarSize - y;
             } else {
@@ -1490,21 +1491,21 @@
                 final int edgeBorder = mEdgeBorder;
                 if (x >= edgeBorder && x < mDisplayMetrics.widthPixels - edgeBorder) {
                     prepareTracking(y, !mExpanded);// opening if we're not already fully visible
-                    mVelocityTracker.addMovement(event);
+                    trackMovement(event);
                 }
             }
         } else if (mTracking) {
-            mVelocityTracker.addMovement(event);
+            trackMovement(event);
             final int minY = statusBarSize + mCloseView.getHeight();
-            if (event.getAction() == MotionEvent.ACTION_MOVE) {
-                int y = (int)event.getRawY();
+            if (action == MotionEvent.ACTION_MOVE) {
                 if (mAnimatingReveal && y < minY) {
                     // nothing
                 } else  {
                     mAnimatingReveal = false;
                     updateExpandedViewPos(y + mViewDelta);
                 }
-            } else if (event.getAction() == MotionEvent.ACTION_UP) {
+            } else if (action == MotionEvent.ACTION_UP
+                    || action == MotionEvent.ACTION_CANCEL) {
                 mVelocityTracker.computeCurrentVelocity(1000);
 
                 float yVel = mVelocityTracker.getYVelocity();
@@ -1531,13 +1532,23 @@
                         vel));
                 }
 
-                performFling((int)event.getRawY(), vel, false);
+                performFling(y + mViewDelta, vel, false);
             }
 
         }
         return false;
     }
 
+    private void trackMovement(MotionEvent event) {
+        // Add movement to velocity tracker using raw screen X and Y coordinates instead
+        // of window coordinates because the window frame may be moving at the same time.
+        float deltaX = event.getRawX() - event.getX();
+        float deltaY = event.getRawY() - event.getY();
+        event.offsetLocation(deltaX, deltaY);
+        mVelocityTracker.addMovement(event);
+        event.offsetLocation(-deltaX, -deltaY);
+    }
+
     @Override // CommandQueue
     public void setSystemUiVisibility(int vis) {
         final int old = mSystemUiVisibility;
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index be2ef82..2938c45 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -497,10 +497,14 @@
 
             case MSG_RUN_FULL_BACKUP:
             {
+                // TODO: refactor full backup to be a looper-based state machine
+                // similar to normal backup/restore.
                 FullBackupParams params = (FullBackupParams)msg.obj;
-                (new PerformFullBackupTask(params.fd, params.observer, params.includeApks,
+                PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
+                        params.observer, params.includeApks,
                         params.includeShared, params.curPassword, params.encryptPassword,
-                        params.allApps, params.packages, params.latch)).run();
+                        params.allApps, params.packages, params.latch);
+                (new Thread(task)).start();
                 break;
             }
 
@@ -519,9 +523,13 @@
 
             case MSG_RUN_FULL_RESTORE:
             {
+                // TODO: refactor full restore to be a looper-based state machine
+                // similar to normal backup/restore.
                 FullRestoreParams params = (FullRestoreParams)msg.obj;
-                (new PerformFullRestoreTask(params.fd, params.curPassword, params.encryptPassword,
-                        params.observer, params.latch)).run();
+                PerformFullRestoreTask task = new PerformFullRestoreTask(params.fd,
+                        params.curPassword, params.encryptPassword,
+                        params.observer, params.latch);
+                (new Thread(task)).start();
                 break;
             }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2714fc5..7e28c4f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -148,7 +148,8 @@
 
             Slog.i(TAG, "Package Manager");
             pm = PackageManagerService.main(context,
-                    factoryTest != SystemServer.FACTORY_TEST_OFF);
+                    factoryTest != SystemServer.FACTORY_TEST_OFF,
+                    false);
 
             ActivityManagerService.setSystemProcess();
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index e6b5898..4b1a4e6 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -69,6 +69,7 @@
 import java.io.PrintWriter;
 
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.server.am.BatteryStatsService;
 import com.android.internal.R;
@@ -96,6 +97,7 @@
     private static final int IDLE_REQUEST = 0;
     private boolean mScreenOff;
     private boolean mDeviceIdle;
+    private boolean mEmergencyCallbackMode = false;
     private int mPluggedType;
 
     /* Chipset supports background scan */
@@ -996,6 +998,9 @@
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
                         BluetoothAdapter.STATE_DISCONNECTED);
                 mWifiStateMachine.sendBluetoothAdapterStateChange(state);
+            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                mEmergencyCallbackMode = intent.getBooleanExtra("phoneinECMState", false);
+                updateWifiState();
             }
         }
 
@@ -1057,7 +1062,13 @@
     private void updateWifiState() {
         boolean lockHeld = mLocks.hasLocks();
         int strongestLockMode = WifiManager.WIFI_MODE_FULL;
-        boolean wifiShouldBeStarted = !mDeviceIdle || lockHeld;
+        boolean wifiShouldBeStarted;
+
+        if (mEmergencyCallbackMode) {
+            wifiShouldBeStarted = false;
+        } else {
+            wifiShouldBeStarted = !mDeviceIdle || lockHeld;
+        }
 
         if (lockHeld) {
             strongestLockMode = mLocks.getStrongestLockMode();
@@ -1097,6 +1108,7 @@
         intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
         intentFilter.addAction(ACTION_DEVICE_IDLE);
         intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
+        intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
         mContext.registerReceiver(mReceiver, intentFilter);
     }
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index bfb244b..4e5ca8e 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -221,6 +221,7 @@
 
     final Context mContext;
     final boolean mFactoryTest;
+    final boolean mOnlyCore;
     final boolean mNoDexOpt;
     final DisplayMetrics mMetrics;
     final int mDefParseFlags;
@@ -809,8 +810,9 @@
         return false;
     }
 
-    public static final IPackageManager main(Context context, boolean factoryTest) {
-        PackageManagerService m = new PackageManagerService(context, factoryTest);
+    public static final IPackageManager main(Context context, boolean factoryTest,
+            boolean onlyCore) {
+        PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
         ServiceManager.addService("package", m);
         return m;
     }
@@ -837,7 +839,7 @@
         return res;
     }
 
-    public PackageManagerService(Context context, boolean factoryTest) {
+    public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                 SystemClock.uptimeMillis());
 
@@ -847,6 +849,7 @@
 
         mContext = context;
         mFactoryTest = factoryTest;
+        mOnlyCore = onlyCore;
         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
         mMetrics = new DisplayMetrics();
         mSettings = new Settings();
@@ -1051,18 +1054,20 @@
             mInstaller.moveFiles();
 
             // Prune any system packages that no longer exist.
-            Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
-            while (psit.hasNext()) {
-                PackageSetting ps = psit.next();
-                if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
-                        && !mPackages.containsKey(ps.name)
-                        && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
-                    psit.remove();
-                    String msg = "System package " + ps.name
-                            + " no longer exists; wiping its data";
-                    reportSettingsProblem(Log.WARN, msg);
-                    mInstaller.remove(ps.name, 0);
-                    mUserManager.removePackageForAllUsers(ps.name);
+            if (!mOnlyCore) {
+                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
+                while (psit.hasNext()) {
+                    PackageSetting ps = psit.next();
+                    if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
+                            && !mPackages.containsKey(ps.name)
+                            && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
+                        psit.remove();
+                        String msg = "System package " + ps.name
+                                + " no longer exists; wiping its data";
+                        reportSettingsProblem(Log.WARN, msg);
+                        mInstaller.remove(ps.name, 0);
+                        mUserManager.removePackageForAllUsers(ps.name);
+                    }
                 }
             }
             
@@ -1077,18 +1082,23 @@
             //delete tmp files
             deleteTempPackageFiles();
 
-            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
-                    SystemClock.uptimeMillis());
-            mAppInstallObserver = new AppDirObserver(
-                mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
-            mAppInstallObserver.startWatching();
-            scanDirLI(mAppInstallDir, 0, scanMode, 0);
-
-            mDrmAppInstallObserver = new AppDirObserver(
-                mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
-            mDrmAppInstallObserver.startWatching();
-            scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
-                    scanMode, 0);
+            if (!mOnlyCore) {
+                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
+                        SystemClock.uptimeMillis());
+                mAppInstallObserver = new AppDirObserver(
+                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
+                mAppInstallObserver.startWatching();
+                scanDirLI(mAppInstallDir, 0, scanMode, 0);
+    
+                mDrmAppInstallObserver = new AppDirObserver(
+                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
+                mDrmAppInstallObserver.startWatching();
+                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
+                        scanMode, 0);
+            } else {
+                mAppInstallObserver = null;
+                mDrmAppInstallObserver = null;
+            }
 
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                     SystemClock.uptimeMillis());
@@ -2749,6 +2759,7 @@
         parseFlags |= mDefParseFlags;
         PackageParser pp = new PackageParser(scanPath);
         pp.setSeparateProcesses(mSeparateProcesses);
+        pp.setOnlyCoreApps(mOnlyCore);
         final PackageParser.Package pkg = pp.parsePackage(scanFile,
                 scanPath, mMetrics, parseFlags);
         if (pkg == null) {
@@ -4044,7 +4055,7 @@
                         + " info=" + bp.pendingInfo);
                 if (bp.packageSetting == null && bp.pendingInfo != null) {
                     final BasePermission tree = findPermissionTreeLP(bp.name);
-                    if (tree != null) {
+                    if (tree != null && tree.perm != null) {
                         bp.packageSetting = tree.packageSetting;
                         bp.perm = new PackageParser.Permission(tree.perm.owner,
                                 new PermissionInfo(bp.pendingInfo));
diff --git a/services/java/com/android/server/wm/DimSurface.java b/services/java/com/android/server/wm/DimSurface.java
index d7bb8b3..dc6cc0d 100644
--- a/services/java/com/android/server/wm/DimSurface.java
+++ b/services/java/com/android/server/wm/DimSurface.java
@@ -53,19 +53,22 @@
     void show(int dw, int dh, int layer, int color) {
         if (!mDimShown) {
             if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
-                    dw + "x" + dh + ")");
+                    dw + "x" + dh + " layer=" + layer + ")");
             mDimShown = true;
             try {
                 mLastDimWidth = dw;
                 mLastDimHeight = dh;
                 mDimSurface.setPosition(0, 0);
                 mDimSurface.setSize(dw, dh);
+                mDimSurface.setLayer(layer);
                 mDimSurface.show();
             } catch (RuntimeException e) {
                 Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e);
             }
         } else if (mLastDimWidth != dw || mLastDimHeight != dh || mDimColor != color
                 || mLayer != layer) {
+            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DIM " + mDimSurface + ": pos=(0,0) (" +
+                    dw + "x" + dh + " layer=" + layer + ")");
             mLastDimWidth = dw;
             mLastDimHeight = dh;
             mLayer = layer;
@@ -80,6 +83,7 @@
         if (mDimShown) {
             mDimShown = false;
             try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  HIDE " + mDimSurface);
                 mDimSurface.hide();
             } catch (RuntimeException e) {
                 Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface");
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index df9698e..5a7fc9f 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -7458,9 +7458,12 @@
                                     windowDetachedWallpaper = w;
                                 }
                                 if (w.mAnimation.getBackgroundColor() != 0) {
-                                    windowAnimationBackground = w;
-                                    windowAnimationBackgroundColor =
-                                            w.mAnimation.getBackgroundColor();
+                                    if (windowAnimationBackground == null || w.mAnimLayer <
+                                            windowAnimationBackground.mAnimLayer) {
+                                        windowAnimationBackground = w;
+                                        windowAnimationBackgroundColor =
+                                                w.mAnimation.getBackgroundColor();
+                                    }
                                 }
                             }
                             animating = true;
@@ -7469,14 +7472,18 @@
                         // If this window's app token is running a detached wallpaper
                         // animation, make a note so we can ensure the wallpaper is
                         // displayed behind it.
-                        if (w.mAppToken != null && w.mAppToken.animation != null) {
+                        if (w.mAppToken != null && w.mAppToken.animation != null
+                                && w.mAppToken.animating) {
                             if (w.mAppToken.animation.getDetachWallpaper()) {
                                 windowDetachedWallpaper = w;
                             }
                             if (w.mAppToken.animation.getBackgroundColor() != 0) {
-                                windowAnimationBackground = w;
-                                windowAnimationBackgroundColor =
-                                        w.mAppToken.animation.getBackgroundColor();
+                                if (windowAnimationBackground == null || w.mAnimLayer <
+                                        windowAnimationBackground.mAnimLayer) {
+                                    windowAnimationBackground = w;
+                                    windowAnimationBackgroundColor =
+                                            w.mAppToken.animation.getBackgroundColor();
+                                }
                             }
                         }
 
diff --git a/services/sensorservice/tests/sensorservicetest.cpp b/services/sensorservice/tests/sensorservicetest.cpp
index 54bce09..1025fa8 100644
--- a/services/sensorservice/tests/sensorservicetest.cpp
+++ b/services/sensorservice/tests/sensorservicetest.cpp
@@ -35,22 +35,21 @@
 
     while ((n = q->read(buffer, 8)) > 0) {
         for (int i=0 ; i<n ; i++) {
-            if (buffer[i].type == Sensor::TYPE_ACCELEROMETER) {
-                printf("time=%lld, value=<%5.1f,%5.1f,%5.1f>\n",
-                        buffer[i].timestamp,
-                        buffer[i].acceleration.x,
-                        buffer[i].acceleration.y,
-                        buffer[i].acceleration.z);
-            }
-
+            float t;
             if (oldTimeStamp) {
-                float t = float(buffer[i].timestamp - oldTimeStamp) / s2ns(1);
-                printf("%f ms (%f Hz)\n", t*1000, 1.0/t);
+                t = float(buffer[i].timestamp - oldTimeStamp) / s2ns(1);
             } else {
-                float t = float(buffer[i].timestamp - sStartTime) / s2ns(1);
-                printf("first event: %f ms\n", t*1000);
+                t = float(buffer[i].timestamp - sStartTime) / s2ns(1);
             }
             oldTimeStamp = buffer[i].timestamp;
+
+            if (buffer[i].type == Sensor::TYPE_ACCELEROMETER) {
+                printf("%lld\t%8f\t%8f\t%8f\t%f\n",
+                        buffer[i].timestamp,
+                        buffer[i].data[0], buffer[i].data[1], buffer[i].data[2],
+                        1.0/t);
+            }
+
         }
     }
     if (n<0 && n != -EAGAIN) {
@@ -79,7 +78,7 @@
 
     q->enableSensor(accelerometer);
 
-    q->setEventRate(accelerometer, ms2ns(200));
+    q->setEventRate(accelerometer, ms2ns(10));
 
     sp<Looper> loop = new Looper(false);
     loop->addFd(q->getFd(), 0, ALOOPER_EVENT_INPUT, receiver, q.get());
diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_extended b/services/tests/servicestests/res/raw/xt_qtaguid_extended
index 5bef3dd..2f3b4ec 100644
--- a/services/tests/servicestests/res/raw/xt_qtaguid_extended
+++ b/services/tests/servicestests/res/raw/xt_qtaguid_extended
@@ -1,3 +1,3 @@
-acct_tag_hex uid_tag_int iface rx_bytes rx_packets tx_bytes tx_packets teleported_goats
-0x0 1000 test0 1024 10 2048 20 2716057
-0x0000F00D00000000 1000 test0 512 5 512 5 3370318
+acct_tag_hex uid_tag_int iface rx_bytes rx_packets tx_bytes tx_packets teleported_goats idx
+0x0 1000 test0 1024 10 2048 20 2716057 2
+0x0000F00D00000000 1000 test0 512 5 512 5 3370318 3
diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_typical b/services/tests/servicestests/res/raw/xt_qtaguid_typical
index 7c4f04e..8df4b1b 100644
--- a/services/tests/servicestests/res/raw/xt_qtaguid_typical
+++ b/services/tests/servicestests/res/raw/xt_qtaguid_typical
@@ -1,32 +1,32 @@
 idx iface acct_tag_hex uid_tag_int rx_bytes tx_bytes
-1 wlan0 0x0 0 14615 4270
-2 wlan0 0x0 1000 5175 915
-3 wlan0 0x0 1021 3381 903
-4 wlan0 0x0 10004 333821 53558
-5 wlan0 0x0 10010 4888 37363
-6 wlan0 0x0 10013 52 104
-7 wlan0 0x74182ada00000000 10004 18725 1066
-8 rmnet0 0x0 0 301274 30244
-9 rmnet0 0x0 1000 304 441
-10 rmnet0 0x0 1013 2880 2272
-11 rmnet0 0x0 1021 31407 8430
-12 rmnet0 0x0 10003 32665 3814
-13 rmnet0 0x0 10004 2373141 420112
-14 rmnet0 0x0 10010 870370 1111727
-15 rmnet0 0x0 10013 240 240
-16 rmnet0 0x0 10016 16703 13512
-17 rmnet0 0x0 10017 3990 3269
-18 rmnet0 0x0 10018 474504 14516062
-19 rmnet0 0x0 10019 782804 71077
-20 rmnet0 0x0 10022 70671 49684
-21 rmnet0 0x0 10029 5785354 397159
-22 rmnet0 0x0 10033 2102 1686
-23 rmnet0 0x0 10034 15495464 227694
-24 rmnet0 0x0 10037 31184994 684122
-25 rmnet0 0x0 10051 298687 113485
-26 rmnet0 0x0 10056 29504 20669
-27 rmnet0 0x0 10069 683 596
-28 rmnet0 0x0 10072 34051 12453
-29 rmnet0 0x0 10077 7025393 213866
-30 rmnet0 0x0 10081 354 1178
-31 rmnet0 0x74182ada00000000 10037 28507378 437004
+2 wlan0 0x0 0 14615 4270
+3 wlan0 0x0 1000 5175 915
+4 wlan0 0x0 1021 3381 903
+5 wlan0 0x0 10004 333821 53558
+6 wlan0 0x0 10010 4888 37363
+7 wlan0 0x0 10013 52 104
+8 wlan0 0x74182ada00000000 10004 18725 1066
+9 rmnet0 0x0 0 301274 30244
+10 rmnet0 0x0 1000 304 441
+11 rmnet0 0x0 1013 2880 2272
+12 rmnet0 0x0 1021 31407 8430
+13 rmnet0 0x0 10003 32665 3814
+14 rmnet0 0x0 10004 2373141 420112
+15 rmnet0 0x0 10010 870370 1111727
+16 rmnet0 0x0 10013 240 240
+17 rmnet0 0x0 10016 16703 13512
+18 rmnet0 0x0 10017 3990 3269
+19 rmnet0 0x0 10018 474504 14516062
+20 rmnet0 0x0 10019 782804 71077
+21 rmnet0 0x0 10022 70671 49684
+22 rmnet0 0x0 10029 5785354 397159
+23 rmnet0 0x0 10033 2102 1686
+24 rmnet0 0x0 10034 15495464 227694
+25 rmnet0 0x0 10037 31184994 684122
+26 rmnet0 0x0 10051 298687 113485
+27 rmnet0 0x0 10056 29504 20669
+28 rmnet0 0x0 10069 683 596
+29 rmnet0 0x0 10072 34051 12453
+30 rmnet0 0x0 10077 7025393 213866
+31 rmnet0 0x0 10081 354 1178
+32 rmnet0 0x74182ada00000000 10037 28507378 437004
diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set
index 3678b10..f9f34ac 100644
--- a/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set
+++ b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set
@@ -1,13 +1,13 @@
 idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_packets rx_tcp_bytes rx_udp_packets rx_udp_bytes rx_other_packets rx_other_bytes tx_tcp_packets tx_tcp_bytes tx_udp_packets tx_udp_bytes tx_other_packets tx_other_bytes

-1 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0

-1 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

-2 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0

-2 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0

-3 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0

-3 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

-4 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0

-4 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

-5 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0

-5 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

-6 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0

-6 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+2 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0

+3 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+4 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0

+5 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0

+6 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0

+7 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+8 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0

+9 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+10 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0

+11 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+12 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0

+13 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
index 8cad82b..aae29a4 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
@@ -37,162 +37,6 @@
 volatile uchar3 uc3;
 volatile uchar4 uc4;
 
-#define TEST_FN_FUNC_FN(fnc)        \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1);                   \
-    f2 = fnc(f2);                   \
-    f3 = fnc(f3);                   \
-    f4 = fnc(f4);
-
-#define TEST_FN_FUNC_FN_PFN(fnc)    \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, (float*) &f1);     \
-    f2 = fnc(f2, (float2*) &f2);    \
-    f3 = fnc(f3, (float3*) &f3);    \
-    f4 = fnc(f4, (float4*) &f4);
-
-#define TEST_FN_FUNC_FN_FN(fnc)     \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1);               \
-    f2 = fnc(f2, f2);               \
-    f3 = fnc(f3, f3);               \
-    f4 = fnc(f4, f4);
-
-#define TEST_FN_FUNC_FN_F(fnc)      \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1);               \
-    f2 = fnc(f2, f1);               \
-    f3 = fnc(f3, f1);               \
-    f4 = fnc(f4, f1);
-
-#define TEST_FN_FUNC_FN_IN(fnc)     \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, i1);               \
-    f2 = fnc(f2, i2);               \
-    f3 = fnc(f3, i3);               \
-    f4 = fnc(f4, i4);
-
-#define TEST_FN_FUNC_FN_I(fnc)      \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, i1);               \
-    f2 = fnc(f2, i1);               \
-    f3 = fnc(f3, i1);               \
-    f4 = fnc(f4, i1);
-
-#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1, f1);           \
-    f2 = fnc(f2, f2, f2);           \
-    f3 = fnc(f3, f3, f3);           \
-    f4 = fnc(f4, f4, f4);
-
-#define TEST_FN_FUNC_FN_PIN(fnc)    \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, (int*) &i1);       \
-    f2 = fnc(f2, (int2*) &i2);      \
-    f3 = fnc(f3, (int3*) &i3);      \
-    f4 = fnc(f4, (int4*) &i4);
-
-#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1, (int*) &i1);   \
-    f2 = fnc(f2, f2, (int2*) &i2);  \
-    f3 = fnc(f3, f3, (int3*) &i3);  \
-    f4 = fnc(f4, f4, (int4*) &i4);
-
-#define TEST_IN_FUNC_FN(fnc)        \
-    rsDebug("Testing " #fnc, 0);    \
-    i1 = fnc(f1);                   \
-    i2 = fnc(f2);                   \
-    i3 = fnc(f3);                   \
-    i4 = fnc(f4);
-
-
-static bool test_fp_math(uint32_t index) {
-    bool failed = false;
-    start();
-
-    TEST_FN_FUNC_FN(acos);
-    TEST_FN_FUNC_FN(acosh);
-    TEST_FN_FUNC_FN(acospi);
-    TEST_FN_FUNC_FN(asin);
-    TEST_FN_FUNC_FN(asinh);
-    TEST_FN_FUNC_FN(asinpi);
-    TEST_FN_FUNC_FN(atan);
-    TEST_FN_FUNC_FN_FN(atan2);
-    TEST_FN_FUNC_FN(atanh);
-    TEST_FN_FUNC_FN(atanpi);
-    TEST_FN_FUNC_FN_FN(atan2pi);
-    TEST_FN_FUNC_FN(cbrt);
-    TEST_FN_FUNC_FN(ceil);
-    TEST_FN_FUNC_FN_FN(copysign);
-    TEST_FN_FUNC_FN(cos);
-    TEST_FN_FUNC_FN(cosh);
-    TEST_FN_FUNC_FN(cospi);
-    TEST_FN_FUNC_FN(erfc);
-    TEST_FN_FUNC_FN(erf);
-    TEST_FN_FUNC_FN(exp);
-    TEST_FN_FUNC_FN(exp2);
-    TEST_FN_FUNC_FN(exp10);
-    TEST_FN_FUNC_FN(expm1);
-    TEST_FN_FUNC_FN(fabs);
-    TEST_FN_FUNC_FN_FN(fdim);
-    TEST_FN_FUNC_FN(floor);
-    TEST_FN_FUNC_FN_FN_FN(fma);
-    TEST_FN_FUNC_FN_FN(fmax);
-    TEST_FN_FUNC_FN_F(fmax);
-    TEST_FN_FUNC_FN_FN(fmin);
-    TEST_FN_FUNC_FN_F(fmin);
-    TEST_FN_FUNC_FN_FN(fmod);
-    TEST_FN_FUNC_FN_PFN(fract);
-    TEST_FN_FUNC_FN_PIN(frexp);
-    TEST_FN_FUNC_FN_FN(hypot);
-    TEST_IN_FUNC_FN(ilogb);
-    TEST_FN_FUNC_FN_IN(ldexp);
-    TEST_FN_FUNC_FN_I(ldexp);
-    TEST_FN_FUNC_FN(lgamma);
-    TEST_FN_FUNC_FN_PIN(lgamma);
-    TEST_FN_FUNC_FN(log);
-    TEST_FN_FUNC_FN(log2);
-    TEST_FN_FUNC_FN(log10);
-    TEST_FN_FUNC_FN(log1p);
-    TEST_FN_FUNC_FN(logb);
-    TEST_FN_FUNC_FN_FN_FN(mad);
-    TEST_FN_FUNC_FN_PFN(modf);
-    // nan
-    TEST_FN_FUNC_FN_FN(nextafter);
-    TEST_FN_FUNC_FN_FN(pow);
-    TEST_FN_FUNC_FN_IN(pown);
-    TEST_FN_FUNC_FN_FN(powr);
-    TEST_FN_FUNC_FN_FN(remainder);
-    TEST_FN_FUNC_FN_FN_PIN(remquo);
-    TEST_FN_FUNC_FN(rint);
-    TEST_FN_FUNC_FN_IN(rootn);
-    TEST_FN_FUNC_FN(round);
-    TEST_FN_FUNC_FN(rsqrt);
-    TEST_FN_FUNC_FN(sin);
-    TEST_FN_FUNC_FN_PFN(sincos);
-    TEST_FN_FUNC_FN(sinh);
-    TEST_FN_FUNC_FN(sinpi);
-    TEST_FN_FUNC_FN(sqrt);
-    TEST_FN_FUNC_FN(tan);
-    TEST_FN_FUNC_FN(tanh);
-    TEST_FN_FUNC_FN(tanpi);
-    TEST_FN_FUNC_FN(tgamma);
-    TEST_FN_FUNC_FN(trunc);
-
-    float time = end(index);
-
-    if (failed) {
-        rsDebug("test_fp_math FAILED", time);
-    }
-    else {
-        rsDebug("test_fp_math PASSED", time);
-    }
-
-    return failed;
-}
-
 #define DECL_INT(prefix)            \
 volatile char prefix##_c_1 = 1;     \
 volatile char2 prefix##_c_2 = 1;    \
@@ -221,6 +65,10 @@
 volatile long prefix##_l_1 = 1;     \
 volatile ulong prefix##_ul_1 = 1;
 
+DECL_INT(res)
+DECL_INT(src1)
+DECL_INT(src2)
+
 #define TEST_INT_OP_TYPE(op, type)                      \
 rsDebug("Testing " #op " for " #type "1", i++);         \
 res_##type##_1 = src1_##type##_1 op src2_##type##_1;    \
@@ -243,9 +91,274 @@
 rsDebug("Testing " #op " for ul1", i++);    \
 res_ul_1 = src1_ul_1 op src2_ul_1;
 
-DECL_INT(res)
-DECL_INT(src1)
-DECL_INT(src2)
+#define TEST_XN_FUNC_YN(typeout, fnc, typein)   \
+    res_##typeout##_1 = fnc(src1_##typein##_1); \
+    res_##typeout##_2 = fnc(src1_##typein##_2); \
+    res_##typeout##_3 = fnc(src1_##typein##_3); \
+    res_##typeout##_4 = fnc(src1_##typein##_4);
+
+#define TEST_XN_FUNC_XN_XN(type, fnc)                       \
+    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \
+    res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \
+    res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \
+    res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4);
+
+#define TEST_X_FUNC_X_X_X(type, fnc)    \
+    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1);
+
+#define TEST_IN_FUNC_IN(fnc)        \
+    rsDebug("Testing " #fnc, 0);    \
+    TEST_XN_FUNC_YN(uc, fnc, uc)    \
+    TEST_XN_FUNC_YN(c, fnc, c)      \
+    TEST_XN_FUNC_YN(us, fnc, us)    \
+    TEST_XN_FUNC_YN(s, fnc, s)      \
+    TEST_XN_FUNC_YN(ui, fnc, ui)    \
+    TEST_XN_FUNC_YN(i, fnc, i)
+
+#define TEST_UIN_FUNC_IN(fnc)       \
+    rsDebug("Testing " #fnc, 0);    \
+    TEST_XN_FUNC_YN(uc, fnc, c)     \
+    TEST_XN_FUNC_YN(us, fnc, s)     \
+    TEST_XN_FUNC_YN(ui, fnc, i)     \
+
+#define TEST_IN_FUNC_IN_IN(fnc)     \
+    rsDebug("Testing " #fnc, 0);    \
+    TEST_XN_FUNC_XN_XN(uc, fnc)     \
+    TEST_XN_FUNC_XN_XN(c, fnc)      \
+    TEST_XN_FUNC_XN_XN(us, fnc)     \
+    TEST_XN_FUNC_XN_XN(s, fnc)      \
+    TEST_XN_FUNC_XN_XN(ui, fnc)     \
+    TEST_XN_FUNC_XN_XN(i, fnc)
+
+#define TEST_I_FUNC_I_I_I(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    TEST_X_FUNC_X_X_X(uc, fnc)      \
+    TEST_X_FUNC_X_X_X(c, fnc)       \
+    TEST_X_FUNC_X_X_X(us, fnc)      \
+    TEST_X_FUNC_X_X_X(s, fnc)       \
+    TEST_X_FUNC_X_X_X(ui, fnc)      \
+    TEST_X_FUNC_X_X_X(i, fnc)
+
+#define TEST_FN_FUNC_FN(fnc)        \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1);                   \
+    f2 = fnc(f2);                   \
+    f3 = fnc(f3);                   \
+    f4 = fnc(f4);
+
+#define TEST_FN_FUNC_FN_PFN(fnc)    \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, (float*) &f1);     \
+    f2 = fnc(f2, (float2*) &f2);    \
+    f3 = fnc(f3, (float3*) &f3);    \
+    f4 = fnc(f4, (float4*) &f4);
+
+#define TEST_FN_FUNC_FN_FN(fnc)     \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1);               \
+    f2 = fnc(f2, f2);               \
+    f3 = fnc(f3, f3);               \
+    f4 = fnc(f4, f4);
+
+#define TEST_F34_FUNC_F34_F34(fnc)  \
+    rsDebug("Testing " #fnc, 0);    \
+    f3 = fnc(f3, f3);               \
+    f4 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_F(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1);               \
+    f2 = fnc(f2, f1);               \
+    f3 = fnc(f3, f1);               \
+    f4 = fnc(f4, f1);
+
+#define TEST_F_FUNC_FN(fnc)         \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1);                   \
+    f1 = fnc(f2);                   \
+    f1 = fnc(f3);                   \
+    f1 = fnc(f4);
+
+#define TEST_F_FUNC_FN_FN(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1);               \
+    f1 = fnc(f2, f2);               \
+    f1 = fnc(f3, f3);               \
+    f1 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_IN(fnc)     \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, i1);               \
+    f2 = fnc(f2, i2);               \
+    f3 = fnc(f3, i3);               \
+    f4 = fnc(f4, i4);
+
+#define TEST_FN_FUNC_FN_I(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, i1);               \
+    f2 = fnc(f2, i1);               \
+    f3 = fnc(f3, i1);               \
+    f4 = fnc(f4, i1);
+
+#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1, f1);           \
+    f2 = fnc(f2, f2, f2);           \
+    f3 = fnc(f3, f3, f3);           \
+    f4 = fnc(f4, f4, f4);
+
+#define TEST_FN_FUNC_FN_FN_F(fnc)   \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1, f1);           \
+    f2 = fnc(f2, f1, f1);           \
+    f3 = fnc(f3, f1, f1);           \
+    f4 = fnc(f4, f1, f1);
+
+#define TEST_FN_FUNC_FN_PIN(fnc)    \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, (int*) &i1);       \
+    f2 = fnc(f2, (int2*) &i2);      \
+    f3 = fnc(f3, (int3*) &i3);      \
+    f4 = fnc(f4, (int4*) &i4);
+
+#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1, (int*) &i1);   \
+    f2 = fnc(f2, f2, (int2*) &i2);  \
+    f3 = fnc(f3, f3, (int3*) &i3);  \
+    f4 = fnc(f4, f4, (int4*) &i4);
+
+#define TEST_IN_FUNC_FN(fnc)        \
+    rsDebug("Testing " #fnc, 0);    \
+    i1 = fnc(f1);                   \
+    i2 = fnc(f2);                   \
+    i3 = fnc(f3);                   \
+    i4 = fnc(f4);
+
+static bool test_fp_math(uint32_t index) {
+    bool failed = false;
+    start();
+
+    TEST_FN_FUNC_FN(acos);
+    TEST_FN_FUNC_FN(acosh);
+    TEST_FN_FUNC_FN(acospi);
+    TEST_FN_FUNC_FN(asin);
+    TEST_FN_FUNC_FN(asinh);
+    TEST_FN_FUNC_FN(asinpi);
+    TEST_FN_FUNC_FN(atan);
+    TEST_FN_FUNC_FN_FN(atan2);
+    TEST_FN_FUNC_FN(atanh);
+    TEST_FN_FUNC_FN(atanpi);
+    TEST_FN_FUNC_FN_FN(atan2pi);
+    TEST_FN_FUNC_FN(cbrt);
+    TEST_FN_FUNC_FN(ceil);
+    TEST_FN_FUNC_FN_FN_FN(clamp);
+    TEST_FN_FUNC_FN_FN_F(clamp);
+    TEST_FN_FUNC_FN_FN(copysign);
+    TEST_FN_FUNC_FN(cos);
+    TEST_FN_FUNC_FN(cosh);
+    TEST_FN_FUNC_FN(cospi);
+    TEST_F34_FUNC_F34_F34(cross);
+    TEST_FN_FUNC_FN(degrees);
+    TEST_F_FUNC_FN_FN(distance);
+    TEST_F_FUNC_FN_FN(dot);
+    TEST_FN_FUNC_FN(erfc);
+    TEST_FN_FUNC_FN(erf);
+    TEST_FN_FUNC_FN(exp);
+    TEST_FN_FUNC_FN(exp2);
+    TEST_FN_FUNC_FN(exp10);
+    TEST_FN_FUNC_FN(expm1);
+    TEST_FN_FUNC_FN(fabs);
+    TEST_FN_FUNC_FN_FN(fdim);
+    TEST_FN_FUNC_FN(floor);
+    TEST_FN_FUNC_FN_FN_FN(fma);
+    TEST_FN_FUNC_FN_FN(fmax);
+    TEST_FN_FUNC_FN_F(fmax);
+    TEST_FN_FUNC_FN_FN(fmin);
+    TEST_FN_FUNC_FN_F(fmin);
+    TEST_FN_FUNC_FN_FN(fmod);
+    TEST_FN_FUNC_FN_PFN(fract);
+    TEST_FN_FUNC_FN_PIN(frexp);
+    TEST_FN_FUNC_FN_FN(hypot);
+    TEST_IN_FUNC_FN(ilogb);
+    TEST_FN_FUNC_FN_IN(ldexp);
+    TEST_FN_FUNC_FN_I(ldexp);
+    TEST_F_FUNC_FN(length);
+    TEST_FN_FUNC_FN(lgamma);
+    TEST_FN_FUNC_FN_PIN(lgamma);
+    TEST_FN_FUNC_FN(log);
+    TEST_FN_FUNC_FN(log2);
+    TEST_FN_FUNC_FN(log10);
+    TEST_FN_FUNC_FN(log1p);
+    TEST_FN_FUNC_FN(logb);
+    TEST_FN_FUNC_FN_FN_FN(mad);
+    TEST_FN_FUNC_FN_FN(max);
+    TEST_FN_FUNC_FN_F(max);
+    TEST_FN_FUNC_FN_FN(min);
+    TEST_FN_FUNC_FN_F(min);
+    TEST_FN_FUNC_FN_FN_FN(mix);
+    TEST_FN_FUNC_FN_FN_F(mix);
+    TEST_FN_FUNC_FN_PFN(modf);
+    // nan
+    TEST_FN_FUNC_FN_FN(nextafter);
+    TEST_FN_FUNC_FN(normalize);
+    TEST_FN_FUNC_FN_FN(pow);
+    TEST_FN_FUNC_FN_IN(pown);
+    TEST_FN_FUNC_FN_FN(powr);
+    TEST_FN_FUNC_FN(radians);
+    TEST_FN_FUNC_FN_FN(remainder);
+    TEST_FN_FUNC_FN_FN_PIN(remquo);
+    TEST_FN_FUNC_FN(rint);
+    TEST_FN_FUNC_FN_IN(rootn);
+    TEST_FN_FUNC_FN(round);
+    TEST_FN_FUNC_FN(rsqrt);
+    TEST_FN_FUNC_FN(sign);
+    TEST_FN_FUNC_FN(sin);
+    TEST_FN_FUNC_FN_PFN(sincos);
+    TEST_FN_FUNC_FN(sinh);
+    TEST_FN_FUNC_FN(sinpi);
+    TEST_FN_FUNC_FN(sqrt);
+    TEST_FN_FUNC_FN_FN(step);
+    TEST_FN_FUNC_FN_F(step);
+    TEST_FN_FUNC_FN(tan);
+    TEST_FN_FUNC_FN(tanh);
+    TEST_FN_FUNC_FN(tanpi);
+    TEST_FN_FUNC_FN(tgamma);
+    TEST_FN_FUNC_FN(trunc);
+
+    float time = end(index);
+
+    if (failed) {
+        rsDebug("test_fp_math FAILED", time);
+    }
+    else {
+        rsDebug("test_fp_math PASSED", time);
+    }
+
+    return failed;
+}
+
+static bool test_int_math(uint32_t index) {
+    bool failed = false;
+    start();
+
+    TEST_UIN_FUNC_IN(abs);
+    TEST_IN_FUNC_IN(clz);
+    TEST_IN_FUNC_IN_IN(min);
+    TEST_IN_FUNC_IN_IN(max);
+    TEST_I_FUNC_I_I_I(rsClamp);
+
+    float time = end(index);
+
+    if (failed) {
+        rsDebug("test_int_math FAILED", time);
+    }
+    else {
+        rsDebug("test_int_math PASSED", time);
+    }
+
+    return failed;
+}
 
 static bool test_basic_operators() {
     bool failed = false;
@@ -310,6 +423,7 @@
     bool failed = false;
     failed |= test_convert();
     failed |= test_fp_math(index);
+    failed |= test_int_math(index);
     failed |= test_basic_operators();
 
     if (failed) {
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index c553947..f417ddd 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -442,6 +442,7 @@
 
             if (wasConnected) {
                 mLocalIp = null;
+                stopPortMappingMeasurement();
                 for (SipSessionGroupExt group : mSipGroups.values()) {
                     group.onConnectivityChanged(false);
                 }
@@ -457,7 +458,6 @@
                 if (isWifi && (mWifiLock != null)) stopWifiScanner();
             } else {
                 mMyWakeLock.reset(); // in case there's a leak
-                stopPortMappingMeasurement();
                 if (isWifi && (mWifiLock != null)) startWifiScanner();
             }
         } catch (SipException e) {
@@ -784,52 +784,50 @@
         private static final int PASS_THRESHOLD = 10;
         private static final int MAX_RETRY_COUNT = 5;
         private static final int NAT_MEASUREMENT_RETRY_INTERVAL = 120; // in seconds
+        private SipProfile mLocalProfile;
         private SipSessionGroupExt mGroup;
         private SipSessionGroup.SipSessionImpl mSession;
         private int mMinInterval;
         private int mMaxInterval;
         private int mInterval;
-        private int mPassCount = 0;
+        private int mPassCount;
 
         public IntervalMeasurementProcess(SipProfile localProfile,
                 int minInterval, int maxInterval) {
             mMaxInterval = maxInterval;
             mMinInterval = minInterval;
-            mInterval = (maxInterval + minInterval) / 2;
-
-            // Don't start measurement if the interval is too small
-            if (mInterval < DEFAULT_KEEPALIVE_INTERVAL) {
-                Log.w(TAG, "interval is too small; measurement aborted; "
-                        + "maxInterval=" + mMaxInterval);
-                return;
-            } else if (checkTermination()) {
-                Log.w(TAG, "interval is too small; measurement aborted; "
-                        + "interval=[" + mMinInterval + "," + mMaxInterval
-                        + "]");
-                return;
-            }
-
-            try {
-                mGroup =  new SipSessionGroupExt(localProfile, null, null);
-                // TODO: remove this line once SipWakeupTimer can better handle
-                // variety of timeout values
-                mGroup.setWakeupTimer(new SipWakeupTimer(mContext, mExecutor));
-            } catch (Exception e) {
-                Log.w(TAG, "start interval measurement error: " + e);
-            }
+            mLocalProfile = localProfile;
         }
 
         public void start() {
             synchronized (SipService.this) {
-                Log.d(TAG, "start measurement w interval=" + mInterval);
-                if (mSession == null) {
+                if (mSession != null) {
+                    return;
+                }
+
+                mInterval = (mMaxInterval + mMinInterval) / 2;
+                mPassCount = 0;
+
+                // Don't start measurement if the interval is too small
+                if (mInterval < DEFAULT_KEEPALIVE_INTERVAL || checkTermination()) {
+                    Log.w(TAG, "measurement aborted; interval=[" +
+                            mMinInterval + "," + mMaxInterval + "]");
+                    return;
+                }
+
+                try {
+                    Log.d(TAG, "start measurement w interval=" + mInterval);
+
+                    mGroup = new SipSessionGroupExt(mLocalProfile, null, null);
+                    // TODO: remove this line once SipWakeupTimer can better handle
+                    // variety of timeout values
+                    mGroup.setWakeupTimer(new SipWakeupTimer(mContext, mExecutor));
+
                     mSession = (SipSessionGroup.SipSessionImpl)
                             mGroup.createSession(null);
-                }
-                try {
                     mSession.startKeepAliveProcess(mInterval, this);
-                } catch (SipException e) {
-                    Log.e(TAG, "start()", e);
+                } catch (Throwable t) {
+                    onError(SipErrorCode.CLIENT_ERROR, t.toString());
                 }
             }
         }
@@ -840,6 +838,10 @@
                     mSession.stopKeepAliveProcess();
                     mSession = null;
                 }
+                if (mGroup != null) {
+                    mGroup.close();
+                    mGroup = null;
+                }
                 mTimer.cancel(this);
             }
         }
diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java
index eb5cce7..06cdaf2 100644
--- a/voip/java/com/android/server/sip/SipSessionGroup.java
+++ b/voip/java/com/android/server/sip/SipSessionGroup.java
@@ -100,7 +100,7 @@
     private static final int EXPIRY_TIME = 3600; // in seconds
     private static final int CANCEL_CALL_TIMER = 3; // in seconds
     private static final int END_CALL_TIMER = 3; // in seconds
-    private static final int KEEPALIVE_TIMEOUT = 3; // in seconds
+    private static final int KEEPALIVE_TIMEOUT = 5; // in seconds
     private static final int INCALL_KEEPALIVE_INTERVAL = 10; // in seconds
     private static final long WAKE_LOCK_HOLDING_TIME = 500; // in milliseconds
 
@@ -1555,7 +1555,7 @@
                     try {
                         sendKeepAlive();
                     } catch (Throwable t) {
-                        Log.w(TAG, "keepalive error: " + ": "
+                        Log.w(TAG, "keepalive error: "
                                 + mLocalProfile.getUriString(), getRootCause(t));
                         // It's possible that the keepalive process is being stopped
                         // during session.sendKeepAlive() so need to check mRunning
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 2f7b927..fb2c134 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -61,6 +61,7 @@
 import android.widget.EditText;
 
 import com.android.internal.R;
+import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
@@ -134,6 +135,8 @@
 
     /* Airplane mode changed */
     private static final int AIRPLANE_MODE_CHANGED          =   BASE + 6;
+    /* Emergency callback mode */
+    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 7;
 
     private final boolean mP2pSupported;
     private final String mDeviceType;
@@ -172,6 +175,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
         filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         mContext.registerReceiver(new WifiStateReceiver(), filter);
 
@@ -185,14 +189,19 @@
     private class WifiStateReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+            String action = intent.getAction();
+            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                 mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                         WifiManager.WIFI_STATE_DISABLED);
-            } else if (intent.getAction().equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
+            } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
                 mWifiApState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
                         WifiManager.WIFI_AP_STATE_DISABLED);
-            } else if (intent.getAction().equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+            } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
                 mP2pStateMachine.sendMessage(AIRPLANE_MODE_CHANGED);
+            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                if (intent.getBooleanExtra("phoneinECMState", false) == true) {
+                    mP2pStateMachine.sendMessage(EMERGENCY_CALLBACK_MODE);
+                }
             }
         }
     }
@@ -361,6 +370,9 @@
                 case AIRPLANE_MODE_CHANGED:
                     if (isAirplaneModeOn()) sendMessage(WifiP2pManager.DISABLE_P2P);
                     break;
+                case EMERGENCY_CALLBACK_MODE:
+                    sendMessage(WifiP2pManager.DISABLE_P2P);
+                    break;
                     // Ignore
                 case WIFI_DISABLE_USER_ACCEPT:
                 case WIFI_DISABLE_USER_REJECT: