Merge "add logging to debug panel touches."
diff --git a/api/current.txt b/api/current.txt
index 111bd65..e4d5fd1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -17360,6 +17360,7 @@
     field public static final java.lang.String CAN_PARTIALLY_UPDATE = "canPartiallyUpdate";
     field public static final java.lang.String DELETED = "deleted";
     field public static final java.lang.String DIRTY = "dirty";
+    field public static final java.lang.String MUTATORS = "mutators";
     field public static final java.lang.String _SYNC_ID = "_sync_id";
   }
 
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 5c75aff..2897ee0 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -289,7 +289,7 @@
 
     /**
      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
-     * array of Intents to be supplied.  The first Intent in the array is
+     * array of Intents to be supplied.  The last Intent in the array is
      * taken as the primary key for the PendingIntent, like the single Intent
      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
      * the resulting PendingIntent, all of the Intents are started in the same
@@ -335,7 +335,7 @@
 
     /**
      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
-     * array of Intents to be supplied.  The first Intent in the array is
+     * array of Intents to be supplied.  The last Intent in the array is
      * taken as the primary key for the PendingIntent, like the single Intent
      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
      * the resulting PendingIntent, all of the Intents are started in the same
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index cf0603e..89b1bbd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1950,7 +1950,7 @@
 
     /**
      * Broadcast Action:  External media is present, but not mounted at its mount point.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the unmounted media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
@@ -1971,7 +1971,7 @@
 
     /**
      * Broadcast Action:  External media is present and mounted at its mount point.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the mounted media is contained in the Intent.mData field.
      * The Intent contains an extra with name "read-only" and Boolean value to indicate if the
      * media was mounted read only.
      */
@@ -2002,7 +2002,7 @@
 
     /**
      * Broadcast Action:  External media is present but cannot be mounted.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the unmountable media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE";
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index af6e88e9..5fdca86 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -302,9 +302,16 @@
          * Used to indicate that local, unsynced, changes are present.
          * <P>Type: INTEGER (long)</P>
          */
+
         public static final String DIRTY = "dirty";
 
         /**
+         * Used in conjunction with {@link #DIRTY} to indicate what packages wrote local changes.
+         * <P>Type: TEXT</P>
+         */
+        public static final String MUTATORS = "mutators";
+
+        /**
          * Whether the row has been deleted but not synced to the server. A
          * deleted row should be ignored.
          * <P>
@@ -525,6 +532,7 @@
 
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID);
                 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
+                DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, MUTATORS);
 
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC1);
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CAL_SYNC2);
@@ -647,6 +655,7 @@
      * <li>{@link #CALENDAR_COLOR}</li>
      * <li>{@link #_SYNC_ID}</li>
      * <li>{@link #DIRTY}</li>
+     * <li>{@link #MUTATORS}</li>
      * <li>{@link #OWNER_ACCOUNT}</li>
      * <li>{@link #MAX_REMINDERS}</li>
      * <li>{@link #ALLOWED_REMINDERS}</li>
@@ -714,6 +723,7 @@
             ACCOUNT_TYPE,
             _SYNC_ID,
             DIRTY,
+            MUTATORS,
             OWNER_ACCOUNT,
             MAX_REMINDERS,
             ALLOWED_REMINDERS,
@@ -1393,6 +1403,7 @@
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, IS_ORGANIZER);
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID);
                 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
+                DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, MUTATORS);
                 DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, LAST_SYNCED);
                 DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, DELETED);
                 DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, SYNC_DATA1);
@@ -1599,6 +1610,7 @@
      * The following Events columns are writable only by a sync adapter
      * <ul>
      * <li>{@link #DIRTY}</li>
+     * <li>{@link #MUTATORS}</li>
      * <li>{@link #_SYNC_ID}</li>
      * <li>{@link #SYNC_DATA1}</li>
      * <li>{@link #SYNC_DATA2}</li>
@@ -1688,6 +1700,7 @@
         public static final String[] SYNC_WRITABLE_COLUMNS = new String[] {
             _SYNC_ID,
             DIRTY,
+            MUTATORS,
             SYNC_DATA1,
             SYNC_DATA2,
             SYNC_DATA3,
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 4912a64..86d04b6 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -29,6 +29,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import com.google.android.gles_jni.EGLImpl;
 
@@ -87,26 +88,22 @@
      *
      * Possible values:
      * "true", to enable profiling
+     * "visual", to enable profiling and visualize the results on screen
      * "false", to disable profiling
      *
+     * @see #PROFILE_PROPERTY_VISUALIZE
+     *
      * @hide
      */
     public static final String PROFILE_PROPERTY = "debug.hwui.profile";
 
     /**
-     * System property used to enable or disable hardware rendering profiling
-     * visualization. The default value of this property is assumed to be false.
-     *
-     * This property is only taken into account when {@link #PROFILE_PROPERTY} is
-     * turned on.
-     *
-     * Possible values:
-     * "true", to enable on screen profiling
-     * "false", to disable on screen profiling
+     * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
+     * value, profiling data will be visualized on screen.
      *
      * @hide
      */
-    public static final String PROFILE_VISUALIZER_PROPERTY = "debug.hwui.profile_visualizer";
+    public static final String PROFILE_PROPERTY_VISUALIZE = "visual";
 
     /**
      * System property used to specify the number of frames to be used
@@ -693,18 +690,33 @@
 
         @Override
         boolean loadSystemProperties(Surface surface) {
+            boolean value;
             boolean changed = false;
 
-            boolean value = SystemProperties.getBoolean(PROFILE_PROPERTY, false);
+            String profiling = SystemProperties.get(PROFILE_PROPERTY);
+            value = PROFILE_PROPERTY_VISUALIZE.equalsIgnoreCase(profiling);
+
+            if (value != mProfileVisualizerEnabled) {
+                changed = true;
+                mProfileVisualizerEnabled = value;
+
+                mProfileRects = null;
+                mProfilePaint = null;
+            }
+
+            // If on-screen profiling is not enabled, we need to check whether
+            // console profiling only is enabled
+            if (!value) {
+                value = Boolean.parseBoolean(profiling);
+            }
+
             if (value != mProfileEnabled) {
                 changed = true;
                 mProfileEnabled = value;
 
                 if (mProfileEnabled) {
                     Log.d(LOG_TAG, "Profiling hardware renderer");
-                }
 
-                if (mProfileEnabled) {
                     int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
                             PROFILE_MAX_FRAMES);
                     mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
@@ -718,17 +730,7 @@
                     mProfileLock = null;
                 }
 
-                mProfileRects = null;
-                mProfilePaint = null;
-            }
-
-            value = SystemProperties.getBoolean(PROFILE_VISUALIZER_PROPERTY, false);
-            if (value != mProfileVisualizerEnabled) {
-                changed = true;
-                mProfileVisualizerEnabled = value;
-
-                mProfileRects = null;
-                mProfilePaint = null;
+                mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
             }
 
             value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
@@ -1241,7 +1243,7 @@
                         mFrameCount++;
 
                         debugDirtyRegions(dirty, canvas);
-                        drawProfileData();
+                        drawProfileData(attachInfo);
                     }
 
                     onPostDraw();
@@ -1260,7 +1262,7 @@
             return false;
         }
 
-        abstract void drawProfileData();
+        abstract void drawProfileData(View.AttachInfo attachInfo);
 
         private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
             // We had to change the current surface and/or context, redraw everything
@@ -1463,17 +1465,18 @@
      * Hardware renderer using OpenGL ES 2.0.
      */
     static class Gl20Renderer extends GlRenderer {
-        // TODO: Convert dimensions to dp instead of px
         private static final int PROFILE_DRAW_MARGIN = 0;
-        private static final int PROFILE_DRAW_WIDTH = 4;
+        private static final int PROFILE_DRAW_WIDTH = 3;
         private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
         private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
         private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
         private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
-        private static final int PROFILE_DRAW_PX_PER_MS = 10;
+        private static final int PROFILE_DRAW_DP_PER_MS = 7;
 
         private GLES20Canvas mGlCanvas;
 
+        private DisplayMetrics mDisplayMetrics;
+
         private static EGLSurface sPbuffer;
         private static final Object[] sPbufferLock = new Object[0];
 
@@ -1577,9 +1580,13 @@
         }
 
         @Override
-        void drawProfileData() {
+        void drawProfileData(View.AttachInfo attachInfo) {
             if (mProfileEnabled && mProfileVisualizerEnabled) {
-                initProfileDrawData();
+                initProfileDrawData(attachInfo);
+
+                final int pxPerMs = (int) (PROFILE_DRAW_DP_PER_MS * mDisplayMetrics.density + 0.5f);
+                final int margin = (int) (PROFILE_DRAW_MARGIN * mDisplayMetrics.density + 0.5f);
+                final int width = (int) (PROFILE_DRAW_WIDTH * mDisplayMetrics.density + 0.5f);
 
                 int x = 0;
                 int count = 0;
@@ -1591,11 +1598,11 @@
                     int index = count * 4;
                     if (i == mProfileCurrentFrame) current = index;
 
-                    x += PROFILE_DRAW_MARGIN;
-                    int x2 = x + PROFILE_DRAW_WIDTH;
+                    x += margin;
+                    int x2 = x + width;
 
                     int y2 = mHeight;
-                    int y1 = (int) (y2 - mProfileData[i] * PROFILE_DRAW_PX_PER_MS);
+                    int y1 = (int) (y2 - mProfileData[i] * pxPerMs);
 
                     float[] r = mProfileRects[0];
                     r[index] = x;
@@ -1604,7 +1611,7 @@
                     r[index + 3] = y2;
 
                     y2 = y1;
-                    y1 = (int) (y2 - mProfileData[i + 1] * PROFILE_DRAW_PX_PER_MS);
+                    y1 = (int) (y2 - mProfileData[i + 1] * pxPerMs);
 
                     r = mProfileRects[1];
                     r[index] = x;
@@ -1613,7 +1620,7 @@
                     r[index + 3] = y2;
 
                     y2 = y1;
-                    y1 = (int) (y2 - mProfileData[i + 2] * PROFILE_DRAW_PX_PER_MS);
+                    y1 = (int) (y2 - mProfileData[i + 2] * pxPerMs);
 
                     r = mProfileRects[2];
                     r[index] = x;
@@ -1621,15 +1628,15 @@
                     r[index + 2] = x2;
                     r[index + 3] = y2;
 
-                    x += PROFILE_DRAW_WIDTH;
+                    x += width;
 
                     count++;
                 }
-                x += PROFILE_DRAW_MARGIN;
+                x += margin;
 
                 drawGraph(count);
                 drawCurrentFrame(current);
-                drawThreshold(x);
+                drawThreshold(x, pxPerMs);
             }
         }
 
@@ -1646,15 +1653,16 @@
                     mProfileRects[2][index + 2], mProfileRects[0][index + 3], mProfilePaint);
         }
 
-        private void drawThreshold(int x) {
+        private void drawThreshold(int x, int pxPerMs) {
             mProfilePaint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
-            mProfilePaint.setStrokeWidth(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH);
-            int y = mHeight - 16 * 10;
+            mProfilePaint.setStrokeWidth((int)
+                    (PROFILE_DRAW_THRESHOLD_STROKE_WIDTH * mDisplayMetrics.density + 0.5f));
+            int y = mHeight - 16 * pxPerMs;
             mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
             mProfilePaint.setStrokeWidth(1.0f);
         }
 
-        private void initProfileDrawData() {
+        private void initProfileDrawData(View.AttachInfo attachInfo) {
             if (mProfileRects == null) {
                 mProfileRects = new float[PROFILE_FRAME_DATA_COUNT][];
                 for (int i = 0; i < mProfileRects.length; i++) {
@@ -1663,6 +1671,11 @@
                 }
                 mProfilePaint = new Paint();
             }
+
+            if (mDisplayMetrics == null) {
+                mDisplayMetrics = new DisplayMetrics();
+            }
+            attachInfo.mDisplay.getMetrics(mDisplayMetrics);
         }
 
         @Override