Merge "heads up notifications, v0.1"
diff --git a/api/current.txt b/api/current.txt
index 80952e3..3318e06 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35600,6 +35600,7 @@
     method public int getResponseCode() throws java.io.IOException;
     method public java.lang.String getResponseMessage() throws java.io.IOException;
     method public void setChunkedStreamingMode(int);
+    method public void setFixedLengthStreamingMode(long);
     method public void setFixedLengthStreamingMode(int);
     method public static void setFollowRedirects(boolean);
     method public void setInstanceFollowRedirects(boolean);
@@ -35643,6 +35644,7 @@
     field public static final int HTTP_VERSION = 505; // 0x1f9
     field protected int chunkLength;
     field protected int fixedContentLength;
+    field protected long fixedContentLengthLong;
     field protected boolean instanceFollowRedirects;
     field protected java.lang.String method;
     field protected int responseCode;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8f0c62d..810a521 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1569,7 +1569,7 @@
                 currentKey = parsePublicKey(encodedKey);
                 definedKeySets.put(currentKey, new HashSet<String>());
                 sa.recycle();
-             } else if (tagname.equals("keyset")) {
+            } else if (tagname.equals("keyset")) {
                 final TypedArray sa = res.obtainAttributes(attrs,
                         com.android.internal.R.styleable.KeySet);
                 final String name = sa.getNonResourceString(
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 5cc1150..c3e9cb7 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -204,37 +204,71 @@
     // TODO(): The following arrays are fragile and error-prone. This needs to be refactored.
 
     // Note: This needs to be updated, whenever a new sensor is added.
-    private static int[] sSensorReportingModes = {
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT };
-
-    // Note: This needs to be updated, whenever a new sensor is added.
-    // Holds the maximum length of the values array associated with {@link SensorEvent} or
-    // {@link TriggerEvent} for the Sensor
-    private static int[] sMaxLengthValuesArray = {
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3,
-            6, 4, 6, 1 };
+    // Holds the reporting mode and maximum length of the values array
+    // associated with
+    // {@link SensorEvent} or {@link TriggerEvent} for the Sensor
+    private static final int[] sSensorReportingModes = {
+            0, 0, // padding because sensor types start at 1
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ACCELEROMETER
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GEOMAGNETIC_FIELD
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ORIENTATION
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GYROSCOPE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_LIGHT
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_PRESSURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_TEMPERATURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_PROXIMITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GRAVITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_LINEAR_ACCELERATION
+            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_ROTATION_VECTOR
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_RELATIVE_HUMIDITY
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_AMBIENT_TEMPERATURE
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+            REPORTING_MODE_CONTINUOUS, 4, // SENSOR_TYPE_GAME_ROTATION_VECTOR
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+            REPORTING_MODE_ONE_SHOT,   1, // SENSOR_TYPE_SIGNIFICANT_MOTION
+            // added post 4.3
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_DETECTOR
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_COUNTER
+            REPORTING_MODE_CONTINUOUS, 5  // SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+    };
 
     static int getReportingMode(Sensor sensor) {
-        // mType starts from offset 1.
-        return sSensorReportingModes[sensor.mType - 1];
+        int offset = sensor.mType * 2;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we figure out the reporting
+            // mode from the sensor meta-data.
+            int minDelay = sensor.mMinDelay;
+            if (minDelay == 0) {
+                return REPORTING_MODE_ON_CHANGE;
+            } else if (minDelay < 0) {
+                return REPORTING_MODE_ONE_SHOT;
+            } else {
+                return REPORTING_MODE_CONTINUOUS;
+            }
+        }
+        return sSensorReportingModes[offset];
     }
 
     static int getMaxLengthValuesArray(Sensor sensor, int sdkLevel) {
-        // mType starts from offset 1.
-        int len = sMaxLengthValuesArray[sensor.mType - 1];
-
+        int type = sensor.mType;
         // RotationVector length has changed to 3 to 5 for API level 18
         // Set it to 3 for backward compatibility.
-        if (sensor.getType() == Sensor.TYPE_ROTATION_VECTOR &&
+        if (type == Sensor.TYPE_ROTATION_VECTOR &&
                 sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            len = 3;
+            return 3;
         }
-        return len;
+        int offset = type * 2 + 1;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we don't know how many value
+            // it has
+            // so we return the maximum and assume the app will know.
+            // FIXME: sensor HAL should advertise how much data is returned per
+            // sensor
+            return 16;
+        }
+        return sSensorReportingModes[offset];
     }
 
     /* Some of these fields are set only by the native bindings in
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 8e0935d..12646bd 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1803,8 +1803,8 @@
             for (int i=0; i<timers.size(); i++) {
                 TimerEntry timer = timers.get(i);
                 sb.setLength(0);
-                sb.append("  Wake lock #");
-                sb.append(timer.mId);
+                sb.append("  Wake lock ");
+                UserHandle.formatUid(sb, timer.mId);
                 sb.append(" ");
                 sb.append(timer.mName);
                 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
@@ -1822,8 +1822,11 @@
             }
             
             Uid u = uidStats.valueAt(iu);
-            
-            pw.println(prefix + "  #" + uid + ":");
+
+            pw.print(prefix);
+            pw.print("  ");
+            UserHandle.formatUid(pw, uid);
+            pw.println(":");
             boolean uidActivity = false;
             
             long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index d205253..6e693a4 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -168,8 +168,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 sb.append('i');
                 sb.append(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
                 sb.append(appId);
             }
         }
@@ -190,8 +193,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 pw.print('i');
                 pw.print(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 pw.print('a');
+                pw.print(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                pw.print('s');
                 pw.print(appId);
             }
         }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index a441c39..4adee14 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -781,7 +781,7 @@
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
@@ -796,14 +796,14 @@
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
         }
     }
 
-    private static native void nDrawPatch(int renderer, int bitmap, int chunk,
+    private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, int chunk,
             float left, float top, float right, float bottom, int paint);
 
     @Override
@@ -813,13 +813,13 @@
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             float left, float top, int paint);
 
     @Override
@@ -829,13 +829,15 @@
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap,  matrix.native_instance, nativePaint);
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
+                    matrix.native_instance, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint);
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+            int matrix, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
@@ -857,7 +859,7 @@
                 bottom = src.bottom;
             }
 
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
@@ -884,14 +886,14 @@
                 bottom = src.bottom;
             }
     
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             float srcLeft, float srcTop, float srcRight, float srcBottom,
             float left, float top, float right, float bottom, int paint);
 
@@ -960,15 +962,15 @@
 
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
-            final int nativePaint = paint == null ? 0 : paint.mNativePaint;        
-            nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight,
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+            nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
                     verts, vertOffset, colors, colorOffset, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmapMesh(int renderer, int bitmap,
+    private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
             int meshWidth, int meshHeight, float[] verts, int vertOffset,
             int[] colors, int colorOffset, int paint);
 
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index d452f58..594b130 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -1037,7 +1037,12 @@
         final int sectionCount = mSections.length;
         final int positionsInSection;
         if (section < sectionCount - 1) {
-            final int nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+            final int nextSectionPos;
+            if (section + 1 < sectionCount) {
+                nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+            } else {
+                nextSectionPos = totalItemCount - 1;
+            }
             positionsInSection = nextSectionPos - sectionPos;
         } else {
             positionsInSection = totalItemCount - sectionPos;
diff --git a/core/java/android/widget/SectionIndexer.java b/core/java/android/widget/SectionIndexer.java
index 24f894c..a1c71f4 100644
--- a/core/java/android/widget/SectionIndexer.java
+++ b/core/java/android/widget/SectionIndexer.java
@@ -20,7 +20,9 @@
  * Interface that should be implemented on Adapters to enable fast scrolling 
  * in an {@link AbsListView} between sections of the list. A section is a group of list items
  * to jump to that have something in common. For example, they may begin with the
- * same letter or they may be songs from the same artist. 
+ * same letter or they may be songs from the same artist. ExpandableListAdapters that
+ * consider groups and sections as synonymous should account for collapsed groups and return
+ * an appropriate section/position.
  */
 public interface SectionIndexer {
     /**
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 43a02cf..fe532b0 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -572,7 +572,7 @@
             if (whichButtons == BIT_BUTTON_POSITIVE) {
                 centerButton(mButtonPositive);
             } else if (whichButtons == BIT_BUTTON_NEGATIVE) {
-                centerButton(mButtonNeutral);
+                centerButton(mButtonNegative);
             } else if (whichButtons == BIT_BUTTON_NEUTRAL) {
                 centerButton(mButtonNeutral);
             }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 4e21324..78389c5 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -432,6 +432,17 @@
         }
     }
 
+    public static CharSequence getImeAndSubtypeDisplayName(Context context, InputMethodInfo imi,
+            InputMethodSubtype subtype) {
+        final CharSequence imiLabel = imi.loadLabel(context.getPackageManager());
+        return subtype != null
+                ? TextUtils.concat(subtype.getDisplayName(context,
+                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
+                                (TextUtils.isEmpty(imiLabel) ?
+                                        "" : " - " + imiLabel))
+                : imiLabel;
+    }
+
     /**
      * Utility class for putting and getting settings for InputMethod
      * TODO: Move all putters and getters of settings to this class.
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 6374494..ae0113b 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -142,7 +142,13 @@
         while ((n = q->read(buffer, 16)) > 0) {
             for (int i=0 ; i<n ; i++) {
 
-                env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
+                    // step-counter returns a uint64, but the java API only deals with floats
+                    float value = float(buffer[i].u64.step_counter);
+                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);
+                } else {
+                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                }
 
                 env->CallVoidMethod(mReceiverObject,
                         gBaseEventQueueClassInfo.dispatchSensorEvent,
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 87ebbd2..70a4daa 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -377,20 +377,31 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jfloat left, jfloat top, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        jfloat left, jfloat top, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, left, top, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap,
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
         float srcLeft, float srcTop, float srcRight, float srcBottom,
         float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
             dstLeft, dstTop, dstRight, dstBottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        SkMatrix* matrix, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, matrix, paint);
 }
 
@@ -420,8 +431,12 @@
 }
 
 static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jint meshWidth, jint meshHeight,
-         jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
+        jint colorOffset, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
     jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
 
@@ -432,8 +447,11 @@
 }
 
 static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, Res_png_9patch* patch,
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, Res_png_9patch* patch,
         float left, float top, float right, float bottom, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
 }
 
@@ -1018,14 +1036,14 @@
     { "nGetMatrix",         "(II)V",           (void*) android_view_GLES20Canvas_getMatrix },
     { "nConcatMatrix",      "(II)V",           (void*) android_view_GLES20Canvas_concatMatrix },
 
-    { "nDrawBitmap",        "(IIFFI)V",        (void*) android_view_GLES20Canvas_drawBitmap },
-    { "nDrawBitmap",        "(IIFFFFFFFFI)V",  (void*) android_view_GLES20Canvas_drawBitmapRect },
-    { "nDrawBitmap",        "(IIII)V",         (void*) android_view_GLES20Canvas_drawBitmapMatrix },
+    { "nDrawBitmap",        "(II[BFFI)V",      (void*) android_view_GLES20Canvas_drawBitmap },
+    { "nDrawBitmap",        "(II[BFFFFFFFFI)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
+    { "nDrawBitmap",        "(II[BII)V",       (void*) android_view_GLES20Canvas_drawBitmapMatrix },
     { "nDrawBitmap",        "(I[IIIFFIIZI)V",  (void*) android_view_GLES20Canvas_drawBitmapData },
 
-    { "nDrawBitmapMesh",    "(IIII[FI[III)V",  (void*) android_view_GLES20Canvas_drawBitmapMesh },
+    { "nDrawBitmapMesh",    "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
 
-    { "nDrawPatch",         "(IIIFFFFI)V",     (void*) android_view_GLES20Canvas_drawPatch },
+    { "nDrawPatch",         "(II[BIFFFFI)V",   (void*) android_view_GLES20Canvas_drawPatch },
 
     { "nDrawColor",         "(III)V",          (void*) android_view_GLES20Canvas_drawColor },
     { "nDrawRect",          "(IFFFFI)V",       (void*) android_view_GLES20Canvas_drawRect },
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 43eead9..880d7e9 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -57,7 +57,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013.
+<p style="clear:both"><em>Data collected during a 14-day period ending on July 8, 2013.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -83,7 +83,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013
+<p style="clear:both"><em>Data collected during a 14-day period ending on July 8, 2013
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -130,7 +130,7 @@
 
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013</em></p>
+<p style="clear:both"><em>Data collected during a 14-day period ending on July 8, 2013</em></p>
 
 
 
@@ -148,7 +148,7 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean&chd=t%3A1.6%2C3.2%2C36.5%2C0.1%2C25.6%2C33.0&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=500x250",
+    "chart": "//chart.googleapis.com/chart?chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean&chco=c4df9b%2C6fad0c&chd=t%3A1.5%2C3.1%2C34.1%2C0.1%2C23.3%2C37.9&chf=bg%2Cs%2C00000000&chs=500x250&cht=p",
     "data": [
       {
         "api": 4,
@@ -158,22 +158,17 @@
       {
         "api": 7,
         "name": "Eclair",
-        "perc": "1.5"
+        "perc": "1.4"
       },
       {
         "api": 8,
         "name": "Froyo",
-        "perc": "3.2"
-      },
-      {
-        "api": 9,
-        "name": "Gingerbread",
-        "perc": "0.1"
+        "perc": "3.1"
       },
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "36.4"
+        "perc": "34.1"
       },
       {
         "api": 13,
@@ -183,17 +178,17 @@
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "25.6"
+        "perc": "23.3"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "29.0"
+        "perc": "32.3"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "4.0"
+        "perc": "5.6"
       }
     ]
   }
@@ -210,16 +205,16 @@
       "Large": {
         "hdpi": "0.4",
         "ldpi": "0.6",
-        "mdpi": "3.0",
+        "mdpi": "3.2",
         "tvdpi": "1.0",
-        "xhdpi": "0.6"
+        "xhdpi": "0.5"
       },
       "Normal": {
-        "hdpi": "36.0",
+        "hdpi": "34.9",
         "ldpi": "0.1",
         "mdpi": "16.0",
-        "xhdpi": "24.5",
-        "xxhdpi": "3.3"
+        "xhdpi": "24.0",
+        "xxhdpi": "4.9"
       },
       "Small": {
         "hdpi": "0.1",
@@ -227,12 +222,12 @@
       },
       "Xlarge": {
         "hdpi": "0.2",
-        "mdpi": "4.2",
+        "mdpi": "4.1",
         "xhdpi": "0.1"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A10.6%2C23.2%2C1.0%2C36.7%2C25.2%2C3.3&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250",
-    "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.5%2C5.6%2C79.9%2C10.0&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250"
+    "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chco=c4df9b%2C6fad0c&chd=t%3A10.7%2C23.3%2C1.0%2C35.6%2C24.6%2C4.9&chf=bg%2Cs%2C00000000&chs=400x250&cht=p",
+    "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chco=c4df9b%2C6fad0c&chd=t%3A4.4%2C5.7%2C79.9%2C10.1&chf=bg%2Cs%2C00000000&chs=400x250&cht=p"
   }
 ];
 
diff --git a/docs/html/distribute/googleplay/quality/tablet.jd b/docs/html/distribute/googleplay/quality/tablet.jd
index 03c180b..5a707be 100644
--- a/docs/html/distribute/googleplay/quality/tablet.jd
+++ b/docs/html/distribute/googleplay/quality/tablet.jd
@@ -25,9 +25,7 @@
 </ol>
 </div></div>
 
-<p>Before you publish an app on Google Play, it's important to make sure that
-the app meets the basic expectations of tablet users through compelling features
-and an intuitive, well-designed UI. </p>
+<p>Before you publish an app on Google Play, it's important to make sure that the app meets the basic expectations of tablet users through compelling features and an intuitive, well-designed UI. </p>
 
 <p>Tablets are a growing part of the Android installed base that offers new
 opportunities for <a
@@ -258,32 +256,34 @@
 <h2 id="use-tablet-icons">4. Use Icons and other assets that are designed
 for tablet screens</h2>
 
-<p>So that your app looks its best, make sure to use icons and other bitmap
-assets that are created specifically for the densities used by tablet screens.
-Specifically, you should create sets of alternative bitmap drawables for each
-density in the range commonly supported by tablets.</p>
+<p>To ensure your app looks its best, provide icons and other bitmap
+assets for each density in the range commonly supported by tablets. Specifically, you should
+design your icons for the action bar, notifications, and launcher according to the
+<a href="{@docRoot}design/style/iconography.html">Iconography</a> guidelines and
+provide them in multiple densities, so they appear at the appropriate size on all screens
+without blurring or other scaling artifacts.</p>
 
 <p class="table-caption"><strong>Table 1</strong>. Raw asset sizes for icon types.<table>
 <tr>
-<th>Density </th>
-<th colspa>Launcher</th>
+<th>Density</th>
+<th>Launcher</th>
 <th>Action Bar</th>
 <th>Small/Contextual</th>
 <th>Notification</th>
 </tr>
 <tr>
 <td><code>mdpi</code></td>
-<td>48x48px</td>
-<td>32x32px</td>
-<td>16x16px</td>
-<td>24x24px</td>
+<td>48x48 px</td>
+<td>32x32 px</td>
+<td>16x16 px</td>
+<td>24x24 px</td>
 </tr>
 <tr>
 <td><code>hdpi</code></td>
-<td>72x72px</td>
-<td>48x48px</td>
-<td>24x24px</td>
-<td>36x36px</td>
+<td>72x72 px</td>
+<td>48x48 px</td>
+<td>24x24 px</td>
+<td>36x36 px</td>
 </tr>
 <tr>
 <td><code>tvdpi</code></td>
@@ -294,34 +294,42 @@
 </tr>
 <tr>
 <td><code>xhdpi</code></td>
-<td>96x96px</td>
-<td>64x64px</td>
-<td>32x32px</td>
-<td>48x48px</td>
+<td>96x96 px</td>
+<td>64x64 px</td>
+<td>32x32 px</td>
+<td>48x48 px</td>
+</tr>
+<tr>
+<td><code>xxhdpi</code></td>
+<td>144x144 px</td>
+<td>96x96 px</td>
+<td>48x48 px</td>
+<td>74x74 px</td>
 </tr>
 
 </table>
 
-<p>Other points to consider: </p>
+<p>Your app should supply a version of each icon and bitmap asset that's optimized
+for <strong>at least one</strong> the following common tablet screen densities:</p>
 
 <ul>
-<li>Icons in the action bar, notifications, and launcher should be designed
-according to the icon design guidelines and have the same physical size on
-tablets as on phones.</li>
-<li>Use density-specific <a
-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-resource qualifiers</a> to ensure that the proper set of alternative resources
-gets loaded.</li>
+  <li><code>hdpi</code></li>
+  <li><code>xhdpi</code></li>
+  <li><code>xxhdpi</code></li>
 </ul>
 
-<p style="margin-bottom:.5em;">At a minimum, your app should supply sets of
-  custom drawables and assets for common tablet screen densities,
-  tagged with these qualifiers as appropriate:</p>
+<p>Other tips:</p>
 
 <ul>
-  <li><code>hdpi</code>, OR</li>
-  <li><code>xhdpi</code>, OR</li>
-  <li><code>xxhdpi</code></li>
+<li>When possible, use vector shapes for your icon designs so you can scale them
+without loss of detail and edge crispness.</li>
+<li>Use density-specific <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+resource qualifiers</a> to ensure that the proper icons are loaded for each screen density.</li>
+<li>Tablets and other large screen devices often request a launcher icon that is one density
+size larger than the device's actual density, so you should provide your launcher
+icon at the highest density possible. For example, if a tablet has an {@code xhdpi} screen,
+it will request the {@code xxhdpi} version of the launcher icon.</li>
 </ul>
 
 <div class="rel-resources">
@@ -331,8 +339,8 @@
 
   <ul>
     <li>
-      <a href="{@docRoot}design/style/iconography.html">Iconography</a>&mdash; Android
-      Design document that shows how to use various types of icons.
+      <a href="{@docRoot}design/style/iconography.html">Iconography</a>&mdash;
+      Design guidelines and tips about how to create various types of icons.
     </li>
 
     <li>
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd
index 8ba6676..54ef20c 100644
--- a/docs/html/guide/topics/graphics/hardware-accel.jd
+++ b/docs/html/guide/topics/graphics/hardware-accel.jd
@@ -164,7 +164,7 @@
   draws views without hardware acceleration as well. The following sections describe the
   software-based  and hardware-accelerated drawing models.</p>
 
-<h3>Software-based drawing model</h3>
+<h3 id="software-model">Software-based drawing model</h3>
 <p>In the software drawing model, views are drawn with the following two steps:</p>
   <ol>
     <li>Invalidate the hierarchy</li>
@@ -196,7 +196,7 @@
   android.view.View#invalidate invalidate()} when their properties change, such as the background
   color or the text in a {@link android.widget.TextView}.</p>
 
-  <h3>Hardware accelerated drawing model</h3>
+  <h3 id="hardware-model">Hardware accelerated drawing model</h3>
   <p>The Android system still uses {@link android.view.View#invalidate invalidate()} and {@link
   android.view.View#draw draw()} to request screen updates and to render views, but handles the
   actual drawing differently. Instead of executing the drawing commands immediately, the Android
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd
index a686efd..12d2527 100644
--- a/docs/html/sdk/installing/studio-tips.jd
+++ b/docs/html/sdk/installing/studio-tips.jd
@@ -10,6 +10,8 @@
  >Eclipse Compatibility Mode</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
  >FAQ on Migrating</a></li>
+ <li><a href="http://android-developers.blogspot.com/2013/06/adding-backend-to-your-app-in-android.html"
+ class="external-link">Adding a Backend to Your App In Android Studio</a></li>
 </ul>
 </div>
 </div>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 106f4bd..50231da 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -45,9 +45,13 @@
 
     /**
      * Backing buffer for the Bitmap.
+     * Made public for quick access from drawing methods -- do NOT modify
+     * from outside this class
+     *
+     * @hide
      */
     @SuppressWarnings("UnusedDeclaration") // native code only
-    private byte[] mBuffer;
+    public byte[] mBuffer;
 
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
     private final BitmapFinalizer mFinalizer;
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 58fa21c..3f77021 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -62,7 +62,7 @@
 }
 
 void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
@@ -100,7 +100,7 @@
 }
 
 void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
@@ -133,7 +133,7 @@
 }
 
 void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
@@ -174,7 +174,7 @@
 }
 
 void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
new file mode 100644
index 0000000..72e6d04
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
@@ -0,0 +1,330 @@
+# Copyright (C) 2012 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.
+
+#
+# English (US), Colemak keyboard layout.
+# Unlike the default (generic) keyboard layout, English (US) does not contain any
+# special ALT characters.
+#
+
+type OVERLAY
+
+map key 18 F
+map key 19 P
+map key 20 G
+map key 21 J
+map key 22 L
+map key 23 U
+map key 24 Y
+map key 25 SEMICOLON
+map key 31 R
+map key 32 S
+map key 33 T
+map key 34 D
+map key 36 N
+map key 37 E
+map key 38 I
+map key 39 O
+map key 49 K
+map key 58 DEL
+
+### ROW 1
+
+key GRAVE {
+    label:                              '`'
+    base:                               '`'
+    shift:                              '~'
+}
+
+key 1 {
+    label:                              '1'
+    base:                               '1'
+    shift:                              '!'
+}
+
+key 2 {
+    label:                              '2'
+    base:                               '2'
+    shift:                              '@'
+}
+
+key 3 {
+    label:                              '3'
+    base:                               '3'
+    shift:                              '#'
+}
+
+key 4 {
+    label:                              '4'
+    base:                               '4'
+    shift:                              '$'
+}
+
+key 5 {
+    label:                              '5'
+    base:                               '5'
+    shift:                              '%'
+}
+
+key 6 {
+    label:                              '6'
+    base:                               '6'
+    shift:                              '^'
+}
+
+key 7 {
+    label:                              '7'
+    base:                               '7'
+    shift:                              '&'
+}
+
+key 8 {
+    label:                              '8'
+    base:                               '8'
+    shift:                              '*'
+}
+
+key 9 {
+    label:                              '9'
+    base:                               '9'
+    shift:                              '('
+}
+
+key 0 {
+    label:                              '0'
+    base:                               '0'
+    shift:                              ')'
+}
+
+key MINUS {
+    label:                              '-'
+    base:                               '-'
+    shift:                              '_'
+}
+
+key EQUALS {
+    label:                              '='
+    base:                               '='
+    shift:                              '+'
+}
+
+### ROW 2
+
+key Q {
+    label:                              'Q'
+    base:                               'q'
+    shift, capslock:                    'Q'
+}
+
+key W {
+    label:                              'W'
+    base:                               'w'
+    shift, capslock:                    'W'
+}
+
+key F {
+    label:                              'F'
+    base:                               'f'
+    shift, capslock:                    'F'
+}
+
+key P {
+    label:                              'P'
+    base:                               'p'
+    shift, capslock:                    'P'
+}
+
+key G {
+    label:                              'G'
+    base:                               'g'
+    shift, capslock:                    'G'
+}
+
+key J {
+    label:                              'J'
+    base:                               'j'
+    shift, capslock:                    'J'
+}
+
+key L {
+    label:                              'L'
+    base:                               'l'
+    shift, capslock:                    'L'
+}
+
+key U {
+    label:                              'U'
+    base:                               'u'
+    shift, capslock:                    'U'
+}
+
+key Y {
+    label:                              'Y'
+    base:                               'y'
+    shift, capslock:                    'Y'
+}
+
+key SEMICOLON {
+    label:                              ';'
+    base:                               ';'
+    shift, capslock:                    ':'
+}
+
+key LEFT_BRACKET {
+    label:                              '['
+    base:                               '['
+    shift:                              '{'
+}
+
+key RIGHT_BRACKET {
+    label:                              ']'
+    base:                               ']'
+    shift:                              '}'
+}
+
+key BACKSLASH {
+    label:                              '\\'
+    base:                               '\\'
+    shift:                              '|'
+}
+
+### ROW 3
+
+key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+}
+
+key R {
+    label:                              'R'
+    base:                               'r'
+    shift, capslock:                    'R'
+}
+
+key S {
+    label:                              'S'
+    base:                               's'
+    shift, capslock:                    'S'
+}
+
+key T {
+    label:                              'T'
+    base:                               't'
+    shift, capslock:                    'T'
+}
+
+key D {
+    label:                              'D'
+    base:                               'd'
+    shift, capslock:                    'D'
+}
+
+key H {
+    label:                              'H'
+    base:                               'h'
+    shift, capslock:                    'H'
+}
+
+key N {
+    label:                              'N'
+    base:                               'n'
+    shift, capslock:                    'N'
+}
+
+key E {
+    label:                              'E'
+    base:                               'e'
+    shift, capslock:                    'E'
+}
+
+key I {
+    label:                              'I'
+    base:                               'i'
+    shift, capslock:                    'I'
+}
+
+key O {
+    label:                              'O'
+    base:                               'o'
+    shift:                              'O'
+}
+
+key APOSTROPHE {
+    label:                              '\''
+    base:                               '\''
+    shift:                              '"'
+}
+
+### ROW 4
+
+key Z {
+    label:                              'Z'
+    base:                               'z'
+    shift, capslock:                    'Z'
+}
+
+key X {
+    label:                              'X'
+    base:                               'x'
+    shift, capslock:                    'X'
+}
+
+key C {
+    label:                              'C'
+    base:                               'c'
+    shift, capslock:                    'C'
+}
+
+key V {
+    label:                              'V'
+    base:                               'v'
+    shift, capslock:                    'V'
+}
+
+key B {
+    label:                              'B'
+    base:                               'b'
+    shift, capslock:                    'B'
+}
+
+key K {
+    label:                              'K'
+    base:                               'k'
+    shift, capslock:                    'K'
+}
+
+key M {
+    label:                              'M'
+    base:                               'm'
+    shift, capslock:                    'M'
+}
+
+key COMMA {
+    label:                              ','
+    base:                               ','
+    shift:                              '<'
+}
+
+key PERIOD {
+    label:                              '.'
+    base:                               '.'
+    shift:                              '>'
+}
+
+key SLASH {
+    label:                              '/'
+    base:                               '/'
+    shift:                              '?'
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 32c665a..54c18f1 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -15,6 +15,9 @@
     <!-- US English (International style) keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_english_us_intl">English (US), International style</string>
 
+    <!-- US English (Colemak style) keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_english_us_colemak_label">English (US), Colemak style</string>
+
     <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak style</string>
 
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index ffd1a23..1f48a36 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -12,6 +12,10 @@
             android:label="@string/keyboard_layout_english_us_intl"
             android:keyboardLayout="@raw/keyboard_layout_english_us_intl" />
 
+    <keyboard-layout android:name="keyboard_layout_english_us_colemak"
+            android:label="@string/keyboard_layout_english_us_colemak_label"
+            android:keyboardLayout="@raw/keyboard_layout_english_us_colemak" />
+
     <keyboard-layout android:name="keyboard_layout_english_us_dvorak"
             android:label="@string/keyboard_layout_english_us_dvorak_label"
             android:keyboardLayout="@raw/keyboard_layout_english_us_dvorak" />
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index a1d11cd..35bea26 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -171,8 +171,6 @@
 
     private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
             Bundle options) {
-        final boolean isActivity = (mContext instanceof Activity); // for test activity
-
         if (mKeyguardHost != null) {
             mKeyguardHost.saveHierarchyState(mStateContainer);
         }
@@ -190,9 +188,6 @@
             if (!mNeedsInput) {
                 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
             }
-            if (ActivityManager.isHighEndGfx()) {
-                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-            }
 
             final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
             final int type = WindowManager.LayoutParams.TYPE_KEYGUARD;
@@ -209,11 +204,8 @@
                         WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
             }
             lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
-            if (isActivity) {
-                lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            }
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-            lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard");
+            lp.setTitle("Keyguard");
             mWindowLayoutParams = lp;
             mViewManager.addView(mKeyguardHost, lp);
         }
@@ -233,9 +225,6 @@
         if (v != null) {
             mKeyguardHost.removeView(v);
         }
-        // TODO: Remove once b/7094175 is fixed
-        if (false) Slog.d(TAG, "inflateKeyguardView: b/7094175 mContext.config="
-                + mContext.getResources().getConfiguration());
         final LayoutInflater inflater = LayoutInflater.from(mContext);
         View view = inflater.inflate(R.layout.keyguard_host_view, mKeyguardHost, true);
         mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6e24d68..1c1b002 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1511,23 +1511,16 @@
                 final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
                 if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
                     // Used to load label
-                    final PackageManager pm = mContext.getPackageManager();
                     final CharSequence title = mRes.getText(
                             com.android.internal.R.string.select_input_method);
-                    final CharSequence imiLabel = imi.loadLabel(pm);
-                    final CharSequence summary = mCurrentSubtype != null
-                            ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
-                                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                                (TextUtils.isEmpty(imiLabel) ?
-                                                        "" : " - " + imiLabel))
-                            : imiLabel;
+                    final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
+                            mContext, imi, mCurrentSubtype);
 
                     mImeSwitcherNotification.setLatestEventInfo(
                             mContext, title, summary, mImeSwitchPendingIntent);
                     if (mNotificationManager != null) {
                         if (DEBUG) {
-                            Slog.d(TAG, "--- show notification: label =  " + imiLabel
-                                    + ", summary = " + summary);
+                            Slog.d(TAG, "--- show notification: label =  " + summary);
                         }
                         mNotificationManager.notifyAsUser(null,
                                 com.android.internal.R.string.select_input_method,
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0bd0d8e..39ce0c6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1795,7 +1795,7 @@
                 return;
             }
 
-            mActivityManagerService.dumpProcessTracker(fd, pw, args);
+            mActivityManagerService.mProcessTracker.dump(fd, pw, args);
         }
     }
 
@@ -1821,7 +1821,7 @@
                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
         mBatteryStatsService.getActiveStatistics().setCallback(this);
 
-        mProcessTracker = new ProcessTracker(new File(systemDir, "procstats"));
+        mProcessTracker = new ProcessTracker(this, new File(systemDir, "procstats"));
 
         mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
@@ -10186,7 +10186,7 @@
                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
                         pw.println("");
                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
-                pw.println("  mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
+                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
                         + " (" + mLruProcesses.size() + " total)"
@@ -11345,12 +11345,6 @@
         return false;
     }
 
-    final void dumpProcessTracker(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (this) {
-            mProcessTracker.dumpLocked(fd, pw, args);
-        }
-    }
-
     private final boolean removeDyingProviderLocked(ProcessRecord proc,
             ContentProviderRecord cpr, boolean always) {
         final boolean inLaunching = mLaunchingProviders.contains(cpr);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index de220e5..98b3ce9 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -70,7 +70,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -103,9 +102,6 @@
     // from the application in order to get its saved state.
     static final int STOP_TIMEOUT = 10*1000;
 
-    // How long we can hold the launch wake lock before giving up.
-    static final int LAUNCH_TIMEOUT = 10*1000;
-
     // How long we wait until giving up on an activity telling us it has
     // finished destroying itself.
     static final int DESTROY_TIMEOUT = 10*1000;
@@ -122,10 +118,6 @@
     // is being started.
     static final boolean SHOW_APP_STARTING_PREVIEW = true;
 
-    // For debugging to make sure the caller when acquiring/releasing our
-    // wake lock is the system process.
-    static final boolean VALIDATE_WAKE_LOCK_CALLER = true;
-
     enum ActivityState {
         INITIALIZING,
         RESUMED,
@@ -168,14 +160,6 @@
     final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();
 
     /**
-     * We don't want to allow the device to go to sleep while in the process
-     * of launching an activity.  This is primarily to allow alarm intent
-     * receivers to launch an activity and get that to run before the device
-     * goes back to sleep.
-     */
-    final PowerManager.WakeLock mLaunchingActivity;
-
-    /**
      * When we are in the process of pausing an activity, before starting the
      * next one, this variable holds the activity that is currently being paused.
      */
@@ -226,8 +210,7 @@
     /** Run all ActivityStacks through this */
     final ActivityStackSupervisor mStackSupervisor;
 
-    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG;
-    static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
+    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
     static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
     static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
     static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
@@ -286,23 +269,6 @@
                         activityDestroyedLocked(r != null ? r.appToken : null);
                     }
                 } break;
-                case LAUNCH_TIMEOUT_MSG: {
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-                        return;
-                    }
-                    synchronized (mService) {
-                        if (mLaunchingActivity.isHeld()) {
-                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
-                            if (VALIDATE_WAKE_LOCK_CALLER
-                                    && Binder.getCallingUid() != Process.myUid()) {
-                                throw new IllegalStateException("Calling must be system uid");
-                            }
-                            mLaunchingActivity.release();
-                        }
-                    }
-                } break;
                 case STOP_TIMEOUT_MSG: {
                     ActivityRecord r = (ActivityRecord)msg.obj;
                     // We don't at this point know if the activity is fullscreen,
@@ -339,12 +305,6 @@
         mStackSupervisor = service.mStackSupervisor;
         mContext = context;
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-            throw new IllegalStateException("Calling must be system uid");
-        }
-        mLaunchingActivity =
-                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
-        mLaunchingActivity.setReferenceCounted(false);
         mStackId = stackId;
         mCurrentUser = service.mCurrentUserId;
     }
@@ -628,16 +588,6 @@
         r.displayStartTime = r.fullyDrawnStartTime = 0;
     }
 
-    void stopIfSleepingLocked() {
-        if (mLaunchingActivity.isHeld()) {
-            if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                throw new IllegalStateException("Calling must be system uid");
-            }
-            mLaunchingActivity.release();
-            mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-        }
-    }
-
     void awakeFromSleepingLocked() {
         // Ensure activities are no longer sleeping.
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -762,14 +712,7 @@
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
         if (!mService.isSleepingOrShuttingDown()) {
-            if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                throw new IllegalStateException("Calling must be system uid");
-            }
-            mLaunchingActivity.acquire();
-            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
-                // To be safe, don't allow the wake lock to be held for too long.
-                mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-            }
+            mStackSupervisor.acquireLaunchWakelock();
         }
 
         if (mPausingActivity != null) {
@@ -2140,29 +2083,6 @@
         }
     }
 
-    final ActivityRecord activityIdleInternalLocked(final IBinder token) {
-        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
-
-        // Get the activity record.
-        ActivityRecord res = isInStackLocked(token);
-        if (res != null) {
-            // No longer need to keep the device awake.
-            if (mResumedActivity == res && mLaunchingActivity.isHeld()) {
-                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                    throw new IllegalStateException("Calling must be system uid");
-                }
-                mLaunchingActivity.release();
-            }
-
-            // If this activity is fullscreen, set up to hide those under it.
-            if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + res);
-            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-        }
-
-        return res;
-    }
-
     /**
      * @return Returns true if the activity is being finished, false if for
      * some reason it is being left as-is.
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 9afac2c..63f91ac 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -62,6 +62,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -98,10 +99,18 @@
     /** How long we can hold the sleep wake lock before giving up. */
     static final int SLEEP_TIMEOUT = 5*1000;
 
+    // How long we can hold the launch wake lock before giving up.
+    static final int LAUNCH_TIMEOUT = 10*1000;
+
     static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
     static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
     static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
     static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
+    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
+
+    // For debugging to make sure the caller when acquiring/releasing our
+    // wake lock is the system process.
+    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
 
     final ActivityManagerService mService;
     final Context mContext;
@@ -183,6 +192,14 @@
     boolean mSleepTimeout = false;
 
     /**
+     * We don't want to allow the device to go to sleep while in the process
+     * of launching an activity.  This is primarily to allow alarm intent
+     * receivers to launch an activity and get that to run before the device
+     * goes back to sleep.
+     */
+    final PowerManager.WakeLock mLaunchingActivity;
+
+    /**
      * Set when the system is going to sleep, until we have
      * successfully paused the current activity and released our wake lock.
      * At that point the system is allowed to actually sleep.
@@ -197,6 +214,12 @@
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
         mHandler = new ActivityStackSupervisorHandler(looper);
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity =
+                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+        mLaunchingActivity.setReferenceCounted(false);
     }
 
     void setWindowManager(WindowManagerService wm) {
@@ -388,7 +411,11 @@
 
     boolean allResumedActivitiesIdle() {
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack)) {
+                continue;
+            }
+            final ActivityRecord resumedActivity = stack.mResumedActivity;
             if (resumedActivity == null || !resumedActivity.idle) {
                 return false;
             }
@@ -1666,13 +1693,22 @@
         return ActivityManager.START_SUCCESS;
     }
 
+    void acquireLaunchWakelock() {
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity.acquire();
+        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
+            // To be safe, don't allow the wake lock to be held for too long.
+            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
+        }
+    }
+
     // Checked.
     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
             Configuration config) {
         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
 
-        ActivityRecord res = null;
-
         ArrayList<ActivityRecord> stops = null;
         ArrayList<ActivityRecord> finishes = null;
         ArrayList<UserStartedState> startingUsers = null;
@@ -1689,41 +1725,50 @@
                     Debug.getCallers(4));
             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
             r.finishLaunchTickingLocked();
-            res = r.task.stack.activityIdleInternalLocked(token);
-            if (res != null) {
-                if (fromTimeout) {
-                    reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
-                }
-
-                // This is a hack to semi-deal with a race condition
-                // in the client where it can be constructed with a
-                // newer configuration from when we asked it to launch.
-                // We'll update with whatever configuration it now says
-                // it used to launch.
-                if (config != null) {
-                    r.configuration = config;
-                }
-
-                // We are now idle.  If someone is waiting for a thumbnail from
-                // us, we can now deliver.
-                r.idle = true;
-                if (allResumedActivitiesIdle()) {
-                    mService.scheduleAppGcsLocked();
-                    mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false);
-                }
-                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
-                    sendThumbnail = r.app.thread;
-                    r.thumbnailNeeded = false;
-                }
-    
-                //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
-                if (!mService.mBooted && isFrontStack(r.task.stack)) {
-                    mService.mBooted = true;
-                    enableScreen = true;
-                }
-            } else if (fromTimeout) {
-                reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
+            if (fromTimeout) {
+                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
             }
+
+            // This is a hack to semi-deal with a race condition
+            // in the client where it can be constructed with a
+            // newer configuration from when we asked it to launch.
+            // We'll update with whatever configuration it now says
+            // it used to launch.
+            if (config != null) {
+                r.configuration = config;
+            }
+
+            // We are now idle.  If someone is waiting for a thumbnail from
+            // us, we can now deliver.
+            r.idle = true;
+
+            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
+                sendThumbnail = r.app.thread;
+                r.thumbnailNeeded = false;
+            }
+
+            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
+            if (!mService.mBooted && isFrontStack(r.task.stack)) {
+                mService.mBooted = true;
+                enableScreen = true;
+            }
+        }
+
+        if (allResumedActivitiesIdle()) {
+            if (r != null) {
+                mService.scheduleAppGcsLocked();
+                mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false);
+            }
+
+            if (mLaunchingActivity.isHeld()) {
+                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+                if (VALIDATE_WAKE_LOCK_CALLER &&
+                        Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
+                }
+                mLaunchingActivity.release();
+            }
+            ensureActivitiesVisibleLocked(null, 0);
         }
 
         // Atomically retrieve all of the other things to do.
@@ -1814,7 +1859,7 @@
             resumeTopActivitiesLocked();
         }
 
-        return res;
+        return r;
     }
 
     void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
@@ -1882,7 +1927,7 @@
     void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
-                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + 
+                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
                         mStacks.get(stackNdx));
                 return;
             }
@@ -1956,11 +2001,12 @@
         scheduleSleepTimeout();
         if (!mGoingToSleep.isHeld()) {
             mGoingToSleep.acquire();
-            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = mStacks.get(stackNdx);
-                if (stack.mResumedActivity != null) {
-                    stack.stopIfSleepingLocked();
+            if (mLaunchingActivity.isHeld()) {
+                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
                 }
+                mLaunchingActivity.release();
+                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
             }
         }
     }
@@ -2423,8 +2469,8 @@
             synchronized (mService) {
                 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
             }
-        }    
-            
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -2459,6 +2505,23 @@
                         }
                     }
                 } break;
+                case LAUNCH_TIMEOUT_MSG: {
+                    if (mService.mDidDexOpt) {
+                        mService.mDidDexOpt = false;
+                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
+                        return;
+                    }
+                    synchronized (mService) {
+                        if (mLaunchingActivity.isHeld()) {
+                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
+                            if (VALIDATE_WAKE_LOCK_CALLER
+                                    && Binder.getCallingUid() != Process.myUid()) {
+                                throw new IllegalStateException("Calling must be system uid");
+                            }
+                            mLaunchingActivity.release();
+                        }
+                    }
+                } break;
             }
         }
     }
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 1671d24..14f4102 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -425,8 +425,14 @@
         } else {
             sb.append('u');
             sb.append(userId);
-            sb.append('a');
-            sb.append(UserHandle.getAppId(info.uid));
+            int appId = UserHandle.getAppId(info.uid);
+            if (appId >= Process.FIRST_APPLICATION_UID) {
+                sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
+                sb.append(appId);
+            }
             if (uid != info.uid) {
                 sb.append('i');
                 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
diff --git a/services/java/com/android/server/am/ProcessTracker.java b/services/java/com/android/server/am/ProcessTracker.java
index 488582d..0ea93e8 100644
--- a/services/java/com/android/server/am/ProcessTracker.java
+++ b/services/java/com/android/server/am/ProcessTracker.java
@@ -140,9 +140,12 @@
 
     static final int MAX_HISTORIC_STATES = 4;   // Maximum number of historic states we will keep.
     static final String STATE_FILE_PREFIX = "state-"; // Prefix to use for state filenames.
+    static final String STATE_FILE_SUFFIX = ".bin"; // Suffix to use for state filenames.
+    static final String STATE_FILE_CHECKIN_SUFFIX = ".ci"; // State files that have checked in.
     static long WRITE_PERIOD = 30*60*1000;      // Write file every 30 minutes or so.
     static long COMMIT_PERIOD = 24*60*60*1000;  // Commit current stats every day.
 
+    final Object mLock;
     final File mBaseDir;
     State mState;
     boolean mCommitPending;
@@ -694,7 +697,7 @@
                     mTimePeriodStartClock).toString();
             if (mBaseDir != null) {
                 mFile = new AtomicFile(new File(mBaseDir,
-                        STATE_FILE_PREFIX + mTimePeriodStartClockStr));
+                        STATE_FILE_PREFIX + mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
             }
         }
 
@@ -1255,8 +1258,7 @@
             return ps;
         }
 
-        void dumpLocked(PrintWriter pw, String reqPackage, boolean dumpAll) {
-            final long now = SystemClock.uptimeMillis();
+        void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpAll) {
             ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
             boolean printedHeader = false;
             for (int ip=0; ip<pkgMap.size(); ip++) {
@@ -1318,29 +1320,53 @@
                 }
             }
 
-            dumpFilteredProcesses(pw, "Processes running while critical mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_CRITICAL},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while low mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_LOW},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while moderate mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_MODERATE},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while normal mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_NORMAL},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
+            if (reqPackage == null) {
+                ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+                printedHeader = false;
+                for (int ip=0; ip<procMap.size(); ip++) {
+                    String procName = procMap.keyAt(ip);
+                    SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                    for (int iu=0; iu<uids.size(); iu++) {
+                        int uid = uids.keyAt(iu);
+                        ProcessState proc = uids.valueAt(iu);
+                        if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
+                                && proc.mPssTableSize == 0) {
+                            continue;
+                        }
+                        if (!printedHeader) {
+                            pw.println("Process Stats:");
+                            printedHeader = true;
+                        }
+                        pw.print("  * "); pw.print(procName); pw.print(" / ");
+                                UserHandle.formatUid(pw, uid);
+                                pw.print(" ("); pw.print(proc.mDurationsTableSize);
+                                pw.print(" entries)"); pw.println(":");
+                        dumpProcessState(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES, now);
+                        dumpProcessPss(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES);
+                    }
+                }
+
+                pw.println();
+                pw.println("Summary:");
+                dumpSummaryLocked(pw, reqPackage, now);
+            }
+
+            if (dumpAll) {
+                pw.println();
+                pw.println("Internal state:");
+                pw.print("  mFile="); pw.println(mFile.getBaseFile());
+                pw.print("  Num long arrays: "); pw.println(mLongs.size());
+                pw.print("  Next long entry: "); pw.println(mNextLong);
+                pw.print("  mRunning="); pw.println(mRunning);
+            }
+        }
+
+        void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now) {
+            dumpFilteredSummaryLocked(pw, null, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                    new int[] { STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS },
                     now, reqPackage);
             pw.println();
             pw.println("Run time Stats:");
@@ -1352,26 +1378,20 @@
             pw.print("  Total elapsed time: ");
             TimeUtils.formatDuration(
                     (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
-                    - mTimePeriodStartRealtime, pw);
+                            - mTimePeriodStartRealtime, pw);
             pw.println();
-            if (dumpAll) {
-                pw.println();
-                pw.println("Internal state:");
-                pw.print("  mFile="); pw.println(mFile.getBaseFile());
-                pw.print("  Num long arrays: "); pw.println(mLongs.size());
-                pw.print("  Next long entry: "); pw.println(mNextLong);
-                pw.print("  mRunning="); pw.println(mRunning);
-            }
         }
 
-        void dumpFilteredProcesses(PrintWriter pw, String header, String prefix,
+        void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
                 int[] screenStates, int[] memStates, int[] procStates, long now, String reqPackage) {
             ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
                     procStates, now, reqPackage);
             if (procs.size() > 0) {
-                pw.println();
-                pw.println(header);
-                dumpProcessList(pw, prefix, procs, screenStates, memStates, procStates, now);
+                if (header != null) {
+                    pw.println();
+                    pw.println(header);
+                }
+                dumpProcessSummary(pw, prefix, procs, screenStates, memStates, procStates, now);
             }
         }
 
@@ -1542,7 +1562,8 @@
         }
     }
 
-    public ProcessTracker(File file) {
+    public ProcessTracker(Object lock, File file) {
+        mLock = lock;
         mBaseDir = file;
         mBaseDir.mkdirs();
         mState = new State(mBaseDir, this);
@@ -1637,27 +1658,34 @@
         mState.writeStateLocked(sync, commitPending);
     }
 
-    private ArrayList<String> getCommittedFiles(int minNum) {
+    private ArrayList<String> getCommittedFiles(int minNum, boolean inclAll) {
         File[] files = mBaseDir.listFiles();
         if (files == null || files.length <= minNum) {
             return null;
         }
         ArrayList<String> filesArray = new ArrayList<String>(files.length);
-        String currentFile = mState.mFile.getBaseFile().toString();
+        String currentFile = mState.mFile.getBaseFile().getPath();
         if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
         for (int i=0; i<files.length; i++) {
             File file = files[i];
-            if (DEBUG) Slog.d(TAG, "Collecting: " + file);
-            if (!file.toString().equals(currentFile)) {
-                filesArray.add(files[i].toString());
+            String fileStr = file.getPath();
+            if (DEBUG) Slog.d(TAG, "Collecting: " + fileStr);
+            if (!inclAll && fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: already checked in");
+                continue;
             }
+            if (fileStr.equals(currentFile)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: current stats");
+                continue;
+            }
+            filesArray.add(fileStr);
         }
         Collections.sort(filesArray);
         return filesArray;
     }
 
     public void trimHistoricStatesWriteLocked() {
-        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES);
+        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, true);
         if (filesArray == null) {
             return;
         }
@@ -1803,6 +1831,76 @@
         pw.println();
     }
 
+    static final class ProcessDataCollection {
+        final int[] screenStates;
+        final int[] memStates;
+        final int[] procStates;
+
+        long totalTime;
+        long numPss;
+        long minPss;
+        long avgPss;
+        long maxPss;
+
+        ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
+            screenStates = _screenStates;
+            memStates = _memStates;
+            procStates = _procStates;
+        }
+
+        void print(PrintWriter pw, boolean full) {
+            TimeUtils.formatDuration(totalTime, pw);
+            if (numPss > 0) {
+                pw.print(" (");
+                printSizeValue(pw, minPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, avgPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, maxPss * 1024);
+                if (full) {
+                    pw.print(" over ");
+                    pw.print(numPss);
+                }
+                pw.print(")");
+            }
+        }
+    }
+
+    static void computeProcessData(ProcessState proc, ProcessDataCollection data, long now) {
+        data.totalTime = 0;
+        data.numPss = data.minPss = data.avgPss = data.maxPss = 0;
+        for (int is=0; is<data.screenStates.length; is++) {
+            for (int im=0; im<data.memStates.length; im++) {
+                for (int ip=0; ip<data.procStates.length; ip++) {
+                    int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
+                            + data.procStates[ip];
+                    data.totalTime += proc.getDuration(bucket, now);
+                    long samples = proc.getPssSampleCount(bucket);
+                    if (samples > 0) {
+                        long minPss = proc.getPssMinimum(bucket);
+                        long avgPss = proc.getPssAverage(bucket);
+                        long maxPss = proc.getPssMaximum(bucket);
+                        if (data.numPss == 0) {
+                            data.minPss = minPss;
+                            data.avgPss = avgPss;
+                            data.maxPss = maxPss;
+                        } else {
+                            if (minPss < data.minPss) {
+                                data.minPss = minPss;
+                            }
+                            data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
+                                    + (avgPss*(double)samples)) / (data.numPss+samples) );
+                            if (maxPss > data.maxPss) {
+                                data.maxPss = maxPss;
+                            }
+                        }
+                        data.numPss += samples;
+                    }
+                }
+            }
+        }
+    }
+
     static long computeProcessTimeLocked(ProcessState proc, int[] screenStates, int[] memStates,
                 int[] procStates, long now) {
         long totalTime = 0;
@@ -1818,7 +1916,7 @@
         for (int is=0; is<screenStates.length; is++) {
             for (int im=0; im<memStates.length; im++) {
                 for (int ip=0; ip<procStates.length; ip++) {
-                    int bucket = ((screenStates[is]+ memStates[im]) * STATE_COUNT)
+                    int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
                             + procStates[ip];
                     totalTime += proc.getDuration(bucket, now);
                 }
@@ -1910,12 +2008,12 @@
                         pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
                         pw.print(count);
                         pw.print(" samples ");
-                        pw.print(proc.getPssMinimum(bucket));
-                        pw.print("kB ");
-                        pw.print(proc.getPssAverage(bucket));
-                        pw.print("kB ");
-                        pw.print(proc.getPssMaximum(bucket));
-                        pw.println("kB");
+                        printSizeValue(pw, proc.getPssMinimum(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssAverage(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssMaximum(bucket) * 1024);
+                        pw.println();
                     }
                 }
             }
@@ -2017,6 +2115,94 @@
         }
     }
 
+    static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix,
+            String label, int[] screenStates, int[] memStates, int[] procStates,
+            long now, boolean full) {
+        ProcessDataCollection totals = new ProcessDataCollection(screenStates,
+                memStates, procStates);
+        computeProcessData(proc, totals, now);
+        if (totals.totalTime != 0 || totals.numPss != 0) {
+            if (prefix != null) {
+                pw.print(prefix);
+            }
+            if (label != null) {
+                pw.print(label);
+            }
+            totals.print(pw, full);
+            if (prefix != null) {
+                pw.println();
+            }
+        }
+    }
+
+    static void dumpProcessSummary(PrintWriter pw, String prefix, ArrayList<ProcessState> procs,
+            int[] screenStates, int[] memStates, int[] procStates, long now) {
+        for (int i=procs.size()-1; i>=0; i--) {
+            ProcessState proc = procs.get(i);
+            pw.print(prefix);
+            pw.print("* ");
+            pw.print(proc.mName);
+            pw.print(" / ");
+            UserHandle.formatUid(pw, proc.mUid);
+            pw.println(":");
+            dumpProcessSummaryDetails(pw, proc, prefix, "         TOTAL: ", screenStates, memStates,
+                    procStates, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Persistent: ", screenStates, memStates,
+                    new int[] {STATE_PERSISTENT}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "           Top: ", screenStates, memStates,
+                    new int[] {STATE_TOP}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Foreground: ", screenStates, memStates,
+                    new int[] {STATE_FOREGROUND, STATE_VISIBLE, STATE_PERCEPTIBLE}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "        Backup: ", screenStates, memStates,
+                    new int[] {STATE_BACKUP}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "       Service: ", screenStates, memStates,
+                    new int[] {STATE_SERVICE}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "          Home: ", screenStates, memStates,
+                    new int[] {STATE_HOME}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      Previous: ", screenStates, memStates,
+                    new int[] {STATE_PREVIOUS}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      (Cached): ", screenStates, memStates,
+                    new int[] {STATE_CACHED}, now, true);
+        }
+    }
+
+    private static void printSizeValue(PrintWriter pw, long number) {
+        float result = number;
+        String suffix = "";
+        if (result > 900) {
+            suffix = "KB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "MB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "GB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "TB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "PB";
+            result = result / 1024;
+        }
+        String value;
+        if (result < 1) {
+            value = String.format("%.2f", result);
+        } else if (result < 10) {
+            value = String.format("%.2f", result);
+        } else if (result < 100) {
+            value = String.format("%.2f", result);
+        } else {
+            value = String.format("%.0f", result);
+        }
+        pw.print(value);
+        pw.print(suffix);
+    }
+
     static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
             boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
             boolean sepProcStates, int[] procStates, long now) {
@@ -2171,7 +2357,7 @@
     static private void dumpHelp(PrintWriter pw) {
         pw.println("Process stats (procstats) dump options:");
         pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
-        pw.println("    [--include-committed] [--commit] [--write] [-h] [<package.name>]");
+        pw.println("    [--details] [--current] [--commit] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: perform a checkin: print and delete old committed states.");
         pw.println("  --c: print only state in checkin format.");
         pw.println("  --csv: output data suitable for putting in a spreadsheet.");
@@ -2179,7 +2365,8 @@
         pw.println("  --csv-mem: norm, mod, low, crit.");
         pw.println("  --csv-proc: pers, top, fore, vis, precept, backup,");
         pw.println("    service, home, prev, cached");
-        pw.println("  --include-committed: also dump any old committed states.");
+        pw.println("  --details: dump all execution details, not just summary.");
+        pw.println("  --current: only dump current state.");
         pw.println("  --commit: commit current stats to disk and reset to start new stats.");
         pw.println("  --write: write current in-memory stats to disk.");
         pw.println("  --read: replace current stats with last-written stats.");
@@ -2188,13 +2375,14 @@
         pw.println("  <package.name>: optional name of package to filter output by.");
     }
 
-    public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         final long now = SystemClock.uptimeMillis();
 
         boolean isCheckin = false;
         boolean isCompact = false;
         boolean isCsv = false;
-        boolean includeCommitted = false;
+        boolean currentOnly = false;
+        boolean dumpDetails = false;
         boolean dumpAll = false;
         String reqPackage = null;
         boolean csvSepScreenStats = false;
@@ -2264,8 +2452,10 @@
                         return;
                     }
                     csvSepProcStats = sep[0];
-                } else if ("--include-committed".equals(arg)) {
-                    includeCommitted = true;
+                } else if ("--details".equals(arg)) {
+                    dumpDetails = true;
+                } else if ("--current".equals(arg)) {
+                    currentOnly = true;
                 } else if ("--commit".equals(arg)) {
                     mState.writeStateLocked(true, true);
                     pw.println("Process stats committed.");
@@ -2282,8 +2472,8 @@
                     dumpHelp(pw);
                     return;
                 } else if ("-a".equals(arg)) {
+                    dumpDetails = true;
                     dumpAll = true;
-                    includeCommitted = true;
                 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
                     pw.println("Unknown option: " + arg);
                     dumpHelp(pw);
@@ -2294,9 +2484,11 @@
                         IPackageManager pm = AppGlobals.getPackageManager();
                         if (pm.getPackageUid(arg, UserHandle.getCallingUserId()) >= 0) {
                             reqPackage = arg;
-                            // We will automatically include all committed state,
-                            // since we are going to end up with much less printed.
-                            includeCommitted = true;
+                            // Include all details, since we know we are only going to
+                            // be dumping a smaller set of data.  In fact only the details
+                            // container per-package data, so that are needed to be able
+                            // to dump anything at all when filtering by package.
+                            dumpDetails = true;
                         }
                     } catch (RemoteException e) {
                     }
@@ -2330,70 +2522,94 @@
                 }
             }
             pw.println();
-            dumpFilteredProcessesCsvLocked(pw, null,
-                    csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
-                    csvSepProcStats, csvProcStats, now, reqPackage);
-            /*
-            dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
-                    false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
-                    true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
-                            STATE_PREVIOUS, STATE_CACHED},
-                    now, reqPackage);
-            dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
-                    false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
-                            ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
-                    true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
-                            STATE_PREVIOUS, STATE_CACHED},
-                    now, reqPackage);
-            */
+            synchronized (mLock) {
+                dumpFilteredProcessesCsvLocked(pw, null,
+                        csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
+                        csvSepProcStats, csvProcStats, now, reqPackage);
+                /*
+                dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
+                                ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                */
+            }
             return;
         }
 
         boolean sepNeeded = false;
-        if (includeCommitted || isCheckin) {
-            ArrayList<String> files = getCommittedFiles(0);
-            if (files != null) {
-                for (int i=0; i<files.size(); i++) {
-                    if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
-                    try {
-                        State state = new State(files.get(i));
-                        if (isCheckin || isCompact) {
-                            state.dumpCheckinLocked(pw, reqPackage);
-                        } else {
-                            if (sepNeeded) {
-                                pw.println();
+        if (!currentOnly || isCheckin) {
+            mWriteLock.lock();
+            try {
+                ArrayList<String> files = getCommittedFiles(0, !isCheckin);
+                if (files != null) {
+                    for (int i=0; i<files.size(); i++) {
+                        if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
+                        try {
+                            State state = new State(files.get(i));
+                            String fileStr = state.mFile.getBaseFile().getPath();
+                            boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
+                            if (isCheckin || isCompact) {
+                                // Don't really need to lock because we uniquely own this object.
+                                state.dumpCheckinLocked(pw, reqPackage);
                             } else {
-                                sepNeeded = true;
+                                if (sepNeeded) {
+                                    pw.println();
+                                } else {
+                                    sepNeeded = true;
+                                }
+                                pw.print("COMMITTED STATS FROM ");
+                                pw.print(state.mTimePeriodStartClockStr);
+                                if (checkedIn) pw.print(" (checked in)");
+                                pw.println(":");
+                                // Don't really need to lock because we uniquely own this object.
+                                if (dumpDetails) {
+                                    state.dumpLocked(pw, reqPackage, now, dumpAll);
+                                } else {
+                                    state.dumpSummaryLocked(pw, reqPackage, now);
+                                }
                             }
-                            pw.print("COMMITTED STATS FROM ");
-                            pw.print(state.mTimePeriodStartClockStr);
-                            pw.println(":");
-                            state.dumpLocked(pw, reqPackage, dumpAll);
+                            if (isCheckin) {
+                                // Rename file suffix to mark that it has checked in.
+                                state.mFile.getBaseFile().renameTo(new File(
+                                        fileStr + STATE_FILE_CHECKIN_SUFFIX));
+                            }
+                        } catch (Throwable e) {
+                            pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
+                            e.printStackTrace(pw);
                         }
-                        if (isCheckin) {
-                            state.mFile.delete();
-                        }
-                    } catch (Throwable e) {
-                        pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
-                        e.printStackTrace(pw);
+                        if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
                     }
-                    if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
                 }
+            } finally {
+                mWriteLock.unlock();
             }
         }
         if (!isCheckin) {
-            if (isCompact) {
-                mState.dumpCheckinLocked(pw, reqPackage);
-            } else {
-                if (sepNeeded) {
-                    pw.println();
-                    pw.println("CURRENT STATS:");
+            synchronized (mLock) {
+                if (isCompact) {
+                    mState.dumpCheckinLocked(pw, reqPackage);
+                } else {
+                    if (sepNeeded) {
+                        pw.println();
+                        pw.println("CURRENT STATS:");
+                    }
+                    if (dumpDetails) {
+                        mState.dumpLocked(pw, reqPackage, now, dumpAll);
+                    } else {
+                        mState.dumpSummaryLocked(pw, reqPackage, now);
+                    }
                 }
-                mState.dumpLocked(pw, reqPackage, dumpAll);
             }
         }
     }
diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java
index cc2473b..3480b19 100644
--- a/services/java/com/android/server/pm/KeySetManager.java
+++ b/services/java/com/android/server/pm/KeySetManager.java
@@ -42,7 +42,10 @@
 
     static final String TAG = "KeySetManager";
 
-    private static final long KEYSET_NOT_FOUND = -1;
+    /** Sentinel value returned when a {@code KeySet} is not found. */
+    public static final long KEYSET_NOT_FOUND = -1;
+
+    /** Sentinel value returned when public key is not found. */
     private static final long PUBLIC_KEY_NOT_FOUND = -1;
 
     private final Object mLockObject = new Object();
@@ -418,6 +421,21 @@
                 pw.print("  ["); pw.print(keySetPackage); pw.println("]");
                 if (pkg.keySetData != null) {
                     boolean printedLabel = false;
+                    for (Map.Entry<String, Long> entry : pkg.keySetData.getAliases().entrySet()) {
+                        if (!printedLabel) {
+                            pw.print("      KeySets Aliases: ");
+                            printedLabel = true;
+                        } else {
+                            pw.print(", ");
+                        }
+                        pw.print(entry.getKey());
+                        pw.print('=');
+                        pw.print(Long.toString(entry.getValue()));
+                    }
+                    if (printedLabel) {
+                        pw.println("");
+                    }
+                    printedLabel = false;
                     for (long keySetId : pkg.keySetData.getDefinedKeySets()) {
                         if (!printedLabel) {
                             pw.print("      Defined KeySets: ");
@@ -433,12 +451,12 @@
                     printedLabel = false;
                     for (long keySetId : pkg.keySetData.getSigningKeySets()) {
                         if (!printedLabel) {
-                            pw.print("      Signing KeySets:");
+                            pw.print("      Signing KeySets: ");
                             printedLabel = true;
                         } else {
                             pw.print(", ");
                         }
-                        pw.print(" "); pw.print(Long.toString(keySetId));
+                        pw.print(Long.toString(keySetId));
                     }
                     if (printedLabel) {
                         pw.println("");
@@ -566,4 +584,4 @@
             mPublicKeys.put(identifier, pub);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
index ba321bc..88a27f5 100644
--- a/services/java/com/android/server/power/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -297,7 +297,9 @@
         
         // First send the high-level shut down broadcast.
         mActionDone = false;
-        mContext.sendOrderedBroadcastAsUser(new Intent(Intent.ACTION_SHUTDOWN),
+        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendOrderedBroadcastAsUser(intent,
                 UserHandle.ALL, null, br, mHandler, 0, null, null);
         
         final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 7c6da92..dd19f89 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -363,7 +363,32 @@
             mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
             mAttachedWindow = attachedWindow;
             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
-            mAttachedWindow.mChildWindows.add(this);
+
+            int children_size = mAttachedWindow.mChildWindows.size();
+            if (children_size == 0) {
+                mAttachedWindow.mChildWindows.add(this);
+            } else {
+                for (int i = 0; i < children_size; i++) {
+                    WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i);
+                    if (this.mSubLayer < child.mSubLayer) {
+                        mAttachedWindow.mChildWindows.add(i, this);
+                        break;
+                    } else if (this.mSubLayer > child.mSubLayer) {
+                        continue;
+                    }
+
+                    if (this.mBaseLayer <= child.mBaseLayer) {
+                        mAttachedWindow.mChildWindows.add(i, this);
+                        break;
+                    } else {
+                        continue;
+                    }
+                }
+                if (children_size == mAttachedWindow.mChildWindows.size()) {
+                    mAttachedWindow.mChildWindows.add(this);
+                }
+            }
+
             mLayoutAttached = mAttrs.type !=
                     WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
             mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD