Merge "The PV aac software decoder screws up if playing a mono-AACplus stream unless we output stereo data. Now we always output stereo data as the legacy OMX nodes did."
diff --git a/api/current.xml b/api/current.xml
index 031506b..8a9a77a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -71453,6 +71453,28 @@
  visibility="public"
 >
 </method>
+<method name="getExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getExposureCompensationStep"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getFlashMode"
  return="java.lang.String"
  abstract="false"
@@ -71543,6 +71565,28 @@
  visibility="public"
 >
 </method>
+<method name="getMaxExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMinExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getPictureFormat"
  return="int"
  abstract="false"
@@ -71843,6 +71887,19 @@
 <parameter name="value" type="java.lang.String">
 </parameter>
 </method>
+<method name="setExposureCompensation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
 <method name="setFlashMode"
  return="void"
  abstract="false"
@@ -89978,6 +90035,356 @@
 </package>
 <package name="android.net.http"
 >
+<class name="AndroidHttpClient"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="org.apache.http.client.HttpClient">
+</implements>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="disableCurlLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="enableCurlLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+<parameter name="level" type="int">
+</parameter>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler&lt;? extends T&gt;">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler&lt;? extends T&gt;">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler&lt;? extends T&gt;">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler&lt;? extends T&gt;">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getCompressedEntity"
+ return="org.apache.http.entity.AbstractHttpEntity"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="resolver" type="android.content.ContentResolver">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getConnectionManager"
+ return="org.apache.http.conn.ClientConnectionManager"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMinGzipSize"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="resolver" type="android.content.ContentResolver">
+</parameter>
+</method>
+<method name="getParams"
+ return="org.apache.http.params.HttpParams"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUngzippedContent"
+ return="java.io.InputStream"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entity" type="org.apache.http.HttpEntity">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="modifyRequestToAcceptGzipResponse"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+</method>
+<method name="newInstance"
+ return="android.net.http.AndroidHttpClient"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="userAgent" type="java.lang.String">
+</parameter>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</method>
+<method name="newInstance"
+ return="android.net.http.AndroidHttpClient"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="userAgent" type="java.lang.String">
+</parameter>
+</method>
+<field name="DEFAULT_SYNC_MIN_GZIP_BYTES"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="HttpDateTime"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="HttpDateTime"
+ type="android.net.http.HttpDateTime"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="parse"
+ return="java.lang.Long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeString" type="java.lang.String">
+</parameter>
+<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
+</exception>
+</method>
+</class>
 <class name="SslCertificate"
  extends="java.lang.Object"
  abstract="false"
@@ -137783,6 +138190,17 @@
  visibility="public"
 >
 </field>
+<field name="EXTRA_CALLING_PACKAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;calling_package&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="EXTRA_LANGUAGE"
  type="java.lang.String"
  transient="false"
@@ -163521,6 +163939,134 @@
 >
 </field>
 </class>
+<class name="Patterns"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="concatGroups"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="matcher" type="java.util.regex.Matcher">
+</parameter>
+</method>
+<method name="digitsAndPlusOnly"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="matcher" type="java.util.regex.Matcher">
+</parameter>
+</method>
+<field name="DOMAIN_NAME"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EMAIL_ADDRESS"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GOOD_IRI_CHAR"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;a-zA-Z0-9\u00a0-\ud7ff\uf900-\ufdcf\ufdf0-\uffef&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IP_ADDRESS"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN_STR"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;((aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(biz|b[abdefghijmnorstvwyz])|(cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(edu|e[cegrstu])|f[ijkmor]|(gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(info|int|i[delmnoqrst])|(jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(name|net|n[acefgilopruz])|(org|om)|(pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)|y[etu]|z[amw])&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)|y[etu]|z[amw]))&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEB_URL"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="PrintStreamPrinter"
  extends="java.lang.Object"
  abstract="false"
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 66f3676..8e4adb1 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -68,7 +68,7 @@
 /* other handy constants */
 
 #define PROTECTED_DIR_PREFIX  "/data/app-private/"
-#define SDCARD_DIR_PREFIX  "/mnt/asec/"
+#define SDCARD_DIR_PREFIX  getenv("ASEC_MOUNTPOINT")
 
 #define DALVIK_CACHE_PREFIX   "/data/dalvik-cache/"
 #define DALVIK_CACHE_POSTFIX  "/classes.dex"
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index 0c7ca83..0a48fe7 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -17,6 +17,7 @@
 package com.android.common;
 
 import android.content.SharedPreferences;
+import android.net.http.HttpDateTime;
 import android.text.format.Time;
 
 import java.util.Map;
diff --git a/common/java/com/android/common/speech/Recognition.java b/common/java/com/android/common/speech/Recognition.java
index 6f164a9..a79a19b 100644
--- a/common/java/com/android/common/speech/Recognition.java
+++ b/common/java/com/android/common/speech/Recognition.java
@@ -19,18 +19,42 @@
 /**
  * Utilities for voice recognition implementations.
  *
- * @see android.app.RecognitionService
+ * @see android.speech.RecognitionService
+ * @see android.speech.RecognizerIntent
  */
 public class Recognition {
-
+    
     /**
-     * The extra key used in an intent to the speech recognizer for voice search. Not
-     * generally to be used by developers. The system search dialog uses this, for example,
-     * to set a calling package for identification by a voice search API. If this extra
-     * is set by anyone but the system process, it should be overridden by the voice search
-     * implementation.
+     * The key to the extra in the Bundle returned by
+     * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS
+     * which is an ArrayList of CharSequences which are hints that can be shown to
+     * the user for voice actions currently supported by voice search for the user's current
+     * language preference for voice search (i.e., the one defined in the extra
+     * android.speech.RecognizerIntent#EXTRA_LANGUAGE_PREFERENCE).
+     *
+     * If this is paired with EXTRA_HINT_CONTEXT, should return a set of hints that are
+     * appropriate for the provided context.
+     *
+     * The CharSequences are SpannedStrings and will contain segments wrapped in
+     * <annotation action="true"></annotation>. This is to indicate the section of the text
+     * which represents the voice action, to be highlighted in the UI if so desired.
      */
-    public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+    public static final String EXTRA_HINT_STRINGS = "android.speech.extra.HINT_STRINGS";
+    
+    /**
+     * The key to an extra to be included in the request intent for
+     * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS.
+     * Should be an int of one of the values defined below. If an
+     * unknown int value is provided, it should be ignored.
+     */
+    public static final String EXTRA_HINT_CONTEXT = "android.speech.extra.HINT_CONTEXT";
+    
+    /**
+     * A set of values for EXTRA_HINT_CONTEXT.
+     */
+    public static final int HINT_CONTEXT_UNKNOWN = 0;
+    public static final int HINT_CONTEXT_VOICE_SEARCH_HELP = 1;
+    public static final int HINT_CONTEXT_CAR_HOME = 2;
 
     private Recognition() { }   // don't instantiate
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b38aeda..8695598 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -678,17 +678,19 @@
     private Thread mUiThread;
     private final Handler mHandler = new Handler();
 
+    // Used for debug only
+    /*
     public Activity() {
         ++sInstanceCount;
     }
 
-
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
         --sInstanceCount;
     }
-    
+    */
+
     public static long getInstanceCount() {
         return sInstanceCount;
     }
diff --git a/core/java/android/app/AliasActivity.java b/core/java/android/app/AliasActivity.java
index 7527a5b..3756529 100644
--- a/core/java/android/app/AliasActivity.java
+++ b/core/java/android/app/AliasActivity.java
@@ -26,7 +26,8 @@
 import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.Xml;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 50dcdf9..8335bf3 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -17,7 +17,7 @@
 package android.app;
 
 import com.android.internal.policy.PolicyManager;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 import com.google.android.collect.Maps;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -209,11 +209,14 @@
 
     private static final String[] EMPTY_FILE_LIST = {};
 
+    // For debug only
+    /*
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
         --sInstanceCount;
     }
+    */
 
     public static long getInstanceCount() {
         return sInstanceCount;
@@ -1446,7 +1449,8 @@
     }
 
     ContextImpl() {
-        ++sInstanceCount;
+        // For debug only
+        //++sInstanceCount;
         mOuterContext = this;
     }
 
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 6a02a58..af68689 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import com.android.common.Patterns;
-import com.android.common.speech.Recognition;
 
 import static android.app.SuggestionsAdapter.getColumnString;
 
@@ -48,6 +46,7 @@
 import android.util.AndroidRuntimeException;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Patterns;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.KeyEvent;
@@ -313,7 +312,6 @@
         mLaunchComponent = null;
         mAppSearchData = null;
         mSearchable = null;
-        mActivityContext = null;
         mUserQuery = null;
     }
 
@@ -411,7 +409,7 @@
             updateSearchAppIcon();
             updateSearchBadge();
             updateQueryHint();
-            updateVoiceButton();
+            updateVoiceButton(TextUtils.isEmpty(mUserQuery));
             
             // In order to properly configure the input method (if one is being used), we
             // need to let it know if we'll be providing suggestions.  Although it would be
@@ -560,10 +558,13 @@
     /**
      * Update the visibility of the voice button.  There are actually two voice search modes, 
      * either of which will activate the button.
+     * @param empty whether the search query text field is empty. If it is, then the other
+     * criteria apply to make the voice button visible. Otherwise the voice button will not
+     * be visible - i.e., if the user has typed a query, remove the voice button.
      */
-    private void updateVoiceButton() {
+    private void updateVoiceButton(boolean empty) {
         int visibility = View.GONE;
-        if (mSearchable.getVoiceSearchEnabled()) {
+        if (mSearchable.getVoiceSearchEnabled() && empty) {
             Intent testIntent = null;
             if (mSearchable.getVoiceSearchLaunchWebSearch()) {
                 testIntent = mVoiceWebSearchIntent;
@@ -666,6 +667,7 @@
                 // The user changed the query, remember it.
                 mUserQuery = s == null ? "" : s.toString();
             }
+            updateVoiceButton(TextUtils.isEmpty(s));
         }
 
         public void afterTextChanged(Editable s) {
@@ -746,9 +748,6 @@
                 return;
             }
             SearchableInfo searchable = mSearchable;
-            // First stop the existing search before starting voice search, or else we'll end
-            // up showing the search dialog again once we return to the app.
-            cancel();
             try {
                 if (searchable.getVoiceSearchLaunchWebSearch()) {
                     getContext().startActivity(mVoiceWebSearchIntent);
@@ -762,6 +761,7 @@
                 // voice search before showing the button. But just in case...
                 Log.w(LOG_TAG, "Could not find voice search activity");
             }
+            dismiss();
          }
     };
     
@@ -819,7 +819,7 @@
         voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
         voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
         voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
-        voiceIntent.putExtra(Recognition.EXTRA_CALLING_PACKAGE,
+        voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                 searchActivity == null ? null : searchActivity.toShortString());
         
         // Add the values that configure forwarding the results
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 607605d..fb3f646 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -34,7 +34,8 @@
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
 import java.io.Serializable;
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 023c024..452fd8a 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -34,7 +34,8 @@
 import android.util.Config;
 import android.util.Log;
 import android.util.Printer;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 /**
  * Structured description of Intent values to be matched.  An IntentFilter can
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index fcb910d..5aad3af 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -18,7 +18,7 @@
 
 import com.android.internal.os.AtomicFile;
 import com.android.internal.util.ArrayUtils;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 98aacaa..b07bafcf 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -30,12 +30,14 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.PatternMatcher;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Config;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import java.io.File;
 import java.io.IOException;
@@ -710,9 +712,10 @@
                     com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
         }
         sa.recycle();
+
         pkg.installLocation = sa.getInteger(
                 com.android.internal.R.styleable.AndroidManifest_installLocation,
-                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+                PackageInfo.INSTALL_LOCATION_AUTO);
 
         // Resource boolean are -1, so 1 means we don't know the value.
         int supportsSmallScreens = 1;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index a885820..b74c073 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -43,7 +43,7 @@
 import java.io.FileInputStream;
 
 import com.android.internal.os.AtomicFile;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
 
 import com.google.android.collect.Maps;
 import com.google.android.collect.Lists;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a5e39d4..0608cc0 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -17,7 +17,7 @@
 package android.content.res;
 
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index 2411177..5e90b91 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -24,7 +24,8 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 /**
  * Conveniences for retrieving data out of a compiled string resource.
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 8f0003b..a7fb31d 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -5,7 +5,8 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import java.util.Arrays;
 
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index 3c2c30a..ad1bfb2 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -17,7 +17,8 @@
 package android.content.res;
 
 import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParserException;
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 6dba94d..da5fa49 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -724,6 +724,9 @@
         private static final String KEY_HORIZONTAL_VIEW_ANGLE = "horizontal-view-angle";
         private static final String KEY_VERTICAL_VIEW_ANGLE = "vertical-view-angle";
         private static final String KEY_EXPOSURE_COMPENSATION = "exposure-compensation";
+        private static final String KEY_MAX_EXPOSURE_COMPENSATION = "max-exposure-compensation";
+        private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
+        private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
         // Parameter key suffix for supported values.
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
 
@@ -1543,38 +1546,63 @@
         }
 
         /**
-         * Gets the current exposure compensation setting.
+         * Gets the current exposure compensation index.
          *
-         * @return the current exposure compensation value multiplied by 100.
-         *         null if exposure compensation is not supported. Ex: -100
-         *         means -1 EV. 130 means +1.3 EV.
-         * @hide
+         * @return current exposure compensation index. The range is {@link
+         *         #getMinExposureCompensation} to {@link
+         *         #getMaxExposureCompensation}. 0 means exposure is not
+         *         adjusted.
          */
         public int getExposureCompensation() {
-            return getInt(KEY_EXPOSURE_COMPENSATION);
+            return getInt(KEY_EXPOSURE_COMPENSATION, 0);
         }
 
         /**
-         * Sets the exposure compensation.
+         * Sets the exposure compensation index.
          *
-         * @param value exposure compensation multiplied by 100. Ex: -100 means
-         *        -1 EV. 130 means +1.3 EV.
-         * @hide
+         * @param value exposure compensation index. The valid value range is
+         *        from {@link #getMinExposureCompensation} (inclusive) to {@link
+         *        #getMaxExposureCompensation} (inclusive). 0 means exposure is
+         *        not adjusted. Application should call
+         *        getMinExposureCompensation and getMaxExposureCompensation to
+         *        know if exposure compensation is supported.
          */
         public void setExposureCompensation(int value) {
             set(KEY_EXPOSURE_COMPENSATION, value);
         }
 
         /**
-         * Gets the supported exposure compensation.
+         * Gets the maximum exposure compensation index.
          *
-         * @return a List of Integer constants. null if exposure compensation is
-         *         not supported. The list is sorted from small to large. Ex:
-         *         -100, -66, -33, 0, 33, 66, 100.
-         * @hide
+         * @return maximum exposure compensation index (>=0). If both this
+         *         method and {@link #getMinExposureCompensation} return 0,
+         *         exposure compensation is not supported.
          */
-        public List<Integer> getSupportedExposureCompensation() {
-            return splitInt(get(KEY_EXPOSURE_COMPENSATION + SUPPORTED_VALUES_SUFFIX));
+        public int getMaxExposureCompensation() {
+            return getInt(KEY_MAX_EXPOSURE_COMPENSATION, 0);
+        }
+
+        /**
+         * Gets the minimum exposure compensation index.
+         *
+         * @return minimum exposure compensation index (<=0). If both this
+         *         method and {@link #getMaxExposureCompensation} return 0,
+         *         exposure compensation is not supported.
+         */
+        public int getMinExposureCompensation() {
+            return getInt(KEY_MIN_EXPOSURE_COMPENSATION, 0);
+        }
+
+        /**
+         * Gets the exposure compensation step.
+         *
+         * @return exposure compensation step. Applications can get EV by
+         *         multiplying the exposure compensation index and step. Ex: if
+         *         exposure compensation index is -6 and step is 0.333333333, EV
+         *         is -2.
+         */
+        public float getExposureCompensationStep() {
+            return getFloat(KEY_EXPOSURE_COMPENSATION_STEP, 0);
         }
 
         /**
@@ -1680,6 +1708,24 @@
             return substrings;
         }
 
+        // Returns the value of a float parameter.
+        private float getFloat(String key, float defaultValue) {
+            try {
+                return Float.parseFloat(mMap.get(key));
+            } catch (NumberFormatException ex) {
+                return defaultValue;
+            }
+        }
+
+        // Returns the value of a integer parameter.
+        private int getInt(String key, int defaultValue) {
+            try {
+                return Integer.parseInt(mMap.get(key));
+            } catch (NumberFormatException ex) {
+                return defaultValue;
+            }
+        }
+
         // Splits a comma delimited string to an ArrayList of Size.
         // Return null if the passing string is null or the size is 0.
         private ArrayList<Size> splitSize(String str) {
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index f959fee..6941e57 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -16,11 +16,12 @@
 
 package android.net;
 
+import com.android.internal.net.DomainNameValidator;
+
 import android.os.SystemProperties;
 import android.util.Config;
 import android.util.Log;
 
-import com.android.common.DomainNameValidator;
 
 import java.io.IOException;
 import java.net.InetAddress;
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index fa13894..a572f60 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -16,7 +16,7 @@
 
 package android.net;
 
-import static com.android.common.Patterns.GOOD_IRI_CHAR;
+import static android.util.Patterns.GOOD_IRI_CHAR;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
diff --git a/common/java/com/android/common/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
similarity index 98%
rename from common/java/com/android/common/AndroidHttpClient.java
rename to core/java/android/net/http/AndroidHttpClient.java
index 4c65eb0..3517737 100644
--- a/common/java/com/android/common/AndroidHttpClient.java
+++ b/core/java/android/net/http/AndroidHttpClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.net.http;
 
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
@@ -36,7 +36,6 @@
 import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.client.RequestWrapper;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
@@ -55,7 +54,6 @@
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 import java.net.URI;
-import java.security.KeyManagementException;
 
 import android.content.Context;
 import android.content.ContentResolver;
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index e1327dd..c527fe4 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -16,7 +16,8 @@
 
 package android.net.http;
 
-import com.android.common.DomainNameValidator;
+
+import com.android.internal.net.DomainNameValidator;
 
 import org.apache.harmony.xnet.provider.jsse.SSLParameters;
 
diff --git a/common/java/com/android/common/HttpDateTime.java b/core/java/android/net/http/HttpDateTime.java
similarity index 98%
rename from common/java/com/android/common/HttpDateTime.java
rename to core/java/android/net/http/HttpDateTime.java
index f4052cc..c7a31ee 100644
--- a/common/java/com/android/common/HttpDateTime.java
+++ b/core/java/android/net/http/HttpDateTime.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.net.http;
 
 import android.text.format.Time;
 
@@ -22,8 +22,9 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-
-/** {@hide} */
+/**
+ * Helper for parsing an HTTP date.
+ */
 public final class HttpDateTime {
 
     /*
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index cb42d73..c9dab60 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -19,15 +19,15 @@
 import android.accounts.Account;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
+import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
-import android.content.EntityIterator;
 import android.content.CursorEntityIterator;
 import android.content.Entity;
-import android.content.ContentProviderClient;
+import android.content.EntityIterator;
+import android.content.Intent;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.net.Uri;
@@ -408,6 +408,12 @@
         public static final String SELF_ATTENDEE_STATUS = "selfAttendeeStatus";
 
         /**
+         * This column is available for use by sync adapters
+         * <P>Type: TEXT</P>
+         */
+        public static final String SYNC_ADAPTER_DATA = "syncAdapterData";
+
+        /**
          * The comments feed uri.
          * <P>Type: TEXT</P>
          */
@@ -644,6 +650,7 @@
                 mProvider = provider;
             }
 
+            @Override
             public Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException {
                 // we expect the cursor is already at the row we need to read from
                 final long eventId = cursor.getLong(cursor.getColumnIndexOrThrow(Events._ID));
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1163106..0b90f91 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3201,28 +3201,33 @@
         public static final String SNIPPET_MIMETYPE = "snippet_mimetype";
 
         /**
-         * The {@link CommonDataKinds.CommonColumns#DATA} field of the data row
-         * that was matched by the filter.
+         * The {@link Data#DATA1} field of the data row that was matched by the filter.
          *
          * @hide
          */
-        public static final String SNIPPET_DATA = "snippet_data";
+        public static final String SNIPPET_DATA1 = "snippet_data1";
 
         /**
-         * The {@link CommonDataKinds.CommonColumns#TYPE} field of the data row
-         * that was matched by the filter.
+         * The {@link Data#DATA2} field of the data row that was matched by the filter.
          *
          * @hide
          */
-        public static final String SNIPPET_TYPE = "snippet_type";
+        public static final String SNIPPET_DATA2 = "snippet_data2";
 
         /**
-         * The {@link CommonDataKinds.CommonColumns#LABEL} field of the data row
-         * that was matched by the filter.
+         * The {@link Data#DATA3} field of the data row that was matched by the filter.
          *
          * @hide
          */
-        public static final String SNIPPET_LABEL = "snippet_label";
+        public static final String SNIPPET_DATA3 = "snippet_data3";
+
+        /**
+         * The {@link Data#DATA4} field of the data row that was matched by the filter.
+         *
+         * @hide
+         */
+        public static final String SNIPPET_DATA4 = "snippet_data4";
+
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b75a8cc..081cf32 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1647,6 +1647,9 @@
             TTY_MODE,
             SOUND_EFFECTS_ENABLED,
             HAPTIC_FEEDBACK_ENABLED,
+            POWER_SOUNDS_ENABLED,
+            DOCK_SOUNDS_ENABLED,
+            LOCKSCREEN_SOUNDS_ENABLED,
             SHOW_WEB_SUGGESTIONS,
             NOTIFICATION_LIGHT_PULSE
         };
@@ -3095,6 +3098,7 @@
             PARENTAL_CONTROL_REDIRECT_URL,
             USB_MASS_STORAGE_ENABLED,
             ACCESSIBILITY_ENABLED,
+            BACKUP_AUTO_RESTORE,
             ENABLED_ACCESSIBILITY_SERVICES,
             TTS_USE_DEFAULTS,
             TTS_DEFAULT_RATE,
diff --git a/core/java/android/provider/SyncConstValue.java b/core/java/android/provider/SyncConstValue.java
index 30966eb..2fcf315 100644
--- a/core/java/android/provider/SyncConstValue.java
+++ b/core/java/android/provider/SyncConstValue.java
@@ -18,6 +18,7 @@
 
 /**
  * Columns for tables that are synced to a server.
+ * @deprecated
  * @hide
  */
 public interface SyncConstValue
@@ -69,7 +70,7 @@
      * <P>Type: INTEGER (long)</P>
      */
     public static final String _SYNC_DIRTY = "_sync_dirty";
-    
+
     /**
      * Used to indicate that this account is not synced
      */
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index adeef54..d96596295 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -29,8 +29,8 @@
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
+import android.util.Patterns;
 
-import com.android.common.Patterns;
 
 import java.util.HashSet;
 import java.util.Set;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index aa20ac4..e7d9d5b 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -52,12 +52,17 @@
 import com.android.internal.app.IBatteryStats;
 
 import java.io.BufferedInputStream;
+import java.io.BufferedReader;
 import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
@@ -65,7 +70,6 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Random;
 
 public class BluetoothService extends IBluetooth.Stub {
     private static final String TAG = "BluetoothService";
@@ -528,6 +532,7 @@
                     persistBluetoothOnSetting(true);
                 }
                 mIsDiscovering = false;
+                mBondState.readAutoPairingData();
                 mBondState.loadBondState();
                 mHandler.sendMessageDelayed(
                         mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
@@ -580,34 +585,17 @@
     public class BondState {
         private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
         private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
-        private final ArrayList<String> mAutoPairingFailures = new ArrayList<String>();
-        // List of all the vendor_id prefix of Bluetooth addresses for
-        // which auto pairing is not attempted.
-        // The following companies are included in the list below:
-        // ALPS (lexus), Murata (Prius 2007, Nokia 616), TEMIC SDS (Porsche, Audi),
-        // Parrot, Zhongshan General K-mate Electronics, Great Well
-        // Electronics, Flaircomm Electronics, Jatty Electronics, Delphi,
-        // Clarion, Novero, Denso (Lexus, Toyota), Johnson Controls (Acura),
-        // Continental Automotive, Harman/Becker, Panasonic/Kyushu Ten,
-        // BMW (Motorola PCS)
-        private final ArrayList<String>  mAutoPairingAddressBlacklist =
-                new ArrayList<String>(Arrays.asList(
-                        "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", "00:21:4F",
-                        "00:23:06", "00:24:33", "00:A0:79", "00:0E:6D", "00:13:E0", "00:21:E8",
-                        "00:60:57", "00:0E:9F", "00:12:1C", "00:18:91", "00:18:96", "00:13:04",
-                        "00:16:FD", "00:22:A0", "00:0B:4C", "00:60:6F", "00:23:3D", "00:C0:59",
-                        "00:0A:30", "00:1E:AE", "00:1C:D7", "00:80:F0", "00:12:8A"
-                        ));
 
-        // List of names of Bluetooth devices for which auto pairing should be
-        // disabled.
-        private final ArrayList<String> mAutoPairingExactNameBlacklist =
-                new ArrayList<String>(Arrays.asList(
-                        "Motorola IHF1000", "i.TechBlueBAND", "X5 Stereo v1.3"));
+        private static final String AUTO_PAIRING_BLACKLIST =
+            "/etc/bluetooth/auto_pairing.conf";
+        private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
+            "/data/misc/bluetooth/dynamic_auto_pairing.conf";
+        private ArrayList<String>  mAutoPairingAddressBlacklist;
+        private ArrayList<String> mAutoPairingExactNameBlacklist;
+        private ArrayList<String> mAutoPairingPartialNameBlacklist;
+        // Addresses added to blacklist dynamically based on usage.
+        private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
 
-        private final ArrayList<String> mAutoPairingPartialNameBlacklist =
-                new ArrayList<String>(Arrays.asList(
-                        "BMW", "Audi"));
 
         // If this is an outgoing connection, store the address.
         // There can be only 1 pending outgoing connection at a time,
@@ -682,18 +670,29 @@
         }
 
         public boolean isAutoPairingBlacklisted(String address) {
-            for (String blacklistAddress : mAutoPairingAddressBlacklist) {
-                if (address.startsWith(blacklistAddress)) return true;
+            if (mAutoPairingAddressBlacklist != null) {
+                for (String blacklistAddress : mAutoPairingAddressBlacklist) {
+                    if (address.startsWith(blacklistAddress)) return true;
+                }
             }
 
+            if (mAutoPairingDynamicAddressBlacklist != null) {
+                for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
+                    if (address.equals(blacklistAddress)) return true;
+                }
+            }
             String name = getRemoteName(address);
             if (name != null) {
-                for (String blacklistName : mAutoPairingExactNameBlacklist) {
-                    if (name.equals(blacklistName)) return true;
+                if (mAutoPairingExactNameBlacklist != null) {
+                    for (String blacklistName : mAutoPairingExactNameBlacklist) {
+                        if (name.equals(blacklistName)) return true;
+                    }
                 }
 
-                for (String blacklistName : mAutoPairingPartialNameBlacklist) {
-                    if (name.startsWith(blacklistName)) return true;
+                if (mAutoPairingPartialNameBlacklist != null) {
+                    for (String blacklistName : mAutoPairingPartialNameBlacklist) {
+                        if (name.startsWith(blacklistName)) return true;
+                    }
                 }
             }
             return false;
@@ -718,9 +717,12 @@
         }
 
         public synchronized void addAutoPairingFailure(String address) {
-            if (!mAutoPairingFailures.contains(address)) {
-                mAutoPairingFailures.add(address);
+            if (mAutoPairingDynamicAddressBlacklist == null) {
+                mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
             }
+
+            updateAutoPairingData(address);
+            mAutoPairingDynamicAddressBlacklist.add(address);
         }
 
         public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
@@ -732,7 +734,9 @@
         }
 
         public synchronized boolean hasAutoPairingFailed(String address) {
-            return mAutoPairingFailures.contains(address);
+            if (mAutoPairingDynamicAddressBlacklist == null) return false;
+
+            return mAutoPairingDynamicAddressBlacklist.contains(address);
         }
 
         public synchronized int getAttempt(String address) {
@@ -754,6 +758,108 @@
             mPinAttempt.put(address, new Integer(newAttempt));
         }
 
+        private void copyAutoPairingData() {
+            File file = null;
+            FileInputStream in = null;
+            FileOutputStream out = null;
+            try {
+                file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+                if (file.exists()) return;
+
+                in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
+                out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+
+                byte[] buf = new byte[1024];
+                int len;
+                while ((len = in.read(buf)) > 0) {
+                    out.write(buf, 0, len);
+                }
+            } catch (FileNotFoundException e) {
+                log("FileNotFoundException: in copyAutoPairingData");
+            } catch (IOException e) {
+                log("IOException: in copyAutoPairingData");
+            } finally {
+                 try {
+                     if (in != null) in.close();
+                     if (out != null) out.close();
+                 } catch (IOException e) {}
+            }
+        }
+
+        public void readAutoPairingData() {
+            if (mAutoPairingAddressBlacklist != null) return;
+            copyAutoPairingData();
+            FileInputStream fstream = null;
+            try {
+                fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+                DataInputStream in = new DataInputStream(fstream);
+                BufferedReader file = new BufferedReader(new InputStreamReader(in));
+                String line;
+                while((line = file.readLine()) != null) {
+                    line = line.trim();
+                    if (line.length() == 0 || line.startsWith("//")) continue;
+                    String[] value = line.split("=");
+                    if (value != null && value.length == 2) {
+                        String[] val = value[1].split(",");
+                        if (value[0].equalsIgnoreCase("AddressBlacklist")) {
+                            mAutoPairingAddressBlacklist =
+                                new ArrayList<String>(Arrays.asList(val));
+                        } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
+                            mAutoPairingExactNameBlacklist =
+                                new ArrayList<String>(Arrays.asList(val));
+                        } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
+                            mAutoPairingPartialNameBlacklist =
+                                new ArrayList<String>(Arrays.asList(val));
+                        } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
+                            mAutoPairingDynamicAddressBlacklist =
+                                new ArrayList<String>(Arrays.asList(val));
+                        } else {
+                            Log.e(TAG, "Error parsing Auto pairing blacklist file");
+                        }
+                    }
+                }
+            } catch (FileNotFoundException e) {
+                log("FileNotFoundException: readAutoPairingData" + e.toString());
+            } catch (IOException e) {
+                log("IOException: readAutoPairingData" + e.toString());
+            } finally {
+                if (fstream != null) {
+                    try {
+                        fstream.close();
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
+
+        // This function adds a bluetooth address to the auto pairing blacklis
+        // file. These addresses are added to DynamicAddressBlacklistSection
+        private void updateAutoPairingData(String address) {
+            BufferedWriter out = null;
+            try {
+                out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
+                StringBuilder str = new StringBuilder();
+                if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
+                    str.append("DynamicAddressBlacklist=");
+                }
+                str.append(address);
+                str.append(",");
+                out.write(str.toString());
+            } catch (FileNotFoundException e) {
+                log("FileNotFoundException: updateAutoPairingData" + e.toString());
+            } catch (IOException e) {
+                log("IOException: updateAutoPairingData" + e.toString());
+            } finally {
+                if (out != null) {
+                    try {
+                        out.close();
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
     }
 
     private static String toBondStateString(int bondState) {
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 7c15cec..bf411e1 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -32,6 +32,15 @@
  * Constants for supporting speech recognition through starting an {@link Intent}
  */
 public class RecognizerIntent {
+    /**
+     * The extra key used in an intent to the speech recognizer for voice search. Not
+     * generally to be used by developers. The system search dialog uses this, for example,
+     * to set a calling package for identification by a voice search API. If this extra
+     * is set by anyone but the system process, it should be overridden by the voice search
+     * implementation.
+     */
+    public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+
     private RecognizerIntent() {
         // Not for instantiating.
     }
diff --git a/core/java/android/test/InstrumentationTestCase.java b/core/java/android/test/InstrumentationTestCase.java
index 22d95d1..cd33d8a 100644
--- a/core/java/android/test/InstrumentationTestCase.java
+++ b/core/java/android/test/InstrumentationTestCase.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import junit.framework.TestCase;
-
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Intent;
@@ -26,9 +24,11 @@
 import android.view.KeyEvent;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.InvocationTargetException;
+
+import junit.framework.TestCase;
 
 /**
  * A test case that has access to {@link Instrumentation}.
@@ -86,7 +86,6 @@
      * @param extras Optional extra stuff to pass to the activity.
      * @return The activity, or null if non launched.
      */
-    @SuppressWarnings("unchecked")
     public final <T extends Activity> T launchActivity(
             String pkg,
             Class<T> activityCls,
@@ -338,6 +337,7 @@
      * 
      * @throws Exception
      */
+    @Override
     protected void tearDown() throws Exception {
         Runtime.getRuntime().gc();
         Runtime.getRuntime().runFinalization();
diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java
new file mode 100644
index 0000000..e4f934e
--- /dev/null
+++ b/core/java/android/text/AndroidBidi.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * Access the ICU bidi implementation.
+ * @hide
+ */
+/* package */ class AndroidBidi {
+
+    public static int bidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo) {
+        if (chs == null || chInfo == null) {
+            throw new NullPointerException();
+        }
+
+        if (n < 0 || chs.length < n || chInfo.length < n) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        switch(dir) {
+            case Layout.DIR_REQUEST_LTR: dir = 0; break;
+            case Layout.DIR_REQUEST_RTL: dir = 1; break;
+            case Layout.DIR_REQUEST_DEFAULT_LTR: dir = -2; break;
+            case Layout.DIR_REQUEST_DEFAULT_RTL: dir = -1; break;
+            default: dir = 0; break;
+        }
+
+        int result = runBidi(dir, chs, chInfo, n, haveInfo);
+        result = (result & 0x1) == 0 ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT;
+        return result;
+    }
+
+    private native static int runBidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo);
+}
\ No newline at end of file
diff --git a/core/java/android/text/AutoText.java b/core/java/android/text/AutoText.java
index 862305b..04730ec 100644
--- a/core/java/android/text/AutoText.java
+++ b/core/java/android/text/AutoText.java
@@ -18,7 +18,9 @@
 
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
+
 import android.view.View;
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 33ecc01..07e71f9 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -46,7 +46,8 @@
 import android.text.style.URLSpan;
 import android.text.style.UnderlineSpan;
 import android.util.Log;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
 import java.io.StringReader;
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 7f87365..98605888c 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -22,10 +22,10 @@
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.Spanned;
+import android.util.Patterns;
 import android.webkit.WebView;
 import android.widget.TextView;
 
-import com.android.common.Patterns;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
diff --git a/common/java/com/android/common/Patterns.java b/core/java/android/util/Patterns.java
similarity index 99%
rename from common/java/com/android/common/Patterns.java
rename to core/java/android/util/Patterns.java
index 3b3b038..2ee6e8a 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.util;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 4f496d7..0fc70d5 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -27,7 +27,7 @@
 import java.util.TimeZone;
 import java.util.Date;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 
 /**
  * A class containing utility methods related to time zones.
diff --git a/core/java/android/util/XmlPullAttributes.java b/core/java/android/util/XmlPullAttributes.java
index 8f855cd..ecedbe1 100644
--- a/core/java/android/util/XmlPullAttributes.java
+++ b/core/java/android/util/XmlPullAttributes.java
@@ -19,7 +19,8 @@
 import org.xmlpull.v1.XmlPullParser;
 
 import android.util.AttributeSet;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 /**
  * Provides an implementation of AttributeSet on top of an XmlPullParser.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 679206d..03b569d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1819,7 +1819,8 @@
         mContext = context;
         mResources = context != null ? context.getResources() : null;
         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
-        ++sInstanceCount;
+        // Used for debug only
+        //++sInstanceCount;
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
     }
 
@@ -2133,11 +2134,14 @@
     View() {
     }
 
+    // Used for debug only
+    /*
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
         --sInstanceCount;
     }
+    */
 
     /**
      * <p>
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 264b8c9..582ef3f 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -230,7 +230,8 @@
             lt = new LatencyTimer(100, 1000);
         }
 
-        ++sInstanceCount;
+        // For debug only
+        //++sInstanceCount;
 
         // Initialize the statics when this class is first instantiated. This is
         // done here instead of in the static block because Zygote does not
@@ -258,11 +259,14 @@
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
     }
 
+    // For debug only
+    /*
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
         --sInstanceCount;
     }
+    */
 
     public static long getInstanceCount() {
         return sInstanceCount;
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 2aba60b..6c58461 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -57,8 +57,12 @@
      * {@link android.hardware.SensorManager SensorManager}). Use the default
      * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL 
      * SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
+     *
+     * This constructor is private since no one uses it and making it public would complicate
+     * things, since the lowpass filtering code depends on the actual sampling period, and there's
+     * no way to get the period from SensorManager based on the rate constant.
      */
-    public WindowOrientationListener(Context context, int rate) {
+    private WindowOrientationListener(Context context, int rate) {
         mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
         mRate = rate;
         mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -107,94 +111,179 @@
     }
     
     class SensorEventListenerImpl implements SensorEventListener {
+        // We work with all angles in degrees in this class.
+        private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);
+
+        // Indices into SensorEvent.values
         private static final int _DATA_X = 0;
         private static final int _DATA_Y = 1;
         private static final int _DATA_Z = 2;
-        // Angle around x-asis that's considered almost too vertical. Beyond
-        // this angle will not result in any orientation changes. f phone faces uses,
-        // the device is leaning backward.
-        private static final int PIVOT_UPPER = 65;
-        // Angle about x-axis that's considered negative vertical. Beyond this
-        // angle will not result in any orientation changes. If phone faces uses,
-        // the device is leaning forward.
-        private static final int PIVOT_LOWER = -10;
-        static final int ROTATION_0 = 0;
-        static final int ROTATION_90 = 1;
-        static final int ROTATION_180 = 2;
-        static final int ROTATION_270 = 3;
-        int mRotation = ROTATION_0;
 
-        // Threshold values defined for device rotation positions
-        // follow order ROTATION_0 .. ROTATION_270
-        final int THRESHOLDS[][][] = new int[][][] {
-            {{60, 135}, {135, 225}, {225, 300}},
-                {{0, 45}, {45, 135}, {135, 210}, {330, 360}},
-                {{0, 45}, {45, 120}, {240, 315}, {315, 360}},
-                {{0, 30}, {150, 225}, {225, 315}, {315, 360}}
+        // Internal aliases for the four orientation states.  ROTATION_0 = default portrait mode,
+        // ROTATION_90 = left side of device facing the sky, etc.
+        private static final int ROTATION_0 = 0;
+        private static final int ROTATION_90 = 1;
+        private static final int ROTATION_180 = 2;
+        private static final int ROTATION_270 = 3;
+
+        // Current orientation state
+        private int mRotation = ROTATION_0;
+
+        // Mapping our internal aliases into actual Surface rotation values
+        private final int[] SURFACE_ROTATIONS = new int[] {Surface.ROTATION_0, Surface.ROTATION_90,
+                Surface.ROTATION_180, Surface.ROTATION_270};
+
+        // Threshold ranges of orientation angle to transition into other orientation states.
+        // The first list is for transitions from ROTATION_0, the next for ROTATION_90, etc.
+        // ROTATE_TO defines the orientation each threshold range transitions to, and must be kept
+        // in sync with this.
+        // The thresholds are nearly regular -- we generally transition about the halfway point
+        // between two states with a swing of 30 degreees for hysteresis.  For ROTATION_180,
+        // however, we enforce stricter thresholds, pushing the thresholds 15 degrees closer to 180.
+        private final int[][][] THRESHOLDS = new int[][][] {
+                {{60, 165}, {165, 195}, {195, 300}},
+                {{0, 45}, {45, 165}, {165, 195}, {330, 360}},
+                {{0, 45}, {45, 135}, {225, 315}, {315, 360}},
+                {{0, 30}, {165, 195}, {195, 315}, {315, 360}}
         };
 
-        // Transform rotation ranges based on THRESHOLDS. This
-        // has to be in step with THESHOLDS
-        final int ROTATE_TO[][] = new int[][] {
-            {ROTATION_270, ROTATION_180, ROTATION_90},
-            {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0},
-            {ROTATION_0, ROTATION_270, ROTATION_90, ROTATION_0},
-            {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}
+        // See THRESHOLDS
+        private final int[][] ROTATE_TO = new int[][] {
+                {ROTATION_270, ROTATION_180, ROTATION_90},
+                {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0},
+                {ROTATION_0, ROTATION_270, ROTATION_90, ROTATION_0},
+                {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}
         };
 
-        // Mapping into actual Surface rotation values
-        final int TRANSFORM_ROTATIONS[] = new int[]{Surface.ROTATION_0,
-                Surface.ROTATION_90, Surface.ROTATION_180, Surface.ROTATION_270};
+        // Maximum absolute tilt angle at which to consider orientation changes.  Beyond this (i.e.
+        // when screen is facing the sky or ground), we refuse to make any orientation changes.
+        private static final int MAX_TILT = 65;
+
+        // Additional limits on tilt angle to transition to each new orientation.  We ignore all
+        // vectors with tilt beyond MAX_TILT, but we can set stricter limits on transition to a
+        // particular orientation here.
+        private final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, MAX_TILT, 40, MAX_TILT};
+
+        // Between this tilt angle and MAX_TILT, we'll allow orientation changes, but we'll filter
+        // with a higher time constant, making us less sensitive to change.  This primarily helps
+        // prevent momentary orientation changes when placing a device on a table from the side (or
+        // picking one up).
+        private static final int PARTIAL_TILT = 45;
+
+        // Maximum allowable deviation of the magnitude of the sensor vector from that of gravity,
+        // in m/s^2.  Beyond this, we assume the phone is under external forces and we can't trust
+        // the sensor data.  However, under constantly vibrating conditions (think car mount), we
+        // still want to pick up changes, so rather than ignore the data, we filter it with a very
+        // high time constant.
+        private static final int MAX_DEVIATION_FROM_GRAVITY = 1;
+
+        // Actual sampling period corresponding to SensorManager.SENSOR_DELAY_NORMAL.  There's no
+        // way to get this information from SensorManager.
+        // Note the actual period is generally 3-30ms larger than this depending on the device, but
+        // that's not enough to significantly skew our results.
+        private static final int SAMPLING_PERIOD_MS = 200;
+
+        // The following time constants are all used in low-pass filtering the accelerometer output.
+        // See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
+        // background.
+
+        // When device is near-vertical (screen approximately facing the horizon)
+        private static final int DEFAULT_TIME_CONSTANT_MS = 200;
+        // When device is partially tilted towards the sky or ground
+        private static final int TILTED_TIME_CONSTANT_MS = 600;
+        // When device is under external acceleration, i.e. not just gravity.  We heavily distrust
+        // such readings.
+        private static final int ACCELERATING_TIME_CONSTANT_MS = 5000;
+
+        private static final float DEFAULT_LOWPASS_ALPHA =
+            (float) SAMPLING_PERIOD_MS / (DEFAULT_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+        private static final float TILTED_LOWPASS_ALPHA =
+            (float) SAMPLING_PERIOD_MS / (TILTED_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+        private static final float ACCELERATING_LOWPASS_ALPHA =
+            (float) SAMPLING_PERIOD_MS / (ACCELERATING_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+
+        // The low-pass filtered accelerometer data
+        private float[] mFilteredVector = new float[] {0, 0, 0};
 
         int getCurrentRotation() {
-            return TRANSFORM_ROTATIONS[mRotation];
+            return SURFACE_ROTATIONS[mRotation];
         }
-        
-        private void calculateNewRotation(int orientation, int zyangle) {
-            if (localLOGV) Log.i(TAG, orientation + ", " + zyangle + ", " + mRotation);
-            int rangeArr[][] = THRESHOLDS[mRotation];
+
+        private void calculateNewRotation(int orientation, int tiltAngle) {
+            if (localLOGV) Log.i(TAG, orientation + ", " + tiltAngle + ", " + mRotation);
+            int thresholdRanges[][] = THRESHOLDS[mRotation];
             int row = -1;
-            for (int i = 0; i < rangeArr.length; i++) {
-                if ((orientation >= rangeArr[i][0]) && (orientation < rangeArr[i][1])) {
+            for (int i = 0; i < thresholdRanges.length; i++) {
+                if (orientation >= thresholdRanges[i][0] && orientation < thresholdRanges[i][1]) {
                     row = i;
                     break;
                 }
             }
-            if (row != -1) {
-                // Find new rotation based on current rotation value.
-                // This also takes care of irregular rotations as well.
-                int rotation = ROTATE_TO[mRotation][row];
-                if (localLOGV) Log.i(TAG, " new rotation = " + rotation);
-                if (rotation != mRotation) {
-                    mRotation = rotation;
-                    // Trigger orientation change
-                    onOrientationChanged(TRANSFORM_ROTATIONS[rotation]);
-                }
+            if (row == -1) return; // no matching transition
+
+            int rotation = ROTATE_TO[mRotation][row];
+            if (tiltAngle > MAX_TRANSITION_TILT[rotation]) {
+                // tilted too far flat to go to this rotation
+                return;
             }
+
+            if (localLOGV) Log.i(TAG, " new rotation = " + rotation);
+            mRotation = rotation;
+            onOrientationChanged(SURFACE_ROTATIONS[rotation]);
+        }
+
+        private float lowpassFilter(float newValue, float oldValue, float alpha) {
+            return alpha * newValue + (1 - alpha) * oldValue;
+        }
+
+        private float vectorMagnitude(float x, float y, float z) {
+            return (float) Math.sqrt(x*x + y*y + z*z);
+        }
+
+        /**
+         * Absolute angle between upVector and the x-y plane (the plane of the screen), in [0, 90].
+         * 90 degrees = screen facing the sky or ground.
+         */
+        private float tiltAngle(float z, float magnitude) {
+            return Math.abs((float) Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
         }
 
         public void onSensorChanged(SensorEvent event) {
-            float[] values = event.values;
-            float X = values[_DATA_X];
-            float Y = values[_DATA_Y];
-            float Z = values[_DATA_Z];
-            float OneEightyOverPi = 57.29577957855f;
-            float gravity = (float) Math.sqrt(X*X+Y*Y+Z*Z);
-            float zyangle = (float)Math.asin(Z/gravity)*OneEightyOverPi;
-            if ((zyangle <= PIVOT_UPPER) && (zyangle >= PIVOT_LOWER)) {
-                // Check orientation only if the phone is flat enough
-                // Don't trust the angle if the magnitude is small compared to the y value
-                float angle = (float)Math.atan2(Y, -X) * OneEightyOverPi;
-                int orientation = 90 - Math.round(angle);
-                // normalize to 0 - 359 range
-                while (orientation >= 360) {
-                    orientation -= 360;
-                }
-                while (orientation < 0) {
-                    orientation += 360;
-                }
-                calculateNewRotation(orientation, Math.round(zyangle));
+            // the vector given in the SensorEvent points straight up (towards the sky) under ideal
+            // conditions (the phone is not accelerating).  i'll call this upVector elsewhere.
+            float x = event.values[_DATA_X];
+            float y = event.values[_DATA_Y];
+            float z = event.values[_DATA_Z];
+            float magnitude = vectorMagnitude(x, y, z);
+            float deviation = Math.abs(magnitude - SensorManager.STANDARD_GRAVITY);
+            float tiltAngle = tiltAngle(z, magnitude);
+
+            float alpha = DEFAULT_LOWPASS_ALPHA;
+            if (tiltAngle > MAX_TILT) {
+                return;
+            } else if (deviation > MAX_DEVIATION_FROM_GRAVITY) {
+                alpha = ACCELERATING_LOWPASS_ALPHA;
+            } else if (tiltAngle > PARTIAL_TILT) {
+                alpha = TILTED_LOWPASS_ALPHA;
             }
+
+            x = mFilteredVector[0] = lowpassFilter(x, mFilteredVector[0], alpha);
+            y = mFilteredVector[1] = lowpassFilter(y, mFilteredVector[1], alpha);
+            z = mFilteredVector[2] = lowpassFilter(z, mFilteredVector[2], alpha);
+            magnitude = vectorMagnitude(x, y, z);
+            tiltAngle = tiltAngle(z, magnitude);
+
+            // Angle between the x-y projection of upVector and the +y-axis, increasing
+            // counter-clockwise.
+            // 0 degrees = speaker end towards the sky
+            // 90 degrees = left edge of device towards the sky
+            float orientationAngle = (float) Math.atan2(-x, y) * RADIANS_TO_DEGREES;
+            int orientation = Math.round(orientationAngle);
+            // atan2 returns (-180, 180]; normalize to [0, 360)
+            if (orientation < 0) {
+                orientation += 360;
+            }
+            calculateNewRotation(orientation, Math.round(tiltAngle));
         }
 
         public void onAccuracyChanged(Sensor sensor, int accuracy) {
@@ -208,13 +297,12 @@
     public boolean canDetectOrientation() {
         return mSensor != null;
     }
-    
+
     /**
      * Called when the rotation view of the device has changed.
-     * Can be either Surface.ROTATION_90 or Surface.ROTATION_0.
-     * @param rotation The new orientation of the device.
      *
-     *  @see #ORIENTATION_UNKNOWN
+     * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants.
+     * @see Surface
      */
     abstract public void onOrientationChanged(int rotation);
 }
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 87cab3c..647556b 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.net.http.Headers;
+import android.net.http.HttpDateTime;
 import android.os.FileUtils;
 import android.util.Log;
 import java.io.File;
@@ -30,7 +31,6 @@
 import java.util.ArrayList;
 import java.util.Map;
 
-import com.android.common.HttpDateTime;
 
 import org.bouncycastle.crypto.Digest;
 import org.bouncycastle.crypto.digests.SHA1Digest;
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 84e34bc..1d28731 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -18,9 +18,9 @@
 
 import android.net.ParseException;
 import android.net.WebAddress;
+import android.net.http.HttpDateTime;
 import android.util.Log;
 
-import com.android.common.HttpDateTime;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 662be95..8981419 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -173,6 +173,9 @@
     private long            mAppCacheMaxSize = Long.MAX_VALUE;
     private String          mAppCachePath = "";
     private String          mDatabasePath = "";
+    // The WebCore DatabaseTracker only allows the database path to be set
+    // once. Keep track of when the path has been set.
+    private boolean         mDatabasePathHasBeenSet = false;
     private String          mGeolocationDatabasePath = "";
     // Don't need to synchronize the get/set methods as they
     // are basic types, also none of these values are used in
@@ -1006,13 +1009,15 @@
 
     /**
      * Set the path to where database storage API databases should be saved.
+     * Nota that the WebCore Database Tracker only allows the path to be set once.
      * This will update WebCore when the Sync runs in the C++ side.
      * @param databasePath String path to the directory where databases should
      *     be saved. May be the empty string but should never be null.
      */
     public synchronized void setDatabasePath(String databasePath) {
-        if (databasePath != null && !databasePath.equals(mDatabasePath)) {
+        if (databasePath != null && !mDatabasePathHasBeenSet) {
             mDatabasePath = databasePath;
+            mDatabasePathHasBeenSet = true;
             postSync();
         }
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c1a4a49..d29d6f3 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3136,7 +3136,8 @@
     }
 
     private void drawExtras(Canvas canvas, int extras) {
-        if (mNativeClass == 0) return;
+        // If mNativeClass is 0, we should not reach here, so we do not
+        // need to check it again.
         // Currently for each draw we compute the animation values;
         // We may in the future decide to do that independently.
         if (nativeEvaluateLayersAnimations()) {
@@ -3153,7 +3154,6 @@
         if (mDrawHistory) {
             canvas.scale(mActualScale, mActualScale);
             canvas.drawPicture(mHistoryPicture);
-            drawExtras(canvas, DRAW_EXTRAS_NONE);
             return;
         }
 
@@ -3369,6 +3369,7 @@
         if (isTextView) {
             rebuildWebTextView();
             if (inEditingMode()) {
+                mWebTextView.setDefaultSelection();
                 imm.showSoftInput(mWebTextView, 0);
                 if (zoom) {
                     didUpdateTextViewBounds(true);
@@ -3686,6 +3687,7 @@
             // might be.  Check it, and if so, hand over to the WebTextView.
             rebuildWebTextView();
             if (inEditingMode()) {
+                mWebTextView.setDefaultSelection();
                 return mWebTextView.dispatchKeyEvent(event);
             }
         }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9ddfeff..bec62b1 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -467,6 +467,18 @@
     // True when the popup should be hidden because of a call to
     // dispatchDisplayHint()
     private boolean mPopupHidden;
+    
+    /**
+     * ID of the active pointer. This is used to retain consistency during
+     * drags/flings if multiple pointers are used.
+     */
+    private int mActivePointerId = INVALID_POINTER;
+    
+    /**
+     * Sentinel value for no current active pointer.
+     * Used by {@link #mActivePointerId}.
+     */
+    private static final int INVALID_POINTER = -1;
 
     /**
      * Interface definition for a callback to be invoked when the list or grid
@@ -1995,8 +2007,6 @@
         }
 
         final int action = ev.getAction();
-        final int x = (int) ev.getX();
-        final int y = (int) ev.getY();
 
         View v;
         int deltaY;
@@ -2006,18 +2016,22 @@
         }
         mVelocityTracker.addMovement(ev);
 
-        switch (action) {
+        switch (action & MotionEvent.ACTION_MASK) {
         case MotionEvent.ACTION_DOWN: {
             switch (mTouchMode) {
             case TOUCH_MODE_OVERFLING: {
                 mFlingRunnable.endFling();
                 mTouchMode = TOUCH_MODE_OVERSCROLL;
-                mLastY = y;
+                mLastY = (int) ev.getY();
                 mMotionCorrection = 0;
+                mActivePointerId = ev.getPointerId(0);
                 break;
             }
             
             default: {
+                mActivePointerId = ev.getPointerId(0);
+                final int x = (int) ev.getX();
+                final int y = (int) ev.getY();
                 int motionPosition = pointToPosition(x, y);
                 if (!mDataChanged) {
                     if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
@@ -2037,12 +2051,15 @@
                             // code in ViewRoot to try to find a nearby view to select
                             return false;
                         }
-                        // User clicked on whitespace, or stopped a fling. It is a scroll.
-                        createScrollingCache();
-                        mTouchMode = TOUCH_MODE_SCROLL;
-                        mMotionCorrection = 0;
-                        motionPosition = findMotionRow(y);
-                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                        
+                        if (mTouchMode == TOUCH_MODE_FLING) {
+                            // Stopped a fling. It is a scroll.
+                            createScrollingCache();
+                            mTouchMode = TOUCH_MODE_SCROLL;
+                            mMotionCorrection = 0;
+                            motionPosition = findMotionRow(y);
+                            reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                        }
                     }
                 }
 
@@ -2062,6 +2079,8 @@
         }
 
         case MotionEvent.ACTION_MOVE: {
+            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+            final int y = (int) ev.getY(pointerIndex);
             deltaY = y - mMotionY;
             switch (mTouchMode) {
             case TOUCH_MODE_DOWN:
@@ -2142,7 +2161,7 @@
 
                             // We did not scroll the full amount. Treat this essentially like the
                             // start of a new touch scroll
-                            final int motionPosition = findMotionRow(y);
+                            final int motionPosition = findClosestMotionRow(y);
 
                             mMotionCorrection = 0;
                             motionView = getChildAt(motionPosition - mFirstPosition);
@@ -2238,7 +2257,7 @@
                     } else {
                         final VelocityTracker velocityTracker = mVelocityTracker;
                         velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                        final int initialVelocity = (int) velocityTracker.getYVelocity();
+                        final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
     
                         if (Math.abs(initialVelocity) > mMinimumVelocity) {
                             if (mFlingRunnable == null) {
@@ -2264,7 +2283,7 @@
                 }
                 final VelocityTracker velocityTracker = mVelocityTracker;
                 velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                final int initialVelocity = (int) velocityTracker.getYVelocity();
+                final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
                 reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
                 if (Math.abs(initialVelocity) > mMinimumVelocity) {
@@ -2290,6 +2309,8 @@
                 mVelocityTracker.recycle();
                 mVelocityTracker = null;
             }
+            
+            mActivePointerId = INVALID_POINTER;
 
             if (PROFILE_SCROLLING) {
                 if (mScrollProfilingStarted) {
@@ -2332,6 +2353,24 @@
                     mVelocityTracker = null;
                 }
             }
+            
+            mActivePointerId = INVALID_POINTER;
+            break;
+        }
+        
+        case MotionEvent.ACTION_POINTER_UP: {
+            onSecondaryPointerUp(ev);
+            final int x = mMotionX;
+            final int y = mMotionY;
+            final int motionPosition = pointToPosition(x, y);
+            if (motionPosition >= 0) {
+                // Remember where the motion event started
+                v = getChildAt(motionPosition - mFirstPosition);
+                mMotionViewOriginalTop = v.getTop();
+                mMotionPosition = motionPosition;
+            }
+            mLastY = y;
+            break;
         }
         }
 
@@ -2380,8 +2419,6 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         int action = ev.getAction();
-        int x = (int) ev.getX();
-        int y = (int) ev.getY();
         View v;
 
         if (mFastScroller != null) {
@@ -2391,13 +2428,17 @@
             }
         }
 
-        switch (action) {
+        switch (action & MotionEvent.ACTION_MASK) {
         case MotionEvent.ACTION_DOWN: {
             int touchMode = mTouchMode;
             if (touchMode == TOUCH_MODE_OVERFLING || touchMode == TOUCH_MODE_OVERSCROLL) {
                 return true;
             }
             
+            final int x = (int) ev.getX();
+            final int y = (int) ev.getY();
+            mActivePointerId = ev.getPointerId(0);
+            
             int motionPosition = findMotionRow(y);
             if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) {
                 // User clicked on an actual view (and was not stopping a fling).
@@ -2420,6 +2461,8 @@
         case MotionEvent.ACTION_MOVE: {
             switch (mTouchMode) {
             case TOUCH_MODE_DOWN:
+                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                final int y = (int) ev.getY(pointerIndex);
                 if (startScrollIfNeeded(y - mMotionY)) {
                     return true;
                 }
@@ -2430,13 +2473,37 @@
 
         case MotionEvent.ACTION_UP: {
             mTouchMode = TOUCH_MODE_REST;
+            mActivePointerId = INVALID_POINTER;
             reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
             break;
         }
+        
+        case MotionEvent.ACTION_POINTER_UP: {
+            onSecondaryPointerUp(ev);
+            break;
+        }
         }
 
         return false;
     }
+    
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        final int pointerId = ev.getPointerId(pointerIndex);
+        if (pointerId == mActivePointerId) {
+            // This was our active pointer going up. Choose a new
+            // active pointer and adjust accordingly.
+            // TODO: Make this decision more intelligent.
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mMotionX = (int) ev.getX(newPointerIndex);
+            mMotionY = (int) ev.getY(newPointerIndex);
+            mActivePointerId = ev.getPointerId(newPointerIndex);
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+        }
+    }
 
     /**
      * {@inheritDoc}
@@ -3150,9 +3217,25 @@
      * Find the row closest to y. This row will be used as the motion row when scrolling
      *
      * @param y Where the user touched
-     * @return The position of the first (or only) item in the row closest to y
+     * @return The position of the first (or only) item in the row containing y
      */
     abstract int findMotionRow(int y);
+    
+    /**
+     * Find the row closest to y. This row will be used as the motion row when scrolling.
+     * 
+     * @param y Where the user touched
+     * @return The position of the first (or only) item in the row closest to y
+     */
+    int findClosestMotionRow(int y) {
+        final int childCount = getChildCount();
+        if (childCount == 0) {
+            return INVALID_POSITION;
+        }
+        
+        final int motionRow = findMotionRow(y);
+        return motionRow != INVALID_POSITION ? motionRow : mFirstPosition + childCount - 1;
+    }
 
     /**
      * Causes all the views to be rebuilt and redrawn.
@@ -4072,9 +4155,9 @@
             final View[] activeViews = mActiveViews;
             for (int i = 0; i < childCount; i++) {
                 View child = getChildAt(i);
-                AbsListView.LayoutParams lp = (AbsListView.LayoutParams)child.getLayoutParams();
+                AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
                 // Don't put header or footer views into the scrap heap
-                if (lp != null && lp.viewType != AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+                if (lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
                     // Note:  We do place AdapterView.ITEM_VIEW_TYPE_IGNORE in active views.
                     //        However, we will NOT place them into scrap views.
                     activeViews[i] = child;
diff --git a/core/java/android/widget/ExpandableListConnector.java b/core/java/android/widget/ExpandableListConnector.java
index ccce7c1..9c43e9b 100644
--- a/core/java/android/widget/ExpandableListConnector.java
+++ b/core/java/android/widget/ExpandableListConnector.java
@@ -25,7 +25,6 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
 
 /*
  * Implementation notes:
@@ -637,7 +636,7 @@
         // Check to see if it's already expanded
         if (posMetadata.groupMetadata != null) return false;
         
-        /* Restrict number of exp groups to mMaxExpGroupCount */
+        /* Restrict number of expanded groups to mMaxExpGroupCount */
         if (mExpGroupMetadataList.size() >= mMaxExpGroupCount) {
             /* Collapse a group */
             // TODO: Collapse something not on the screen instead of the first one?
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index b9acf5e..9e930a5 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -431,8 +431,6 @@
                     }
                 }
             }
-
-            return mFirstPosition + childCount - 1;
         }
         return INVALID_POSITION;
     }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index a7b819a..acb7e02 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -116,7 +116,19 @@
     private int mTouchSlop;
     private int mMinimumVelocity;
     private int mMaximumVelocity;
-
+    
+    /**
+     * ID of the active pointer. This is used to retain consistency during
+     * drags/flings if multiple pointers are used.
+     */
+    private int mActivePointerId = INVALID_POINTER;
+    
+    /**
+     * Sentinel value for no current active pointer.
+     * Used by {@link #mActivePointerId}.
+     */
+    private static final int INVALID_POINTER = -1;
+    
     public HorizontalScrollView(Context context) {
         this(context, null);
     }
@@ -362,6 +374,17 @@
         return handled;
     }
 
+    private boolean inChild(int x, int y) {
+        if (getChildCount() > 0) {
+            final View child = getChildAt(0);
+            return !(y < child.getTop()
+                    || y >= child.getBottom()
+                    || x < child.getLeft()
+                    || x >= child.getRight());
+        }
+        return false;
+    }
+    
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         /*
@@ -380,10 +403,8 @@
             return true;
         }
 
-        final float x = ev.getX();
-
-        switch (action) {
-            case MotionEvent.ACTION_MOVE:
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_MOVE: {
                 /*
                  * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
                  * whether the user has moved far enough from his original down touch.
@@ -393,16 +414,30 @@
                 * Locally do absolute value. mLastMotionX is set to the x value
                 * of the down event.
                 */
+                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                final float x = ev.getX(pointerIndex);
                 final int xDiff = (int) Math.abs(x - mLastMotionX);
                 if (xDiff > mTouchSlop) {
                     mIsBeingDragged = true;
+                    mLastMotionX = x;
                     if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
                 }
                 break;
+            }
 
-            case MotionEvent.ACTION_DOWN:
-                /* Remember location of down touch */
+            case MotionEvent.ACTION_DOWN: {
+                final float x = ev.getX();
+                if (!inChild((int) x, (int) ev.getY())) {
+                    mIsBeingDragged = false;
+                    break;
+                }
+                
+                /*
+                 * Remember location of down touch.
+                 * ACTION_DOWN always refers to pointer index 0.
+                 */
                 mLastMotionX = x;
+                mActivePointerId = ev.getPointerId(0);
 
                 /*
                 * If being flinged and user touches the screen, initiate drag;
@@ -411,11 +446,16 @@
                 */
                 mIsBeingDragged = !mScroller.isFinished();
                 break;
+            }
 
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                 /* Release the drag */
                 mIsBeingDragged = false;
+                mActivePointerId = INVALID_POINTER;
+                break;
+            case MotionEvent.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
                 break;
         }
 
@@ -441,10 +481,9 @@
         mVelocityTracker.addMovement(ev);
 
         final int action = ev.getAction();
-        final float x = ev.getX();
 
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN: {
                 /*
                 * If being flinged and user touches, stop the fling. isFinished
                 * will be false if being flinged.
@@ -452,42 +491,78 @@
                 if (!mScroller.isFinished()) {
                     mScroller.abortAnimation();
                 }
+                
+                final float x = ev.getX();
+                if (!(mIsBeingDragged = inChild((int) x, (int) ev.getY()))) {
+                    return false;
+                }
 
                 // Remember where the motion event started
                 mLastMotionX = x;
                 break;
+            }
             case MotionEvent.ACTION_MOVE:
-                // Scroll to follow the motion event
-                final int deltaX = (int) (mLastMotionX - x);
-                mLastMotionX = x;
+                if (mIsBeingDragged) {
+                    // Scroll to follow the motion event
+                    final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                    final float x = ev.getX(activePointerIndex);
+                    final int deltaX = (int) (mLastMotionX - x);
+                    mLastMotionX = x;
 
-                overscrollBy(deltaX, 0, mScrollX, 0, getScrollRange(), 0,
-                        getOverscrollMax(), 0);
+                    overscrollBy(deltaX, 0, mScrollX, 0, getScrollRange(), 0,
+                            getOverscrollMax(), 0);
+                }
                 break;
             case MotionEvent.ACTION_UP:
-                final VelocityTracker velocityTracker = mVelocityTracker;
-                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                int initialVelocity = (int) velocityTracker.getXVelocity();
+                if (mIsBeingDragged) {
+                    final VelocityTracker velocityTracker = mVelocityTracker;
+                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                    int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
 
-                if (getChildCount() > 0) {
-                    if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                        fling(-initialVelocity);
-                    } else {
-                        final int right = getScrollRange();
-                        if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
-                            invalidate();
+                    if (getChildCount() > 0) {
+                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+                            fling(-initialVelocity);
+                        } else {
+                            final int right = getScrollRange();
+                            if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
+                                invalidate();
+                            }
                         }
                     }
-                }
+                    
+                    mActivePointerId = INVALID_POINTER;
+                    mIsBeingDragged = false;
 
-                if (mVelocityTracker != null) {
-                    mVelocityTracker.recycle();
-                    mVelocityTracker = null;
+                    if (mVelocityTracker != null) {
+                        mVelocityTracker.recycle();
+                        mVelocityTracker = null;
+                    }
                 }
+                break;
+            case MotionEvent.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                break;
         }
         return true;
     }
     
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        final int pointerId = ev.getPointerId(pointerIndex);
+        if (pointerId == mActivePointerId) {
+            // This was our active pointer going up. Choose a new
+            // active pointer and adjust accordingly.
+            // TODO: Make this decision more intelligent.
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mLastMotionX = ev.getX(newPointerIndex);
+            mActivePointerId = ev.getPointerId(newPointerIndex);
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+        }
+    }
+    
     @Override
     protected void onOverscrolled(int scrollX, int scrollY,
             boolean clampedX, boolean clampedY) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 4bd3a82..bd07e1f 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -632,6 +632,8 @@
 
         final boolean baselineAligned = mBaselineAligned;
         final boolean useLargestChild = mUseLargestChild;
+        
+        final boolean isExactly = widthMode == MeasureSpec.EXACTLY;
 
         int largestChildWidth = Integer.MIN_VALUE;
 
@@ -658,7 +660,13 @@
                 // Optimization: don't bother measuring children who are going to use
                 // leftover space. These views will get measured again down below if
                 // there is any leftover space.
-                mTotalLength += lp.leftMargin + lp.rightMargin;
+                if (isExactly) {
+                    mTotalLength += lp.leftMargin + lp.rightMargin;
+                } else {
+                    final int totalLength = mTotalLength;
+                    mTotalLength = Math.max(totalLength, totalLength +
+                            lp.leftMargin + lp.rightMargin);
+                }
 
                 // Baseline alignment requires to measure widgets to obtain the
                 // baseline offset (in particular for TextViews). The following
@@ -694,8 +702,14 @@
                 }
 
                 final int childWidth = child.getMeasuredWidth();
-                mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
-                        getNextLocationOffset(child);
+                if (isExactly) {
+                    mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
+                            getNextLocationOffset(child);
+                } else {
+                    final int totalLength = mTotalLength;
+                    mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin +
+                           lp.rightMargin + getNextLocationOffset(child));
+                }
 
                 if (useLargestChild) {
                     largestChildWidth = Math.max(childWidth, largestChildWidth);
@@ -780,8 +794,14 @@
 
                 final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
                         child.getLayoutParams();
-                mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin +
-                        getNextLocationOffset(child);
+                if (isExactly) {
+                    mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin +
+                            getNextLocationOffset(child);
+                } else {
+                    final int totalLength = mTotalLength;
+                    mTotalLength = Math.max(totalLength, totalLength + largestChildWidth +
+                            lp.leftMargin + lp.rightMargin + getNextLocationOffset(child));
+                }
             }
         }
 
@@ -851,8 +871,14 @@
                     }
                 }
 
-                mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin +
-                        getNextLocationOffset(child);
+                if (isExactly) {
+                    mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin +
+                            getNextLocationOffset(child);
+                } else {
+                    final int totalLength = mTotalLength;
+                    mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredWidth() +
+                            lp.leftMargin + lp.rightMargin + getNextLocationOffset(child));
+                }
 
                 boolean matchHeightLocally = heightMode != MeasureSpec.EXACTLY &&
                         lp.height == LayoutParams.MATCH_PARENT;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 8d688a5..912dd5e 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -138,7 +138,7 @@
 
     // the single allocated result per list view; kinda cheesey but avoids
     // allocating these thingies too often.
-    private ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult();
+    private final ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult();
 
     public ListView(Context context) {
         this(context, null);
@@ -1040,7 +1040,8 @@
             childWidth = child.getMeasuredWidth();
             childHeight = child.getMeasuredHeight();
 
-            if (recycleOnMeasure()) {
+            if (recycleOnMeasure() && mRecycler.shouldRecycleViewType(
+                    ((LayoutParams) child.getLayoutParams()).viewType)) {
                 mRecycler.addScrapView(child);
             }
         }
@@ -1155,7 +1156,8 @@
             }
 
             // Recycle the view before we possibly return from the method
-            if (recyle) {
+            if (recyle && recycleBin.shouldRecycleViewType(
+                    ((LayoutParams) child.getLayoutParams()).viewType)) {
                 recycleBin.addScrapView(child);
             }
 
@@ -1192,7 +1194,6 @@
                     return mFirstPosition + i;
                 }
             }
-            return mFirstPosition + childCount - 1;
         }
         return INVALID_POSITION;
     }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 6dc9f78..202e658 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -696,8 +696,7 @@
      * <p>Start the indeterminate progress animation.</p>
      */
     void startAnimation() {
-        int visibility = getVisibility();
-        if (visibility != VISIBLE) {
+        if (getVisibility() != VISIBLE) {
             return;
         }
 
@@ -771,7 +770,7 @@
                 // let's be nice with the UI thread
                 if (v == GONE || v == INVISIBLE) {
                     stopAnimation();
-                } else if (v == VISIBLE) {
+                } else {
                     startAnimation();
                 }
             }
@@ -779,6 +778,20 @@
     }
 
     @Override
+    protected void onVisibilityChanged(View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+
+        if (mIndeterminate) {
+            // let's be nice with the UI thread
+            if (visibility == GONE || visibility == INVISIBLE) {
+                stopAnimation();
+            } else {
+                startAnimation();
+            }
+        }
+    }
+
+    @Override
     public void invalidateDrawable(Drawable dr) {
         if (!mInDrawing) {
             if (verifyDrawable(dr)) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index fd24058..489c44d 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -427,7 +427,7 @@
 
             case MotionEvent.ACTION_DOWN: {
                 final float y = ev.getY();
-                if (!inChild((int)ev.getX(), (int)y)) {
+                if (!inChild((int) ev.getX(), (int) y)) {
                     mIsBeingDragged = false;
                     break;
                 }
@@ -493,7 +493,7 @@
                 }
 
                 final float y = ev.getY();
-                if (!(mIsBeingDragged = inChild((int)ev.getX(), (int)y))) {
+                if (!(mIsBeingDragged = inChild((int) ev.getX(), (int) y))) {
                     return false;
                 }
                 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 951563a..51e1c57 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2823,9 +2823,6 @@
      * Null means to use the normal empty text. The hint does not currently
      * participate in determining the size of the view.
      *
-     * This method is deprecated. Use {link #setHint(int, String)} or
-     * {link #setHint(CharSequence, String)} instead.
-     *
      * @attr ref android.R.styleable#TextView_hint
      */
     @android.view.RemotableViewMethod
@@ -2845,9 +2842,6 @@
      * Sets the text to be displayed when the text of the TextView is empty,
      * from a resource.
      *
-     * This method is deprecated. Use {link #setHint(int, String)} or
-     * {link #setHint(CharSequence, String)} instead.
-     *
      * @attr ref android.R.styleable#TextView_hint
      */
     @android.view.RemotableViewMethod
diff --git a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java b/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
index cd6a9a1..274082c 100644
--- a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
+++ b/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
@@ -50,6 +50,11 @@
 
     public static final String PATH = "syncstate";
 
+    private static final String QUERY_COUNT_SYNC_STATE_ROWS =
+            "SELECT count(*)"
+                    + " FROM " + SYNC_STATE_TABLE
+                    + " WHERE " + SyncStateContract.Columns._ID + "=?";
+
     public void createDatabase(SQLiteDatabase db) {
         db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_TABLE);
         db.execSQL("CREATE TABLE " + SYNC_STATE_TABLE + " ("
@@ -96,11 +101,17 @@
         return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
     }
 
-    public void update(SQLiteDatabase db, long rowId, Object data) {
+    public int update(SQLiteDatabase db, long rowId, Object data) {
+        if (DatabaseUtils.longForQuery(db, QUERY_COUNT_SYNC_STATE_ROWS,
+                new String[]{Long.toString(rowId)}) < 1) {
+            return 0;
+        }
         db.execSQL("UPDATE " + SYNC_STATE_TABLE
                 + " SET " + SyncStateContract.Columns.DATA + "=?"
                 + " WHERE " + SyncStateContract.Columns._ID + "=" + rowId,
                 new Object[]{data});
+        // assume a row was modified since we know it exists
+        return 1;
     }
 
     public void onAccountsChanged(SQLiteDatabase db, Account[] accounts) {
diff --git a/common/java/com/android/common/DNParser.java b/core/java/com/android/internal/net/DNParser.java
similarity index 99%
rename from common/java/com/android/common/DNParser.java
rename to core/java/com/android/internal/net/DNParser.java
index 32d57c0..5254207 100644
--- a/common/java/com/android/common/DNParser.java
+++ b/core/java/com/android/internal/net/DNParser.java
@@ -15,7 +15,8 @@
  *  limitations under the License.
  */
 
-package com.android.common;
+package com.android.internal.net;
+
 
 import android.util.Log;
 
@@ -34,6 +35,8 @@
  *
  * <p>This class is used by {@link DomainNameValidator} only.  However, in order to make this
  * class visible from unit tests, it's made public.
+ * 
+ * @hide
  */
 public final class DNParser {
     private static final String TAG = "DNParser";
diff --git a/common/java/com/android/common/DomainNameValidator.java b/core/java/com/android/internal/net/DomainNameValidator.java
similarity index 99%
rename from common/java/com/android/common/DomainNameValidator.java
rename to core/java/com/android/internal/net/DomainNameValidator.java
index 25dc007..dbd5019 100644
--- a/common/java/com/android/common/DomainNameValidator.java
+++ b/core/java/com/android/internal/net/DomainNameValidator.java
@@ -13,7 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.common;
+package com.android.internal.net;
+
 
 import android.util.Config;
 import android.util.Log;
@@ -30,6 +31,7 @@
 
 import javax.security.auth.x500.X500Principal;
 
+/** @hide */
 public class DomainNameValidator {
     private final static String TAG = "DomainNameValidator";
 
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 9e5bdff..2369d25 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -20,7 +20,7 @@
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/common/java/com/android/common/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
similarity index 99%
rename from common/java/com/android/common/FastXmlSerializer.java
rename to core/java/com/android/internal/util/FastXmlSerializer.java
index 0d33941..592a8fa 100644
--- a/common/java/com/android/common/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package com.android.internal.util;
 
 import org.xmlpull.v1.XmlSerializer;
 
diff --git a/common/java/com/android/common/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
similarity index 99%
rename from common/java/com/android/common/XmlUtils.java
rename to core/java/com/android/internal/util/XmlUtils.java
index dd57e49..8d8df16 100644
--- a/common/java/com/android/common/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package com.android.internal.util;
+
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 9713c27f..1956b4e 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -17,15 +17,20 @@
 package com.android.internal.widget;
 
 import android.app.DevicePolicyManager;
-import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.security.MessageDigest;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.widget.Button;
 
+import com.android.internal.R;
+import com.android.internal.telephony.ITelephony;
 import com.google.android.collect.Lists;
 
 import java.io.FileNotFoundException;
@@ -675,4 +680,43 @@
             || (mode == MODE_PIN || mode == MODE_PASSWORD) && savedPasswordExists();
         return secure;
     }
+
+    /**
+     * Sets the text on the emergency button to indicate what action will be taken.
+     * If there's currently a call in progress, the button will take them to the call
+     * @param button the button to update
+     */
+    public void updateEmergencyCallButtonState(Button button) {
+        int newState = TelephonyManager.getDefault().getCallState();
+        int textId;
+        if (newState == TelephonyManager.CALL_STATE_OFFHOOK) {
+            // show "return to call" text and show phone icon
+            textId = R.string.lockscreen_return_to_call;
+            int phoneCallIcon = R.drawable.stat_sys_phone_call;
+            button.setCompoundDrawablesWithIntrinsicBounds(phoneCallIcon, 0, 0, 0);
+        } else {
+            textId = R.string.lockscreen_emergency_call;
+            int emergencyIcon = R.drawable.ic_emergency;
+            button.setCompoundDrawablesWithIntrinsicBounds(emergencyIcon, 0, 0, 0);
+        }
+        button.setText(textId);
+    }
+
+    /**
+     * Resumes a call in progress. Typically launched from the EmergencyCall button
+     * on various lockscreens.
+     *
+     * @return true if we were able to tell InCallScreen to show.
+     */
+    public boolean resumeCall() {
+        ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+        try {
+            if (phone != null && phone.showCallScreen()) {
+                return true;
+            }
+        } catch (RemoteException e) {
+            // What can we do?
+        }
+        return false;
+    }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index e8749ed..85d1a6f 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -45,6 +45,7 @@
 	android_view_Surface.cpp \
 	android_view_ViewRoot.cpp \
 	android_text_AndroidCharacter.cpp \
+	android_text_AndroidBidi.cpp \
 	android_text_KeyCharacterMap.cpp \
 	android_os_Debug.cpp \
 	android_os_FileUtils.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7c8df03..8586aca 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -142,6 +142,7 @@
 extern int register_android_net_wifi_WifiManager(JNIEnv* env);
 extern int register_android_security_Md5MessageDigest(JNIEnv *env);
 extern int register_android_text_AndroidCharacter(JNIEnv *env);
+extern int register_android_text_AndroidBidi(JNIEnv *env);
 extern int register_android_text_KeyCharacterMap(JNIEnv *env);
 extern int register_android_opengl_classes(JNIEnv *env);
 extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
@@ -1184,6 +1185,7 @@
     REG_JNI(register_android_emoji_EmojiFactory),
     REG_JNI(register_android_security_Md5MessageDigest),
     REG_JNI(register_android_text_AndroidCharacter),
+    REG_JNI(register_android_text_AndroidBidi),
     REG_JNI(register_android_text_KeyCharacterMap),
     REG_JNI(register_android_os_Process),
     REG_JNI(register_android_os_Binder),
diff --git a/core/jni/android_text_AndroidBidi.cpp b/core/jni/android_text_AndroidBidi.cpp
new file mode 100644
index 0000000..7696bb3
--- /dev/null
+++ b/core/jni/android_text_AndroidBidi.cpp
@@ -0,0 +1,81 @@
+/* //device/libs/android_runtime/android_text_AndroidBidi.cpp
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#define LOG_TAG "AndroidUnicode"
+
+#include <jni.h>
+#include <android_runtime/AndroidRuntime.h>
+#include "utils/misc.h"
+#include "utils/Log.h"
+#include "unicode/ubidi.h"
+
+namespace android {
+    
+static void jniThrowException(JNIEnv* env, const char* exc, const char* msg = NULL)
+{
+    jclass excClazz = env->FindClass(exc);
+    LOG_ASSERT(excClazz, "Unable to find class %s", exc);
+
+    env->ThrowNew(excClazz, msg);
+}
+
+static jint runBidi(JNIEnv* env, jobject obj, jint dir, jcharArray chsArray, 
+                    jbyteArray infoArray, int n, jboolean haveInfo)
+{
+    // Parameters are checked on java side
+    // Failures from GetXXXArrayElements indicate a serious out-of-memory condition
+    // that we don't bother to report, we're probably dead anyway.
+    jint result = 0;
+    jchar* chs = env->GetCharArrayElements(chsArray, NULL);
+    if (chs != NULL) {
+        jbyte* info = env->GetByteArrayElements(infoArray, NULL);
+        if (info != NULL) {
+            UErrorCode status = U_ZERO_ERROR;
+            UBiDi* bidi = ubidi_openSized(n, 0, &status);
+            ubidi_setPara(bidi, chs, n, dir, NULL, &status);
+            if (U_SUCCESS(status)) {
+                for (int i = 0; i < n; ++i) {
+                  info[i] = ubidi_getLevelAt(bidi, i);
+                }
+                result = ubidi_getParaLevel(bidi);
+            } else {
+                jniThrowException(env, "java/lang/RuntimeException", NULL);
+            }
+            ubidi_close(bidi);
+
+            env->ReleaseByteArrayElements(infoArray, info, 0);
+        }
+        env->ReleaseCharArrayElements(chsArray, chs, JNI_ABORT);
+    }
+    return result;
+}
+
+static JNINativeMethod gMethods[] = {
+        { "runBidi", "(I[C[BIZ)I",
+        (void*) runBidi }
+};
+
+int register_android_text_AndroidBidi(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/text/AndroidBidi");
+    LOG_ASSERT(clazz, "Cannot find android/text/AndroidBidi");
+    
+    return AndroidRuntime::registerNativeMethods(env, "android/text/AndroidBidi",
+            gMethods, NELEM(gMethods));
+}
+
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d561b8..1e11a99 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -138,6 +138,9 @@
          closed.  The default is 0. -->
     <integer name="config_lidNavigationAccessibility">0</integer>
 
+    <!-- Indicate whether the SD card is accessible without removing the battery. -->
+    <bool name="config_batterySdCardAccessibility">false</bool>
+
     <!-- Vibrator pattern for feedback about a long screen/key press -->
     <integer-array name="config_longPressVibePattern">
         <item>0</item>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5d2d272..b791bf8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1441,6 +1441,8 @@
     <string name="lockscreen_pattern_instructions">Draw pattern to unlock</string>
     <!-- Button at the bottom of the unlock screen to make an emergency call. -->
     <string name="lockscreen_emergency_call">Emergency call</string>
+    <!-- Button at the bottom of the unlock screen that lets the user return to a call -->
+    <string name="lockscreen_return_to_call">Return to call</string>
     <!-- Shown to confirm that the user entered their lock pattern correctly. -->
     <string name="lockscreen_pattern_correct">Correct!</string>
     <!-- On the unlock pattern screen, shown when the user enters the wrong lock pattern and must try again. -->
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 1fb9852..b0e2843 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -9,6 +9,8 @@
 	$(call all-java-files-under, src) \
 	src/android/os/IAidlTest.aidl
 
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
diff --git a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
index ccd0dae..da6036a 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
@@ -88,7 +88,38 @@
         int resultDir = StaticLayout.bidi(dir, chs, chInfo, n, false);
         
         {
-            StringBuilder sb = new StringBuilder("xdirs:");
+            StringBuilder sb = new StringBuilder("info:");
+            for (int i = 0; i < n; ++i) {
+                sb.append(" ").append(String.valueOf(chInfo[i]));
+            }
+            Log.i("BIDI", sb.toString());
+        }
+        
+        char[] resultLevelChars = new char[n];
+        for (int i = 0; i < n; ++i) {
+            resultLevelChars[i] = (char)('0' + chInfo[i]);
+        }
+        String resultLevels = new String(resultLevelChars);
+        assertEquals("direction", expectedDir, resultDir);
+        assertEquals("levels", expectedLevels, resultLevels);
+    }
+    
+    @SmallTest
+    public void testNativeBidi() {
+        // native bidi returns levels, not simply directions
+        expectNativeBidi(REQ_DL,  ALEF + BET + GIMEL + " abc", "1111222", R);
+    }
+    
+    private void expectNativeBidi(int dir, String text, 
+            String expectedLevels, int expectedDir) {
+        char[] chs = text.toCharArray();
+        int n = chs.length;
+        byte[] chInfo = new byte[n];
+        
+        int resultDir = AndroidBidi.bidi(dir, chs, chInfo, n, false);
+        
+        {
+            StringBuilder sb = new StringBuilder("info:");
             for (int i = 0; i < n; ++i) {
                 sb.append(" ").append(String.valueOf(chInfo[i]));
             }
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
index 23a4cde..22bbabc 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
@@ -16,29 +16,28 @@
 
 package android.widget.expandablelistview;
 
-import android.widget.expandablelistview.ExpandableListSimple;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.util.ExpandableListScenario;
 import android.util.ListUtil;
 import android.util.ExpandableListScenario.MyGroup;
-
-import java.util.List;
-
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.view.KeyEvent;
+import android.view.View;
 import android.widget.BaseExpandableListAdapter;
 import android.widget.ExpandableListAdapter;
 import android.widget.ExpandableListView;
 
-public class ExpandableListBasicTest extends ActivityInstrumentationTestCase<ExpandableListSimple> {
+import java.util.List;
+
+public class ExpandableListBasicTest extends ActivityInstrumentationTestCase2<ExpandableListSimple> {
     private ExpandableListScenario mActivity;
     private ExpandableListView mListView;
     private ExpandableListAdapter mAdapter;
     private ListUtil mListUtil;
     
     public ExpandableListBasicTest() {
-        super("com.android.frameworks.coretests",
-                ExpandableListSimple.class);
+        super(ExpandableListSimple.class);
     }
 
     @Override
@@ -87,7 +86,6 @@
     
     @MediumTest
     public void testExpandedGroupMovement() {
-
         // Expand the first group
         mListUtil.arrowScrollToSelectedPosition(0);
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
@@ -125,5 +123,55 @@
         assertFalse("The expanded state was given to the inserted group",
                 mListView.isGroupExpanded(0));
     }
-    
+
+    // Static utility method, shared by different ExpandableListView scenario.
+    static void checkGroupAndChildPositions(ExpandableListView elv,
+            ActivityInstrumentationTestCase2<? extends ExpandableListScenario> activityInstrumentation) {
+        // Add a position tester ContextMenu listener to the ExpandableListView
+        PositionTesterContextMenuListener menuListener = new PositionTesterContextMenuListener();
+        elv.setOnCreateContextMenuListener(menuListener);
+
+        ListUtil listUtil = new ListUtil(elv, activityInstrumentation.getInstrumentation());
+        ExpandableListAdapter adapter = elv.getExpandableListAdapter();
+        Instrumentation instrumentation = activityInstrumentation.getInstrumentation();
+
+        int index = elv.getHeaderViewsCount();
+        int groupCount = adapter.getGroupCount();
+        for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) {
+
+            // Expand group
+            assertFalse("Group is already expanded", elv.isGroupExpanded(groupIndex));
+            listUtil.arrowScrollToSelectedPosition(index);
+            instrumentation.waitForIdleSync();
+            activityInstrumentation.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+            activityInstrumentation.getInstrumentation().waitForIdleSync();
+            assertTrue("Group did not expand " + groupIndex, elv.isGroupExpanded(groupIndex));
+
+            // Check group index in context menu
+            menuListener.expectGroupContextMenu(groupIndex);
+            // Make sure the group is visible so that getChild finds it
+            listUtil.arrowScrollToSelectedPosition(index);
+            View groupChild = elv.getChildAt(index - elv.getFirstVisiblePosition());
+            elv.showContextMenuForChild(groupChild);
+            index++;
+
+            final int childrenCount = adapter.getChildrenCount(groupIndex);
+            for (int childIndex = 0; childIndex < childrenCount; childIndex++) {
+                // Check child index in context menu
+                listUtil.arrowScrollToSelectedPosition(index);
+                menuListener.expectChildContextMenu(groupIndex, childIndex);
+                View child = elv.getChildAt(index - elv.getFirstVisiblePosition());
+                elv.showContextMenuForChild(child);
+                index++;
+            }
+        }
+
+        // Cleanup: remove the listener we added.
+        elv.setOnCreateContextMenuListener(null);
+    }
+
+    @MediumTest
+    public void testGroupChildPositions() {
+        checkGroupAndChildPositions(mListView, this);
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
index 7965f9f..2251c1d 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
@@ -16,13 +16,10 @@
 
 package android.widget.expandablelistview;
 
-import android.util.ExpandableListScenario;
-
 import android.os.Bundle;
+import android.util.ExpandableListScenario;
 import android.widget.Button;
 import android.widget.ExpandableListView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
 
 public class ExpandableListWithHeaders extends ExpandableListScenario {
     private static final int[] sNumChildren = {1, 4, 3, 2, 6};
@@ -46,13 +43,13 @@
 
         for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
             Button header = new Button(this);
-            header.setText("Header View");
+            header.setText("Header View " + i);
             expandableListView.addHeaderView(header);
         }
 
         for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
             Button footer = new Button(this);
-            footer.setText("Footer View");
+            footer.setText("Footer View " + i);
             expandableListView.addFooterView(footer);
         }
         
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
index 50d0929..ca07e6b 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
@@ -16,22 +16,20 @@
 
 package android.widget.expandablelistview;
 
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.util.ListUtil;
 import android.view.KeyEvent;
 import android.widget.ExpandableListView;
 
-import android.widget.expandablelistview.ExpandableListWithHeaders;
-import android.util.ListUtil;
-
-public class ExpandableListWithHeadersTest extends ActivityInstrumentationTestCase<ExpandableListWithHeaders> {
+public class ExpandableListWithHeadersTest extends
+        ActivityInstrumentationTestCase2<ExpandableListWithHeaders> {
     private ExpandableListView mExpandableListView;
     private ListUtil mListUtil;
     
     public ExpandableListWithHeadersTest() {
-        super("com.android.frameworks.coretests",
-                ExpandableListWithHeaders.class);
+        super(ExpandableListWithHeaders.class);
     }
 
     @Override
@@ -63,4 +61,9 @@
         getInstrumentation().waitForIdleSync();
         assertTrue(mExpandableListView.isGroupExpanded(0));
     }
+
+    @MediumTest
+    public void testGroupChildPositions() {
+        ExpandableListBasicTest.checkGroupAndChildPositions(mExpandableListView, this);
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java b/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
index 08b0d31..f4c9d56 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.widget.expandablelistview;
+package android.widget.expandablelistview;
 
 import com.android.frameworks.coretests.R;
 
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java b/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java
new file mode 100644
index 0000000..b96bca1
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java
@@ -0,0 +1,43 @@
+package android.widget.expandablelistview;
+
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.ExpandableListView;
+
+import junit.framework.Assert;
+
+public class PositionTesterContextMenuListener implements OnCreateContextMenuListener {
+
+    private int groupPosition, childPosition;
+
+    private int testType; // as returned by getPackedPositionType
+
+    public void expectGroupContextMenu(int groupPosition) {
+        this.groupPosition = groupPosition;
+        testType = ExpandableListView.PACKED_POSITION_TYPE_GROUP;
+    }
+
+    public void expectChildContextMenu(int groupPosition, int childPosition) {
+        this.groupPosition = groupPosition;
+        this.childPosition = childPosition;
+        testType = ExpandableListView.PACKED_POSITION_TYPE_CHILD;
+    }
+
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        ExpandableListView.ExpandableListContextMenuInfo elvMenuInfo = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
+        long packedPosition = elvMenuInfo.packedPosition;
+
+        int packedPositionType = ExpandableListView.getPackedPositionType(packedPosition);
+        Assert.assertEquals("Wrong packed position type", testType, packedPositionType);
+
+        int packedPositionGroup = ExpandableListView.getPackedPositionGroup(packedPosition);
+        Assert.assertEquals("Wrong group position", groupPosition, packedPositionGroup);
+
+        if (testType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+            int packedPositionChild = ExpandableListView.getPackedPositionChild(packedPosition);
+            Assert.assertEquals("Wrong child position", childPosition, packedPositionChild);
+        }
+    }
+}
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index ab3b3d3..baed020 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -356,25 +356,19 @@
 
 <p>There are several alternatives for iterating through an array:</p>
 
-<pre>public class Foo {
-    int mSplat;
-}
-public class ArrayBenchmark {
-    Foo[] mArray = new Foo[27];
-    {
-        for (int i = 0; i &lt; mArray.length; ++i) {
-            mArray[i] = new Foo();
-        }
+<pre>    static class Foo {
+        int mSplat;
     }
+    Foo[] mArray = ...
 
-    public static void zero() {
+    public void zero() {
         int sum = 0;
         for (int i = 0; i &lt; mArray.length; ++i) {
             sum += mArray[i].mSplat;
         }
     }
 
-    public static void one() {
+    public void one() {
         int sum = 0;
         Foo[] localArray = mArray;
         int len = localArray.length;
@@ -384,13 +378,13 @@
         }
     }
 
-    public static void two() {
+    public void two() {
         int sum = 0;
         for (Foo a : mArray) {
             sum += a.mSplat;
         }
     }
-}</pre>
+</pre>
 
 <p><strong>zero()</strong> is slowest, because the JIT can't yet optimize away
 the cost of getting the array length once for every iteration through the
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index e328f33..9df2695 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -187,16 +187,23 @@
     // Vertical angle of view in degrees.
     // Example value: "42.5". Read only.
     static const char KEY_VERTICAL_VIEW_ANGLE[];
-    // Exposure compensation. The value is multiplied by 100. -100 means -1 EV.
-    // 130 means +1.3 EV.
-    // Example value: "0" or "133". Read/write.
+    // Exposure compensation index. 0 means exposure is not adjusted.
+    // Example value: "0" or "5". Read/write.
     static const char KEY_EXPOSURE_COMPENSATION[];
-    // Supported exposure compensation.
-    // Example value: "-100,-66,-33,0,33,66,100". Read only.
-    static const char KEY_SUPPORTED_EXPOSURE_COMPENSATION[];
+    // The maximum exposure compensation index (>=0).
+    // Example value: "6". Read only.
+    static const char KEY_MAX_EXPOSURE_COMPENSATION[];
+    // The minimum exposure compensation index (<=0).
+    // Example value: "-6". Read only.
+    static const char KEY_MIN_EXPOSURE_COMPENSATION[];
+    // The exposure compensation step. Exposure compensation index multiply by
+    // step eqals to EV. Ex: if exposure compensation index is 6 and step is
+    // 0.3333, EV is -2.
+    // Example value: "0.333333333" or "0.5". Read only.
+    static const char KEY_EXPOSURE_COMPENSATION_STEP[];
 
 
-        // Values for white balance settings.
+    // Values for white balance settings.
     static const char WHITE_BALANCE_AUTO[];
     static const char WHITE_BALANCE_INCANDESCENT[];
     static const char WHITE_BALANCE_FLUORESCENT[];
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 3f253f9..eb96d20 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -52,6 +52,7 @@
      * or -1 if error.
      *
      * Supported param name are:
+     * duration - the recording duration.
      * file.format - output file format. see mediarecorder.h for details
      * vid.codec - video encoder. see mediarecorder.h for details.
      * aud.codec - audio encoder. see mediarecorder.h for details.
@@ -120,6 +121,16 @@
       */
     Vector<audio_decoder> getAudioDecoders() const;
 
+    /**
+     * Returns the number of image encoding quality levels supported.
+     */
+    Vector<int> getImageEncodingQualityLevels() const;
+
+    /**
+     * Returns the maximum amount of memory in bytes we can use for decoding a JPEG file.
+     */
+    int getImageDecodingMaxMemory() const;
+
 private:
     MediaProfiles& operator=(const MediaProfiles&);  // Don't call me
     MediaProfiles(const MediaProfiles&);             // Don't call me
@@ -257,6 +268,8 @@
     static VideoEncoderCap* createVideoEncoderCap(const char **atts);
     static AudioEncoderCap* createAudioEncoderCap(const char **atts);
     static CamcorderProfile* createCamcorderProfile(const char **atts);
+    static int getImageEncodingQualityLevel(const char **atts);
+    static int getImageDecodingMaxMemory(const char **atts);
 
     // Customized element tag handler for parsing the xml configuration file.
     static void startElementHandler(void *userData, const char *name, const char **atts);
@@ -271,6 +284,8 @@
     static void createDefaultVideoDecoders(MediaProfiles *profiles);
     static void createDefaultAudioDecoders(MediaProfiles *profiles);
     static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
+    static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
+    static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
     static VideoEncoderCap* createDefaultH263VideoEncoderCap();
     static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
     static AudioEncoderCap* createDefaultAmrNBEncoderCap();
@@ -295,6 +310,8 @@
     Vector<AudioDecoderCap*>  mAudioDecoders;
     Vector<VideoDecoderCap*>  mVideoDecoders;
     Vector<output_format>     mEncoderOutputFileFormats;
+    Vector<int>               mImageEncodingQualityLevels;
+    int                       mImageDecodingMaxMemory;
 };
 
 }; // namespace android
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index 1bf1759..8439e2b 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -60,7 +60,9 @@
 const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
 const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
 const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
-const char CameraParameters::KEY_SUPPORTED_EXPOSURE_COMPENSATION[] = "exposure-compensation-values";
+const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
+const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
 
 // Values for white balance settings.
 const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
diff --git a/location/java/com/android/internal/location/GpsXtraDownloader.java b/location/java/com/android/internal/location/GpsXtraDownloader.java
index 02a9f48..978bda2 100644
--- a/location/java/com/android/internal/location/GpsXtraDownloader.java
+++ b/location/java/com/android/internal/location/GpsXtraDownloader.java
@@ -32,10 +32,10 @@
 
 import android.content.Context;
 import android.net.Proxy;
+import android.net.http.AndroidHttpClient;
 import android.util.Config;
 import android.util.Log;
 
-import com.android.common.AndroidHttpClient;
 
 
 /**
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index e1e09b9..09aec2e 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -72,10 +72,8 @@
                 Log.w(mTag, "Notification sound delayed by " + delay + "msecs");
             }
         }
-        catch (IOException e) {
+        catch (Exception e) {
             Log.w(mTag, "error loading sound for " + cmd.uri, e);
-        } catch (IllegalStateException e) {
-            Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);
         }
     }
 
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index ce56443..eade680 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -38,6 +38,7 @@
  */
 public class CamcorderProfile
 {
+    private final int mDuration;  // Recording duration in seconds
 
     /**
      * The Quality class represents the quality level of each CamcorderProfile.
@@ -56,6 +57,14 @@
     };
 
     /**
+     * Returns the recording duration in seconds for LOW quality CamcorderProfile
+     * used by the MMS application.
+     */
+    public static final int getMmsRecordingDurationInSeconds() {
+        return get(Quality.LOW).mDuration;
+    }
+
+    /**
      * The quality level of the camcorder profile
      * @see android.media.CamcorderProfile.Quality
      */
@@ -129,7 +138,8 @@
     }
 
     // Private constructor called by JNI
-    private CamcorderProfile(int quality,
+    private CamcorderProfile(int duration,
+                             int quality,
                              int fileFormat,
                              int videoCodec,
                              int videoBitRate,
@@ -141,6 +151,7 @@
                              int audioSampleRate,
                              int audioChannels) {
 
+        mDuration         = duration;
         mQuality          = Quality.values()[quality];
         mFileFormat       = fileFormat;
         mVideoCodec       = videoCodec;
diff --git a/media/java/android/media/CameraProfile.java b/media/java/android/media/CameraProfile.java
new file mode 100644
index 0000000..9685e7e
--- /dev/null
+++ b/media/java/android/media/CameraProfile.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * The CameraProfile class is used to retrieve the pre-defined still image
+ * capture (jpeg) quality levels (0-100) used for low, medium, and high
+ * quality settings in the Camera application.
+ *
+ * {@hide}
+ */
+public class CameraProfile
+{
+    /**
+     * Returns a list of the pre-defined still image capture (jpeg) quality levels
+     * used for low, medium and high quality settings in the Camera application.
+     */
+    public static int[] getImageEncodingQualityLevels() {
+        int nLevels = native_get_num_image_encoding_quality_levels();
+        if (nLevels == 0) return null;
+
+        int[] levels = new int[nLevels];
+        for (int i = 0; i < nLevels; ++i) {
+            levels[i] = native_get_image_encoding_quality_level(i);
+        }
+        return levels;
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    // Methods implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_image_encoding_quality_levels();
+    private static native final int native_get_image_encoding_quality_level(int index);
+}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 19132c5..7d7533a 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -171,6 +171,7 @@
     }
 
     camcorder_quality q = static_cast<camcorder_quality>(quality);
+    int duration         = sProfiles->getCamcorderProfileParamByName("duration", q);
     int fileFormat       = sProfiles->getCamcorderProfileParamByName("file.format", q);
     int videoCodec       = sProfiles->getCamcorderProfileParamByName("vid.codec",   q);
     int videoBitRate     = sProfiles->getCamcorderProfileParamByName("vid.bps",     q);
@@ -183,7 +184,7 @@
     int audioChannels    = sProfiles->getCamcorderProfileParamByName("aud.ch",      q);
 
     // Check on the values retrieved
-    if (fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
+    if (duration == -1 || fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
         videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 ||
         audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) {
 
@@ -192,9 +193,10 @@
     }
 
     jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile");
-    jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIII)V");
+    jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIIII)V");
     return env->NewObject(camcorderProfileClazz,
                           camcorderProfileConstructorMethodID,
+                          duration,
                           quality,
                           fileFormat,
                           videoCodec,
@@ -250,6 +252,25 @@
     return static_cast<jint>(decoders[index]);
 }
 
+static jint
+android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_image_encoding_quality_levels");
+    return sProfiles->getImageEncodingQualityLevels().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_image_encoding_quality_level");
+    Vector<int> levels = sProfiles->getImageEncodingQualityLevels();
+    if (index < 0 || index >= levels.size()) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return -1;
+    }
+    return static_cast<jint>(levels[index]);
+}
+
 static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
     {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
     {"native_get_num_file_formats",            "()I",                    (void *)android_media_MediaProfiles_native_get_num_file_formats},
@@ -278,9 +299,17 @@
     {"native_get_audio_decoder_type",          "(I)I",                   (void *)android_media_MediaProfiles_native_get_audio_decoder_type},
 };
 
+static JNINativeMethod gMethodsForCameraProfileClass[] = {
+    {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
+    {"native_get_num_image_encoding_quality_levels",
+                                               "()I",                    (void *)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels},
+    {"native_get_image_encoding_quality_level","(I)I",                   (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level},
+};
+
 static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
 static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
 static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
+static const char* const kCameraProfileClassPathName = "android/media/CameraProfile";
 
 // This function only registers the native methods, and is called from
 // JNI_OnLoad in android_media_MediaPlayer.cpp
@@ -301,6 +330,11 @@
                gMethodsForDecoderCapabilitiesClass,
                NELEM(gMethodsForDecoderCapabilitiesClass));
 
-    // Success if ret1 == 0 && ret2 == 0 && ret3 == 0
-    return (ret1 || ret2 || ret3);
+    int ret4 = AndroidRuntime::registerNativeMethods(env,
+               kCameraProfileClassPathName,
+               gMethodsForCameraProfileClass,
+               NELEM(gMethodsForCameraProfileClass));
+
+    // Success if all return values from above are 0
+    return (ret1 || ret2 || ret3 || ret4);
 }
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 0efade1..1263373 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -293,6 +293,13 @@
     return profile;
 }
 
+/*static*/ int
+MediaProfiles::getImageEncodingQualityLevel(const char** atts)
+{
+    CHECK(!strcmp("quality", atts[0]));
+    return atoi(atts[1]);
+}
+
 /*static*/ void
 MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
 {
@@ -317,6 +324,8 @@
         profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
     } else if (strcmp("EncoderProfile", name) == 0) {
         profiles->mCamcorderProfiles.add(createCamcorderProfile(atts));
+    } else if (strcmp("ImageEncoding", name) == 0) {
+        profiles->mImageEncodingQualityLevels.add(getImageEncodingQualityLevel(atts));
     }
 }
 
@@ -446,6 +455,14 @@
         AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
 }
 
+/*static*/ void
+MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
+{
+    profiles->mImageEncodingQualityLevels.add(70);
+    profiles->mImageEncodingQualityLevels.add(80);
+    profiles->mImageEncodingQualityLevels.add(90);
+}
+
 /*static*/ MediaProfiles*
 MediaProfiles::createDefaultInstance()
 {
@@ -456,6 +473,7 @@
     createDefaultVideoDecoders(profiles);
     createDefaultAudioDecoders(profiles);
     createDefaultEncoderOutputFileFormats(profiles);
+    createDefaultImageEncodingQualityLevels(profiles);
     sIsInitialized = true;
     return profiles;
 }
@@ -627,6 +645,7 @@
         return -1;
     }
 
+    if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration;
     if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat;
     if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodec->mCodec;
     if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameWidth;
@@ -642,6 +661,11 @@
     return -1;
 }
 
+Vector<int> MediaProfiles::getImageEncodingQualityLevels() const
+{
+    return mImageEncodingQualityLevels;  // copy out
+}
+
 MediaProfiles::~MediaProfiles()
 {
     CHECK("destructor should never be called" == 0);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 50dad33..c26d682 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -430,6 +430,8 @@
 
         snprintf(buffer, SIZE, " Allocation count %i\n", count);
         result.append(buffer);
+        snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
+        result.append(buffer);
 
         AllocEntry * entries = new AllocEntry[count];
 
@@ -478,7 +480,7 @@
         for (size_t i = 0; i < count; i++) {
             AllocEntry *e = &entries[i];
 
-            snprintf(buffer, SIZE, "size %8i, dup %4i", e->size, e->dups);
+            snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
             result.append(buffer);
             for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
                 if (ct) {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 165ac09..f1c3f0f 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -439,14 +439,16 @@
     printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
 
     char buffer[256];
-    if (chunk_size <= sizeof(buffer)) {
-        if (mDataSource->readAt(*offset, buffer, chunk_size)
-                < (ssize_t)chunk_size) {
-            return ERROR_IO;
-        }
-
-        hexdump(buffer, chunk_size);
+    size_t n = chunk_size;
+    if (n > sizeof(buffer)) {
+        n = sizeof(buffer);
     }
+    if (mDataSource->readAt(*offset, buffer, n)
+            < (ssize_t)n) {
+        return ERROR_IO;
+    }
+
+    hexdump(buffer, n);
 #endif
 
     PathAdder autoAdder(&mPath, chunk_type);
@@ -981,7 +983,13 @@
 
             if (U32_AT(buffer) != 0) {
                 // Should be version 0, flags 0.
-                return ERROR_MALFORMED;
+
+                // If it's not, let's assume this is one of those
+                // apparently malformed chunks that don't have flags
+                // and completely different semantics than what's
+                // in the MPEG4 specs and skip it.
+                *offset += chunk_size;
+                return OK;
             }
 
             off_t stop_offset = *offset + chunk_size;
@@ -1626,7 +1634,8 @@
 
     if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
         || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
-        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)) {
+        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
+        || !memcmp(header, "ftypkddi", 8)) {
         *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
         *confidence = 0.1;
 
diff --git a/mms-common/Android.mk b/mms-common/Android.mk
index de994c0..57f1ccc 100644
--- a/mms-common/Android.mk
+++ b/mms-common/Android.mk
@@ -20,6 +20,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := mms-common
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # Include this library in the build server's output directory
diff --git a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
index 0237bc2..87e4758 100644
--- a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
+++ b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
@@ -32,8 +32,8 @@
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
+import android.util.Patterns;
 
-import com.android.common.Patterns;
 import android.database.sqlite.SqliteWrapper;
 
 /**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 8036e52..18e247e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -44,8 +44,8 @@
 import android.util.Config;
 import android.util.Log;
 import android.util.Xml;
-import com.android.common.XmlUtils;
 import com.android.internal.telephony.RILConstants;
+import com.android.internal.util.XmlUtils;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockPatternView;
diff --git a/preloaded-classes b/preloaded-classes
index aaae440..9fc000f 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -308,10 +308,12 @@
 android.net.Uri$OpaqueUri
 android.net.Uri$Part
 android.net.WebAddress
+android.net.http.AndroidHttpClient
 android.net.http.AndroidHttpClientConnection
 android.net.http.EventHandler
 android.net.http.Headers
 android.net.http.HttpsConnection
+android.net.http.HttpDateTime
 android.net.http.Request
 android.net.http.RequestQueue
 android.net.http.SslCertificate
@@ -473,6 +475,7 @@
 android.util.Log
 android.util.LongSparseArray
 android.util.MonthDisplayHelper
+android.util.Patterns
 android.util.SparseArray
 android.util.StateSet
 android.util.TypedValue
@@ -618,13 +621,6 @@
 android.widget.ZoomButton
 android.widget.ZoomButtonsController
 android.widget.ZoomControls
-com.android.common.AndroidHttpClient
-com.android.common.DomainNameValidator
-com.android.common.FastXmlSerializer
-com.android.common.HttpDateTime
-com.android.common.Patterns
-com.android.common.Rfc822Validator
-com.android.common.userhappiness.UserHappinessSignals
 com.android.internal.R$styleable
 com.android.internal.app.AlertActivity
 com.android.internal.app.AlertController
@@ -652,6 +648,7 @@
 com.android.internal.os.ZygoteConnection
 com.android.internal.os.ZygoteConnection$Arguments
 com.android.internal.os.ZygoteInit
+com.android.internal.net.DomainNameValidator
 com.android.internal.policy.PolicyManager
 com.android.internal.policy.impl.PhoneLayoutInflater
 com.android.internal.policy.impl.PhoneWindow
@@ -672,7 +669,9 @@
 com.android.internal.telephony.gsm.SmsMessage$PduParser
 com.android.internal.util.ArrayUtils
 com.android.internal.util.FastMath
+com.android.internal.util.FastXmlSerializer
 com.android.internal.util.HanziToPinyin
+com.android.internal.util.XmlUtils
 com.android.internal.view.IInputConnectionWrapper
 com.android.internal.view.IInputContext$Stub
 com.android.internal.view.IInputMethodManager$Stub
diff --git a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
index bee3938..e8cf2f7 100644
--- a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
+++ b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
@@ -29,7 +29,7 @@
 import android.text.format.Time;
 import android.util.Log;
 import android.util.Xml;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 0b466f1..a5b0db9 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -57,7 +57,7 @@
 
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.appwidget.IAppWidgetHost;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index d4b28e2..27faf3dc5 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -374,7 +374,7 @@
         mProvisioned = Settings.Secure.getInt(context.getContentResolver(),
                 Settings.Secure.BACKUP_PROVISIONED, 0) != 0;
         mAutoRestore = Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.BACKUP_AUTO_RESTORE, 0) != 0;
+                Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
         // If Encrypted file systems is enabled or disabled, this call will return the
         // correct directory.
         mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
@@ -2289,7 +2289,7 @@
         if (DEBUG) Log.v(TAG, "restoreAtInstall pkg=" + packageName
                 + " token=" + Integer.toHexString(token));
 
-        if (restoreSet != 0) {
+        if (mAutoRestore && mProvisioned && restoreSet != 0) {
             // okay, we're going to attempt a restore of this package from this restore set.
             // The eventual message back into the Package Manager to run the post-install
             // steps for 'token' will be issued from the restore handling code.
@@ -2306,8 +2306,8 @@
                     restoreSet, pkg, token);
             mBackupHandler.sendMessage(msg);
         } else {
-            // No way to attempt a restore; just tell the Package Manager to proceed
-            // with the post-install handling for this package.
+            // Auto-restore disabled or no way to attempt a restore; just tell the Package
+            // Manager to proceed with the post-install handling for this package.
             if (DEBUG) Log.v(TAG, "No restore set -- skipping restore");
             try {
                 mPackageManagerBinder.finishPackageInstall(token);
@@ -2484,6 +2484,7 @@
             pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                     + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
                     + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
+            pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
             pw.println("Last backup pass: " + mLastBackupPass
                     + " (now = " + System.currentTimeMillis() + ')');
             pw.println("  next scheduled: " + mNextBackupPass);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index df685ab..19f4b8a 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -934,9 +934,18 @@
 
             int newType = -1;
             int newPriority = -1;
+            boolean noMobileData = !getMobileDataEnabled();
             for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
                 if (checkType == prevNetType) continue;
                 if (mNetAttributes[checkType] == null) continue;
+                if (mNetAttributes[checkType].mRadio == ConnectivityManager.TYPE_MOBILE &&
+                        noMobileData) {
+                    if (DBG) {
+                        Log.d(TAG, "not failing over to mobile type " + checkType +
+                                " because Mobile Data Disabled");
+                    }
+                    continue;
+                }
                 if (mNetAttributes[checkType].isDefault()) {
                     /* TODO - if we have multiple nets we could use
                      * we may want to put more thought into which we choose
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index ac65aa9..9899e99 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -16,9 +16,9 @@
 
 package com.android.server;
 
-import com.android.common.FastXmlSerializer;
-import com.android.common.XmlUtils;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 027f35c..a0c850f 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -305,6 +305,14 @@
                     (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE);
             mKeyguardLock = keyguardManager.newKeyguardLock(TAG);
 
+            final boolean enableCarMode = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
+            if (enableCarMode) {
+                try {
+                    setCarMode(enableCarMode);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Unable to change car mode.", e);
+                }
+            }
             // don't bother broadcasting undocked here
             if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                 update();
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 2640cfb..1bb897b 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -32,7 +32,7 @@
 import android.view.Surface;
 import android.view.WindowManagerPolicy;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index a23fac4..63fdaef 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -18,9 +18,9 @@
 
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.app.ResolverActivity;
-import com.android.common.FastXmlSerializer;
-import com.android.common.XmlUtils;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
 import com.android.server.JournaledFile;
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 481e6a4..aebb0ff 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -67,9 +67,9 @@
 
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.service.wallpaper.ImageWallpaper;
+import com.android.internal.util.FastXmlSerializer;
 import com.android.server.DevicePolicyManagerService.ActiveAdmin;
 import com.android.server.DevicePolicyManagerService.MyPackageMonitor;
-import com.android.common.FastXmlSerializer;
 
 class WallpaperManagerService extends IWallpaperManager.Stub {
     static final String TAG = "WallpaperService";
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
index 4232887..fa91457 100644
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ b/telephony/java/com/android/internal/telephony/IccProvider.java
@@ -19,8 +19,9 @@
 import android.content.ContentProvider;
 import android.content.UriMatcher;
 import android.content.ContentValues;
-import com.android.common.ArrayListCursor;
+import android.database.AbstractCursor;
 import android.database.Cursor;
+import android.database.CursorWindow;
 import android.net.Uri;
 import android.os.SystemProperties;
 import android.os.RemoteException;
@@ -35,6 +36,149 @@
 import com.android.internal.telephony.AdnRecord;
 import com.android.internal.telephony.IIccPhoneBook;
 
+/**
+ * XXX old code -- should be replaced with MatrixCursor.
+ * @deprecated This is has been replaced by MatrixCursor.
+*/
+class ArrayListCursor extends AbstractCursor {
+    private String[] mColumnNames;
+    private ArrayList<Object>[] mRows;
+
+    @SuppressWarnings({"unchecked"})
+    public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
+        int colCount = columnNames.length;
+        boolean foundID = false;
+        // Add an _id column if not in columnNames
+        for (int i = 0; i < colCount; ++i) {
+            if (columnNames[i].compareToIgnoreCase("_id") == 0) {
+                mColumnNames = columnNames;
+                foundID = true;
+                break;
+            }
+        }
+
+        if (!foundID) {
+            mColumnNames = new String[colCount + 1];
+            System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
+            mColumnNames[colCount] = "_id";
+        }
+
+        int rowCount = rows.size();
+        mRows = new ArrayList[rowCount];
+
+        for (int i = 0; i < rowCount; ++i) {
+            mRows[i] = rows.get(i);
+            if (!foundID) {
+                mRows[i].add(i);
+            }
+        }
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        if (position < 0 || position > getCount()) {
+            return;
+        }
+
+        window.acquireReference();
+        try {
+            int oldpos = mPos;
+            mPos = position - 1;
+            window.clear();
+            window.setStartPosition(position);
+            int columnNum = getColumnCount();
+            window.setNumColumns(columnNum);
+            while (moveToNext() && window.allocRow()) {
+                for (int i = 0; i < columnNum; i++) {
+                    final Object data = mRows[mPos].get(i);
+                    if (data != null) {
+                        if (data instanceof byte[]) {
+                            byte[] field = (byte[]) data;
+                            if (!window.putBlob(field, mPos, i)) {
+                                window.freeLastRow();
+                                break;
+                            }
+                        } else {
+                            String field = data.toString();
+                            if (!window.putString(field, mPos, i)) {
+                                window.freeLastRow();
+                                break;
+                            }
+                        }
+                    } else {
+                        if (!window.putNull(mPos, i)) {
+                            window.freeLastRow();
+                            break;
+                        }
+                    }
+                }
+            }
+
+            mPos = oldpos;
+        } catch (IllegalStateException e){
+            // simply ignore it
+        } finally {
+            window.releaseReference();
+        }
+    }
+
+    @Override
+    public int getCount() {
+        return mRows.length;
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        return (byte[]) mRows[mPos].get(columnIndex);
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        Object cell = mRows[mPos].get(columnIndex);
+        return (cell == null) ? null : cell.toString();
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.shortValue();
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.intValue();
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.longValue();
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.floatValue();
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        Number num = (Number) mRows[mPos].get(columnIndex);
+        return num.doubleValue();
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        return mRows[mPos].get(columnIndex) == null;
+    }
+}
+
 
 /**
  * {@hide}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
index 0e186d0..37c1d55 100644
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
@@ -23,8 +23,8 @@
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
+import com.android.internal.util.XmlUtils;
 
-import com.android.common.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 905d5e3..d893ec4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -18,8 +18,8 @@
 
 import android.os.Message;
 import android.util.Log;
+import android.util.Patterns;
 
-import com.android.common.Patterns;
 import com.android.internal.telephony.DataConnection;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.RILConstants;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
index abb0230..9ea30101 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
@@ -13,7 +13,7 @@
 import android.util.Log;
 import android.util.Xml;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 
 public class SpnOverride {
     private HashMap<String, String> CarrierSpnMap;
diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
index 0bedd53..0e49e35 100644
--- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
@@ -28,7 +28,8 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
 
 /**
  * {@hide}
diff --git a/common/tests/res/raw/alt_ip_only.crt b/tests/AndroidTests/res/raw/alt_ip_only.crt
similarity index 100%
rename from common/tests/res/raw/alt_ip_only.crt
rename to tests/AndroidTests/res/raw/alt_ip_only.crt
diff --git a/common/tests/res/raw/subject_alt_only.crt b/tests/AndroidTests/res/raw/subject_alt_only.crt
similarity index 100%
rename from common/tests/res/raw/subject_alt_only.crt
rename to tests/AndroidTests/res/raw/subject_alt_only.crt
diff --git a/common/tests/res/raw/subject_only.crt b/tests/AndroidTests/res/raw/subject_only.crt
similarity index 100%
rename from common/tests/res/raw/subject_only.crt
rename to tests/AndroidTests/res/raw/subject_only.crt
diff --git a/common/tests/res/raw/subject_with_alt_names.crt b/tests/AndroidTests/res/raw/subject_with_alt_names.crt
similarity index 100%
rename from common/tests/res/raw/subject_with_alt_names.crt
rename to tests/AndroidTests/res/raw/subject_with_alt_names.crt
diff --git a/common/tests/res/raw/subject_with_wild_alt_name.crt b/tests/AndroidTests/res/raw/subject_with_wild_alt_name.crt
similarity index 100%
rename from common/tests/res/raw/subject_with_wild_alt_name.crt
rename to tests/AndroidTests/res/raw/subject_with_wild_alt_name.crt
diff --git a/common/tests/res/raw/wild_alt_name_only.crt b/tests/AndroidTests/res/raw/wild_alt_name_only.crt
similarity index 100%
rename from common/tests/res/raw/wild_alt_name_only.crt
rename to tests/AndroidTests/res/raw/wild_alt_name_only.crt
diff --git a/common/tests/src/com/android/common/DNParserTest.java b/tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
similarity index 95%
rename from common/tests/src/com/android/common/DNParserTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
index 34b140a..61d0b42 100644
--- a/common/tests/src/com/android/common/DNParserTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.common;
+package com.android.unit_tests;
+
+import com.android.internal.net.DNParser;
 
 import javax.security.auth.x500.X500Principal;
 
diff --git a/common/tests/src/com/android/common/DomainNameValidatorTest.java b/tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
similarity index 98%
rename from common/tests/src/com/android/common/DomainNameValidatorTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
index b825be4..1754dbe 100644
--- a/common/tests/src/com/android/common/DomainNameValidatorTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
@@ -13,9 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.common;
+package com.android.unit_tests;
 
-import com.android.common.tests.R;
+import com.android.internal.net.DomainNameValidator;
 
 import android.test.AndroidTestCase;
 
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
similarity index 97%
rename from common/tests/src/com/android/common/PatternsTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
index 9e2ad58..0edcd6d 100644
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.android.common;
+package com.android.unit_tests;
 
 import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
+import android.util.Patterns;
 
 import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+
+import junit.framework.TestCase;
 
 public class PatternsTest extends TestCase {
 
diff --git a/tests/SslLoad/src/com/android/sslload/SslLoad.java b/tests/SslLoad/src/com/android/sslload/SslLoad.java
index 1470d48..62aa524 100644
--- a/tests/SslLoad/src/com/android/sslload/SslLoad.java
+++ b/tests/SslLoad/src/com/android/sslload/SslLoad.java
@@ -35,7 +35,7 @@
 import android.widget.Button;
 import android.widget.TextView;
 import android.util.Log;
-import com.android.common.AndroidHttpClient;
+import android.net.http.AndroidHttpClient;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.ResponseHandler;
 import org.apache.http.client.methods.HttpGet;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 41d9f9d..8e9e75f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 import com.android.layoutlib.api.ILayoutBridge;
 import com.android.layoutlib.api.ILayoutLog;
 import com.android.layoutlib.api.ILayoutResult;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
index 6a98780..70c5bd7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge;
 
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
 import com.android.layoutlib.api.IResourceValue;
 import com.android.layoutlib.api.IStyleResourceValue;