Merge "Fix NPE in SQLiteDatabase#updateWithOnConflict"
diff --git a/api/current.xml b/api/current.xml
index fcb0c0e..ba168be 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -9429,7 +9429,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843558"
+ value="16843559"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -10371,6 +10371,17 @@
  visibility="public"
 >
 </field>
+<field name="windowEnableSplitTouch"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843560"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="windowEnterAnimation"
  type="int"
  transient="false"
@@ -219352,6 +219363,19 @@
 <parameter name="iconId" type="int">
 </parameter>
 </method>
+<method name="switchToLastInputMethod"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="imeToken" type="android.os.IBinder">
+</parameter>
+</method>
 <method name="toggleSoftInput"
  return="void"
  abstract="false"
@@ -243426,17 +243450,6 @@
 <parameter name="attrs" type="android.content.res.TypedArray">
 </parameter>
 </method>
-<method name="getTextIsSelectable"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getTextScaleX"
  return="float"
  abstract="false"
@@ -243558,6 +243571,17 @@
  visibility="public"
 >
 </method>
+<method name="isTextSelectable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="length"
  return="int"
  abstract="false"
@@ -246481,7 +246505,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 01414fa..3a6fd23 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -33,10 +33,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 /**
  * The download manager is a system service that handles long-running HTTP downloads. Clients may
@@ -281,46 +278,32 @@
      */
     public static final String EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS = "extra_click_download_ids";
 
-    // this array must contain all public columns
-    private static final String[] COLUMNS = new String[] {
-        COLUMN_ID,
-        COLUMN_MEDIAPROVIDER_URI,
-        Downloads.Impl.COLUMN_DESTINATION,
-        COLUMN_TITLE,
-        COLUMN_DESCRIPTION,
-        COLUMN_URI,
-        COLUMN_MEDIA_TYPE,
-        COLUMN_TOTAL_SIZE_BYTES,
-        COLUMN_LOCAL_URI,
-        COLUMN_STATUS,
-        COLUMN_REASON,
-        COLUMN_BYTES_DOWNLOADED_SO_FAR,
-        COLUMN_LAST_MODIFIED_TIMESTAMP,
-        COLUMN_LOCAL_FILENAME,
-    };
-
-    // columns to request from DownloadProvider
-    private static final String[] UNDERLYING_COLUMNS = new String[] {
+    /**
+     * columns to request from DownloadProvider.
+     * @hide
+     */
+    public static final String[] UNDERLYING_COLUMNS = new String[] {
         Downloads.Impl._ID,
+        Downloads.Impl._DATA,
         Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
         Downloads.Impl.COLUMN_DESTINATION,
         Downloads.Impl.COLUMN_TITLE,
         Downloads.Impl.COLUMN_DESCRIPTION,
         Downloads.Impl.COLUMN_URI,
-        Downloads.Impl.COLUMN_MIME_TYPE,
-        Downloads.Impl.COLUMN_TOTAL_BYTES,
         Downloads.Impl.COLUMN_STATUS,
-        Downloads.Impl.COLUMN_CURRENT_BYTES,
-        Downloads.Impl.COLUMN_LAST_MODIFICATION,
         Downloads.Impl.COLUMN_FILE_NAME_HINT,
-        Downloads.Impl._DATA,
+        Downloads.Impl.COLUMN_MIME_TYPE + " AS " + COLUMN_MEDIA_TYPE,
+        Downloads.Impl.COLUMN_TOTAL_BYTES + " AS " + COLUMN_TOTAL_SIZE_BYTES,
+        Downloads.Impl.COLUMN_LAST_MODIFICATION + " AS " + COLUMN_LAST_MODIFIED_TIMESTAMP,
+        Downloads.Impl.COLUMN_CURRENT_BYTES + " AS " + COLUMN_BYTES_DOWNLOADED_SO_FAR,
+        /* add the following 'computed' columns to the cursor.
+         * they are not 'returned' by the database, but their inclusion
+         * eliminates need to have lot of methods in CursorTranslator
+         */
+        "'placeholder' AS " + COLUMN_LOCAL_URI,
+        "'placeholder' AS " + COLUMN_REASON
     };
 
-    private static final Set<String> LONG_COLUMNS = new HashSet<String>(
-            Arrays.asList(COLUMN_ID, COLUMN_TOTAL_SIZE_BYTES, COLUMN_STATUS, COLUMN_REASON,
-                          COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP,
-                          Downloads.Impl.COLUMN_DESTINATION));
-
     /**
      * This class contains all the information necessary to request a new download. The URI is the
      * only required parameter.
@@ -871,11 +854,7 @@
      * @return the number of downloads actually removed
      */
     public int remove(long... ids) {
-        if (ids == null || ids.length == 0) {
-            // called with nothing to remove!
-            throw new IllegalArgumentException("input param 'ids' can't be null");
-        }
-        return mResolver.delete(mBaseUri, getWhereClauseForIds(ids), getWhereArgsForIds(ids));
+        return markRowDeleted(ids);
     }
 
     /**
@@ -1032,117 +1011,32 @@
         }
 
         @Override
-        public int getColumnIndex(String columnName) {
-            return Arrays.asList(COLUMNS).indexOf(columnName);
-        }
-
-        @Override
-        public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
-            int index = getColumnIndex(columnName);
-            if (index == -1) {
-                throw new IllegalArgumentException("No such column: " + columnName);
-            }
-            return index;
-        }
-
-        @Override
-        public String getColumnName(int columnIndex) {
-            int numColumns = COLUMNS.length;
-            if (columnIndex < 0 || columnIndex >= numColumns) {
-                throw new IllegalArgumentException("Invalid column index " + columnIndex + ", "
-                                                   + numColumns + " columns exist");
-            }
-            return COLUMNS[columnIndex];
-        }
-
-        @Override
-        public String[] getColumnNames() {
-            String[] returnColumns = new String[COLUMNS.length];
-            System.arraycopy(COLUMNS, 0, returnColumns, 0, COLUMNS.length);
-            return returnColumns;
-        }
-
-        @Override
-        public int getColumnCount() {
-            return COLUMNS.length;
-        }
-
-        @Override
-        public byte[] getBlob(int columnIndex) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public double getDouble(int columnIndex) {
-            return getLong(columnIndex);
-        }
-
-        private boolean isLongColumn(String column) {
-            return LONG_COLUMNS.contains(column);
-        }
-
-        @Override
-        public float getFloat(int columnIndex) {
-            return (float) getDouble(columnIndex);
-        }
-
-        @Override
         public int getInt(int columnIndex) {
             return (int) getLong(columnIndex);
         }
 
         @Override
         public long getLong(int columnIndex) {
-            return translateLong(getColumnName(columnIndex));
-        }
-
-        @Override
-        public short getShort(int columnIndex) {
-            return (short) getLong(columnIndex);
+            if (getColumnName(columnIndex).equals(COLUMN_REASON)) {
+                return getReason(super.getInt(getColumnIndex(Downloads.Impl.COLUMN_STATUS)));
+            } else if (getColumnName(columnIndex).equals(COLUMN_STATUS)) {
+                return translateStatus(super.getInt(getColumnIndex(Downloads.Impl.COLUMN_STATUS)));
+            } else {
+                return super.getLong(columnIndex);
+            }
         }
 
         @Override
         public String getString(int columnIndex) {
-            return translateString(getColumnName(columnIndex));
-        }
-
-        private String translateString(String column) {
-            if (isLongColumn(column)) {
-                return Long.toString(translateLong(column));
-            }
-            if (column.equals(COLUMN_TITLE)) {
-                return getUnderlyingString(Downloads.Impl.COLUMN_TITLE);
-            }
-            if (column.equals(COLUMN_DESCRIPTION)) {
-                return getUnderlyingString(Downloads.Impl.COLUMN_DESCRIPTION);
-            }
-            if (column.equals(COLUMN_URI)) {
-                return getUnderlyingString(Downloads.Impl.COLUMN_URI);
-            }
-            if (column.equals(COLUMN_MEDIA_TYPE)) {
-                return getUnderlyingString(Downloads.Impl.COLUMN_MIME_TYPE);
-            }
-            if (column.equals(COLUMN_LOCAL_FILENAME)) {
-                return getUnderlyingString(Downloads.Impl._DATA);
-            }
-            if (column.equals(COLUMN_MEDIAPROVIDER_URI)) {
-                return getUnderlyingString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
-            }
-
-            assert column.equals(COLUMN_LOCAL_URI);
-            return getLocalUri();
+            return (getColumnName(columnIndex).equals(COLUMN_LOCAL_URI)) ? getLocalUri() :
+                    super.getString(columnIndex);
         }
 
         private String getLocalUri() {
-            long destinationType = getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
-            if (destinationType == Downloads.Impl.DESTINATION_FILE_URI) {
-                // return client-provided file URI for external download
-                return getUnderlyingString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
-            }
-
-            if (destinationType == Downloads.Impl.DESTINATION_EXTERNAL) {
-                // return stored destination for legacy external download
-                String localPath = getUnderlyingString(Downloads.Impl._DATA);
+            long destinationType = getLong(getColumnIndex(Downloads.Impl.COLUMN_DESTINATION));
+            if (destinationType == Downloads.Impl.DESTINATION_FILE_URI ||
+                    destinationType == Downloads.Impl.DESTINATION_EXTERNAL) {
+                String localPath = getString(getColumnIndex(Downloads.Impl._DATA));
                 if (localPath == null) {
                     return null;
                 }
@@ -1150,38 +1044,10 @@
             }
 
             // return content URI for cache download
-            long downloadId = getUnderlyingLong(Downloads.Impl._ID);
+            long downloadId = getLong(getColumnIndex(Downloads.Impl._ID));
             return ContentUris.withAppendedId(mBaseUri, downloadId).toString();
         }
 
-        private long translateLong(String column) {
-            if (!isLongColumn(column)) {
-                // mimic behavior of underlying cursor -- most likely, throw NumberFormatException
-                return Long.valueOf(translateString(column));
-            }
-
-            if (column.equals(COLUMN_ID)) {
-                return getUnderlyingLong(Downloads.Impl._ID);
-            }
-            if (column.equals(COLUMN_TOTAL_SIZE_BYTES)) {
-                return getUnderlyingLong(Downloads.Impl.COLUMN_TOTAL_BYTES);
-            }
-            if (column.equals(COLUMN_STATUS)) {
-                return translateStatus((int) getUnderlyingLong(Downloads.Impl.COLUMN_STATUS));
-            }
-            if (column.equals(COLUMN_REASON)) {
-                return getReason((int) getUnderlyingLong(Downloads.Impl.COLUMN_STATUS));
-            }
-            if (column.equals(COLUMN_BYTES_DOWNLOADED_SO_FAR)) {
-                return getUnderlyingLong(Downloads.Impl.COLUMN_CURRENT_BYTES);
-            }
-            if (column.equals(Downloads.Impl.COLUMN_DESTINATION)) {
-                return getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
-            }
-            assert column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP);
-            return getUnderlyingLong(Downloads.Impl.COLUMN_LAST_MODIFICATION);
-        }
-
         private long getReason(int status) {
             switch (translateStatus(status)) {
                 case STATUS_FAILED:
@@ -1249,14 +1115,6 @@
             }
         }
 
-        private long getUnderlyingLong(String column) {
-            return super.getLong(super.getColumnIndex(column));
-        }
-
-        private String getUnderlyingString(String column) {
-            return super.getString(super.getColumnIndex(column));
-        }
-
         private int translateStatus(int status) {
             switch (status) {
                 case Downloads.Impl.STATUS_PENDING:
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 033ee7c..1d75b42 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1432,6 +1432,17 @@
         }
     }
 
+    public boolean switchToLastInputMethod(IBinder imeToken) {
+        synchronized (mH) {
+            try {
+                return mService.switchToLastInputMethod(imeToken);
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+                return false;
+            }
+        }
+    }
+
     void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
         final Printer p = new PrintWriterPrinter(fout);
         p.println("Input method client state for " + this + ":");
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 27a6ad3..690164c 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -298,7 +298,8 @@
             p.y = anchorpos[1] + mAnchor.getHeight() - p.height;
             p.format = PixelFormat.TRANSLUCENT;
             p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-            p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
             p.token = null;
             p.windowAnimations = 0; // android.R.style.DropDownAnimationDown;
             mWindowManager.addView(mDecor, p);
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 95678c6..0f61cd4 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -25,6 +25,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.os.Build;
 import android.os.IBinder;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -87,7 +88,7 @@
     private boolean mTouchable = true;
     private boolean mOutsideTouchable = false;
     private boolean mClippingEnabled = true;
-    private boolean mSplitTouchEnabled;
+    private int mSplitTouchEnabled = -1;
     private boolean mLayoutInScreen;
     private boolean mClipToScreen;
 
@@ -602,14 +603,17 @@
      * @hide
      */
     public boolean isSplitTouchEnabled() {
-        return mSplitTouchEnabled;
+        if (mSplitTouchEnabled < 0 && mContext != null) {
+            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
+        }
+        return mSplitTouchEnabled == 1;
     }
 
     /**
      * <p>Allows the popup window to split touches across other windows that also
-     * support split touch.  When this flag is not set, the first pointer
+     * support split touch.  When this flag is false, the first pointer
      * that goes down determines the window to which all subsequent touches
-     * go until all pointers go up.  When this flag is set, each pointer
+     * go until all pointers go up.  When this flag is true, each pointer
      * (not necessarily the first) that goes down determines the window
      * to which all subsequent touches of that pointer will go until that
      * pointer goes up thereby enabling touches with multiple pointers
@@ -620,7 +624,7 @@
      * @hide
      */
     public void setSplitTouchEnabled(boolean enabled) {
-        mSplitTouchEnabled = enabled;
+        mSplitTouchEnabled = enabled ? 1 : 0;
     }
 
     /**
@@ -993,7 +997,7 @@
         if (!mClippingEnabled) {
             curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
         }
-        if (mSplitTouchEnabled) {
+        if (isSplitTouchEnabled()) {
             curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
         }
         if (mLayoutInScreen) {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index ca1cd59..7d8e624 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -57,7 +57,7 @@
     void updateStatusIcon(in IBinder token, String packageName, int iconId);
     void setIMEButtonVisible(in IBinder token, boolean visible);
     InputMethodSubtype getCurrentInputMethodSubtype();
+    boolean switchToLastInputMethod(in IBinder token);
     
     boolean setInputMethodEnabled(String id, boolean enabled);
 }
-
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d305260..d6684fe 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -345,6 +345,18 @@
              because there will be no such interaction coming. -->
         <attr name="windowNoDisplay" format="boolean" />
 
+        <!-- Flag indicating that this window should allow touches to be split
+             across other windows that also support split touch.
+             The default value is true for applications with a targetSdkVersion
+             of Honeycomb or newer; false otherwise.
+             When this flag is false, the first pointer that goes down determines
+             the window to which all subsequent touches go until all pointers go up.
+             When this flag is true, each pointer (not necessarily the first) that
+             goes down determines the window to which all subsequent touches of that
+             pointer will go until that pointers go up thereby enabling touches
+             with multiple pointers to be split across multiple windows. -->
+        <attr name="windowEnableSplitTouch" format="boolean" />
+
         <!-- ============ -->
         <!-- Alert Dialog styles -->
         <!-- ============ -->
@@ -1227,6 +1239,7 @@
         <attr name="windowActionBar" />
         <attr name="windowActionModeOverlay" />
         <attr name="windowActionBarOverlay" />
+        <attr name="windowEnableSplitTouch" />
     </declare-styleable>
 
     <!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index cecf470..28df995 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1365,12 +1365,13 @@
   <public type="attr" name="selectableItemBackground" />
   <public type="attr" name="autoAdvanceViewId" />
   <public type="attr" name="useIntrinsicSizeAsMinimum" />
-
   <public type="attr" name="actionModeCutDrawable" />
   <public type="attr" name="actionModeCopyDrawable" />
   <public type="attr" name="actionModePasteDrawable" />
   <public type="attr" name="textEditPasteWindowLayout" />
   <public type="attr" name="textEditNoPasteWindowLayout" />
+  <public type="attr" name="textIsSelectable" />
+  <public type="attr" name="windowEnableSplitTouch" />
 
   <public type="anim" name="animator_fade_in" />
   <public type="anim" name="animator_fade_out" />
@@ -1440,6 +1441,4 @@
   <public type="style" name="Theme.Holo.DialogWhenLarge" />
   
   <public type="string" name="selectTextMode" />
-
-  <public type="attr" name="textIsSelectable" />
 </resources>
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 8907cd2..4b007f2 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -22,6 +22,25 @@
 /**
  * @hide
  *
+ * Element is the basic data type of RenderScript.  An element can be of 2
+ * forms.  Basic elements contain a single component of data.  This can be of
+ * any of the legal RS types.  Examples of basic element types.
+ * Single float value
+ * 4 element float vector
+ * single RGB-565 color
+ * single unsigned int 16
+ *
+ * Complex elements will contain a list of sub-elements and names.  This in
+ * effect represents a structure of data.  The fields can be accessed by name
+ * from a script or shader.  The memory layout is defined and ordered.  Data
+ * alignment is determinied by the most basic primitive type.  i.e. a float4
+ * vector will be alligned to sizeof(float) and not sizeof(float4).  The
+ * ordering of elements in memory will be the order in which they were added
+ * with each component aligned as necessary. No re-ordering will be done.
+ *
+ * The primary source of elements will be from scripts.  A script that exports a
+ * bind point for a data structure will generate a RS element to represent the
+ * data exported by the script.
  **/
 public class Element extends BaseObj {
     int mSize;
@@ -36,6 +55,21 @@
 
     int getSizeBytes() {return mSize;}
 
+
+    /**
+     * DataType represents the basic type information for a basic element.  The
+     * naming convention follows.  For numeric types its FLOAT, SIGNED, UNSIGNED
+     * followed by the _BITS where BITS is the size of the data.  BOOLEAN is a
+     * true / false (1,0) represented in an 8 bit container.  The UNSIGNED
+     * variants with multiple bit definitions are for packed graphical data
+     * formats and represents vectors with per vector member sizes which are
+     * treated as a single unit for packing and alignment purposes.
+     *
+     * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+     * as 32 bits for alignment purposes.
+     *
+     * RS_* objects.  32 bit opaque handles.
+     */
     public enum DataType {
         //FLOAT_16 (1, 2),
         FLOAT_32 (2, 4),
@@ -78,6 +112,12 @@
         }
     }
 
+    /**
+     * The special interpretation of the data if required.  This is primarly
+     * useful for graphical data.  USER indicates no special interpretation is
+     * expected.  PIXEL is used in conjunction with the standard data types for
+     * representing texture formats.
+     */
     public enum DataKind {
         USER (0),
 
@@ -93,6 +133,12 @@
         }
     }
 
+    /**
+     * Return if a element is too complex for use as a data source for a Mesh or
+     * a Program.
+     *
+     * @return boolean
+     */
     public boolean isComplex() {
         if (mElements == null) {
             return false;
@@ -105,6 +151,13 @@
         return false;
     }
 
+    /**
+     * Utility function for returning an Element containing a single Boolean.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
     public static Element BOOLEAN(RenderScript rs) {
         if(rs.mElement_BOOLEAN == null) {
             rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
@@ -112,6 +165,13 @@
         return rs.mElement_BOOLEAN;
     }
 
+    /**
+     * Utility function for returning an Element containing a single UNSIGNED_8.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
     public static Element U8(RenderScript rs) {
         if(rs.mElement_U8 == null) {
             rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
@@ -119,6 +179,13 @@
         return rs.mElement_U8;
     }
 
+    /**
+     * Utility function for returning an Element containing a single SIGNED_8.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
     public static Element I8(RenderScript rs) {
         if(rs.mElement_I8 == null) {
             rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
@@ -414,7 +481,14 @@
         super.destroy();
     }
 
-    /////////////////////////////////////////
+    /**
+     * Create a custom Element of the specified DataType.  The DataKind will be
+     * set to USER and the vector size to 1 indicating non-vector.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new element.
+     * @return Element
+     */
     public static Element createUser(RenderScript rs, DataType dt) {
         DataKind dk = DataKind.USER;
         boolean norm = false;
@@ -423,6 +497,17 @@
         return new Element(id, rs, dt, dk, norm, vecSize);
     }
 
+    /**
+     * Create a custom vector element of the specified DataType and vector size.
+     *  DataKind will be set to USER.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new element.
+     * @param size Vector size for the new Element.  Range 2-4 inclusive
+     *             supported.
+     *
+     * @return Element
+     */
     public static Element createVector(RenderScript rs, DataType dt, int size) {
         if (size < 2 || size > 4) {
             throw new RSIllegalArgumentException("Vector size out of rance 2-4.");
@@ -433,6 +518,18 @@
         return new Element(id, rs, dt, dk, norm, size);
     }
 
+    /**
+     * Create a new pixel Element type.  A matching DataType and DataKind must
+     * be provided.  The DataType and DataKind must contain the same number of
+     * components.  Vector size will be set to 1.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new element.
+     * @param dk The DataKind to specify the mapping of each component in the
+     *           DataType.
+     *
+     * @return Element
+     */
     public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
         if (!(dk == DataKind.PIXEL_L ||
               dk == DataKind.PIXEL_A ||
@@ -473,6 +570,12 @@
         return new Element(id, rs, dt, dk, norm, size);
     }
 
+    /**
+     * Builder class for producing complex elements with matching field and name
+     * pairs.  The builder starts empty.  The order in which elements are added
+     * is retained for the layout in memory.
+     *
+     */
     public static class Builder {
         RenderScript mRS;
         Element[] mElements;
@@ -480,6 +583,11 @@
         int[] mArraySizes;
         int mCount;
 
+        /**
+         * Create a builder object.
+         *
+         * @param rs
+         */
         public Builder(RenderScript rs) {
             mRS = rs;
             mCount = 0;
@@ -488,6 +596,13 @@
             mArraySizes = new int[8];
         }
 
+        /**
+         * Add an array of elements to this element.
+         *
+         * @param element
+         * @param name
+         * @param arraySize
+         */
         public void add(Element element, String name, int arraySize) {
             if (arraySize < 1) {
                 throw new RSIllegalArgumentException("Array size cannot be less than 1.");
@@ -509,10 +624,22 @@
             mCount++;
         }
 
+        /**
+         * Add a single element to this Element.
+         *
+         * @param element
+         * @param name
+         */
         public void add(Element element, String name) {
             add(element, name, 1);
         }
 
+        /**
+         * Create the element from this builder.
+         *
+         *
+         * @return Element
+         */
         public Element create() {
             mRS.validate();
             Element[] ein = new Element[mCount];
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index ad933b8..44aee63 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -23,6 +23,20 @@
 /**
  * @hide
  *
+ * Type is an allocation template.  It consists of an Element and one or more
+ * dimensions.  It describes only the layout of memory but does not allocate and
+ * storage for the data thus described.
+ *
+ * A Type consists of several dimensions.  Those are X, Y, Z, LOD (level of
+ * detail), Faces (faces of a cube map).  The X,Y,Z dimensions can be assigned
+ * any positive integral value within the constraints of available memory.  A
+ * single dimension allocation would have an X dimension of greater than zero
+ * while the Y and Z dimensions would be zero to indicate not present.  In this
+ * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
+ * x=10, y=0 would be considered 1 dimensional.
+ *
+ * The LOD and Faces dimensions are booleans to indicate present or not present.
+ *
  **/
 public class Type extends BaseObj {
     int mDimX;
@@ -33,25 +47,65 @@
     int mElementCount;
     Element mElement;
 
+    /**
+     * Return the element associated with this Type.
+     *
+     * @return Element
+     */
     public Element getElement() {
         return mElement;
     }
 
+    /**
+     * Return the value of the X dimension.
+     *
+     * @return int
+     */
     public int getX() {
         return mDimX;
     }
+
+    /**
+     * Return the value of the Y dimension or 0 for a 1D allocation.
+     *
+     * @return int
+     */
     public int getY() {
         return mDimY;
     }
+
+    /**
+     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
+     *
+     * @return int
+     */
     public int getZ() {
         return mDimZ;
     }
+
+    /**
+     * Return if the Type has a mipmap chain.
+     *
+     * @return boolean
+     */
     public boolean getLOD() {
         return mDimLOD;
     }
+
+    /**
+     * Return if the Type is a cube map.
+     *
+     * @return boolean
+     */
     public boolean getFaces() {
         return mDimFaces;
     }
+
+    /**
+     * Return the total number of accessable cells in the Type.
+     *
+     * @return int
+     */
     public int getElementCount() {
         return mElementCount;
     }
@@ -122,6 +176,10 @@
         calcElementCount();
     }
 
+    /**
+     * Builder class for Type.
+     *
+     */
     public static class Builder {
         RenderScript mRS;
         Dimension[] mDimensions;
@@ -134,6 +192,12 @@
             int mValue;
         }
 
+        /**
+         * Create a new builder object.
+         *
+         * @param rs
+         * @param e The element for the type to be created.
+         */
         public Builder(RenderScript rs, Element e) {
             if(e.getID() == 0) {
                 throw new RSIllegalArgumentException("Invalid element.");
@@ -145,6 +209,13 @@
             mElement = e;
         }
 
+        /**
+         * Add a dimension to the Type.
+         *
+         *
+         * @param d
+         * @param value
+         */
         public void add(Dimension d, int value) {
             if(value < 1) {
                 throw new RSIllegalArgumentException("Values of less than 1 for Dimensions are not valid.");
@@ -163,6 +234,11 @@
             mEntryCount++;
         }
 
+        /**
+         * Validate structure and create a new type.
+         *
+         * @return Type
+         */
         public Type create() {
             int dims[] = new int[mEntryCount];
             for (int ct=0; ct < mEntryCount; ct++) {
@@ -190,6 +266,26 @@
                     t.mDimFaces = mDimensionValues[ct] != 0;
                 }
             }
+
+            if (t.mDimZ > 0) {
+                if ((t.mDimX < 1) || (t.mDimY < 1)) {
+                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
+                }
+                if (t.mDimFaces) {
+                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
+                }
+            }
+            if (t.mDimY > 0) {
+                if (t.mDimX < 1) {
+                    throw new RSInvalidStateException("X dimension required when Y is present.");
+                }
+            }
+            if (t.mDimFaces) {
+                if (t.mDimY < 1) {
+                    throw new RSInvalidStateException("Cube maps require 2D Types.");
+                }
+            }
+
             t.calcElementCount();
             return t;
         }
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 1081c35..cce2400 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -472,7 +472,7 @@
     AudioParameter(const String8& keyValuePairs);
     virtual ~AudioParameter();
 
-    // reserved parameter keys for changeing standard parameters with setParameters() function.
+    // reserved parameter keys for changing standard parameters with setParameters() function.
     // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
     // configuration changes and act accordingly.
     //  keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
@@ -480,11 +480,14 @@
     //  keyFormat: to change audio format, value is an int in AudioSystem::audio_format
     //  keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
     //  keyFrameCount: to change audio output frame count, value is an int
+    //  keyInputSource: to change audio input source, value is an int in audio_source
+    //     (defined in media/mediarecorder.h)
     static const char *keyRouting;
     static const char *keySamplingRate;
     static const char *keyFormat;
     static const char *keyChannels;
     static const char *keyFrameCount;
+    static const char *keyInputSource;
 
     String8 toString();
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index b4c5d3c..295b127 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -37,7 +37,8 @@
     kKeyStride            = 'strd',  // int32_t
     kKeySliceHeight       = 'slht',  // int32_t
     kKeyChannelCount      = '#chn',  // int32_t
-    kKeySampleRate        = 'srte',  // int32_t (also video frame rate)
+    kKeySampleRate        = 'srte',  // int32_t (audio sampling rate Hz)
+    kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
     kKeyBitRate           = 'brte',  // int32_t (bps)
     kKeyESDS              = 'esds',  // raw data
     kKeyAVCC              = 'avcc',  // raw data
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index d09ff41..15a3925 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -219,6 +219,8 @@
      * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
      */
     bool isTrustedOverlay() const;
+
+    bool supportsSplitTouch() const;
 };
 
 
@@ -946,7 +948,7 @@
     struct TouchedWindow {
         const InputWindow* window;
         int32_t targetFlags;
-        BitSet32 pointerIds;
+        BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
         sp<InputChannel> channel;
     };
     struct TouchState {
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index 9c845aa..359f334 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -30,7 +30,8 @@
     private RenderScriptGL mRS;
     private ScriptC_balls mScript;
     private ScriptC_ball_physics mPhysicsScript;
-    private ProgramFragment mPF;
+    private ProgramFragment mPFLines;
+    private ProgramFragment mPFPoints;
     private ProgramVertex mPV;
     private ProgramRaster mPR;
     private ProgramStore mPS;
@@ -89,10 +90,13 @@
         pfb.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
                            ProgramFragment.Builder.Format.RGBA, 0);
         pfb.setVaryingColor(true);
-        mPF = pfb.create();
-        rs.contextBindProgramFragment(mPF);
+        mPFPoints = pfb.create();
 
-        mPF.bindTexture(loadTexture(R.drawable.flares), 0);
+        pfb = new ProgramFragment.Builder(rs);
+        pfb.setVaryingColor(true);
+        mPFLines = pfb.create();
+
+        mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
 
         mPoints = new ScriptField_Point(mRS, PART_COUNT);
         mArcs = new ScriptField_Point(mRS, PART_COUNT * 2);
@@ -118,7 +122,8 @@
         mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT));
         mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT));
 
-        mScript.set_gPF(mPF);
+        mScript.set_gPFLines(mPFLines);
+        mScript.set_gPFPoints(mPFPoints);
         createProgramVertex();
         createProgramRaster();
 
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs
index 493633b..bbd03cf 100644
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rs
+++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs
@@ -6,7 +6,8 @@
 
 #pragma stateFragment(parent)
 
-rs_program_fragment gPF;
+rs_program_fragment gPFPoints;
+rs_program_fragment gPFLines;
 rs_program_vertex gPV;
 rs_program_raster gPR;
 rs_program_store gPS;
@@ -93,11 +94,12 @@
     }
 
     frame++;
-    rsgBindProgramFragment(gPF);
+    rsgBindProgramFragment(gPFLines);
     rsgBindProgramVertex(gPV);
     rsgBindProgramRaster(gPR);
     rsgBindProgramStore(gPS);
     rsgDrawMesh(arcMesh, 0, 0, arcIdx);
+    rsgBindProgramFragment(gPFPoints);
     rsgDrawMesh(partMesh);
     rsClearObject(&bc.ain);
     rsClearObject(&bc.aout);
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 7ddb3c7..db7d448 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -157,6 +157,10 @@
             || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
 }
 
+bool InputWindow::supportsSplitTouch() const {
+    return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
+}
+
 
 // --- InputDispatcher ---
 
@@ -1110,8 +1114,7 @@
         }
 
         // Figure out whether splitting will be allowed for this window.
-        if (newTouchedWindow
-                && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
+        if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
             // New window supports splitting.
             isSplit = true;
         } else if (isSplit) {
@@ -2648,13 +2651,8 @@
 
                 mTouchState.windows.removeAt(i);
 
-                int32_t newTargetFlags = 0;
-                if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
-                    newTargetFlags |= InputTarget::FLAG_FOREGROUND;
-                    if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
-                        newTargetFlags |= InputTarget::FLAG_SPLIT;
-                    }
-                }
+                int32_t newTargetFlags = oldTargetFlags
+                        & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
                 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
 
                 found = true;
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index a969ac1..a4b0770 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -162,62 +162,41 @@
      * @param durationMs The duration of the image in the storyboard timeline

      */

     public void setDuration(long durationMs) {

-        // Invalidate the beginning and end transitions if necessary

-        if (mBeginTransition != null) {

-            final long transitionDurationMs = mBeginTransition.getDuration();

-

-            // The begin transition must be invalidated if it overlaps with

-            // an effect. To optimize this code we could invalidate the

-            // begin transition only for a Ken Burns effect (color effects

-            // should not affect the begin transition) however when new effects

-            // will be added this code would have to be modified... so we

-            // opted to always invalidate the transition if there is an

-            // overlap.

-            final List<Effect> effects = getAllEffects();

-            for (Effect effect : effects) {

-                // Check if the effect overlaps with the begin transition

-                if (effect.getStartTime() < transitionDurationMs) {

-                    mBeginTransition.invalidate();

-                    break;

-                }

-            }

+        if (durationMs == mDurationMs) {

+            return;

         }

 

-        if (mEndTransition != null) {

-            final long transitionDurationMs = mEndTransition.getDuration();

+        // Invalidate the end transitions if necessary.

+        // This invalidation is necessary for the case in which an effect or

+        // an overlay is overlapping with the end transition

+        // (before the duration is changed) and it no longer overlaps with the

+        // transition after the duration is increased.

 

-            // The end transition must be invalidated if it overlaps with

-            // an effect

-            final List<Effect> effects = getAllEffects();

-            for (Effect effect : effects) {

-                // Check if the effect overlaps with the end transition

-                if (effect.getStartTime() + effect.getDuration() >

-                            mDurationMs - transitionDurationMs) {

-                    mEndTransition.invalidate();

-                    break;

-                }

-            }

+        // The beginning transition does not need to be invalidated at this time

+        // because an effect or an overlay overlaps with the beginning

+        // transition, the begin transition is unaffected by a media item

+        // duration change.

+        invalidateEndTransition();

 

-            if (mEndTransition.isGenerated()) {

-                // The end transition must be invalidated if it overlaps with

-                // an overlay

-                final List<Overlay> overlays = getAllOverlays();

-                for (Overlay overlay : overlays) {

-                    // Check if the overlay overlaps with the end transition

-                    if (overlay.getStartTime() + overlay.getDuration() >

-                                mDurationMs - transitionDurationMs) {

-                        mEndTransition.invalidate();

-                        break;

-                    }

-                }

-            }

-        }

-

+        final long oldDurationMs = mDurationMs;

         mDurationMs = durationMs;

 

         adjustTransitions();

         adjustOverlays();

         adjustEffects();

+

+        // Invalidate the beginning and end transitions after adjustments.

+        // This invalidation is necessary for the case in which an effect or

+        // an overlay was not overlapping with the beginning or end transitions

+        // before the setDuration reduces the duration of the media item and

+        // causes an overlap of the beginning and/or end transition with the

+        // effect.

+        // If the duration is growing, the begin transition does not need to

+        // be invalidated since the effects, overlays are not adjusted.

+        if (mDurationMs < oldDurationMs) {

+            invalidateBeginTransition();

+        }

+        invalidateEndTransition();

     }

 

     /*

@@ -278,6 +257,76 @@
     }

 

     /**

+     * Invalidate the begin transition if any effects and overlays overlap

+     * with the begin transition.

+     */

+    private void invalidateBeginTransition() {

+        if (mBeginTransition != null && mBeginTransition.isGenerated()) {

+            final long transitionDurationMs = mBeginTransition.getDuration();

+

+            // The begin transition must be invalidated if it overlaps with

+            // an effect.

+            final List<Effect> effects = getAllEffects();

+            for (Effect effect : effects) {

+                // Check if the effect overlaps with the begin transition

+                if (effect.getStartTime() < transitionDurationMs) {

+                    mBeginTransition.invalidate();

+                    break;

+                }

+            }

+

+            if (mBeginTransition.isGenerated()) {

+                // The end transition must be invalidated if it overlaps with

+                // an overlay.

+                final List<Overlay> overlays = getAllOverlays();

+                for (Overlay overlay : overlays) {

+                    // Check if the overlay overlaps with the end transition

+                    if (overlay.getStartTime() < transitionDurationMs) {

+                        mBeginTransition.invalidate();

+                        break;

+                    }

+                }

+            }

+        }

+    }

+

+    /**

+     * Invalidate the end transition if any effects and overlays overlap

+     * with the end transition.

+     */

+    private void invalidateEndTransition() {

+        if (mEndTransition != null && mEndTransition.isGenerated()) {

+            final long transitionDurationMs = mEndTransition.getDuration();

+

+            // The end transition must be invalidated if it overlaps with

+            // an effect.

+            final List<Effect> effects = getAllEffects();

+            for (Effect effect : effects) {

+                // Check if the effect overlaps with the end transition

+                if (effect.getStartTime() + effect.getDuration() >

+                            mDurationMs - transitionDurationMs) {

+                    mEndTransition.invalidate();

+                    break;

+                }

+            }

+

+            if (mEndTransition.isGenerated()) {

+                // The end transition must be invalidated if it overlaps with

+                // an overlay.

+                final List<Overlay> overlays = getAllOverlays();

+                for (Overlay overlay : overlays) {

+                    // Check if the overlay overlaps with the end transition

+                    if (overlay.getStartTime() + overlay.getDuration() >

+                                mDurationMs - transitionDurationMs) {

+                        mEndTransition.invalidate();

+                        break;

+                    }

+                }

+            }

+        }

+    }

+

+    /**

      * Adjust the start time and/or duration of effects.

      */

     private void adjustEffects() {

diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9c2a8ba..1a3fcd6 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -835,6 +835,7 @@
 const char *AudioParameter::keyFormat = "format";
 const char *AudioParameter::keyChannels = "channels";
 const char *AudioParameter::keyFrameCount = "frame_count";
+const char *AudioParameter::keyInputSource = "input_source";
 
 AudioParameter::AudioParameter(const String8& keyValuePairs)
 {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 5f9b6e6..dadd1db 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1078,7 +1078,7 @@
     if (mFrameRate == -1) {
         int32_t frameRate = 0;
         CHECK ((*cameraSource)->getFormat()->findInt32(
-                    kKeySampleRate, &frameRate));
+                    kKeyFrameRate, &frameRate));
         LOGI("Frame rate is not explicitly set. Use the current frame "
              "rate (%d fps)", frameRate);
         mFrameRate = frameRate;
@@ -1100,7 +1100,7 @@
 
     sp<MetaData> enc_meta = new MetaData;
     enc_meta->setInt32(kKeyBitRate, videoBitRate);
-    enc_meta->setInt32(kKeySampleRate, mFrameRate);
+    enc_meta->setInt32(kKeyFrameRate, mFrameRate);
 
     switch (mVideoEncoder) {
         case VIDEO_ENCODER_H263:
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 159d937..b8450fb 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -531,7 +531,7 @@
     mMeta->setInt32(kKeyHeight,      mVideoSize.height);
     mMeta->setInt32(kKeyStride,      mVideoSize.width);
     mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
-    mMeta->setInt32(kKeySampleRate,  mVideoFrameRate);
+    mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
     return OK;
 }
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3d490c9..8edcd12 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -935,7 +935,7 @@
     int32_t width, height, frameRate, bitRate, stride, sliceHeight;
     bool success = meta->findInt32(kKeyWidth, &width);
     success = success && meta->findInt32(kKeyHeight, &height);
-    success = success && meta->findInt32(kKeySampleRate, &frameRate);
+    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
     success = success && meta->findInt32(kKeyBitRate, &bitRate);
     success = success && meta->findInt32(kKeyStride, &stride);
     success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
@@ -1155,7 +1155,7 @@
 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
     int32_t iFramesInterval, frameRate, bitRate;
     bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeySampleRate, &frameRate);
+    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
     CHECK(success);
     OMX_VIDEO_PARAM_H263TYPE h263type;
@@ -1202,7 +1202,7 @@
 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
     int32_t iFramesInterval, frameRate, bitRate;
     bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeySampleRate, &frameRate);
+    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
     CHECK(success);
     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
@@ -1254,7 +1254,7 @@
 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
     int32_t iFramesInterval, frameRate, bitRate;
     bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeySampleRate, &frameRate);
+    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
     success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
     CHECK(success);
 
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index a6b179e..e6a0976 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -207,7 +207,7 @@
     LOGV("initCheck");
     CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
     CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
-    CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
+    CHECK(meta->findInt32(kKeyFrameRate, &mVideoFrameRate));
     CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));
 
     // XXX: Add more color format support
@@ -322,7 +322,7 @@
     mFormat->setInt32(kKeyWidth, mVideoWidth);
     mFormat->setInt32(kKeyHeight, mVideoHeight);
     mFormat->setInt32(kKeyBitRate, mVideoBitRate);
-    mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
+    mFormat->setInt32(kKeyFrameRate, mVideoFrameRate);
     mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);
     mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
     mFormat->setCString(kKeyDecoderComponent, "AVCEncoder");
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 72611cf..c7a475b 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -200,7 +200,7 @@
     LOGV("initCheck");
     CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
     CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
-    CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
+    CHECK(meta->findInt32(kKeyFrameRate, &mVideoFrameRate));
     CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));
 
     // XXX: Add more color format support
@@ -299,7 +299,7 @@
     mFormat->setInt32(kKeyWidth, mVideoWidth);
     mFormat->setInt32(kKeyHeight, mVideoHeight);
     mFormat->setInt32(kKeyBitRate, mVideoBitRate);
-    mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
+    mFormat->setInt32(kKeyFrameRate, mVideoFrameRate);
     mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);
 
     mFormat->setCString(kKeyMIMEType, mime);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index b174973..d3d2285 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -298,7 +298,8 @@
                     | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.y += height * 1.5; // FIXME
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 00b39c5..776b59c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -109,7 +109,8 @@
                 height,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
+                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.RGBX_8888);
         lp.gravity = getStatusBarGravity();
         lp.setTitle("StatusBar");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index 7ee3c19..09c8cd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -197,7 +197,8 @@
                 250,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
 //        int pos[] = new int[2];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 29f0fe2..da44f43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -153,7 +153,8 @@
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
         lp.setTitle("NotificationPanel");
@@ -188,7 +189,8 @@
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
         lp.setTitle("NotificationPeekWindow");
@@ -208,7 +210,8 @@
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
         lp.setTitle("SystemPanel");
@@ -232,7 +235,8 @@
                     ViewGroup.LayoutParams.WRAP_CONTENT,
                     WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                     WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                     PixelFormat.TRANSLUCENT);
             lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
             lp.setTitle("RecentsPanel");
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 1bded54..71bf956 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 
 import com.android.internal.view.BaseSurfaceHolder;
 import com.android.internal.view.RootViewSurfaceTaker;
@@ -497,7 +498,8 @@
                 WRAP_CONTENT, WRAP_CONTENT,
                 st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
                 WindowManager.LayoutParams.FLAG_DITHER
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 st.decorView.mDefaultOpacity);
 
         lp.gravity = st.gravity;
@@ -2164,6 +2166,12 @@
             setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
         }
 
+        if (a.getBoolean(com.android.internal.R.styleable.Window_windowEnableSplitTouch,
+                getContext().getApplicationInfo().targetSdkVersion
+                        >= android.os.Build.VERSION_CODES.HONEYCOMB)) {
+            setFlags(FLAG_SPLIT_TOUCH, FLAG_SPLIT_TOUCH&(~getForcedWindowFlags()));
+        }
+
         if (getContext().getApplicationInfo().targetSdkVersion
                 < android.os.Build.VERSION_CODES.HONEYCOMB) {
             addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index edea2c5..b17584a 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -760,10 +760,8 @@
     AudioParameter param = AudioParameter();
     param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
 
-    // use Voice Recognition mode or not for this input based on input source
-    int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
-    param.addInt(String8("vr_mode"), vr_enabled);
-    LOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
+    param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
+    LOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
 
     mpClientInterface->setParameters(input, param.toString());
 
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 0d3cfde..1df4405 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1279,6 +1279,21 @@
         setInputMethodWithSubtype(token, id, NOT_A_SUBTYPE_ID);
     }
 
+    public boolean switchToLastInputMethod(IBinder token) {
+        synchronized (mMethodMap) {
+            Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
+            if (lastIme != null) {
+                InputMethodInfo imi = mMethodMap.get(lastIme.first);
+                if (imi != null) {
+                    setInputMethodWithSubtype(token, lastIme.first, getSubtypeIdFromHashCode(
+                            imi, Integer.valueOf(lastIme.second)));
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     private void setInputMethodWithSubtype(IBinder token, String id, int subtypeId) {
         synchronized (mMethodMap) {
             if (token == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 374bbb4..a5f3456 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -480,13 +480,9 @@
             graphics.setTransform(new AffineTransform());
 
             // set the color
-            graphics.setColor(new Color(color));
+            graphics.setColor(new Color(color, true /*alpha*/));
 
-            // set the mode and alpha.
-            int alpha = color >>> 24;
-            float falpha = alpha / 255.f;
-
-            setModeInGraphics(graphics, mode, falpha);
+            setModeInGraphics(graphics, mode);
 
             graphics.fillRect(0, 0, canvasDelegate.mBufferedImage.getWidth(),
                     canvasDelegate.mBufferedImage.getHeight());
@@ -996,15 +992,8 @@
             }
         }
 
-        // need to get the alpha to set it in the composite.
-        float falpha = 1.f;
-
         if (useColorPaint) {
-            g.setColor(new Color(paint.getColor()));
-
-            // the alpha is taken from the alpha channel of the color
-            int alpha = paint.getAlpha();
-            falpha = alpha / 255.f;
+            g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
         }
 
         int style = paint.getStyle();
@@ -1036,10 +1025,10 @@
         if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
             int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
 
-            setModeInGraphics(g, mode, falpha);
+            setModeInGraphics(g, mode);
         } else {
             // default mode is src_over
-            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
 
             // if xfermode wasn't null, then it's something we don't support. log it.
             if (mLogger != null && xfermodeDelegate != null) {
@@ -1052,36 +1041,36 @@
         return g;
     }
 
-    private static void setModeInGraphics(Graphics2D g, int mode, float falpha) {
+    private static void setModeInGraphics(Graphics2D g, int mode) {
         for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
             if (m.nativeInt == mode) {
-                setModeInGraphics(g, m, falpha);
+                setModeInGraphics(g, m);
                 return;
             }
         }
     }
 
-    private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode, float falpha) {
+    private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode) {
         switch (mode) {
             case CLEAR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/));
                 break;
             case DARKEN:
                 break;
             case DST:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/));
                 break;
             case DST_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/));
                 break;
             case DST_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/));
                 break;
             case DST_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/));
                 break;
             case DST_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/));
                 break;
             case LIGHTEN:
                 break;
@@ -1090,22 +1079,22 @@
             case SCREEN:
                 break;
             case SRC:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/));
                 break;
             case SRC_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/));
                 break;
             case SRC_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/));
                 break;
             case SRC_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/));
                 break;
             case SRC_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/));
                 break;
             case XOR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, falpha));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/));
                 break;
         }
     }
@@ -1156,12 +1145,6 @@
                 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                         RenderingHints.VALUE_INTERPOLATION_BILINEAR);
             }
-
-            if (paintDelegate.getAlpha() != 0xFF) {
-                c = g.getComposite();
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
-                        paintDelegate.getAlpha()/255.f));
-            }
         }
 
         g.drawImage(image, dleft, dtop, dright, dbottom,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index d83a33b..93f757a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -114,10 +114,6 @@
         return mColor;
     }
 
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
     public int getTextAlign() {
         return mTextAlign;
     }
@@ -260,7 +256,7 @@
             return 0;
         }
 
-        return delegate.getAlpha();
+        return delegate.mColor >>> 24;
     }
 
     /*package*/ static void setAlpha(Paint thisPaint, int a) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
index 5fcb9ff..8b67166 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -22,6 +22,7 @@
 import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
 
 import java.awt.image.BufferedImage;
+import java.util.Map;
 
 /**
  * An implementation of {@link LayoutScene}.
@@ -52,6 +53,11 @@
     }
 
     @Override
+    public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
+        return mScene.getDefaultViewPropertyValues(viewObject);
+    }
+
+    @Override
     public SceneResult render() {
 
         synchronized (mBridge) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 79aecff..02db2cf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -63,6 +63,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.Map.Entry;
@@ -82,6 +83,9 @@
     private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
     private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
 
+    private final Map<Object, Map<String, String>> mDefaultPropMaps =
+        new IdentityHashMap<Object, Map<String,String>>();
+
     // maps for dynamically generated id representing style objects (IStyleResourceValue)
     private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap;
     private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap;
@@ -180,6 +184,9 @@
         return mLogger;
     }
 
+    public Map<String, String> getDefaultPropMap(Object key) {
+        return mDefaultPropMaps.get(key);
+    }
 
     // ------------- Activity Methods
 
@@ -285,13 +292,16 @@
             return null;
         }
 
-        Object key = null;
+        Map<String, String> defaultPropMap = null;
         if (parser != null) {
-            key = parser.getViewKey();
-        }
-        if (key != null) {
-            String attrs_name = Bridge.resolveResourceValue(attrs);
-            System.out.println("KEY: " + key.toString() + "(" + attrs_name + ")");
+            Object key = parser.getViewKey();
+            if (key != null) {
+                defaultPropMap = mDefaultPropMaps.get(key);
+                if (defaultPropMap == null) {
+                    defaultPropMap = new HashMap<String, String>();
+                    mDefaultPropMaps.put(key, defaultPropMap);
+                }
+            }
         }
 
         boolean[] frameworkAttributes = new boolean[1];
@@ -309,9 +319,6 @@
             customStyle = parser.getAttributeValue(null /* namespace*/, "style");
         }
         if (customStyle != null) {
-            if (key != null) {
-                print("style", customStyle, false);
-            }
             IResourceValue item = findResValue(customStyle, false /*forceFrameworkOnly*/);
 
             if (item instanceof IStyleResourceValue) {
@@ -323,8 +330,8 @@
             // get the name from the int.
             String defStyleName = searchAttr(defStyleAttr);
 
-            if (key != null) {
-                print("style", defStyleName, true);
+            if (defaultPropMap != null) {
+                defaultPropMap.put("style", defStyleName);
             }
 
             // look for the style in the current theme, and its parent:
@@ -385,20 +392,16 @@
                     // if we found a value, we make sure this doesn't reference another value.
                     // So we resolve it.
                     if (resValue != null) {
-                        if (key != null) {
-                            print(name, resValue.getValue(), true);
+                        // put the first default value, before the resolution.
+                        if (defaultPropMap != null) {
+                            defaultPropMap.put(name, resValue.getValue());
                         }
 
                         resValue = resolveResValue(resValue);
-                    } else if (key != null) {
-                        print(name, "<unknown>", true);
                     }
 
                     ta.bridgeSetValue(index, name, resValue);
                 } else {
-                    if (key != null) {
-                        print(name, value, false);
-                    }
                     // there is a value in the XML, but we need to resolve it in case it's
                     // referencing another resource or a theme value.
                     ta.bridgeSetValue(index, name, resolveValue(null, name, value));
@@ -411,15 +414,6 @@
         return ta;
     }
 
-    private void print(String name, String value, boolean isDefault) {
-        System.out.print("\t" + name + " : " + value);
-        if (isDefault) {
-            System.out.println(" (default)");
-        } else {
-            System.out.println("");
-        }
-    }
-
     @Override
     public Looper getMainLooper() {
         return Looper.myLooper();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index d8a59ce..b0316a3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -665,7 +665,8 @@
 
         ViewInfo result = new ViewInfo(view.getClass().getName(),
                 context.getViewKey(view),
-                view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+                view.getLeft(), view.getTop(), view.getRight(), view.getBottom(),
+                view, view.getLayoutParams());
 
         if (view instanceof ViewGroup) {
             ViewGroup group = ((ViewGroup) view);
@@ -686,4 +687,8 @@
     public ViewInfo getViewInfo() {
         return mViewInfo;
     }
+
+    public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
+        return mContext.getDefaultPropMap(viewObject);
+    }
 }