Merge "Remove some old logging code." into honeycomb
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1acb620..337b30f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -89,6 +89,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_aacdec_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_mp3dec_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/11.xml b/api/11.xml
index 945c614..31cfc85 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -160213,17 +160213,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_VIDEO_CAPTURE"
  type="java.lang.String"
  transient="false"
diff --git a/api/current.xml b/api/current.xml
index 945c614..83bfedb 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -146705,6 +146705,17 @@
  visibility="public"
 >
 </method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="detectAll"
  return="android.os.StrictMode.VmPolicy.Builder"
  abstract="false"
@@ -160213,17 +160224,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_VIDEO_CAPTURE"
  type="java.lang.String"
  transient="false"
diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk
index afc45ee..630cf03 100644
--- a/build/phone-hdpi-512-dalvik-heap.mk
+++ b/build/phone-hdpi-512-dalvik-heap.mk
@@ -19,5 +19,5 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=32m \
-    dalvik.vm.heapsize=32m
+    dalvik.vm.growthlimit=32m \
+    dalvik.vm.heapsize=128m
diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk
index ee30b92..ab33b96 100644
--- a/build/phone-hdpi-dalvik-heap.mk
+++ b/build/phone-hdpi-dalvik-heap.mk
@@ -18,5 +18,4 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=32m \
     dalvik.vm.heapsize=32m
diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk
index 9cb2f6b..37c3ec5 100644
--- a/build/tablet-dalvik-heap.mk
+++ b/build/tablet-dalvik-heap.mk
@@ -18,5 +18,5 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=48m \
-    dalvik.vm.heapsize=48m
+    dalvik.vm.growthlimit=48m \
+    dalvik.vm.heapsize=256m
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0a64070..ec6eaaa 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4433,6 +4433,9 @@
             mStopped = true;
         }
         mResumed = false;
+
+        // Check for Activity leaks, if enabled.
+        StrictMode.conditionallyCheckInstanceCounts();
     }
 
     final void performDestroy() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d5aa961..133a7d0 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -64,8 +64,11 @@
     static public int staticGetMemoryClass() {
         // Really brain dead right now -- just take this from the configured
         // vm heap size, and assume it is in megabytes and thus ends with "m".
-        String vmHeapSize = SystemProperties.get("dalvik.vm.smallheapsize", "16m");
-        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        String vmHeapSize = SystemProperties.get("dalvik.vm.growthlimit", "");
+        if (vmHeapSize != null && !"".equals(vmHeapSize)) {
+            return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        }
+        return staticGetLargeMemoryClass();
     }
     
     /**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index db046ef..7cf60f9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3463,7 +3463,7 @@
         }
 
         if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
-            // XXX bump up Dalvik's heap.
+            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
         }
 
         // If the app is being launched for full backup or restore, bring it up in
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0243b02..de84c56 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -34,6 +34,9 @@
  * A class that represents how a persistent notification is to be presented to
  * the user using the {@link android.app.NotificationManager}.
  *
+ * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
+ * easier to construct Notifications.</p>
+ *
  * <p>For a guide to creating notifications, see the
  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status 
  * Bar Notifications</a> document in the Dev Guide.</p>
@@ -119,15 +122,8 @@
 
     /**
      * An intent to launch instead of posting the notification to the status bar.
-     * Only for use with extremely high-priority notifications demanding the user's
-     * <strong>immediate</strong> attention, such as an incoming phone call or
-     * alarm clock that the user has explicitly set to a particular time.
-     * If this facility is used for something else, please give the user an option
-     * to turn it off and use a normal notification, as this can be extremely
-     * disruptive.
-     * 
-     * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
-     * will reach the user even when other notifications are suppressed.
+     *
+     * @see Notification.Builder#setFullScreenIntent
      */
     public PendingIntent fullScreenIntent;
 
@@ -278,7 +274,7 @@
     /**
      * Bit to be bitwise-ored into the {@link #flags} field that should be
      * set if the notification should be canceled when it is clicked by the
-     * user. 
+     * user.  On tablets, the 
      */
     public static final int FLAG_AUTO_CANCEL        = 0x00000010;
 
@@ -618,6 +614,10 @@
         return sb.toString();
     }
 
+    /**
+     * Builder class for {@link Notification} objects.  Allows easier control over
+     * all the flags, as well as help constructing the typical notification layouts.
+     */
     public static class Builder {
         private Context mContext;
 
@@ -644,6 +644,16 @@
         private int mDefaults;
         private int mFlags;
 
+        /**
+         * Constructor.
+         *
+         * Automatically sets the when field to {@link System#currentTimeMillis()
+         * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
+         *
+         * @param context A {@link Context} that will be used to construct the
+         *      RemoteViews. The Context will not be held past the lifetime of this
+         *      Builder object.
+         */
         public Builder(Context context) {
             mContext = context;
 
@@ -652,96 +662,192 @@
             mAudioStreamType = STREAM_DEFAULT;
         }
 
+        /**
+         * Set the time that the event occurred.  Notifications in the panel are
+         * sorted by this time.
+         */
         public Builder setWhen(long when) {
             mWhen = when;
             return this;
         }
 
+        /**
+         * Set the small icon to use in the notification layouts.  Different classes of devices
+         * may return different sizes.  See the UX guidelines for more information on how to
+         * design these icons.
+         *
+         * @param icon A resource ID in the application's package of the drawble to use.
+         */
         public Builder setSmallIcon(int icon) {
             mSmallIcon = icon;
             return this;
         }
 
+        /**
+         * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
+         * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
+         * LevelListDrawable}.
+         *
+         * @param icon A resource ID in the application's package of the drawble to use.
+         * @param level The level to use for the icon.
+         *
+         * @see android.graphics.drawable.LevelListDrawable
+         */
         public Builder setSmallIcon(int icon, int level) {
             mSmallIcon = icon;
             mSmallIconLevel = level;
             return this;
         }
 
+        /**
+         * Set the title (first row) of the notification, in a standard notification.
+         */
         public Builder setContentTitle(CharSequence title) {
             mContentTitle = title;
             return this;
         }
 
+        /**
+         * Set the text (second row) of the notification, in a standard notification.
+         */
         public Builder setContentText(CharSequence text) {
             mContentText = text;
             return this;
         }
 
+        /**
+         * Set the large number at the right-hand side of the notification.  This is
+         * equivalent to setContentInfo, although it might show the number in a different
+         * font size for readability.
+         */
         public Builder setNumber(int number) {
             mNumber = number;
             return this;
         }
 
+        /**
+         * Set the large text at the right-hand side of the notification.
+         */
         public Builder setContentInfo(CharSequence info) {
             mContentInfo = info;
             return this;
         }
 
+        /**
+         * Supply a custom RemoteViews to use instead of the standard one.
+         */
         public Builder setContent(RemoteViews views) {
             mContentView = views;
             return this;
         }
 
+        /**
+         * Supply a {@link PendingIntent} to send when the notification is clicked.
+         * If you do not supply an intent, you can now add PendingIntents to individual
+         * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
+         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+         */
         public Builder setContentIntent(PendingIntent intent) {
             mContentIntent = intent;
             return this;
         }
 
+        /**
+         * Supply a {@link PendingIntent} to send when the notification is cleared by the user
+         * directly from the notification panel.  For example, this intent is sent when the user
+         * clicks the "Clear all" button, or the individual "X" buttons on notifications.  This
+         * intent is not sent when the application calls {@link NotificationManager#cancel
+         * NotificationManager.cancel(int)}.
+         */
         public Builder setDeleteIntent(PendingIntent intent) {
             mDeleteIntent = intent;
             return this;
         }
 
+        /**
+         * An intent to launch instead of posting the notification to the status bar.
+         * Only for use with extremely high-priority notifications demanding the user's
+         * <strong>immediate</strong> attention, such as an incoming phone call or
+         * alarm clock that the user has explicitly set to a particular time.
+         * If this facility is used for something else, please give the user an option
+         * to turn it off and use a normal notification, as this can be extremely
+         * disruptive.
+         *
+         * @param intent The pending intent to launch.
+         * @param highPriority Passing true will cause this notification to be sent
+         *          even if other notifications are suppressed.
+         */
         public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
             mFullScreenIntent = intent;
             setFlag(FLAG_HIGH_PRIORITY, highPriority);
             return this;
         }
 
+        /**
+         * Set the text that is displayed in the status bar when the notification first
+         * arrives.
+         */
         public Builder setTicker(CharSequence tickerText) {
             mTickerText = tickerText;
             return this;
         }
 
+        /**
+         * Set the text that is displayed in the status bar when the notification first
+         * arrives, and also a RemoteViews object that may be displayed instead on some
+         * devices.
+         */
         public Builder setTicker(CharSequence tickerText, RemoteViews views) {
             mTickerText = tickerText;
             mTickerView = views;
             return this;
         }
 
+        /**
+         * Set the large icon that is shown in the ticker and notification.
+         */
         public Builder setLargeIcon(Bitmap icon) {
             mLargeIcon = icon;
             return this;
         }
 
+        /**
+         * Set the sound to play.  It will play on the default stream.
+         */
         public Builder setSound(Uri sound) {
             mSound = sound;
             mAudioStreamType = STREAM_DEFAULT;
             return this;
         }
 
+        /**
+         * Set the sound to play.  It will play on the stream you supply.
+         *
+         * @see #STREAM_DEFAULT
+         * @see AudioManager for the <code>STREAM_</code> constants.
+         */
         public Builder setSound(Uri sound, int streamType) {
             mSound = sound;
             mAudioStreamType = streamType;
             return this;
         }
 
+        /**
+         * Set the vibration pattern to use.
+         *
+         * @see android.os.Vibrator for a discussion of the <code>pattern</code>
+         * parameter.
+         */
         public Builder setVibrate(long[] pattern) {
             mVibrate = pattern;
             return this;
         }
 
+        /**
+         * Set the argb value that you would like the LED on the device to blnk, as well as the
+         * rate.  The rate is specified in terms of the number of milliseconds to be on
+         * and then the number of milliseconds to be off.
+         */
         public Builder setLights(int argb, int onMs, int offMs) {
             mLedArgb = argb;
             mLedOnMs = onMs;
@@ -749,21 +855,51 @@
             return this;
         }
 
+        /**
+         * Set whether this is an ongoing notification.
+         *
+         * <p>Ongoing notifications differ from regular notifications in the following ways:
+         * <ul>
+         *   <li>Ongoing notifications are sorted above the regular notifications in the
+         *   notification panel.</li>
+         *   <li>Ongoing notifications do not have an 'X' close button, and are not affected
+         *   by the "Clear all" button.
+         * </ul>
+         */
         public Builder setOngoing(boolean ongoing) {
             setFlag(FLAG_ONGOING_EVENT, ongoing);
             return this;
         }
 
+        /**
+         * Set this flag if you would only like the sound, vibrate
+         * and ticker to be played if the notification is not already showing.
+         */
         public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
             setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
             return this;
         }
 
+        /**
+         * Setting this flag will make it so the notification is automatically
+         * canceled when the user clicks it in the panel.  The PendingIntent
+         * set with {@link #setDeleteIntent} will be broadcast when the notification
+         * is canceled.
+         */
         public Builder setAutoCancel(boolean autoCancel) {
             setFlag(FLAG_AUTO_CANCEL, autoCancel);
             return this;
         }
 
+        /**
+         * Set the default notification options that will be used.
+         * <p>
+         * The value should be one or more of the following fields combined with
+         * bitwise-or:
+         * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
+         * <p>
+         * For all default values, use {@link #DEFAULT_ALL}.
+         */
         public Builder setDefaults(int defaults) {
             mDefaults = defaults;
             return this;
@@ -834,6 +970,10 @@
             }
         }
 
+        /**
+         * Combine all of the options that have been set and return a new {@link Notification}
+         * object.
+         */
         public Notification getNotification() {
             Notification n = new Notification();
             n.when = mWhen;
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index bc8a836..a70de59 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -85,6 +85,19 @@
      */
     public static final int PRIORITY_UNDEFINED = -1;
 
+    /**
+     * Return codes for the connect and disconnect Bluez / Dbus calls.
+     */
+    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+
+    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+
+    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+
+    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+
+    public static final int INPUT_OPERATION_SUCCESS = 5004;
+
     private final IBluetooth mService;
     private final Context mContext;
 
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7dee25e..1f07349 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -70,6 +70,19 @@
     public static final int STATE_CONNECTED    = 2;
     public static final int STATE_DISCONNECTING = 3;
 
+    /**
+     * Return codes for the connect and disconnect Bluez / Dbus calls.
+     */
+    public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
+
+    public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001;
+
+    public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002;
+
+    public static final int PAN_OPERATION_GENERIC_FAILURE = 1003;
+
+    public static final int PAN_OPERATION_SUCCESS = 1004;
+
     private final IBluetooth mService;
     private final Context mContext;
 
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 997ea53..ae92b09 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -30,6 +30,7 @@
 
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -184,6 +185,15 @@
     /**
      * @hide
      */
+    private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000;  // for VmPolicy
+
+    private static final int ALL_VM_DETECT_BITS =
+            DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
+            DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS;
+
+    /**
+     * @hide
+     */
     public static final int PENALTY_LOG = 0x10;  // normal android.util.Log
 
     // Used for both process and thread policy:
@@ -573,11 +583,15 @@
                 } else if (mClassInstanceLimit == null) {
                     mClassInstanceLimit = new HashMap<Class, Integer>();
                 }
+                mMask |= DETECT_VM_INSTANCE_LEAKS;
                 mClassInstanceLimit.put(klass, instanceLimit);
                 return this;
             }
 
-            private Builder detectActivityLeaks() {
+            /**
+             * Detect leaks of {@link android.app.Activity} subclasses.
+             */
+            public Builder detectActivityLeaks() {
                 return enable(DETECT_VM_ACTIVITY_LEAKS);
             }
 
@@ -585,8 +599,8 @@
              * Detect everything that's potentially suspect.
              *
              * <p>In the Honeycomb release this includes leaks of
-             * SQLite cursors and other closable objects but will
-             * likely expand in future releases.
+             * SQLite cursors, Activities, and other closable objects
+             * but will likely expand in future releases.
              */
             public Builder detectAll() {
                 return enable(DETECT_VM_ACTIVITY_LEAKS |
@@ -1347,6 +1361,41 @@
     }
 
     /**
+     * @hide
+     */
+    public static void conditionallyCheckInstanceCounts() {
+        VmPolicy policy = getVmPolicy();
+        if (policy.classInstanceLimit.size() == 0) {
+            return;
+        }
+        Runtime.getRuntime().gc();
+        // Note: classInstanceLimit is immutable, so this is lock-free
+        for (Class klass : policy.classInstanceLimit.keySet()) {
+            int limit = policy.classInstanceLimit.get(klass);
+            long instances = VMDebug.countInstancesOfClass(klass, false);
+            if (instances <= limit) {
+                continue;
+            }
+            Throwable tr = new InstanceCountViolation(klass, instances, limit);
+            onVmPolicyViolation(tr.getMessage(), tr);
+        }
+    }
+
+    private static long sLastInstanceCountCheckMillis = 0;
+    private static boolean sIsIdlerRegistered = false;  // guarded by sProcessIdleHandler
+    private static final MessageQueue.IdleHandler sProcessIdleHandler =
+            new MessageQueue.IdleHandler() {
+                public boolean queueIdle() {
+                    long now = SystemClock.uptimeMillis();
+                    if (now - sLastInstanceCountCheckMillis > 30 * 1000) {
+                        sLastInstanceCountCheckMillis = now;
+                        conditionallyCheckInstanceCounts();
+                    }
+                    return true;
+                }
+            };
+
+    /**
      * Sets the policy for what actions in the VM process (on any
      * thread) should be detected, as well as the penalty if such
      * actions occur.
@@ -1357,6 +1406,19 @@
         sVmPolicy = policy;
         sVmPolicyMask = policy.mask;
         setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+
+        Looper looper = Looper.getMainLooper();
+        if (looper != null) {
+            MessageQueue mq = looper.mQueue;
+            synchronized (sProcessIdleHandler) {
+                if (policy.classInstanceLimit.size() == 0) {
+                    mq.removeIdleHandler(sProcessIdleHandler);
+                } else if (!sIsIdlerRegistered) {
+                    mq.addIdleHandler(sProcessIdleHandler);
+                    sIsIdlerRegistered = true;
+                }
+            }
+        }
     }
 
     /**
@@ -1406,19 +1468,39 @@
         onVmPolicyViolation(message, originStack);
     }
 
+    // Map from VM violation fingerprint to uptime millis.
+    private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
+
     /**
      * @hide
      */
     public static void onVmPolicyViolation(String message, Throwable originStack) {
-        if ((sVmPolicyMask & PENALTY_LOG) != 0) {
+        final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+        final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+        final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0;
+        final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+        final Integer fingerprint = info.hashCode();
+        final long now = SystemClock.uptimeMillis();
+        long lastViolationTime = 0;
+        long timeSinceLastViolationMillis = Long.MAX_VALUE;
+        synchronized (sLastVmViolationTime) {
+            if (sLastVmViolationTime.containsKey(fingerprint)) {
+                lastViolationTime = sLastVmViolationTime.get(fingerprint);
+                timeSinceLastViolationMillis = now - lastViolationTime;
+            }
+            if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
+                sLastVmViolationTime.put(fingerprint, now);
+            }
+        }
+
+        Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis);
+
+        if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
             Log.e(TAG, message, originStack);
         }
 
-        boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
-        boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
-
-        int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
-        ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+        int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask);
 
         if (penaltyDropbox && !penaltyDeath) {
             // Common case for userdebug/eng builds.  If no death and
@@ -1428,7 +1510,7 @@
             return;
         }
 
-        if (penaltyDropbox) {
+        if (penaltyDropbox && lastViolationTime == 0) {
             // The violationMask, passed to ActivityManager, is a
             // subset of the original StrictMode policy bitmask, with
             // only the bit violated and penalty bits to be executed
@@ -1786,6 +1868,12 @@
         public String broadcastIntentAction;
 
         /**
+         * If this is a instance count violation, the number of instances in memory,
+         * else -1.
+         */
+        public long numInstances = -1;
+
+        /**
          * Create an uninitialized instance of ViolationInfo
          */
         public ViolationInfo() {
@@ -1806,6 +1894,9 @@
                 broadcastIntentAction = broadcastIntent.getAction();
             }
             ThreadSpanState state = sThisThreadSpanState.get();
+            if (tr instanceof InstanceCountViolation) {
+                this.numInstances = ((InstanceCountViolation) tr).mInstances;
+            }
             synchronized (state) {
                 int spanActiveCount = state.mActiveSize;
                 if (spanActiveCount > MAX_SPAN_TAGS) {
@@ -1867,6 +1958,7 @@
             violationNumThisLoop = in.readInt();
             numAnimationsRunning = in.readInt();
             violationUptimeMillis = in.readLong();
+            numInstances = in.readLong();
             broadcastIntentAction = in.readString();
             tags = in.readStringArray();
         }
@@ -1881,6 +1973,7 @@
             dest.writeInt(violationNumThisLoop);
             dest.writeInt(numAnimationsRunning);
             dest.writeLong(violationUptimeMillis);
+            dest.writeLong(numInstances);
             dest.writeString(broadcastIntentAction);
             dest.writeStringArray(tags);
         }
@@ -1895,6 +1988,9 @@
             if (durationMillis != -1) {
                 pw.println(prefix + "durationMillis: " + durationMillis);
             }
+            if (numInstances != -1) {
+                pw.println(prefix + "numInstances: " + numInstances);
+            }
             if (violationNumThisLoop != 0) {
                 pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
             }
@@ -1914,4 +2010,29 @@
         }
 
     }
+
+    // Dummy throwable, for now, since we don't know when or where the
+    // leaked instances came from.  We might in the future, but for
+    // now we suppress the stack trace because it's useless and/or
+    // misleading.
+    private static class InstanceCountViolation extends Throwable {
+        final Class mClass;
+        final long mInstances;
+        final int mLimit;
+
+        private static final StackTraceElement[] FAKE_STACK = new StackTraceElement[1];
+        static {
+            FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit",
+                                                  "StrictMode.java", 1);
+        }
+
+        public InstanceCountViolation(Class klass, long instances, int limit) {
+            // Note: now including instances here, otherwise signatures would all be different.
+            super(klass.toString() + "; limit=" + limit);
+            setStackTrace(FAKE_STACK);
+            mClass = klass;
+            mInstances = instances;
+            mLimit = limit;
+        }
+    }
 }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9f0ea32..82fe7de 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -57,6 +57,8 @@
      * Broadcast Action:  A broadcast to indicate the end of an MTP session with the host.
      * This broadcast is only sent if MTP activity has modified the media database during the
      * most recent MTP session.
+     *
+     * @hide
      */
     public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
 
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 539a696..cd3bc3e 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -748,9 +748,9 @@
         }
     }
 
-    private void onInputDeviceConnectionResult(String path, boolean result) {
+    private void onInputDeviceConnectionResult(String path, int result) {
         // Success case gets handled by Property Change signal
-        if (!result) {
+        if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
             String address = mBluetoothService.getAddressFromObjectPath(path);
             if (address == null) return;
 
@@ -758,9 +758,18 @@
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             int state = mBluetoothService.getInputDeviceState(device);
             if (state == BluetoothInputDevice.STATE_CONNECTING) {
-                connected = false;
+                if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
+                    connected = true;
+                } else {
+                    connected = false;
+                }
             } else if (state == BluetoothInputDevice.STATE_DISCONNECTING) {
-                connected = true;
+                if (result == BluetoothInputDevice.INPUT_DISCONNECT_FAILED_NOT_CONNECTED) {
+                    connected = false;
+                } else {
+                    // There is no better way to handle this, this shouldn't happen
+                    connected = true;
+                }
             } else {
                 Log.e(TAG, "Error onInputDeviceConnectionResult. State is:" + state);
             }
@@ -768,10 +777,10 @@
         }
     }
 
-    private void onPanDeviceConnectionResult(String path, boolean result) {
+    private void onPanDeviceConnectionResult(String path, int result) {
         log ("onPanDeviceConnectionResult " + path + " " + result);
         // Success case gets handled by Property Change signal
-        if (!result) {
+        if (result != BluetoothPan.PAN_OPERATION_SUCCESS) {
             String address = mBluetoothService.getAddressFromObjectPath(path);
             if (address == null) return;
 
@@ -779,9 +788,18 @@
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             int state = mBluetoothService.getPanDeviceState(device);
             if (state == BluetoothPan.STATE_CONNECTING) {
-                connected = false;
+                if (result == BluetoothPan.PAN_CONNECT_FAILED_ALREADY_CONNECTED) {
+                    connected = true;
+                } else {
+                    connected = false;
+                }
             } else if (state == BluetoothPan.STATE_DISCONNECTING) {
-                connected = true;
+                if (result == BluetoothPan.PAN_DISCONNECT_FAILED_NOT_CONNECTED) {
+                    connected = false;
+                } else {
+                    // There is no better way to handle this, this shouldn't happen
+                    connected = true;
+                }
             } else {
                 Log.e(TAG, "Error onPanDeviceConnectionResult. State is: "
                         + state + " result: "+ result);
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 6634f00..25b680e6 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -274,7 +274,7 @@
     public String toString() {
         return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
         + " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
-        + " data=" + mClipData + " result=" + mDragResult
+        + " data=" + mClipData + " local=" + mLocalState + " result=" + mDragResult
         + "}";
     }
 
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 99b686e..f480554 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -452,11 +452,14 @@
     @Override
     public int saveLayer(float left, float top, float right, float bottom, Paint paint,
             int saveFlags) {
-        boolean hasColorFilter = paint != null && setupColorFilter(paint);
-        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-        int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
-        if (hasColorFilter) nResetModifiers(mRenderer);
-        return count;
+        if (left < right && top < bottom) {
+            boolean hasColorFilter = paint != null && setupColorFilter(paint);
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+            int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
+            if (hasColorFilter) nResetModifiers(mRenderer);
+            return count;
+        }
+        return save(saveFlags);
     }
 
     private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
@@ -471,7 +474,10 @@
     @Override
     public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
             int saveFlags) {
-        return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+        if (left < right && top < bottom) {
+            return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+        }
+        return save(saveFlags);
     }
 
     private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 270ea76..2447f8c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -58,7 +58,6 @@
 import android.util.Pools;
 import android.util.SparseArray;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d1781cc..115431e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -935,15 +935,17 @@
         } break;
 
         case DragEvent.ACTION_DRAG_ENDED: {
-            // If a child was notified about an ongoing drag, it's told that it's over
-            for (View child : mDragNotifiedChildren) {
-                child.dispatchDragEvent(event);
-            }
-
             // Release the bookkeeping now that the drag lifecycle has ended
-            mDragNotifiedChildren.clear();
-            mCurrentDrag.recycle();
-            mCurrentDrag = null;
+            if (mDragNotifiedChildren != null) {
+                for (View child : mDragNotifiedChildren) {
+                    // If a child was notified about an ongoing drag, it's told that it's over
+                    child.dispatchDragEvent(event);
+                }
+
+                mDragNotifiedChildren.clear();
+                mCurrentDrag.recycle();
+                mCurrentDrag = null;
+            }
 
             // We consider drag-ended to have been handled if one of our children
             // had offered to handle the drag.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 961b633..1f15628 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2803,6 +2803,7 @@
 
                 // Report the drop result when we're done
                 if (what == DragEvent.ACTION_DROP) {
+                    mDragDescription = null;
                     try {
                         Log.i(TAG, "Reporting drop result: " + result);
                         sWindowSession.reportDropResult(mWindow, result);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c54a3cf..8eb4269 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -817,7 +817,7 @@
         public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
 
         /**
-         * Desired operating mode for any soft input area.  May any combination
+         * Desired operating mode for any soft input area.  May be any combination
          * of:
          * 
          * <ul>
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c509dae..7b3ea74 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -408,10 +408,13 @@
     PluginFullScreenHolder mFullScreenHolder;
 
     /**
-     * Position of the last touch event.
+     * Position of the last touch event in pixels.
+     * Use integer to prevent loss of dragging delta calculation accuracy;
+     * which was done in float and converted to integer, and resulted in gradual
+     * and compounding touch position and view dragging mismatch.
      */
-    private float mLastTouchX;
-    private float mLastTouchY;
+    private int mLastTouchX;
+    private int mLastTouchY;
 
     /**
      * Time of the last touch event.
@@ -2218,8 +2221,8 @@
         if (type == HitTestResult.UNKNOWN_TYPE
                 || type == HitTestResult.SRC_ANCHOR_TYPE) {
             // Now check to see if it is an image.
-            int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-            int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+            int contentX = viewToContentX(mLastTouchX + mScrollX);
+            int contentY = viewToContentY(mLastTouchY + mScrollY);
             String text = nativeImageURI(contentX, contentY);
             if (text != null) {
                 result.setType(type == HitTestResult.UNKNOWN_TYPE ?
@@ -2256,8 +2259,8 @@
         if (hrefMsg == null) {
             return;
         }
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
                 contentX, contentY, hrefMsg);
     }
@@ -2271,8 +2274,8 @@
      */
     public void requestImageRef(Message msg) {
         if (0 == mNativeClass) return; // client isn't initialized
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         String ref = nativeImageURI(contentX, contentY);
         Bundle data = msg.getData();
         data.putString("url", ref);
@@ -3856,8 +3859,8 @@
      * @hide pending API council approval
      */
     public boolean selectText() {
-        int x = viewToContentX((int) mLastTouchX + mScrollX);
-        int y = viewToContentY((int) mLastTouchY + mScrollY);
+        int x = viewToContentX(mLastTouchX + mScrollX);
+        int y = viewToContentY(mLastTouchY + mScrollY);
         return selectText(x, y);
     }
 
@@ -4858,8 +4861,8 @@
             mSelectX = contentToViewX(rect.left);
             mSelectY = contentToViewY(rect.top);
         } else if (mLastTouchY > getVisibleTitleHeight()) {
-            mSelectX = mScrollX + (int) mLastTouchX;
-            mSelectY = mScrollY + (int) mLastTouchY;
+            mSelectX = mScrollX + mLastTouchX;
+            mSelectY = mScrollY + mLastTouchY;
         } else {
             mSelectX = mScrollX + getViewWidth() / 2;
             mSelectY = mScrollY + getViewHeightWithTitle() / 2;
@@ -5357,7 +5360,7 @@
             return true;
         }
 
-        return handleTouchEventCommon(ev, ev.getX(), ev.getY());
+        return handleTouchEventCommon(ev, Math.round(ev.getX()), Math.round(ev.getY()));
     }
 
     /*
@@ -5365,7 +5368,7 @@
      * (x, y) denotes current focus point, which is the touch point for single touch
      * and the middle point for multi-touch.
      */
-    private boolean handleTouchEventCommon(MotionEvent ev, float x, float y) {
+    private boolean handleTouchEventCommon(MotionEvent ev, int x, int y) {
         int action = ev.getAction();
         long eventTime = ev.getEventTime();
 
@@ -5377,12 +5380,10 @@
         x = Math.min(x, getViewWidth() - 1);
         y = Math.min(y, getViewHeightWithTitle() - 1);
 
-        float fDeltaX = mLastTouchX - x;
-        float fDeltaY = mLastTouchY - y;
-        int deltaX = (int) fDeltaX;
-        int deltaY = (int) fDeltaY;
-        int contentX = viewToContentX((int) x + mScrollX);
-        int contentY = viewToContentY((int) y + mScrollY);
+        int deltaX = mLastTouchX - x;
+        int deltaY = mLastTouchY - y;
+        int contentX = viewToContentX(x + mScrollX);
+        int contentY = viewToContentY(y + mScrollY);
 
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
@@ -5607,8 +5608,6 @@
                     mTouchMode = TOUCH_DRAG_MODE;
                     mLastTouchX = x;
                     mLastTouchY = y;
-                    fDeltaX = 0.0f;
-                    fDeltaY = 0.0f;
                     deltaX = 0;
                     deltaY = 0;
 
@@ -5619,9 +5618,7 @@
                 // do pan
                 boolean done = false;
                 boolean keepScrollBarsVisible = false;
-                if (Math.abs(fDeltaX) < 1.0f && Math.abs(fDeltaY) < 1.0f) {
-                    mLastTouchX = x;
-                    mLastTouchY = y;
+                if (deltaX == 0 && deltaY == 0) {
                     keepScrollBarsVisible = done = true;
                 } else {
                     if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
@@ -5670,12 +5667,6 @@
                             mLastTouchY = y;
                         }
                         mHeldMotionless = MOTIONLESS_FALSE;
-                    } else {
-                        // keep the scrollbar on the screen even there is no
-                        // scroll
-                        mLastTouchX = x;
-                        mLastTouchY = y;
-                        keepScrollBarsVisible = true;
                     }
                     mLastTouchTime = eventTime;
                     mUserScroll = true;
@@ -5937,8 +5928,8 @@
             action = MotionEvent.ACTION_DOWN;
         } else if (action == MotionEvent.ACTION_POINTER_UP) {
             // set mLastTouchX/Y to the remaining point
-            mLastTouchX = x;
-            mLastTouchY = y;
+            mLastTouchX = Math.round(x);
+            mLastTouchY = Math.round(y);
         } else if (action == MotionEvent.ACTION_MOVE) {
             // negative x or y indicate it is on the edge, skip it.
             if (x < 0 || y < 0) {
@@ -5946,7 +5937,7 @@
             }
         }
 
-        return handleTouchEventCommon(ev, x, y);
+        return handleTouchEventCommon(ev, Math.round(x), Math.round(y));
     }
 
     private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
@@ -5967,8 +5958,8 @@
 
     private void startTouch(float x, float y, long eventTime) {
         // Remember where the motion event started
-        mLastTouchX = x;
-        mLastTouchY = y;
+        mLastTouchX = Math.round(x);
+        mLastTouchY = Math.round(y);
         mLastTouchTime = eventTime;
         mVelocityTracker = VelocityTracker.obtain();
         mSnapScrollMode = SNAP_NONE;
@@ -6598,8 +6589,8 @@
             return;
         }
         // mLastTouchX and mLastTouchY are the point in the current viewport
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
                 contentX + mNavSlop, contentY + mNavSlop);
         nativeSelectBestAt(rect);
@@ -6630,8 +6621,8 @@
         if (!inEditingMode()) {
             return;
         }
-        mLastTouchX = x + (float) (mWebTextView.getLeft() - mScrollX);
-        mLastTouchY = y + (float) (mWebTextView.getTop() - mScrollY);
+        mLastTouchX = Math.round(x + mWebTextView.getLeft() - mScrollX);
+        mLastTouchY = Math.round(y + mWebTextView.getTop() - mScrollY);
         mLastTouchTime = eventTime;
         if (!mScroller.isFinished()) {
             abortAnimation();
@@ -6690,8 +6681,8 @@
         mTouchMode = TOUCH_DONE_MODE;
         switchOutDrawHistory();
         // mLastTouchX and mLastTouchY are the point in the current viewport
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         if (getSettings().supportTouchOnly()) {
             removeTouchHighlight(false);
             WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -7052,8 +7043,8 @@
                             || (msg.arg1 == MotionEvent.ACTION_MOVE
                             && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
                         cancelWebCoreTouchEvent(
-                                viewToContentX((int) mLastTouchX + mScrollX),
-                                viewToContentY((int) mLastTouchY + mScrollY),
+                                viewToContentX(mLastTouchX + mScrollX),
+                                viewToContentY(mLastTouchY + mScrollY),
                                 true);
                     }
                     break;
@@ -7104,8 +7095,8 @@
                         ted.mIds = new int[1];
                         ted.mIds[0] = 0;
                         ted.mPoints = new Point[1];
-                        ted.mPoints[0] = new Point(viewToContentX((int) mLastTouchX + mScrollX),
-                                                   viewToContentY((int) mLastTouchY + mScrollY));
+                        ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + mScrollX),
+                                                   viewToContentY(mLastTouchY + mScrollY));
                         // metaState for long press is tricky. Should it be the
                         // state when the press started or when the press was
                         // released? Or some intermediary key state? For
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index b4ece24..593cb59 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,9 +25,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
-import java.util.Comparator;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 /**
  * A concrete BaseAdapter that is backed by an array of arbitrary
@@ -86,6 +86,8 @@
 
     private Context mContext;
 
+    // A copy of the original mObjects array, initialized from and then used instead as soon as
+    // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
     private ArrayList<T> mOriginalValues;
     private ArrayFilter mFilter;
 
@@ -170,15 +172,14 @@
      * @param object The object to add at the end of the array.
      */
     public void add(T object) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.add(object);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.add(object);
             }
-        } else {
-            mObjects.add(object);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -187,15 +188,14 @@
      * @param collection The Collection to add at the end of the array.
      */
     public void addAll(Collection<? extends T> collection) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.addAll(collection);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.addAll(collection);
             }
-        } else {
-            mObjects.addAll(collection);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -204,19 +204,18 @@
      * @param items The items to add at the end of the array.
      */
     public void addAll(T ... items) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 for (T item : items) {
                     mOriginalValues.add(item);
                 }
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                for (T item : items) {
+                    mObjects.add(item);
+                }
             }
-        } else {
-            for (T item : items) {
-                mObjects.add(item);
-            }
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -226,15 +225,14 @@
      * @param index The index at which the object must be inserted.
      */
     public void insert(T object, int index) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.add(index, object);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.add(index, object);
             }
-        } else {
-            mObjects.add(index, object);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -243,12 +241,12 @@
      * @param object The object to remove.
      */
     public void remove(T object) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.remove(object);
+            } else {
+                mObjects.remove(object);
             }
-        } else {
-            mObjects.remove(object);
         }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
@@ -257,12 +255,12 @@
      * Remove all elements from the list.
      */
     public void clear() {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.clear();
+            } else {
+                mObjects.clear();
             }
-        } else {
-            mObjects.clear();
         }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
@@ -274,7 +272,13 @@
      *        in this adapter.
      */
     public void sort(Comparator<? super T> comparator) {
-        Collections.sort(mObjects, comparator);
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
+                Collections.sort(mOriginalValues, comparator);
+            } else {
+                Collections.sort(mObjects, comparator);
+            }
+        }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
 
@@ -482,6 +486,7 @@
                         final String[] words = valueText.split(" ");
                         final int wordCount = words.length;
 
+                        // Start at index 0, in case valueText starts with space(s)
                         for (int k = 0; k < wordCount; k++) {
                             if (words[k].startsWith(prefixString)) {
                                 newValues.add(value);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4d8d21f..707b92d5 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
@@ -36,8 +38,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
-import com.android.internal.R;
-
 
 /**
  * <p>An editable text view that shows completion suggestions automatically
@@ -113,6 +113,7 @@
 
     private Validator mValidator = null;
 
+    // Set to true when text is set directly and no filtering shall be performed
     private boolean mBlockCompletion;
 
     private PassThroughClickListener mPassThroughClickListener;
@@ -721,6 +722,10 @@
             return;
         }
 
+        updateList();
+    }
+
+    private void updateList() {
         // the drop down is shown only when a minimum number of characters
         // was typed in the text view
         if (enoughToFilter()) {
@@ -840,7 +845,7 @@
 
             mBlockCompletion = true;
             replaceText(convertSelectionToString(selectedItem));
-            mBlockCompletion = false;            
+            mBlockCompletion = false;
 
             if (mItemClickListener != null) {
                 final ListPopupWindow list = mPopup;
@@ -903,10 +908,10 @@
 
     /** {@inheritDoc} */
     public void onFilterComplete(int count) {
-        updateDropDownForFilter(count);
+        updateDropDownForFilter(count, true);
     }
 
-    private void updateDropDownForFilter(int count) {
+    private void updateDropDownForFilter(int count, boolean forceShow) {
         // Not attached to window, don't update drop-down
         if (getWindowVisibility() == View.GONE) return;
 
@@ -919,7 +924,7 @@
 
         final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
         if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
-            if (hasFocus() && hasWindowFocus()) {
+            if (hasFocus() && hasWindowFocus() && (forceShow || isPopupShowing())) {
                 showDropDown();
             }
         } else if (!dropDownAlwaysVisible) {
@@ -1182,12 +1187,14 @@
                 // If the popup is not showing already, showing it will cause
                 // the list of data set observers attached to the adapter to
                 // change. We can't do it from here, because we are in the middle
-                // of iterating throught he list of observers.
+                // of iterating through the list of observers.
                 post(new Runnable() {
                     public void run() {
                         final ListAdapter adapter = mAdapter;
                         if (adapter != null) {
-                            updateDropDownForFilter(adapter.getCount());
+                            // This will re-layout, thus resetting mDataChanged, so that the
+                            // listView click listener stays responsive
+                            updateDropDownForFilter(adapter.getCount(), false);
                         }
                     }
                 });
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index f6b1dbc..db22a0c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -511,8 +511,10 @@
 
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
-                final float x = ev.getX();
-                mIsBeingDragged = true;
+                mIsBeingDragged = getChildCount() != 0;
+                if (!mIsBeingDragged) {
+                    return false;
+                }
 
                 /*
                  * If being flinged and user touches, stop the fling. isFinished
@@ -523,7 +525,7 @@
                 }
 
                 // Remember where the motion event started
-                mLastMotionX = x;
+                mLastMotionX = ev.getX();
                 mActivePointerId = ev.getPointerId(0);
                 break;
             }
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 8558c70..ce6da72 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -521,8 +521,10 @@
 
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
-                final float y = ev.getY();
-                mIsBeingDragged = true;
+                mIsBeingDragged = getChildCount() != 0;
+                if (!mIsBeingDragged) {
+                    return false;
+                }
 
                 /*
                  * If being flinged and user touches, stop the fling. isFinished
@@ -537,7 +539,7 @@
                 }
 
                 // Remember where the motion event started
-                mLastMotionY = y;
+                mLastMotionY = ev.getY();
                 mActivePointerId = ev.getPointerId(0);
                 break;
             }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 0baddcb..e38a69f 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -23,13 +23,14 @@
 import android.content.DialogInterface.OnClickListener;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 
 
 /**
@@ -69,6 +70,8 @@
 
     private int mGravity;
 
+    private LayoutObserver mLayoutObserver;
+
     /**
      * Construct a new spinner with the given context's theme.
      *
@@ -169,6 +172,7 @@
                     com.android.internal.R.styleable.Spinner_dropDownHorizontalOffset, 0));
 
             mPopup = popup;
+            mLayoutObserver = new LayoutObserver();
             break;
         }
         }
@@ -421,6 +425,11 @@
             handled = true;
 
             if (!mPopup.isShowing()) {
+                if (mLayoutObserver != null) {
+                    final ViewTreeObserver vto = getViewTreeObserver();
+                    vto.addOnGlobalLayoutListener(mLayoutObserver);
+                    vto.addOnScrollChangedListener(mLayoutObserver);
+                }
                 mPopup.show();
             }
         }
@@ -668,6 +677,7 @@
             super.show();
             getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
             setSelection(Spinner.this.getSelectedItemPosition());
+            setOnDismissListener(mLayoutObserver);
         }
 
         @Override
@@ -718,4 +728,28 @@
                     ViewGroup.LayoutParams.WRAP_CONTENT);
         }
     }
+
+    private class LayoutObserver implements ViewTreeObserver.OnGlobalLayoutListener,
+            ViewTreeObserver.OnScrollChangedListener, PopupWindow.OnDismissListener {
+        @Override
+        public void onScrollChanged() {
+            if (mPopup != null && mPopup.isShowing()) {
+                mPopup.show();
+            }
+        }
+
+        @Override
+        public void onGlobalLayout() {
+            if (mPopup != null && mPopup.isShowing()) {
+                mPopup.show();
+            }
+        }
+
+        @Override
+        public void onDismiss() {
+            ViewTreeObserver vto = getViewTreeObserver();
+            vto.removeGlobalOnLayoutListener(mLayoutObserver);
+            vto.removeOnScrollChangedListener(mLayoutObserver);
+        }
+    }
 }
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 1ebe622..2cfc016 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -78,15 +78,15 @@
     // URL color
     private ColorStateList mUrlColor;
 
-    // Cached column indexes, updated when the cursor changes.
-    private int mText1Col;
-    private int mText2Col;
-    private int mText2UrlCol;
-    private int mIconName1Col;
-    private int mIconName2Col;
-    private int mFlagsCol;
+    static final int INVALID_INDEX = -1;
 
-    static final int NONE = -1;
+    // Cached column indexes, updated when the cursor changes.
+    private int mText1Col = INVALID_INDEX;
+    private int mText2Col = INVALID_INDEX;
+    private int mText2UrlCol = INVALID_INDEX;
+    private int mIconName1Col = INVALID_INDEX;
+    private int mIconName2Col = INVALID_INDEX;
+    private int mFlagsCol = INVALID_INDEX;
 
     private final Runnable mStartSpinnerRunnable;
     private final Runnable mStopSpinnerRunnable;
@@ -308,7 +308,7 @@
         ChildViewCache views = (ChildViewCache) view.getTag();
 
         int flags = 0;
-        if (mFlagsCol != -1) {
+        if (mFlagsCol != INVALID_INDEX) {
             flags = cursor.getInt(mFlagsCol);
         }
         if (views.mText1 != null) {
@@ -391,7 +391,7 @@
     }
 
     private Drawable getIcon1(Cursor cursor) {
-        if (mIconName1Col < 0) {
+        if (mIconName1Col == INVALID_INDEX) {
             return null;
         }
         String value = cursor.getString(mIconName1Col);
@@ -403,7 +403,7 @@
     }
 
     private Drawable getIcon2(Cursor cursor) {
-        if (mIconName2Col < 0) {
+        if (mIconName2Col == INVALID_INDEX) {
             return null;
         }
         String value = cursor.getString(mIconName2Col);
@@ -687,7 +687,7 @@
     }
 
     private static String getStringOrNull(Cursor cursor, int col) {
-        if (col == NONE) {
+        if (col == INVALID_INDEX) {
             return null;
         }
         try {
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index a8f9f62..6a7db1f0 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -33,8 +33,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
-import java.lang.ref.WeakReference;
-
 /**
  * A toast is a view containing a quick little message for the user.  The toast class
  * helps you create and show those.
@@ -72,11 +70,6 @@
     final Context mContext;
     final TN mTN;
     int mDuration;
-    int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    int mX, mY;
-    float mHorizontalMargin;
-    float mVerticalMargin;
-    View mView;
     View mNextView;
 
     /**
@@ -88,8 +81,8 @@
      */
     public Toast(Context context) {
         mContext = context;
-        mTN = new TN(this);
-        mY = context.getResources().getDimensionPixelSize(
+        mTN = new TN();
+        mTN.mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
     }
     
@@ -103,9 +96,11 @@
 
         INotificationManager service = getService();
         String pkg = mContext.getPackageName();
+        TN tn = mTN;
+        tn.mNextView = mNextView;
 
         try {
-            service.enqueueToast(pkg, mTN, mDuration);
+            service.enqueueToast(pkg, tn, mDuration);
         } catch (RemoteException e) {
             // Empty
         }
@@ -165,22 +160,22 @@
      *        notification
      */
     public void setMargin(float horizontalMargin, float verticalMargin) {
-        mHorizontalMargin = horizontalMargin;
-        mVerticalMargin = verticalMargin;
+        mTN.mHorizontalMargin = horizontalMargin;
+        mTN.mVerticalMargin = verticalMargin;
     }
 
     /**
      * Return the horizontal margin.
      */
     public float getHorizontalMargin() {
-        return mHorizontalMargin;
+        return mTN.mHorizontalMargin;
     }
 
     /**
      * Return the vertical margin.
      */
     public float getVerticalMargin() {
-        return mVerticalMargin;
+        return mTN.mVerticalMargin;
     }
 
     /**
@@ -189,9 +184,9 @@
      * @see #getGravity
      */
     public void setGravity(int gravity, int xOffset, int yOffset) {
-        mGravity = gravity;
-        mX = xOffset;
-        mY = yOffset;
+        mTN.mGravity = gravity;
+        mTN.mX = xOffset;
+        mTN.mY = yOffset;
     }
 
      /**
@@ -200,21 +195,21 @@
      * @see #getGravity
      */
     public int getGravity() {
-        return mGravity;
+        return mTN.mGravity;
     }
 
     /**
      * Return the X offset in pixels to apply to the gravity's location.
      */
     public int getXOffset() {
-        return mX;
+        return mTN.mX;
     }
     
     /**
      * Return the Y offset in pixels to apply to the gravity's location.
      */
     public int getYOffset() {
-        return mY;
+        return mTN.mY;
     }
     
     /**
@@ -281,21 +276,6 @@
         tv.setText(s);
     }
 
-    private void trySendAccessibilityEvent() {
-        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
-        if (!accessibilityManager.isEnabled()) {
-            return;
-        }
-        // treat toasts as notifications since they are used to
-        // announce a transient piece of information to the user
-        AccessibilityEvent event = AccessibilityEvent.obtain(
-                AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
-        event.setClassName(getClass().getName());
-        event.setPackageName(mContext.getPackageName());
-        mView.dispatchPopulateAccessibilityEvent(event);
-        accessibilityManager.sendAccessibilityEvent(event);
-    }
-
     // =======================================================================================
     // All the gunk below is the interaction with the Notification Service, which handles
     // the proper ordering of these system-wide.
@@ -312,8 +292,6 @@
     }
 
     private static class TN extends ITransientNotification.Stub {
-        final Handler mHandler = new Handler();    
-
         final Runnable mShow = new Runnable() {
             public void run() {
                 handleShow();
@@ -327,12 +305,20 @@
         };
 
         private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
-        private final WeakReference<Toast> mToast;
+        final Handler mHandler = new Handler();    
+
+        int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+        int mX, mY;
+        float mHorizontalMargin;
+        float mVerticalMargin;
+
+       
+        View mView;
+        View mNextView;
         
         WindowManagerImpl mWM;
 
-        TN(Toast toast) {
-            mToast = new WeakReference<Toast>(toast);
+        TN() {
             // XXX This should be changed to use a Dialog, with a Theme.Toast
             // defined that sets up the layout params appropriately.
             final WindowManager.LayoutParams params = mParams;
@@ -364,53 +350,64 @@
         }
 
         public void handleShow() {
-            final Toast toast = mToast.get();
-            if (toast != null) {
-                if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + toast.mView
-                        + " mNextView=" + toast.mNextView);
-                if (toast.mView != toast.mNextView) {
-                    // remove the old view if necessary
-                    handleHide();
-                    toast.mView = toast.mNextView;
-                    mWM = WindowManagerImpl.getDefault();
-                    final int gravity = toast.mGravity;
-                    mParams.gravity = gravity;
-                    if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
-                        mParams.horizontalWeight = 1.0f;
-                    }
-                    if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
-                        mParams.verticalWeight = 1.0f;
-                    }
-                    mParams.x = toast.mX;
-                    mParams.y = toast.mY;
-                    mParams.verticalMargin = toast.mVerticalMargin;
-                    mParams.horizontalMargin = toast.mHorizontalMargin;
-                    if (toast.mView.getParent() != null) {
-                        if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this);
-                        mWM.removeView(toast.mView);
-                    }
-                    if (localLOGV) Log.v(TAG, "ADD! " + toast.mView + " in " + this);
-                    mWM.addView(toast.mView, mParams);
-                    toast.trySendAccessibilityEvent();
+            if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
+                    + " mNextView=" + mNextView);
+            if (mView != mNextView) {
+                // remove the old view if necessary
+                handleHide();
+                mView = mNextView;
+                mWM = WindowManagerImpl.getDefault();
+                final int gravity = mGravity;
+                mParams.gravity = gravity;
+                if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
+                    mParams.horizontalWeight = 1.0f;
                 }
+                if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
+                    mParams.verticalWeight = 1.0f;
+                }
+                mParams.x = mX;
+                mParams.y = mY;
+                mParams.verticalMargin = mVerticalMargin;
+                mParams.horizontalMargin = mHorizontalMargin;
+                if (mView.getParent() != null) {
+                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
+                    mWM.removeView(mView);
+                }
+                if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
+                mWM.addView(mView, mParams);
+                trySendAccessibilityEvent();
             }
         }
 
+        private void trySendAccessibilityEvent() {
+            AccessibilityManager accessibilityManager =
+                    AccessibilityManager.getInstance(mView.getContext());
+            if (!accessibilityManager.isEnabled()) {
+                return;
+            }
+            // treat toasts as notifications since they are used to
+            // announce a transient piece of information to the user
+            AccessibilityEvent event = AccessibilityEvent.obtain(
+                    AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+            event.setClassName(getClass().getName());
+            event.setPackageName(mView.getContext().getPackageName());
+            mView.dispatchPopulateAccessibilityEvent(event);
+            accessibilityManager.sendAccessibilityEvent(event);
+        }        
+
         public void handleHide() {
-            final Toast toast = mToast.get();
-            if (toast != null) {
-                if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + toast.mView);
-                if (toast.mView != null) {
-                    // note: checking parent() just to make sure the view has
-                    // been added...  i have seen cases where we get here when
-                    // the view isn't yet added, so let's try not to crash.
-                    if (toast.mView.getParent() != null) {
-                        if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this);
-                        mWM.removeView(toast.mView);
-                    }
-    
-                    toast.mView = null;
+            if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
+            if (mView != null) {
+                // note: checking parent() just to make sure the view has
+                // been added...  i have seen cases where we get here when
+                // the view isn't yet added, so let's try not to crash.
+                if (mView.getParent() != null) {
+                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
+                    mWM.removeView(mView);
                 }
+
+                mView = null;
+                mNextView = null;
             }
         }
     }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f023e94..342b884 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -568,6 +568,7 @@
     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
     char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
     char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
+    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
     char extraOptsBuf[PROPERTY_VALUE_MAX];
     char* stackTraceFile = NULL;
     bool checkJni = false;
@@ -659,6 +660,13 @@
     opt.optionString = heapsizeOptsBuf;
     mOptions.add(opt);
 
+    strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
+    property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
+    if (heapgrowthlimitOptsBuf[20] != '\0') {
+        opt.optionString = heapgrowthlimitOptsBuf;
+        mOptions.add(opt);
+    }
+
     /*
      * Enable or disable dexopt features, such as bytecode verification and
      * calculation of register maps for precise GC.
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index c43b5ce..2445229 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -154,6 +154,16 @@
         scale_rgn(rgn, *rgn, scale);
 }
 
+static jstring Region_toString(JNIEnv* env, jobject clazz, SkRegion* region) {
+    char* str = region->toString();
+    if (str == NULL) {
+        return NULL;
+    }
+    jstring result = env->NewStringUTF(str);
+    free(str);
+    return result;
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
@@ -262,6 +272,7 @@
     { "quickReject",            "(Landroid/graphics/Region;)Z",     (void*)Region_quickRejectRgn    },
     { "scale",                  "(FLandroid/graphics/Region;)V",    (void*)Region_scale             },
     { "translate",              "(IILandroid/graphics/Region;)V",   (void*)Region_translate         },
+    { "nativeToString",         "(I)Ljava/lang/String;",            (void*)Region_toString          },
     // parceling methods
     { "nativeCreateFromParcel", "(Landroid/os/Parcel;)I",           (void*)Region_createFromParcel  },
     { "nativeWriteToParcel",    "(ILandroid/os/Parcel;)Z",          (void*)Region_writeToParcel     },
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index 9222e1a..3364703 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -38,6 +38,7 @@
 #ifdef HAVE_BLUETOOTH
 #define BLUEZ_DBUS_BASE_PATH      "/org/bluez"
 #define BLUEZ_DBUS_BASE_IFC       "org.bluez"
+#define BLUEZ_ERROR_IFC           "org.bluez.Error"
 
 // It would be nicer to retrieve this from bluez using GetDefaultAdapter,
 // but this is only possible when the adapter is up (and hcid is running).
@@ -171,6 +172,30 @@
 
 bool debug_no_encrypt();
 
+
+// Result codes from Bluez DBus calls
+#define BOND_RESULT_ERROR                      -1
+#define BOND_RESULT_SUCCESS                     0
+#define BOND_RESULT_AUTH_FAILED                 1
+#define BOND_RESULT_AUTH_REJECTED               2
+#define BOND_RESULT_AUTH_CANCELED               3
+#define BOND_RESULT_REMOTE_DEVICE_DOWN          4
+#define BOND_RESULT_DISCOVERY_IN_PROGRESS       5
+#define BOND_RESULT_AUTH_TIMEOUT                6
+#define BOND_RESULT_REPEATED_ATTEMPTS           7
+
+#define PAN_DISCONNECT_FAILED_NOT_CONNECTED  1000
+#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
+#define PAN_CONNECT_FAILED_ATTEMPT_FAILED    1002
+#define PAN_OPERATION_GENERIC_FAILURE        1003
+#define PAN_OPERATION_SUCCESS                1004
+
+#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED  5000
+#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
+#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED    5002
+#define INPUT_OPERATION_GENERIC_FAILURE        5003
+#define INPUT_OPERATION_SUCCESS                5004
+
 #endif
 } /* namespace android */
 
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index b0ba695..fd12c2d7 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -134,11 +134,11 @@
     method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
                                                "(Ljava/lang/String;[Ljava/lang/String;)V");
     method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
-                                               "(Ljava/lang/String;Z)V");
+                                               "(Ljava/lang/String;I)V");
     method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
                                                "(Ljava/lang/String;[Ljava/lang/String;)V");
     method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
-                                               "(Ljava/lang/String;Z)V");
+                                               "(Ljava/lang/String;I)V");
     method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
                                                "(Ljava/lang/String;I)V");
 
@@ -1227,16 +1227,6 @@
 
 
 #ifdef HAVE_BLUETOOTH
-//TODO: Unify result codes in a header
-#define BOND_RESULT_ERROR -1000
-#define BOND_RESULT_SUCCESS 0
-#define BOND_RESULT_AUTH_FAILED 1
-#define BOND_RESULT_AUTH_REJECTED 2
-#define BOND_RESULT_AUTH_CANCELED 3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-#define BOND_RESULT_AUTH_TIMEOUT 6
-#define BOND_RESULT_REPEATED_ATTEMPTS 7
 
 void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
     LOGV(__FUNCTION__);
@@ -1406,11 +1396,25 @@
     JNIEnv *env;
     nat->vm->GetEnv((void**)&env, nat->envVer);
 
-    bool result = JNI_TRUE;
+    jint result = INPUT_OPERATION_SUCCESS;
     if (dbus_set_error_from_message(&err, msg)) {
+        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+            result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
+            result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+            // TODO():This is flaky, need to change Bluez to add new error codes
+            if (!strcmp(err.message, "Transport endpoint is not connected")) {
+              result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
+            } else {
+              result = INPUT_OPERATION_GENERIC_FAILURE;
+            }
+        } else {
+            result = INPUT_OPERATION_GENERIC_FAILURE;
+        }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
     }
+
     LOGV("... Device Path = %s, result = %d", path, result);
     jstring jPath = env->NewStringUTF(path);
     env->CallVoidMethod(nat->me,
@@ -1431,11 +1435,25 @@
     JNIEnv *env;
     nat->vm->GetEnv((void**)&env, nat->envVer);
 
-    bool result = JNI_TRUE;
+    jint result = PAN_OPERATION_SUCCESS;
     if (dbus_set_error_from_message(&err, msg)) {
+        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+            result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+            // TODO():This is flaky, need to change Bluez to add new error codes
+            if (!strcmp(err.message, "Device already connected")) {
+                result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
+            } else if (!strcmp(err.message, "Device not connected")) {
+                result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
+            } else {
+                result = PAN_OPERATION_GENERIC_FAILURE;
+            }
+        } else {
+            result = PAN_OPERATION_GENERIC_FAILURE;
+        }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
     }
+
     LOGV("... Pan Device Path = %s, result = %d", path, result);
     jstring jPath = env->NewStringUTF(path);
     env->CallVoidMethod(nat->me,
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 75edac6..ddbd220 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -382,7 +382,7 @@
     }
 
     data.writeInt32(playbackStatus);
-    data.writeInt32(position);
+    data.writeInt64(position);
 
     remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
     return reply.readInt32();
@@ -1111,7 +1111,7 @@
         }
 
         const status_t status
-            = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+            = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
         reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index e540806..27ea0f0 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -287,6 +287,10 @@
                         region2.mNativeRegion, op.nativeInt);
     }
 
+    public String toString() {
+        return nativeToString(mNativeRegion);
+    }
+
     //////////////////////////////////////////////////////////////////////////
     
     public static final Parcelable.Creator<Region> CREATOR
@@ -357,6 +361,8 @@
         return mNativeRegion;
     }
 
+    private static native boolean nativeEquals(int native_r1, int native_r2);
+
     private static native int nativeConstructor();
     private static native void nativeDestructor(int native_region);
 
@@ -381,5 +387,5 @@
     private static native boolean nativeWriteToParcel(int native_region,
                                                       Parcel p);
 
-    private static native boolean nativeEquals(int native_r1, int native_r2);
+    private static native String nativeToString(int native_region);
 }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index c080501..c43e40d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -298,8 +298,10 @@
 // FontRenderer
 ///////////////////////////////////////////////////////////////////////////////
 
+static bool sLogFontRendererCreate = true;
+
 FontRenderer::FontRenderer() {
-    LOGD("Creating FontRenderer");
+    if (sLogFontRendererCreate) LOGD("Creating FontRenderer");
 
     mGammaTable = NULL;
     mInitialized = false;
@@ -317,18 +319,24 @@
 
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
-        LOGD("  Setting text cache width to %s pixels", property);
+        if (sLogFontRendererCreate) LOGD("  Setting text cache width to %s pixels", property);
         mCacheWidth = atoi(property);
     } else {
-        LOGD("  Using default text cache width of %i pixels", mCacheWidth);
+        if (sLogFontRendererCreate) {
+            LOGD("  Using default text cache width of %i pixels", mCacheWidth);
+        }
     }
 
     if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
-        LOGD("  Setting text cache width to %s pixels", property);
+        if (sLogFontRendererCreate) LOGD("  Setting text cache width to %s pixels", property);
         mCacheHeight = atoi(property);
     } else {
-        LOGD("  Using default text cache height of %i pixels", mCacheHeight);
+        if (sLogFontRendererCreate) {
+            LOGD("  Using default text cache height of %i pixels", mCacheHeight);
+        }
     }
+
+    sLogFontRendererCreate = false;
 }
 
 FontRenderer::~FontRenderer() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e6bea78..a167429 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -29,7 +29,6 @@
 void LayerRenderer::prepare(bool opaque) {
     LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
 
-    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
     glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
 
     OpenGLRenderer::prepare(opaque);
@@ -37,11 +36,17 @@
 
 void LayerRenderer::finish() {
     OpenGLRenderer::finish();
-    glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
 
     generateMesh();
 
     LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo);
+
+    // No need to unbind our FBO, this will be taken care of by the caller
+    // who will invoke OpenGLRenderer::resume()
+}
+
+GLint LayerRenderer::getTargetFbo() {
+    return mLayer->fbo;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index f2fb898..1e39847 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -51,6 +51,7 @@
 
     bool hasLayer();
     Region* getRegion();
+    GLint getTargetFbo();
 
     static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
     static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
@@ -61,8 +62,6 @@
     void generateMesh();
 
     Layer* mLayer;
-    GLuint mPreviousFbo;
-
 }; // class LayerRenderer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2067acc1..6477eb0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -200,7 +200,7 @@
 
     glDisable(GL_DITHER);
 
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
     mCaches.blend = true;
@@ -430,18 +430,18 @@
     } else {
         // Copy the framebuffer into the layer
         glBindTexture(GL_TEXTURE_2D, layer->texture);
-
-        if (layer->empty) {
-            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
-                    snapshot->height - bounds.bottom, layer->width, layer->height, 0);
-            layer->empty = false;
-        } else {
-            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
-                    snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+        if (!bounds.isEmpty()) {
+            if (layer->empty) {
+                glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
+                        snapshot->height - bounds.bottom, layer->width, layer->height, 0);
+                layer->empty = false;
+            } else {
+                glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
+                        snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+            }
+            // Enqueue the buffer coordinates to clear the corresponding region later
+            mLayers.push(new Rect(bounds));
         }
-
-        // Enqueue the buffer coordinates to clear the corresponding region later
-        mLayers.push(new Rect(bounds));
     }
 
     return true;
@@ -565,8 +565,10 @@
             resetColorFilter();
         }
     } else {
-        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
-        composeLayerRect(layer, rect, true);
+        if (!rect.isEmpty()) {
+            dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+            composeLayerRect(layer, rect, true);
+        }
     }
 
     if (fboLayer) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 272c5c2..4150ddc 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -145,14 +145,27 @@
         return mSnapshot;
     }
 
+    /**
+     * Returns the region of the current layer.
+     */
     virtual Region* getRegion() {
         return mSnapshot->region;
     }
 
+    /**
+     * Indicates whether rendering is currently targeted at a layer.
+     */
     virtual bool hasLayer() {
         return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
     }
 
+    /**
+     * Returns the name of the FBO this renderer is rendering into.
+     */
+    virtual GLint getTargetFbo() {
+        return 0;
+    }
+
 private:
     /**
      * Saves the current state of the renderer as a new snapshot.
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
index b02f85d..b6f2b2a6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
@@ -102,8 +102,7 @@
     start();
 
     // Do ~100 M ops
-    int ct;
-    for (ct=0; ct < 1000 * 100; ct++) {
+    for (int ct=0; ct < 1000 * 100; ct++) {
         for (int i=0; i < (1000); i++) {
             data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
         }
@@ -114,7 +113,7 @@
 
     start();
     // Do ~100 M ops
-    for (ct=0; ct < 1000 * 100; ct++) {
+    for (int ct=0; ct < 1000 * 100; ct++) {
         for (int i=0; i < (1000); i++) {
             if (data_f1[i] < -1.f) data_f1[i] = -1.f;
             if (data_f1[i] > -1.f) data_f1[i] = 1.f;
@@ -130,8 +129,7 @@
 
     float total = 0;
     // Do ~100 M ops
-    int ct;
-    for (ct=0; ct < 1000 * 100 /4; ct++) {
+    for (int ct=0; ct < 1000 * 100 /4; ct++) {
         for (int i=0; i < (1000); i++) {
             data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
         }
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
index 5b1ad15..3ff7910 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -7,37 +7,154 @@
 volatile float3 f3;
 volatile float4 f4;
 
-#define TEST_F(fnc, var)            \
-    rsDebug("Testing " #fnc, 0);    \
-    var##1 = fnc(var##1);           \
-    var##2 = fnc(var##2);           \
-    var##3 = fnc(var##3);           \
-    var##4 = fnc(var##4);
+volatile int i1;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
 
-#define TEST_FP(fnc, var)           \
+#define TEST_FN_FUNC_FN(fnc)        \
     rsDebug("Testing " #fnc, 0);    \
-    var##1 = fnc(var##1, (float*) &f1);  \
-    var##2 = fnc(var##2, (float2*) &f2);  \
-    var##3 = fnc(var##3, (float3*) &f3);  \
-    var##4 = fnc(var##4, (float4*) &f4);
+    f1 = fnc(f1);                   \
+    f2 = fnc(f2);                   \
+    f3 = fnc(f3);                   \
+    f4 = fnc(f4);
 
-#define TEST_F2(fnc, var)           \
+#define TEST_FN_FUNC_FN_PFN(fnc)    \
     rsDebug("Testing " #fnc, 0);    \
-    var##1 = fnc(var##1, var##1);   \
-    var##2 = fnc(var##2, var##2);   \
-    var##3 = fnc(var##3, var##3);   \
-    var##4 = fnc(var##4, var##4);
+    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_math(uint32_t index) {
     bool failed = false;
     start();
 
-    TEST_F(cos, f);
-    TEST_FP(modf, f);
-    TEST_F2(pow, f);
-    TEST_F(sin, f);
-    TEST_F(sqrt, f);
-
+    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);
 
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 7310418..3acb624 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -253,7 +253,11 @@
     LOGV("%p, deinitEGL", this);
 
     if (mEGL.mContext != EGL_NO_CONTEXT) {
-        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
+        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        eglDestroySurface(mEGL.mDisplay, mEGL.mSurfaceDefault);
+        if (mEGL.mSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+        }
         eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
         checkEglError("eglDestroyContext");
     }
diff --git a/libs/rs/rsScriptC_LibCL.cpp b/libs/rs/rsScriptC_LibCL.cpp
index 28c558d..65b5ff4 100644
--- a/libs/rs/rsScriptC_LibCL.cpp
+++ b/libs/rs/rsScriptC_LibCL.cpp
@@ -58,6 +58,10 @@
     return log10(v) / log10(2.f);
 }
 
+static float SC_mad(float v1, float v2, float v3) {
+    return v1 * v2 + v3;
+}
+
 static float SC_pown(float v, int p) {
     return powf(v, (float)p);
 }
@@ -188,6 +192,7 @@
     { "_Z6asinpif", (void *)&SC_asinpi, true },
     { "_Z4atanf", (void *)&atanf, true },
     { "_Z5atan2ff", (void *)&atan2f, true },
+    { "_Z5atanhf", (void *)&atanhf, true },
     { "_Z6atanpif", (void *)&SC_atanpi, true },
     { "_Z7atan2piff", (void *)&SC_atan2pi, true },
     { "_Z4cbrtf", (void *)&cbrtf, true },
@@ -215,33 +220,32 @@
     { "_Z5ilogbf", (void *)&ilogbf, true },
     { "_Z5ldexpfi", (void *)&ldexpf, true },
     { "_Z6lgammaf", (void *)&lgammaf, true },
+    { "_Z6lgammafPi", (void *)&lgammaf_r, true },
     { "_Z3logf", (void *)&logf, true },
     { "_Z4log2f", (void *)&SC_log2, true },
     { "_Z5log10f", (void *)&log10f, true },
     { "_Z5log1pf", (void *)&log1pf, true },
-    //{ "logb", (void *)&, true },
-    //{ "mad", (void *)&, true },
+    { "_Z4logbf", (void *)&logbf, true },
+    { "_Z3madfff", (void *)&SC_mad, true },
     { "_Z4modffPf", (void *)&modff, true },
     //{ "nan", (void *)&, true },
     { "_Z9nextafterff", (void *)&nextafterf, true },
     { "_Z3powff", (void *)&powf, true },
-    { "_Z4pownfi", (void *)&SC_pown, true },
-    { "_Z4powrff", (void *)&SC_powr, true },
     { "_Z9remainderff", (void *)&remainderf, true },
-    { "remquo", (void *)&remquof, true },
+    { "_Z6remquoffPi", (void *)&remquof, true },
     { "_Z4rintf", (void *)&rintf, true },
     { "_Z5rootnfi", (void *)&SC_rootn, true },
     { "_Z5roundf", (void *)&roundf, true },
     { "_Z5rsqrtf", (void *)&SC_rsqrt, true },
     { "_Z3sinf", (void *)&sinf, true },
-    { "sincos", (void *)&SC_sincos, true },
+    { "_Z6sincosfPf", (void *)&SC_sincos, true },
     { "_Z4sinhf", (void *)&sinhf, true },
     { "_Z5sinpif", (void *)&SC_sinpi, true },
     { "_Z4sqrtf", (void *)&sqrtf, true },
     { "_Z3tanf", (void *)&tanf, true },
     { "_Z4tanhf", (void *)&tanhf, true },
     { "_Z5tanpif", (void *)&SC_tanpi, true },
-    //{ "tgamma", (void *)&, true },
+    { "_Z6tgammaf", (void *)&lgammaf, true }, // FIXME!!! NEEDS TO USE tgammaf
     { "_Z5truncf", (void *)&truncf, true },
 
     // OpenCL Int
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index ab8270f40..a7e46d8 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -42,7 +42,7 @@
 
 // Float ops, 6.11.2
 
-#define DEF_FUNC_1(fnc) \
+#define FN_FUNC_FN(fnc) \
 _RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v) { \
     float2 r; \
     r.x = fnc(v.x); \
@@ -65,7 +65,7 @@
     return r; \
 }
 
-#define DEF_FUNC_1_RI(fnc) \
+#define IN_FUNC_FN(fnc) \
 _RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
     int2 r; \
     r.x = fnc(v.x); \
@@ -88,7 +88,7 @@
     return r; \
 }
 
-#define DEF_FUNC_2(fnc) \
+#define FN_FUNC_FN_FN(fnc) \
 _RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
     float2 r; \
     r.x = fnc(v1.x, v2.x); \
@@ -111,7 +111,7 @@
     return r; \
 }
 
-#define DEF_FUNC_2F(fnc) \
+#define FN_FUNC_FN_F(fnc) \
 _RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
     float2 r; \
     r.x = fnc(v1.x, v2); \
@@ -134,7 +134,53 @@
     return r; \
 }
 
-#define DEF_FUNC_2P(fnc) \
+#define FN_FUNC_FN_IN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    r.z = fnc(v1.z, v2.z); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    r.z = fnc(v1.z, v2.z); \
+    r.w = fnc(v1.w, v2.w); \
+    return r; \
+}
+
+#define FN_FUNC_FN_I(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int v2) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int v2) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    r.z = fnc(v1.z, v2); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int v2) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    r.z = fnc(v1.z, v2); \
+    r.w = fnc(v1.w, v2); \
+    return r; \
+}
+
+#define FN_FUNC_FN_PFN(fnc) \
 _RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 *v2) { \
     float2 r; \
     float q; \
@@ -169,112 +215,205 @@
     return r; \
 }
 
+#define FN_FUNC_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) { \
+    float2 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) { \
+    float3 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) { \
+    float4 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    r.w = fnc(v1.w, &q); \
+    v2->w = q; \
+    return r; \
+}
+
+#define FN_FUNC_FN_FN_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2, float2 v3) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2, float3 v3) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    r.z = fnc(v1.z, v2.z, v3.z); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2, float4 v3) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    r.z = fnc(v1.z, v2.z, v3.z); \
+    r.w = fnc(v1.w, v2.w, v3.w); \
+    return r; \
+}
+
+#define FN_FUNC_FN_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2, int2 *v3) { \
+    float2 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2, int3 *v3) { \
+    float3 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    r.z = fnc(v1.z, v2.z, &q); \
+    v3->z = q; \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2, int4 *v3) { \
+    float4 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    r.z = fnc(v1.z, v2.z, &q); \
+    v3->z = q; \
+    r.w = fnc(v1.w, v2.w, &q); \
+    v3->w = q; \
+    return r; \
+}
+
+
+
 extern float __attribute__((overloadable)) acos(float);
-DEF_FUNC_1(acos)
+FN_FUNC_FN(acos)
 
 extern float __attribute__((overloadable)) acosh(float);
-DEF_FUNC_1(acosh)
+FN_FUNC_FN(acosh)
 
 _RS_STATIC float __attribute__((overloadable)) acospi(float v) {
     return acos(v) / M_PI;
 }
-DEF_FUNC_1(acospi)
+FN_FUNC_FN(acospi)
 
 extern float __attribute__((overloadable)) asin(float);
-DEF_FUNC_1(asin)
+FN_FUNC_FN(asin)
 
 extern float __attribute__((overloadable)) asinh(float);
-DEF_FUNC_1(asinh)
+FN_FUNC_FN(asinh)
 
 _RS_STATIC float __attribute__((overloadable)) asinpi(float v) {
     return asin(v) / M_PI;
 }
-DEF_FUNC_1(asinpi)
+FN_FUNC_FN(asinpi)
 
 extern float __attribute__((overloadable)) atan(float);
-DEF_FUNC_1(atan)
+FN_FUNC_FN(atan)
 
 extern float __attribute__((overloadable)) atan2(float, float);
-DEF_FUNC_2(atan2)
+FN_FUNC_FN_FN(atan2)
 
 extern float __attribute__((overloadable)) atanh(float);
-DEF_FUNC_1(atanh)
+FN_FUNC_FN(atanh)
 
 _RS_STATIC float __attribute__((overloadable)) atanpi(float v) {
     return atan(v) / M_PI;
 }
-DEF_FUNC_1(atanpi)
+FN_FUNC_FN(atanpi)
 
 _RS_STATIC float __attribute__((overloadable)) atan2pi(float y, float x) {
     return atan2(y, x) / M_PI;
 }
-DEF_FUNC_2(atan2pi)
+FN_FUNC_FN_FN(atan2pi)
 
 extern float __attribute__((overloadable)) cbrt(float);
-DEF_FUNC_1(cbrt)
+FN_FUNC_FN(cbrt)
 
 extern float __attribute__((overloadable)) ceil(float);
-DEF_FUNC_1(ceil)
+FN_FUNC_FN(ceil)
 
 extern float __attribute__((overloadable)) copysign(float, float);
-DEF_FUNC_2(copysign)
+FN_FUNC_FN_FN(copysign)
 
 extern float __attribute__((overloadable)) cos(float);
-DEF_FUNC_1(cos)
+FN_FUNC_FN(cos)
 
 extern float __attribute__((overloadable)) cosh(float);
-DEF_FUNC_1(cosh)
+FN_FUNC_FN(cosh)
 
 _RS_STATIC float __attribute__((overloadable)) cospi(float v) {
     return cos(v * M_PI);
 }
-DEF_FUNC_1(cospi)
+FN_FUNC_FN(cospi)
 
 extern float __attribute__((overloadable)) erfc(float);
-DEF_FUNC_1(erfc)
+FN_FUNC_FN(erfc)
 
 extern float __attribute__((overloadable)) erf(float);
-DEF_FUNC_1(erf)
+FN_FUNC_FN(erf)
 
 extern float __attribute__((overloadable)) exp(float);
-DEF_FUNC_1(exp)
+FN_FUNC_FN(exp)
 
 extern float __attribute__((overloadable)) exp2(float);
-DEF_FUNC_1(exp2)
+FN_FUNC_FN(exp2)
 
 extern float __attribute__((overloadable)) pow(float, float);
 _RS_STATIC float __attribute__((overloadable)) exp10(float v) {
     return pow(10.f, v);
 }
-DEF_FUNC_1(exp10)
+FN_FUNC_FN(exp10)
 
 extern float __attribute__((overloadable)) expm1(float);
-DEF_FUNC_1(expm1)
+FN_FUNC_FN(expm1)
 
 extern float __attribute__((overloadable)) fabs(float);
-DEF_FUNC_1(fabs)
+FN_FUNC_FN(fabs)
 
 extern float __attribute__((overloadable)) fdim(float, float);
-DEF_FUNC_2(fdim)
+FN_FUNC_FN_FN(fdim)
 
 extern float __attribute__((overloadable)) floor(float);
-DEF_FUNC_1(floor)
+FN_FUNC_FN(floor)
 
 extern float __attribute__((overloadable)) fma(float, float, float);
-extern float2 __attribute__((overloadable)) fma(float2, float2, float2);
-extern float3 __attribute__((overloadable)) fma(float3, float3, float3);
-extern float4 __attribute__((overloadable)) fma(float4, float4, float4);
+FN_FUNC_FN_FN_FN(fma)
 
 extern float __attribute__((overloadable)) fmax(float, float);
-DEF_FUNC_2(fmax);
-DEF_FUNC_2F(fmax);
+FN_FUNC_FN_FN(fmax);
+FN_FUNC_FN_F(fmax);
 
 extern float __attribute__((overloadable)) fmin(float, float);
-DEF_FUNC_2(fmin);
-DEF_FUNC_2F(fmin);
+FN_FUNC_FN_FN(fmin);
+FN_FUNC_FN_F(fmin);
 
 extern float __attribute__((overloadable)) fmod(float, float);
-DEF_FUNC_2(fmod)
+FN_FUNC_FN_FN(fmod)
 
 _RS_STATIC float __attribute__((overloadable)) fract(float v, float *iptr) {
     int i = (int)floor(v);
@@ -315,64 +454,54 @@
     return r;
 }
 
-extern float __attribute__((overloadable)) frexp(float, float *);
-extern float2 __attribute__((overloadable)) frexp(float2, float2 *);
-extern float3 __attribute__((overloadable)) frexp(float3, float3 *);
-extern float4 __attribute__((overloadable)) frexp(float4, float4 *);
+extern float __attribute__((overloadable)) frexp(float, int *);
+FN_FUNC_FN_PIN(frexp)
 
 extern float __attribute__((overloadable)) hypot(float, float);
-DEF_FUNC_2(hypot)
+FN_FUNC_FN_FN(hypot)
 
 extern int __attribute__((overloadable)) ilogb(float);
-DEF_FUNC_1_RI(ilogb)
+IN_FUNC_FN(ilogb)
 
 extern float __attribute__((overloadable)) ldexp(float, int);
-extern float2 __attribute__((overloadable)) ldexp(float2, int2);
-extern float3 __attribute__((overloadable)) ldexp(float3, int3);
-extern float4 __attribute__((overloadable)) ldexp(float4, int4);
-extern float2 __attribute__((overloadable)) ldexp(float2, int);
-extern float3 __attribute__((overloadable)) ldexp(float3, int);
-extern float4 __attribute__((overloadable)) ldexp(float4, int);
+FN_FUNC_FN_IN(ldexp)
+FN_FUNC_FN_I(ldexp)
 
 extern float __attribute__((overloadable)) lgamma(float);
-DEF_FUNC_1(lgamma)
-extern float __attribute__((overloadable)) lgamma(float, float *);
-extern float2 __attribute__((overloadable)) lgamma(float2, float2 *);
-extern float3 __attribute__((overloadable)) lgamma(float3, float3 *);
-extern float4 __attribute__((overloadable)) lgamma(float4, float4 *);
+FN_FUNC_FN(lgamma)
+extern float __attribute__((overloadable)) lgamma(float, int*);
+FN_FUNC_FN_PIN(lgamma)
 
 extern float __attribute__((overloadable)) log(float);
-DEF_FUNC_1(log)
+FN_FUNC_FN(log)
 
 
 extern float __attribute__((overloadable)) log10(float);
-DEF_FUNC_1(log10)
+FN_FUNC_FN(log10)
 
 _RS_STATIC float __attribute__((overloadable)) log2(float v) {
     return log10(v) / log10(2.f);
 }
-DEF_FUNC_1(log2)
+FN_FUNC_FN(log2)
 
 extern float __attribute__((overloadable)) log1p(float);
-DEF_FUNC_1(log1p)
+FN_FUNC_FN(log1p)
 
 extern float __attribute__((overloadable)) logb(float);
-DEF_FUNC_1(logb)
+FN_FUNC_FN(logb)
 
 extern float __attribute__((overloadable)) mad(float, float, float);
-extern float2 __attribute__((overloadable)) mad(float2, float2, float2);
-extern float3 __attribute__((overloadable)) mad(float3, float3, float3);
-extern float4 __attribute__((overloadable)) mad(float4, float4, float4);
+FN_FUNC_FN_FN_FN(mad)
 
 extern float __attribute__((overloadable)) modf(float, float *);
-DEF_FUNC_2P(modf);
+FN_FUNC_FN_PFN(modf);
 
 //extern float __attribute__((overloadable)) nan(uint);
 
 extern float __attribute__((overloadable)) nextafter(float, float);
-DEF_FUNC_2(nextafter)
+FN_FUNC_FN_FN(nextafter)
 
-DEF_FUNC_2(pow)
+FN_FUNC_FN_FN(pow)
 
 _RS_STATIC float __attribute__((overloadable)) pown(float v, int p) {
     return pow(v, (float)p);
@@ -401,15 +530,13 @@
 }
 
 extern float __attribute__((overloadable)) remainder(float, float);
-DEF_FUNC_2(remainder)
+FN_FUNC_FN_FN(remainder)
 
 extern float __attribute__((overloadable)) remquo(float, float, int *);
-extern float2 __attribute__((overloadable)) remquo(float2, float2, int2 *);
-extern float3 __attribute__((overloadable)) remquo(float3, float3, int3 *);
-extern float4 __attribute__((overloadable)) remquo(float4, float4, int4 *);
+FN_FUNC_FN_FN_PIN(remquo)
 
 extern float __attribute__((overloadable)) rint(float);
-DEF_FUNC_1(rint)
+FN_FUNC_FN(rint)
 
 _RS_STATIC float __attribute__((overloadable)) rootn(float v, int r) {
     return pow(v, 1.f / r);
@@ -428,16 +555,16 @@
 }
 
 extern float __attribute__((overloadable)) round(float);
-DEF_FUNC_1(round)
+FN_FUNC_FN(round)
 
 extern float __attribute__((overloadable)) sqrt(float);
 _RS_STATIC float __attribute__((overloadable)) rsqrt(float v) {
     return 1.f / sqrt(v);
 }
-DEF_FUNC_1(rsqrt)
+FN_FUNC_FN(rsqrt)
 
 extern float __attribute__((overloadable)) sin(float);
-DEF_FUNC_1(sin)
+FN_FUNC_FN(sin)
 
 _RS_STATIC float __attribute__((overloadable)) sincos(float v, float *cosptr) {
     *cosptr = cos(v);
@@ -457,35 +584,35 @@
 }
 
 extern float __attribute__((overloadable)) sinh(float);
-DEF_FUNC_1(sinh)
+FN_FUNC_FN(sinh)
 
 _RS_STATIC float __attribute__((overloadable)) sinpi(float v) {
     return sin(v * M_PI);
 }
-DEF_FUNC_1(sinpi)
+FN_FUNC_FN(sinpi)
 
-DEF_FUNC_1(sqrt)
+FN_FUNC_FN(sqrt)
 
 extern float __attribute__((overloadable)) tan(float);
-DEF_FUNC_1(tan)
+FN_FUNC_FN(tan)
 
 extern float __attribute__((overloadable)) tanh(float);
-DEF_FUNC_1(tanh)
+FN_FUNC_FN(tanh)
 
 _RS_STATIC float __attribute__((overloadable)) tanpi(float v) {
     return tan(v * M_PI);
 }
-DEF_FUNC_1(tanpi)
+FN_FUNC_FN(tanpi)
 
 extern float __attribute__((overloadable)) tgamma(float);
-DEF_FUNC_1(tgamma)
+FN_FUNC_FN(tgamma)
 
 extern float __attribute__((overloadable)) trunc(float);
-DEF_FUNC_1(trunc)
+FN_FUNC_FN(trunc)
 
 // Int ops (partial), 6.11.3
 
-#define DEF_RIFUNC_1(typeout, typein, fnc)                          \
+#define XN_FUNC_YN(typeout, fnc, typein)                            \
 extern typeout __attribute__((overloadable)) fnc(typein);           \
 _RS_STATIC typeout##2 __attribute__((overloadable)) fnc(typein##2 v) {  \
     typeout##2 r;                                                   \
@@ -509,20 +636,20 @@
     return r;                                                       \
 }
 
-#define DEF_UIFUNC_1(fnc)           \
-DEF_RIFUNC_1(uchar, char, fnc)      \
-DEF_RIFUNC_1(ushort, short, fnc)    \
-DEF_RIFUNC_1(uint, int, fnc)
+#define UIN_FUNC_IN(fnc)           \
+XN_FUNC_YN(uchar, fnc, char)      \
+XN_FUNC_YN(ushort, fnc, short)    \
+XN_FUNC_YN(uint, fnc, int)
 
-#define DEF_IFUNC_1(fnc)            \
-DEF_RIFUNC_1(uchar, uchar, fnc)     \
-DEF_RIFUNC_1(char, char, fnc)       \
-DEF_RIFUNC_1(ushort, ushort, fnc)   \
-DEF_RIFUNC_1(short, short, fnc)     \
-DEF_RIFUNC_1(uint, uint, fnc)       \
-DEF_RIFUNC_1(int, int, fnc)
+#define IN_FUNC_IN(fnc)            \
+XN_FUNC_YN(uchar, fnc, uchar)     \
+XN_FUNC_YN(char, fnc, char)       \
+XN_FUNC_YN(ushort, fnc, ushort)   \
+XN_FUNC_YN(short, fnc, short)     \
+XN_FUNC_YN(uint, fnc, uint)       \
+XN_FUNC_YN(int, fnc, int)
 
-#define DEF_RIFUNC_2(type, fnc, body)                                       \
+#define XN_FUNC_XN_XN_BODY(type, fnc, body)                                       \
 _RS_STATIC type __attribute__((overloadable)) fnc(type v1, type v2) {           \
     return body;                                                            \
 }                                                                           \
@@ -548,23 +675,23 @@
     return r;                                                               \
 }                                                                           \
 
-#define DEF_IFUNC_2(fnc, body)  \
-DEF_RIFUNC_2(uchar, fnc, body)  \
-DEF_RIFUNC_2(char, fnc, body)   \
-DEF_RIFUNC_2(ushort, fnc, body) \
-DEF_RIFUNC_2(short, fnc, body)  \
-DEF_RIFUNC_2(uint, fnc, body)   \
-DEF_RIFUNC_2(int, fnc, body)    \
-DEF_RIFUNC_2(float, fnc, body)
+#define IN_FUNC_IN_IN_BODY(fnc, body)  \
+XN_FUNC_XN_XN_BODY(uchar, fnc, body)  \
+XN_FUNC_XN_XN_BODY(char, fnc, body)   \
+XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
+XN_FUNC_XN_XN_BODY(short, fnc, body)  \
+XN_FUNC_XN_XN_BODY(uint, fnc, body)   \
+XN_FUNC_XN_XN_BODY(int, fnc, body)    \
+XN_FUNC_XN_XN_BODY(float, fnc, body)
 
-DEF_UIFUNC_1(abs)
-DEF_IFUNC_1(clz)
+UIN_FUNC_IN(abs)
+IN_FUNC_IN(clz)
 
-DEF_IFUNC_2(min, (v1 < v2 ? v1 : v2))
-DEF_FUNC_2F(min)
+IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
+FN_FUNC_FN_F(min)
 
-DEF_IFUNC_2(max, (v1 > v2 ? v1 : v2))
-DEF_FUNC_2F(max)
+IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
+FN_FUNC_FN_F(max)
 
 // 6.11.4
 
@@ -617,7 +744,7 @@
 _RS_STATIC float __attribute__((overloadable)) degrees(float radians) {
     return radians * (180.f / M_PI);
 }
-DEF_FUNC_1(degrees)
+FN_FUNC_FN(degrees)
 
 _RS_STATIC float __attribute__((overloadable)) mix(float start, float stop, float amount) {
     return start + (stop - start) * amount;
@@ -644,7 +771,7 @@
 _RS_STATIC float __attribute__((overloadable)) radians(float degrees) {
     return degrees * (M_PI / 180.f);
 }
-DEF_FUNC_1(radians)
+FN_FUNC_FN(radians)
 
 _RS_STATIC float __attribute__((overloadable)) step(float edge, float v) {
     return (v < edge) ? 0.f : 1.f;
@@ -705,7 +832,7 @@
     if (v < 0) return -1.f;
     return v;
 }
-DEF_FUNC_1(sign)
+FN_FUNC_FN(sign)
 
 // 6.11.5
 _RS_STATIC float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
@@ -779,15 +906,21 @@
 
 #undef CVT_FUNC
 #undef CVT_FUNC_2
-#undef DEF_FUNC_1
-#undef DEF_FUNC_1_RI
-#undef DEF_FUNC_2
-#undef DEF_FUNC_2F
-#undef DEF_RIFUNC_1
-#undef DEF_UIFUNC_1
-#undef DEF_IFUNC_1
-#undef DEF_RIFUNC_2
-#undef DEF_IFUNC_2
+#undef FN_FUNC_FN
+#undef IN_FUNC_FN
+#undef FN_FUNC_FN_FN
+#undef FN_FUNC_FN_F
+#undef FN_FUNC_FN_IN
+#undef FN_FUNC_FN_I
+#undef FN_FUNC_FN_PFN
+#undef FN_FUNC_FN_PIN
+#undef FN_FUNC_FN_FN_FN
+#undef FN_FUNC_FN_FN_PIN
+#undef XN_FUNC_YN
+#undef UIN_FUNC_IN
+#undef IN_FUNC_IN
+#undef XN_FUNC_XN_XN_BODY
+#undef IN_FUNC_IN_IN_BODY
 #undef _RS_STATIC
 
 #endif
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index ce84683..33ef1fc 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -61,7 +61,7 @@
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
             list.keyAt(i), rec.size/1024.0f, 
             rec.w, rec.s, rec.h, rec.format, rec.usage);
         result.append(buffer);
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index b03588f..1c02878 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -93,29 +93,28 @@
      *
      * @throws IOException
      */
-    public MediaImageItem(VideoEditor editor, String mediaItemId,
-                         String filename, long durationMs,
-                         int renderingMode) throws IOException {
+    public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
+        int renderingMode) throws IOException {
 
         super(editor, mediaItemId, filename, renderingMode);
 
         mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
         mVideoEditor = ((VideoEditorImpl)editor);
         try {
-            final Properties properties =
-                                   mMANativeHelper.getMediaProperties(filename);
+            final Properties properties = mMANativeHelper.getMediaProperties(filename);
 
             switch (mMANativeHelper.getFileType(properties.fileType)) {
                 case MediaProperties.FILE_JPEG:
+                case MediaProperties.FILE_PNG: {
                     break;
-                case MediaProperties.FILE_PNG:
-                    break;
+                }
 
-                default:
-                throw new IllegalArgumentException("Unsupported Input File Type");
+                default: {
+                    throw new IllegalArgumentException("Unsupported Input File Type");
+                }
             }
         } catch (Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found");
+            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
         }
 
         /**
@@ -130,13 +129,13 @@
         mDurationMs = durationMs;
         mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
                 "/" + "decoded" + getId()+ ".rgb");
-        final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
-        final DataOutputStream dos = new DataOutputStream(fl);
+
         try {
             mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
         } catch(IllegalArgumentException e) {
             throw new IllegalArgumentException ("Null width and height");
         }
+
         mGeneratedClipHeight = 0;
         mGeneratedClipWidth = 0;
 
@@ -146,9 +145,12 @@
          */
         final Pair<Integer, Integer>[] resolutions =
             MediaProperties.getSupportedResolutions(mAspectRatio);
+
         /**
          *  Get the highest resolution
          */
+        final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
+        final DataOutputStream dos = new DataOutputStream(fl);
         final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
         if (mHeight > maxResolution.second) {
             /**
@@ -171,16 +173,16 @@
             int mNewHeight = 0;
             if ((mScaledWidth % 2 ) != 0) {
                 mNewWidth = mScaledWidth - 1;
-            }
-            else {
+            } else {
                 mNewWidth = mScaledWidth;
             }
+
             if ((mScaledHeight % 2 ) != 0) {
                 mNewHeight = mScaledHeight - 1;
-            }
-            else {
+            } else {
                 mNewHeight = mScaledHeight;
             }
+
             final int [] framingBuffer = new int[mNewWidth];
             final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
             IntBuffer intBuffer;
@@ -195,6 +197,7 @@
                 dos.write(array);
                 tmp += 1;
             }
+
             mScaledWidth = mNewWidth;
             mScaledHeight = mNewHeight;
             scaledImage.recycle();
@@ -204,10 +207,11 @@
                                 + "/" + "scaled" + getId()+ ".JPG");
             if (!((new File(mScaledFilename)).exists())) {
                 super.mRegenerateClip = true;
-                FileOutputStream f1 = new FileOutputStream(mScaledFilename);
+                final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
                 scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1);
                 f1.close();
             }
+
             mScaledWidth = scaledImage.getWidth();
             mScaledHeight = scaledImage.getHeight();
 
@@ -215,17 +219,17 @@
             int mNewheight = 0;
             if ((mScaledWidth % 2 ) != 0) {
                 mNewWidth = mScaledWidth - 1;
-            }
-            else {
+            } else {
                 mNewWidth = mScaledWidth;
             }
+
             if ((mScaledHeight % 2 ) != 0) {
                 mNewheight = mScaledHeight - 1;
-            }
-            else {
+            } else {
                 mNewheight = mScaledHeight;
             }
-            Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
+
+            final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
             final int [] framingBuffer = new int[mNewWidth];
             ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
             IntBuffer intBuffer;
@@ -240,10 +244,12 @@
                 dos.write(array);
                 tmp += 1;
             }
+
             mScaledWidth = mNewWidth;
             mScaledHeight = mNewheight;
             imageBitmap.recycle();
         }
+
         fl.close();
         System.gc();
     }
@@ -286,7 +292,7 @@
 
     /**
      * @return The file name of image which is decoded and stored
-     * in rgb format
+     * in RGB format
      */
     String getDecodedImageFileName() {
         return mDecodedFilename;
@@ -447,7 +453,7 @@
                  *  Check if the effect overlaps with the end transition
                  */
                 if (effect.getStartTime() + effect.getDuration() >
-                mDurationMs - transitionDurationMs) {
+                    mDurationMs - transitionDurationMs) {
                     mEndTransition.invalidate();
                     break;
                 }
@@ -464,7 +470,7 @@
                      *  Check if the overlay overlaps with the end transition
                      */
                     if (overlay.getStartTime() + overlay.getDuration() >
-                    mDurationMs - transitionDurationMs) {
+                        mDurationMs - transitionDurationMs) {
                         mEndTransition.invalidate();
                         break;
                     }
@@ -648,23 +654,24 @@
             for (int i = 0; i < thumbnailCount; i++) {
                 thumbnailArray[i] = thumbnail;
             }
+
             return thumbnailArray;
-
-
-        }
-        else {
+        } else {
             if (startMs > endMs) {
                 throw new IllegalArgumentException("Start time is greater than end time");
             }
+
             if (endMs > mDurationMs) {
                 throw new IllegalArgumentException("End time is greater than file duration");
             }
+
             if (startMs == endMs) {
                 Bitmap[] bitmap = new Bitmap[1];
                 bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
                     width, height,startMs);
                 return bitmap;
             }
+
             return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
                 height,startMs,endMs,thumbnailCount);
         }
@@ -704,31 +711,51 @@
          */
         if (mBeginTransition != null) {
             final long transitionDurationMs = mBeginTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
+                    transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
+                    transitionDurationMs);
             /**
-             *  If the start time has changed and if the old or the new item
-             *  overlaps with the begin transition, invalidate the transition.
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (((oldStartTimeMs != newStartTimeMs)
-                    || (oldDurationMs != newDurationMs) )&&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
-                    isOverlapping(newStartTimeMs, newDurationMs, 0,
-                    transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mBeginTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs != newStartTimeMs) ||
+                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
+                    mBeginTransition.invalidate();
+                }
             }
         }
 
         if (mEndTransition != null) {
             final long transitionDurationMs = mEndTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mDurationMs - transitionDurationMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mDurationMs - transitionDurationMs, transitionDurationMs);
             /**
-             *  If the start time + duration has changed and if the old or the new
-             *  item overlaps the end transition, invalidate the transition
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs) ||
-                    isOverlapping(newStartTimeMs, newDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mEndTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+                        ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
+                        newStartTimeMs > mDurationMs - transitionDurationMs)) {
+                    mEndTransition.invalidate();
+                }
             }
         }
     }
@@ -743,10 +770,12 @@
             setGeneratedImageClip(null);
             setRegenerateClip(true);
         }
+
         if (mScaledFilename != null) {
             new File(mScaledFilename).delete();
             mScaledFilename = null;
         }
+
         if (mDecodedFilename != null) {
             new File(mDecodedFilename).delete();
             mDecodedFilename = null;
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 772b360..2981b41 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -78,12 +78,9 @@
      *
      * @throws IOException if the file cannot be opened for reading
      */
-    public MediaVideoItem(VideoEditor editor, String mediaItemId,
-            String filename,
-            int renderingMode)
-    throws IOException {
-        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE,
-                100, false, null);
+    public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
+            int renderingMode) throws IOException {
+        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
     }
 
     /**
@@ -105,20 +102,22 @@
      * @throws IOException if the file cannot be opened for reading
      */
     MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
-            int renderingMode,
-            long beginMs, long endMs, int volumePercent, boolean muted,
+            int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
             String audioWaveformFilename)  throws IOException {
         super(editor, mediaItemId, filename, renderingMode);
+
         if (editor instanceof VideoEditorImpl) {
             mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
             mVideoEditor = ((VideoEditorImpl)editor);
         }
-        Properties properties = null;
+
+        final Properties properties;
         try {
              properties = mMANativeHelper.getMediaProperties(filename);
         } catch ( Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found");
+            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
         }
+
         switch (mMANativeHelper.getFileType(properties.fileType)) {
             case MediaProperties.FILE_3GP:
                 break;
@@ -163,8 +162,7 @@
         mMuted = muted;
         mAudioWaveformFilename = audioWaveformFilename;
         if (audioWaveformFilename != null) {
-            mWaveformData =
-                new SoftReference<WaveformData>(
+            mWaveformData = new SoftReference<WaveformData>(
                         new WaveformData(audioWaveformFilename));
         } else {
             mWaveformData = null;
@@ -190,9 +188,11 @@
         if (beginMs > mDurationMs) {
             throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
         }
+
         if (endMs > mDurationMs) {
             throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
         }
+
         if ((endMs != -1) && (beginMs >= endMs) ) {
             throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
         }
@@ -255,18 +255,18 @@
      */
     @Override
     public Bitmap getThumbnail(int width, int height, long timeMs) {
-        if (timeMs > mDurationMs)
-        {
+        if (timeMs > mDurationMs) {
             throw new IllegalArgumentException("Time Exceeds duration");
         }
-        if (timeMs < 0)
-        {
+
+        if (timeMs < 0) {
             throw new IllegalArgumentException("Invalid Time duration");
         }
-        if ((width <=0) || (height <= 0))
-        {
+
+        if ((width <=0) || (height <= 0)) {
             throw new IllegalArgumentException("Invalid Dimensions");
         }
+
         return mMANativeHelper.getPixels(super.getFilename(),
                 width, height,timeMs);
     }
@@ -280,18 +280,21 @@
         if (startMs > endMs) {
             throw new IllegalArgumentException("Start time is greater than end time");
         }
+
         if (endMs > mDurationMs) {
             throw new IllegalArgumentException("End time is greater than file duration");
         }
+
         if ((height <= 0) || (width <= 0)) {
             throw new IllegalArgumentException("Invalid dimension");
         }
+
         if (startMs == endMs) {
-            Bitmap[] bitmap = new Bitmap[1];
-            bitmap[0] = mMANativeHelper.getPixels(super.getFilename(),
-                    width, height,startMs);
+            final Bitmap[] bitmap = new Bitmap[1];
+            bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
             return bitmap;
         }
+
         return mMANativeHelper.getPixelsList(super.getFilename(), width,
                 height,startMs,endMs,thumbnailCount);
     }
@@ -324,40 +327,58 @@
      * {@inheritDoc}
      */
     @Override
-    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
-            long newStartTimeMs,
+    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
             long newDurationMs) {
         /**
          *  Check if the item overlaps with the beginning and end transitions
          */
         if (mBeginTransition != null) {
             final long transitionDurationMs = mBeginTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mBeginBoundaryTimeMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mBeginBoundaryTimeMs, transitionDurationMs);
             /**
-             *  If the start time has changed and if the old or the new item
-             *  overlaps with the begin transition, invalidate the transition.
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (((oldStartTimeMs != newStartTimeMs)
-                    || (oldDurationMs != newDurationMs) )&&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                            mBeginBoundaryTimeMs, transitionDurationMs) ||
-                            isOverlapping(newStartTimeMs, newDurationMs,
-                                    mBeginBoundaryTimeMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mBeginTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs != newStartTimeMs) ||
+                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
+                    mBeginTransition.invalidate();
+                }
             }
         }
 
         if (mEndTransition != null) {
             final long transitionDurationMs = mEndTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
             /**
-             *  If the start time + duration has changed and if the old or the new
-             *  item overlaps the end transition, invalidate the transition
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                            mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
-                            isOverlapping(newStartTimeMs, newDurationMs,
-                                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mEndTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+                        ((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
+                        newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
+                    mEndTransition.invalidate();
+                }
             }
         }
     }
@@ -434,7 +455,7 @@
             throw new IllegalArgumentException("requested time not correct");
         }
 
-        Surface surface = surfaceHolder.getSurface();
+        final Surface surface = surfaceHolder.getSurface();
         if (surface == null) {
             throw new RuntimeException("Surface could not be retrieved from Surface holder");
         }
@@ -442,8 +463,7 @@
         if (mFilename != null) {
             return mMANativeHelper.renderMediaItemPreviewFrame(surface,
                     mFilename,timeMs,mWidth,mHeight);
-        }
-        else {
+        } else {
             return 0;
         }
     }
@@ -462,7 +482,7 @@
      *             Audio track
      */
     public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
-    throws IOException {
+        throws IOException {
         int frameDuration = 0;
         int sampleCount = 0;
         final String projectPath = mMANativeHelper.getProjectPath();
@@ -481,19 +501,17 @@
              * Logic to get frame duration = (no. of frames per sample * 1000)/
              * sampling frequency
              */
-            if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AMRNB ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
                 sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
-            }
-            else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AMRWB ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
                 sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
-            }
-            else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AAC_LC ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
@@ -682,5 +700,4 @@
 
         return clipSettings;
     }
-
 }
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 27c41be..0a01fb2 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -85,6 +85,6 @@
 # to add this library to the prelink map and set this to true.
 LOCAL_PRELINK_MODULE := false
 
-LOCAL_MODULE_TAGS := eng development
+LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 58c4a2e..11ac56c 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -58,6 +58,8 @@
 
 static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
 static int64_t kHighWaterMarkUs = 10000000ll;  // 10secs
+static const size_t kLowWaterMarkBytes = 40000;
+static const size_t kHighWaterMarkBytes = 200000;
 
 struct AwesomeEvent : public TimedEventQueue::Event {
     AwesomeEvent(
@@ -610,9 +612,6 @@
                 // We don't know the bitrate of the stream, use absolute size
                 // limits to maintain the cache.
 
-                const size_t kLowWaterMarkBytes = 40000;
-                const size_t kHighWaterMarkBytes = 200000;
-
                 if ((mFlags & PLAYING) && !eos
                         && (cachedDataRemaining < kLowWaterMarkBytes)) {
                     LOGI("cache is running low (< %d) , pausing.",
@@ -1535,6 +1534,34 @@
         mConnectingDataSource.clear();
 
         dataSource = mCachedSource;
+
+        // We're going to prefill the cache before trying to instantiate
+        // the extractor below, as the latter is an operation that otherwise
+        // could block on the datasource for a significant amount of time.
+        // During that time we'd be unable to abort the preparation phase
+        // without this prefill.
+
+        mLock.unlock();
+
+        for (;;) {
+            status_t finalStatus;
+            size_t cachedDataRemaining =
+                mCachedSource->approxDataRemaining(&finalStatus);
+
+            if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+                    || (mFlags & PREPARE_CANCELLED)) {
+                break;
+            }
+
+            usleep(200000);
+        }
+
+        mLock.lock();
+
+        if (mFlags & PREPARE_CANCELLED) {
+            LOGI("Prepare cancelled while waiting for initial cache fill.");
+            return UNKNOWN_ERROR;
+        }
     } else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
         String8 uri("http://");
         uri.append(mUri.string() + 11);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 06c4c98..a47ee3a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -590,6 +590,7 @@
 
     status_t err = OK;
     int64_t maxDurationUs = 0;
+    int64_t minDurationUs = 0x7fffffffffffffffLL;
     for (List<Track *>::iterator it = mTracks.begin();
          it != mTracks.end(); ++it) {
         status_t status = (*it)->stop();
@@ -601,6 +602,14 @@
         if (durationUs > maxDurationUs) {
             maxDurationUs = durationUs;
         }
+        if (durationUs < minDurationUs) {
+            minDurationUs = durationUs;
+        }
+    }
+
+    if (mTracks.size() > 1) {
+        LOGD("Duration from tracks range is [%lld, %lld] us",
+            minDurationUs, maxDurationUs);
     }
 
     stopWriterThread();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 20f1655..741aa1c 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
 #define LOG_TAG "NuCachedSource2"
 #include <utils/Log.h>
 
@@ -487,4 +488,5 @@
 String8 NuCachedSource2::getUri() {
     return mSource->getUri();
 }
+
 }  // namespace android
diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf
index 3945183..7b550eed 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock.ttf
Binary files differ
diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
index fa0221e..a95d548 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
index dadb0cd..92ffde9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
index 51d7cc2..0cd05a30 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
index 3359602..993ea55 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
index 91bc4ee..d00a0c9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
index aa64de4..7d225346 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
new file mode 100644
index 0000000..22d6c79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
new file mode 100644
index 0000000..24166da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
new file mode 100644
index 0000000..85d9795
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..b389a35
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/panel_notification.png b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
new file mode 100644
index 0000000..3789f3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
deleted file mode 100755
index e9589d9..0000000
--- a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
new file mode 100644
index 0000000..0371322
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/notify_panel_bg_protect"
+    android:tileMode="repeat"
+    />
+
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index 9da92a7..3a50aa9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -20,7 +20,6 @@
     >
     <item
         android:drawable="@drawable/notification_item_background_color"
-        android:left="16dp"
         />
 </layer-list>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 0533b6f..852b729 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -78,15 +78,14 @@
             </LinearLayout>
 
             <!-- fake space bar zone -->
-            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/fake_space_bar"
+            <com.android.systemui.statusbar.policy.EventHole android:id="@+id/fake_space_bar"
                 android:layout_height="match_parent"
-                android:layout_width="match_parent"
+                android:layout_width="0dp"
                 android:paddingLeft="8dip"
                 android:paddingRight="8dip"
                 android:layout_toRightOf="@+id/navigationArea"
                 android:layout_toLeftOf="@+id/notificationArea"
                 android:visibility="gone"
-                systemui:keyCode="62"
                 />
         </RelativeLayout>
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 7f84b21..26e045c 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -25,8 +25,8 @@
 
     <View
         android:id="@+id/scrim"
-        android:background="@drawable/notify_panel_bg_protect"
-        android:layout_width="match_parent"
+        android:background="@drawable/notify_panel_bg_protect_tiled"
+        android:layout_width="512dp"
         android:layout_height="match_parent"
         android:layout_alignParentTop="true"
         android:layout_alignParentRight="true"
@@ -35,142 +35,27 @@
     <RelativeLayout
         android:id="@+id/content_parent"
         android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_alignParentBottom="true"
         android:layout_alignParentRight="true"
         >
-        <RelativeLayout
-            android:id="@+id/title_area"
-            android:layout_height="160dp"
-            android:layout_width="384dp"
-            android:layout_marginLeft="24dp"
-            android:paddingTop="20dp"
-            android:orientation="vertical"
+
+        <include layout="@layout/status_bar_notification_panel_title"
+            android:layout_width="471dp"
+            android:layout_height="465dp"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
-            android:background="@drawable/panel_notification_tiled"
-            >
-
-            <com.android.systemui.statusbar.tablet.HoloClock
-                android:id="@+id/clock"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:layout_alignParentTop="true"
-                android:layout_marginRight="40dip"
-                android:layout_marginBottom="4dip"
-                >
-                <TextView android:id="@+id/time_bg"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:gravity="right"
-                    android:singleLine="true"
-                    android:textSize="90dip"
-                    android:textColor="#999999" />
-                <TextView android:id="@+id/time_fg"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:gravity="right"
-                    android:singleLine="true"
-                    android:textSize="90dip"
-                    android:textColor="#666666" />
-            </com.android.systemui.statusbar.tablet.HoloClock>
-
-            <com.android.systemui.statusbar.policy.DateView
-                android:id="@+id/date"
-                style="@style/StatusBarNotificationText"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:layout_below="@id/clock"
-                android:layout_marginTop="4dp"
-                android:layout_marginRight="48dp"
-                android:gravity="right"
-                />
-
-            <ImageView
-                android:id="@+id/battery"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_below="@id/date"
-                android:layout_marginLeft="48dp"
-                android:layout_marginTop="18dp"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <TextView
-                android:id="@+id/battery_text"
-                style="@style/StatusBarNotificationText"
-                android:layout_width="56dp"
-                android:layout_height="wrap_content"
-                android:layout_toRightOf="@id/battery"
-                android:layout_alignBaseline="@id/battery"
-                android:singleLine="true"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <ImageView
-                android:id="@+id/network_signal"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_toRightOf="@id/battery_text"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <ImageView
-                android:id="@+id/network_type"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_toRightOf="@id/battery_text"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <TextView
-                android:id="@+id/network_text"
-                style="@style/StatusBarNotificationText"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_toRightOf="@id/network_signal"
-                android:layout_alignBaseline="@id/battery"
-                android:singleLine="true"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <ImageView
-                android:id="@+id/settings_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_alignParentRight="true"
-                android:paddingRight="16dp"
-                android:src="@drawable/ic_notification_open"
-                android:baseline="21dp"
-                />
-
-            <ImageView
-                android:id="@+id/notification_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_alignBaseline="@id/battery"
-                android:paddingRight="16dp"
-                android:visibility="invisible"
-                android:src="@drawable/status_bar_veto"
-                android:baseline="21dp"
-                />
-        </RelativeLayout>
+            />
 
         <LinearLayout
             android:id="@+id/content_frame"
+            android:background="@drawable/notify_panel_notify_bg"
             android:layout_height="wrap_content"
-            android:layout_width="408dp"
+            android:layout_width="447dp"
             android:orientation="vertical"
-            android:layout_below="@id/title_area"
             android:layout_alignParentRight="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="352dp"
             >
             <ScrollView
                 android:id="@+id/notification_scroller"
@@ -189,17 +74,9 @@
                     android:clickable="true"
                     android:focusable="true"
                     android:descendantFocusability="afterDescendants"
-                    systemui:insetLeft="16dp"
                     >
                 </com.android.systemui.statusbar.tablet.NotificationLinearLayout>
             </ScrollView>
-            <ImageView
-                android:id="@+id/notification_glow"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/status_bar_panel_bottom_offset"
-                android:layout_marginLeft="16dp"
-                android:src="@drawable/notify_item_glow_bottom"
-                />
         </LinearLayout>
     </RelativeLayout>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
new file mode 100644
index 0000000..992995c
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -0,0 +1,153 @@
+<!--
+  Copyright (C) 2006 The Android Open Source Project
+ 
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+ 
+       http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    android:id="@+id/title_area"
+    android:layout_width="0dp"
+    android:layout_height="0dp"
+    android:orientation="vertical"
+    android:background="@drawable/notify_panel_clock_bg"
+    >
+
+    <ImageView
+        android:id="@+id/network_signal"
+        android:layout_height="32dp"
+        android:layout_width="32dp"
+        android:scaleType="centerInside"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:baseline="22dp"
+        android:layout_marginLeft="32dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="16dp"
+        />
+
+    <ImageView
+        android:id="@+id/network_type"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_alignLeft="@id/network_signal"
+        android:layout_alignBottom="@id/network_signal"
+        android:layout_marginRight="8dp"
+        />
+
+    <TextView
+        android:id="@+id/network_text"
+        style="@style/StatusBarNotificationText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/network_signal"
+        android:layout_marginRight="8dp"
+        android:layout_alignBaseline="@id/network_signal"
+        android:singleLine="true"
+        android:text="@string/status_bar_settings_settings_button"
+        />
+
+    <ImageView
+        android:id="@+id/battery"
+        android:layout_height="32dp"
+        android:layout_width="32dp"
+        android:scaleType="centerInside"
+        android:layout_toRightOf="@id/network_text"
+        android:layout_alignBaseline="@id/network_signal"
+        android:baseline="22dp"
+        />
+
+    <TextView
+        android:id="@+id/battery_text"
+        style="@style/StatusBarNotificationText"
+        android:layout_width="56dp"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/battery"
+        android:layout_alignBaseline="@id/battery"
+        android:layout_marginRight="8dp"
+        android:singleLine="true"
+        android:text="@string/status_bar_settings_settings_button"
+        />
+
+    <ImageView
+        android:id="@+id/settings_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@id/battery"
+        android:layout_alignParentRight="true"
+        android:paddingRight="16dp"
+        android:src="@drawable/ic_notification_open"
+        android:baseline="21dp"
+        />
+
+    <ImageView
+        android:id="@+id/notification_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignBaseline="@id/battery"
+        android:paddingRight="16dp"
+        android:visibility="invisible"
+        android:src="@drawable/status_bar_veto"
+        android:baseline="21dp"
+        />
+
+    <View
+        android:id="@+id/title_divider"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_marginLeft="32dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="64dip"
+        android:background="@android:drawable/divider_horizontal_dark"
+        />
+
+    <com.android.systemui.statusbar.tablet.HoloClock
+        android:id="@+id/clock"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_alignParentRight="true"
+        android:layout_above="@id/title_divider"
+        android:layout_marginRight="32dip"
+        android:layout_marginBottom="8dip"
+        >
+        <TextView android:id="@+id/time_bg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:singleLine="true"
+            android:textSize="80sp"
+            android:textColor="#999999" />
+        <TextView android:id="@+id/time_fg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:singleLine="true"
+            android:textSize="80sp"
+            android:textColor="#666666" />
+    </com.android.systemui.statusbar.tablet.HoloClock>
+
+    <com.android.systemui.statusbar.policy.DateView
+        android:id="@+id/date"
+        style="@style/StatusBarNotificationText"
+        android:layout_height="wrap_content"
+        android:layout_width="142dp"
+        android:layout_alignBottom="@id/clock"
+        android:layout_alignParentLeft="true"
+        android:gravity="left"
+        android:layout_marginLeft="32dp"
+        />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
index e97345b..233cb46 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
@@ -32,7 +32,6 @@
         android:layout_alignParentTop="true"
         android:layout_toRightOf="@id/large_icon"
         android:layout_toLeftOf="@id/veto"
-        android:layout_marginLeft="16dp"
         android:focusable="true"
         android:clickable="true"
         />
@@ -40,7 +39,6 @@
     <View
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:layout_marginLeft="16dp"
         android:layout_alignParentBottom="true"
         android:background="@android:drawable/divider_horizontal_dark"
         />
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 8a477e4..1dbd759 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -22,8 +22,7 @@
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:background="@drawable/status_bar_item_background"
-        android:paddingLeft="16dp"
-        android:paddingRight="46dp"
+        android:paddingRight="48dp"
         >
 
     <!-- Airplane mode -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
new file mode 100644
index 0000000..47e758c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Region;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.ServiceManager;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.HapticFeedbackConstants;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
+import android.widget.RemoteViews.RemoteView;
+
+import com.android.systemui.R;
+
+public class EventHole extends View implements ViewTreeObserver.OnComputeInternalInsetsListener {
+    private static final String TAG = "StatusBar.EventHole";
+
+    private boolean mWindowVis;
+    private int[] mLoc = new int[2];
+
+    public EventHole(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public EventHole(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onWindowVisibilityChanged(int visibility) {
+        super.onWindowVisibilityChanged(visibility);
+        mWindowVis = visibility == View.VISIBLE;
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+    }
+
+    public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+        final boolean visible = isShown() && mWindowVis && getWidth() > 0 && getHeight() > 0;
+        final int[] loc = mLoc;
+        getLocationInWindow(loc);
+        final int l = loc[0];
+        final int r = l + getWidth();
+        final int t = loc[1];
+        final int b = t + getHeight();
+        
+        View top = this;
+        while (top.getParent() instanceof View) {
+            top = (View)top.getParent();
+        }
+
+        if (visible) {
+            info.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+            info.touchableRegion.set(0, 0, top.getWidth(), top.getHeight());
+            info.touchableRegion.op(l, t, r, b, Region.Op.DIFFERENCE);
+        } else {
+            info.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+        }
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 45a22b6..692d41c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -50,9 +50,8 @@
     View mSettingsButton;
     View mNotificationButton;
     View mNotificationScroller;
-    View mNotificationGlow;
     ViewGroup mContentFrame;
-    Rect mContentArea;
+    Rect mContentArea = new Rect();
     View mSettingsView;
     View mScrim, mGlow;
     ViewGroup mContentParent;
@@ -85,7 +84,6 @@
         mNotificationButton = (ImageView)findViewById(R.id.notification_button);
 
         mNotificationScroller = findViewById(R.id.notification_scroller);
-        mNotificationGlow = findViewById(R.id.notification_glow);
         mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
     }
 
@@ -130,13 +128,13 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
+
         mChoreo.setPanelHeight(mContentParent.getHeight());
     }
 
     @Override
     public void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mContentArea = null;
     }
 
     public void onClick(View v) {
@@ -165,13 +163,11 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        if (mContentArea == null) {
-            mContentArea = new Rect(mContentFrame.getLeft(),
-                    mTitleArea.getTop(),
-                    mContentFrame.getRight(),
-                    mContentFrame.getBottom());
-            offsetDescendantRectToMyCoords(mContentParent, mContentArea);
-        }
+        mContentArea.left = mContentFrame.getLeft();
+        mContentArea.top = mTitleArea.getTop();
+        mContentArea.right = mContentFrame.getRight();
+        mContentArea.bottom = mContentFrame.getBottom();
+        offsetDescendantRectToMyCoords(mContentParent, mContentArea);
         return mContentArea.contains(x, y);
     }
 
@@ -185,7 +181,7 @@
     void addSettingsView() {
         LayoutInflater infl = LayoutInflater.from(getContext());
         mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
-        mContentFrame.addView(mSettingsView, mContentFrame.indexOfChild(mNotificationGlow));
+        mContentFrame.addView(mSettingsView);
     }
 
     private class Choreographer implements Animator.AnimatorListener {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3e930ae..2af291d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -583,7 +583,7 @@
         void broadcastDragStartedLw(final float touchX, final float touchY) {
             // Cache a base-class instance of the clip metadata so that parceling
             // works correctly in calling out to the apps.
-            mDataDescription = mData.getDescription();
+            mDataDescription = (mData != null) ? mData.getDescription() : null;
             mNotifiedWindows.clear();
             mDragInProgress = true;
 
@@ -708,16 +708,20 @@
 
             // Move the surface to the given touch
             if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
-            mSurface.openTransaction();
+            Surface.openTransaction();
             try {
                 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
             } finally {
-                mSurface.closeTransaction();
+                Surface.closeTransaction();
                 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
             }
 
             // Tell the affected window
             WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+            if (touchedWin == null) {
+                if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
+                return;
+            }
             if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
                 final IBinder touchedBinder = touchedWin.mClient.asBinder();
                 if (touchedBinder != mLocalWin) {
@@ -5865,7 +5869,7 @@
             final InputWindow inputWindow = windowList.add();
             inputWindow.inputChannel = mDragState.mServerChannel;
             inputWindow.name = "drag";
-            inputWindow.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+            inputWindow.layoutParamsFlags = 0;
             inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
             inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
             inputWindow.visible = true;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2ef85d5..9e9a4f2 100755
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6817,6 +6817,9 @@
             if (info.durationMillis != -1) {
                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
             }
+            if (info.numInstances != -1) {
+                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
+            }
             if (info.tags != null) {
                 for (String tag : info.tags) {
                     sb.append("Span-Tag: ").append(tag).append("\n");
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 0c1fcf9..9ddb05f 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -534,6 +534,12 @@
     result.append(buffer);
 }
 
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBase::dump(result, scratch, size);
+}
+
+
 // ---------------------------------------------------------------------------
 
 int32_t LayerBaseClient::sIdentity = 1;
@@ -585,6 +591,12 @@
     result.append(buffer);
 }
 
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBaseClient::dump(result, scratch, size);
+}
+
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::Surface::Surface(
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index f6c49fc..13af223 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -211,6 +211,7 @@
     
     /** always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 
     enum { // flags for doTransaction()
@@ -324,6 +325,7 @@
 
 protected:
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 private:
     mutable Mutex mLock;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 65ad956..434e473 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1491,8 +1491,13 @@
             result.append(buffer);
         }
 
+        /*
+         * Dump the visible layer list
+         */
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
+        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+        result.append(buffer);
         for (size_t i=0 ; i<count ; i++) {
             const sp<LayerBase>& layer(currentLayers[i]);
             layer->dump(result, buffer, SIZE);
@@ -1502,6 +1507,24 @@
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
         }
 
+        /*
+         * Dump the layers in the purgatory
+         */
+
+        const size_t purgatorySize =  mLayerPurgatory.size();
+        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+        result.append(buffer);
+        for (size_t i=0 ; i<purgatorySize ; i++) {
+            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+            layer->shortDump(result, buffer, SIZE);
+        }
+
+        /*
+         * Dump SurfaceFlinger global state
+         */
+
+        snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+        result.append(buffer);
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
@@ -1527,6 +1550,9 @@
             result.append(buffer);
         }
 
+        /*
+         * Dump HWComposer state
+         */
         HWComposer& hwc(hw.getHwComposer());
         snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
                 hwc.initCheck()==NO_ERROR ? "present" : "not present",
@@ -1534,6 +1560,9 @@
         result.append(buffer);
         hwc.dump(result, buffer, SIZE);
 
+        /*
+         * Dump gralloc state
+         */
         const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
         alloc.dump(result);
         hw.dump(result);
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 691aff28..7a61b3c 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -53,6 +53,15 @@
         </activity>
         
         <activity
+                android:name="ViewLayersActivity3"
+                android:label="_ViewLayers3">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <activity
                 android:name="AlphaLayersActivity"
                 android:label="_αLayers">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/res/layout/view_layers_3.xml b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
new file mode 100644
index 0000000..a820f5f
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:background="#30ff0000"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+
+    <LinearLayout
+        android:background="#3000ff00"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:padding="12dip">
+
+        <ListView
+            android:id="@+id/list1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:background="#300000ff"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
new file mode 100644
index 0000000..c8ae75b
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ViewLayersActivity3 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.view_layers_3);
+
+        setupList(R.id.list1);
+    }
+
+    private void setupList(int listId) {
+        final ListView list = (ListView) findViewById(listId);
+        list.setAdapter(new SimpleListAdapter(this));
+        list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        ((View) list.getParent()).setLayerType(View.LAYER_TYPE_HARDWARE, null);
+    }
+
+    private static class SimpleListAdapter extends ArrayAdapter<String> {
+        public SimpleListAdapter(Context context) {
+            super(context, android.R.layout.simple_list_item_1, DATA_LIST);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            TextView v = (TextView) super.getView(position, convertView, parent);
+            final Resources r = getContext().getResources();
+            final DisplayMetrics metrics = r.getDisplayMetrics();
+            v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f));
+            v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon),
+                    null, null, null);
+            return v;
+        }
+    }
+
+    private static final String[] DATA_LIST = {
+            "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+            "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+            "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+            "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+            "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+            "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
+            "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
+            "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+            "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+            "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+            "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+            "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+            "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+            "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+            "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+            "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+            "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+            "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+            "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+            "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+            "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+            "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+            "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+            "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+            "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+            "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+            "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+            "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+            "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+            "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+            "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+            "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+            "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+            "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+            "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+            "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+            "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+            "Ukraine", "United Arab Emirates", "United Kingdom",
+            "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+            "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+            "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+    };
+}