Merge change 25853 into eclair

* changes:
  Don't back up / restore certain sync-related settings
diff --git a/api/current.xml b/api/current.xml
index b38176d..0495764 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -7841,6 +7841,28 @@
  visibility="public"
 >
 </field>
+<field name="textAppearanceSearchResultSubtitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843424"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textAppearanceSearchResultTitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843425"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="textAppearanceSmall"
  type="int"
  transient="false"
@@ -31692,6 +31714,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="true"
@@ -33028,6 +33073,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="false"
@@ -35761,17 +35829,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_REMOTE_INTENT"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.intent.action.REMOTE_INTENT&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_RUN"
  type="java.lang.String"
  transient="false"
@@ -98695,6 +98752,116 @@
  visibility="public"
 >
 </field>
+<field name="EXTRA_HEALTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;health&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ICON_SMALL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;icon-small&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_LEVEL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;level&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PLUGGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;plugged&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PRESENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;present&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_SCALE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;scale&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_STATUS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;status&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TECHNOLOGY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;technology&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TEMPERATURE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;temperature&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_VOLTAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;voltage&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Binder"
  extends="java.lang.Object"
@@ -126684,6 +126851,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="false"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index dc8d873..afafe64 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -659,6 +659,38 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        IIntentReceiver rd = null;
+        if (resultReceiver != null) {
+            if (mPackageInfo != null) {
+                if (scheduler == null) {
+                    scheduler = mMainThread.getHandler();
+                }
+                rd = mPackageInfo.getReceiverDispatcher(
+                    resultReceiver, getOuterContext(), scheduler,
+                    mMainThread.getInstrumentation(), false);
+            } else {
+                if (scheduler == null) {
+                    scheduler = mMainThread.getHandler();
+                }
+                rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
+                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
+            }
+        }
+        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+        try {
+            ActivityManagerNative.getDefault().broadcastIntent(
+                mMainThread.getApplicationThread(), intent, resolvedType, rd,
+                initialCode, initialData, initialExtras, null,
+                true, true);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         if (resolvedType != null) {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index f81ba73..b52a822 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -28,6 +28,7 @@
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.util.UUID;
 
 /**
  * Represents a remote Bluetooth device.
@@ -226,6 +227,20 @@
     public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
 
     /**
+     * Broadcast Action: This intent is used to broadcast the {@link UUID}
+     * wrapped as a {@link ParcelUuid} of the remote device after it has been
+     * fetched. This intent is sent only when the UUIDs of the remote device
+     * are requested to be fetched using Service Discovery Protocol
+     * <p> Always contains the extra field {@link #EXTRA_DEVICE}
+     * <p> Always contains the extra filed {@link #EXTRA_UUID}
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_UUID =
+            "android.bleutooth.device.action.UUID";
+
+    /**
      * Broadcast Action: Indicates a failure to retrieve the name of a remote
      * device.
      * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
@@ -292,6 +307,15 @@
      * @hide */
     public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
 
+    /**
+     * Used as an extra field in {@link #ACTION_UUID} intents,
+     * Contains the {@link ParcelUuid}s of the remote device which is a parcelable
+     * version of {@link UUID}.
+     * @hide
+     */
+    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
+
+
     private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
 
     private final String mAddress;
@@ -507,6 +531,27 @@
         return null;
     }
 
+     /**
+      *  Perform a SDP query on the remote device to get the UUIDs
+      *  supported. This API is asynchronous and an Intent is sent,
+      *  with the UUIDs supported by the remote end. If there is an error
+      *  in getting the SDP records or if the process takes a long time,
+      *  an Intent is sent with the UUIDs that is currently present in the
+      *  cache. Clients should use the {@link getUuids} to get UUIDs
+      *  is SDP is not to be performed.
+      *
+      *  @return False if the sanity check fails, True if the process
+      *               of initiating an ACL connection to the remote device
+      *               was started.
+      *  @hide
+      */
+     public boolean fetchUuidsWithSdp() {
+        try {
+            return sService.fetchRemoteUuidsWithSdp(mAddress);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
     /** @hide */
     public int getServiceChannel(ParcelUuid uuid) {
          try {
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 04c8ec9..203a61d 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -53,6 +53,7 @@
     String getRemoteName(in String address);
     int getRemoteClass(in String address);
     ParcelUuid[] getRemoteUuids(in String address);
+    boolean fetchRemoteUuidsWithSdp(in String address);
     int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
 
     boolean setPin(in String address, in byte[] pin);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a3c4f9a..fe4665e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -657,8 +657,7 @@
      * supplying your own BroadcastReceiver when calling, which will be
      * treated as a final receiver at the end of the broadcast -- its
      * {@link BroadcastReceiver#onReceive} method will be called with
-     * the result values collected from the other receivers.  If you use
-     * an <var>resultReceiver</var> with this method, then the broadcast will
+     * the result values collected from the other receivers.  The broadcast will
      * be serialized in the same way as calling
      * {@link #sendOrderedBroadcast(Intent, String)}.
      *
@@ -689,6 +688,7 @@
      * @see #sendBroadcast(Intent, String)
      * @see #sendOrderedBroadcast(Intent, String)
      * @see #sendStickyBroadcast(Intent)
+     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
      * @see android.content.BroadcastReceiver
      * @see #registerReceiver
      * @see android.app.Activity#RESULT_OK
@@ -715,8 +715,55 @@
      * be re-broadcast to future receivers.
      *
      * @see #sendBroadcast(Intent)
+     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendStickyBroadcast(Intent intent);
+    
+    /**
+     * Version of {@link #sendStickyBroadcast} that allows you to
+     * receive data back from the broadcast.  This is accomplished by
+     * supplying your own BroadcastReceiver when calling, which will be
+     * treated as a final receiver at the end of the broadcast -- its
+     * {@link BroadcastReceiver#onReceive} method will be called with
+     * the result values collected from the other receivers.  The broadcast will
+     * be serialized in the same way as calling
+     * {@link #sendOrderedBroadcast(Intent, String)}.
+     *
+     * <p>Like {@link #sendBroadcast(Intent)}, this method is
+     * asynchronous; it will return before
+     * resultReceiver.onReceive() is called.  Note that the sticky data
+     * stored is only the data you initially supply to the broadcast, not
+     * the result of any changes made by the receivers.
+     *
+     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+     *
+     * @param intent The Intent to broadcast; all receivers matching this
+     *               Intent will receive the broadcast.
+     * @param resultReceiver Your own BroadcastReceiver to treat as the final
+     *                       receiver of the broadcast.
+     * @param scheduler A custom Handler with which to schedule the
+     *                  resultReceiver callback; if null it will be
+     *                  scheduled in the Context's main thread.
+     * @param initialCode An initial value for the result code.  Often
+     *                    Activity.RESULT_OK.
+     * @param initialData An initial value for the result data.  Often
+     *                    null.
+     * @param initialExtras An initial value for the result extras.  Often
+     *                      null.
+     *
+     * @see #sendBroadcast(Intent)
+     * @see #sendBroadcast(Intent, String)
+     * @see #sendOrderedBroadcast(Intent, String)
+     * @see #sendStickyBroadcast(Intent)
+     * @see android.content.BroadcastReceiver
+     * @see #registerReceiver
+     * @see android.app.Activity#RESULT_OK
+     */
+    public abstract void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras);
+
 
     /**
      * Remove the data previously sent with {@link #sendStickyBroadcast},
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index d580c47..1b34320 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -288,6 +288,16 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(
+        Intent intent, BroadcastReceiver resultReceiver,
+        Handler scheduler, int initialCode, String initialData,
+        Bundle initialExtras) {
+        mBase.sendStickyOrderedBroadcast(intent,
+                resultReceiver, scheduler, initialCode,
+                initialData, initialExtras);
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         mBase.removeStickyBroadcast(intent);
     }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1359761..c1b9f28 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1352,14 +1352,20 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
     /**
-     * Broadcast Action:  The charging state, or charge level of the battery has
-     * changed.
+     * Broadcast Action:  This is a <em>sticky broadcast</em> containing the
+     * charging state, level, and other information about the battery.
+     * See {@link android.os.BatteryManager} for documentation on the
+     * contents of the Intent.
      *
      * <p class="note">
      * You can <em>not</em> receive this through components declared
      * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
-     * Context.registerReceiver()}.
+     * Context.registerReceiver()}.  See {@link #ACTION_BATTERY_LOW},
+     * {@link #ACTION_BATTERY_OKAY}, {@link #ACTION_POWER_CONNECTED},
+     * and {@link #ACTION_POWER_DISCONNECTED} for distinct battery-related
+     * broadcasts that are sent and can be received through manifest
+     * receivers.
      * 
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1434,7 +1440,8 @@
      */
     public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";
     /**
-     * Broadcast Action:  Indicates low memory condition on the device
+     * Broadcast Action:  A sticky broadcast that indicates low memory
+     * condition on the device
      * 
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1711,6 +1718,18 @@
             "android.intent.action.REBOOT";
 
     /**
+     * Broadcast Action:  A sticky broadcast indicating the phone was docked
+     * or undocked.  Includes the extra
+     * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
+     * This is intended for monitoring the current dock state.
+     * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
+     * or {@link #CATEGORY_DESK_DOCK} instead.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DOCK_EVENT =
+            "android.intent.action.DOCK_EVENT";
+
+    /**
      * Broadcast Action: a remote intent is to be broadcasted.
      *
      * A remote intent is used for remote RPC between devices. The remote intent
@@ -1720,6 +1739,7 @@
      * does not trust intent broadcasts from arbitrary intent senders, it should require
      * the sender to hold certain permissions so only trusted sender's broadcast will be
      * let through.
+     * @hide
      */
     public static final String ACTION_REMOTE_INTENT =
             "android.intent.action.REMOTE_INTENT";
@@ -1878,16 +1898,6 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK";
 
-    /**
-     * Broadcast Action:  The phone was docked or undocked.  Includes the extra
-     * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
-     * This is intended for monitoring the current dock state.
-     * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
-     * or {@link #CATEGORY_DESK_DOCK} instead.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT";
-
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard extra data keys.
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 8f1a756..44b73c5 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -18,10 +18,73 @@
 
 /**
  * The BatteryManager class contains strings and constants used for values
- * in the ACTION_BATTERY_CHANGED Intent.
+ * in the {@link android.content.Intent#ACTION_BATTERY_CHANGED} Intent.
  */
 public class BatteryManager {
-
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current status constant.
+     */
+    public static final String EXTRA_STATUS = "status";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current health constant.
+     */
+    public static final String EXTRA_HEALTH = "health";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * boolean indicating whether a battery is present.
+     */
+    public static final String EXTRA_PRESENT = "present";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer field containing the current battery level, from 0 to
+     * {@link #EXTRA_SCALE}.
+     */
+    public static final String EXTRA_LEVEL = "level";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the maximum battery level.
+     */
+    public static final String EXTRA_SCALE = "scale";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the resource ID of a small status bar icon
+     * indicating the current battery state.
+     */
+    public static final String EXTRA_ICON_SMALL = "icon-small";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer indicating whether the device is plugged in to a power
+     * source; 0 means it is on battery, other constants are different
+     * types of power sources.
+     */
+    public static final String EXTRA_PLUGGED = "plugged";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current battery voltage level.
+     */
+    public static final String EXTRA_VOLTAGE = "voltage";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current battery temperature.
+     */
+    public static final String EXTRA_TEMPERATURE = "temperature";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * String describing the technology of the current battery.
+     */
+    public static final String EXTRA_TECHNOLOGY = "technology";
+    
     // values for "status" field in the ACTION_BATTERY_CHANGED Intent
     public static final int BATTERY_STATUS_UNKNOWN = 1;
     public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 93ee3ba..0e72aaf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -677,12 +677,20 @@
     }
 
     /**
+     * Combines all columns returned by {@link Data} table queries.
+     */
+    private interface DataColumnsWithJoins extends BaseColumns, DataColumns, RawContactsColumns,
+            ContactsColumns, ContactOptionsColumns {
+
+    }
+
+    /**
      * Constants for the data table, which contains data points tied to a raw contact.
      * For example, a phone number or email address. Each row in this table contains a type
      * definition and some generic columns. Each data type can define the meaning for each of
      * the generic columns.
      */
-    public static final class Data implements BaseColumns, DataColumns {
+    public final static class Data implements DataColumnsWithJoins {
         /**
          * This utility class cannot be instantiated
          */
@@ -950,7 +958,7 @@
         /**
          * Parts of the name.
          */
-        public static final class StructuredName implements BaseCommonColumns {
+        public static final class StructuredName implements DataColumnsWithJoins {
             private StructuredName() {}
 
             /** MIME type used when storing this in data table. */
@@ -1016,7 +1024,7 @@
         /**
          * A nickname.
          */
-        public static final class Nickname implements CommonColumns, BaseCommonColumns {
+        public static final class Nickname implements DataColumnsWithJoins, CommonColumns {
             private Nickname() {}
 
             /** MIME type used when storing this in data table. */
@@ -1037,7 +1045,7 @@
         /**
          * Common data definition for telephone numbers.
          */
-        public static final class Phone implements BaseCommonColumns, CommonColumns {
+        public static final class Phone implements DataColumnsWithJoins, CommonColumns {
             private Phone() {}
 
             /** MIME type used when storing this in data table. */
@@ -1123,13 +1131,18 @@
         /**
          * Common data definition for email addresses.
          */
-        public static final class Email implements BaseCommonColumns, CommonColumns {
+        public static final class Email implements DataColumnsWithJoins, CommonColumns {
             private Email() {}
 
             /** MIME type used when storing this in data table. */
             public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2";
 
             /**
+             * The MIME type of {@link #CONTENT_URI} providing a directory of email addresses.
+             */
+            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
+
+            /**
              * The content:// style URI for all data records of the
              * {@link Email#CONTENT_ITEM_TYPE} MIME type, combined with the
              * associated raw contact and aggregate contact data.
@@ -1145,9 +1158,6 @@
             public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI,
                     "lookup");
 
-            @Deprecated
-            public static final Uri CONTENT_FILTER_EMAIL_URI = CONTENT_LOOKUP_URI;
-
             /**
              * The content:// style URL for email lookup using a filter. The filter returns
              * records of MIME type {@link Email#CONTENT_ITEM_TYPE}. The filter is applied
@@ -1172,7 +1182,7 @@
         /**
          * Common data definition for postal addresses.
          */
-        public static final class StructuredPostal implements BaseCommonColumns, CommonColumns {
+        public static final class StructuredPostal implements DataColumnsWithJoins, CommonColumns {
             private StructuredPostal() {
             }
 
@@ -1266,7 +1276,7 @@
         /**
          * Common data definition for IM addresses.
          */
-        public static final class Im implements BaseCommonColumns, CommonColumns {
+        public static final class Im implements DataColumnsWithJoins, CommonColumns {
             private Im() {}
 
             /** MIME type used when storing this in data table. */
@@ -1304,7 +1314,7 @@
         /**
          * Common data definition for organizations.
          */
-        public static final class Organization implements BaseCommonColumns, CommonColumns {
+        public static final class Organization implements DataColumnsWithJoins, CommonColumns {
             private Organization() {}
 
             /** MIME type used when storing this in data table. */
@@ -1353,7 +1363,7 @@
         /**
          * Common data definition for miscellaneous information.
          */
-        public static final class Miscellaneous implements BaseCommonColumns {
+        public static final class Miscellaneous implements DataColumnsWithJoins {
             private Miscellaneous() {}
 
             /** MIME type used when storing this in data table. */
@@ -1375,7 +1385,7 @@
         /**
          * Common data definition for relations.
          */
-        public static final class Relation implements BaseCommonColumns, CommonColumns {
+        public static final class Relation implements DataColumnsWithJoins, CommonColumns {
             private Relation() {}
 
             /** MIME type used when storing this in data table. */
@@ -1406,7 +1416,7 @@
         /**
          * Common data definition for events.
          */
-        public static final class Event implements BaseCommonColumns, CommonColumns {
+        public static final class Event implements DataColumnsWithJoins, CommonColumns {
             private Event() {}
 
             /** MIME type used when storing this in data table. */
@@ -1425,7 +1435,7 @@
         /**
          * Photo of the contact.
          */
-        public static final class Photo implements BaseCommonColumns {
+        public static final class Photo implements DataColumnsWithJoins {
             private Photo() {}
 
             /** MIME type used when storing this in data table. */
@@ -1443,7 +1453,7 @@
         /**
          * Notes about the contact.
          */
-        public static final class Note implements BaseCommonColumns {
+        public static final class Note implements DataColumnsWithJoins {
             private Note() {}
 
             /** MIME type used when storing this in data table. */
@@ -1459,7 +1469,7 @@
         /**
          * Group Membership.
          */
-        public static final class GroupMembership implements BaseCommonColumns {
+        public static final class GroupMembership implements DataColumnsWithJoins {
             private GroupMembership() {}
 
             /** MIME type used when storing this in data table. */
@@ -1484,7 +1494,7 @@
         /**
          * Website related to the contact.
          */
-        public static final class Website implements BaseCommonColumns, CommonColumns {
+        public static final class Website implements DataColumnsWithJoins, CommonColumns {
             private Website() {}
 
             /** MIME type used when storing this in data table. */
@@ -1672,24 +1682,12 @@
          */
         public static final int TYPE_KEEP_TOGETHER = 1;
 
-        @Deprecated
-        public static final int TYPE_KEEP_IN = 1;
-
         /**
          * Makes sure that the specified raw contacts are NOT included in the same
          * aggregate contact.
          */
         public static final int TYPE_KEEP_SEPARATE = 2;
 
-        @Deprecated
-        public static final int TYPE_KEEP_OUT = 2;
-
-        @Deprecated
-        public static final String CONTACT_ID = "contact_id";
-
-        @Deprecated
-        public static final String RAW_CONTACT_ID = "raw_contact_id";
-
         /**
          * A reference to the {@link RawContacts#_ID} of the raw contact that the rule applies to.
          */
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index ba53307..ba0a0d4 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -330,6 +330,9 @@
             Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
             return;
         }
+        if (DBG) {
+            log("Device property changed:" + address + "property:" + name);
+        }
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
         if (name.equals("Name")) {
             Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
@@ -366,6 +369,7 @@
                 uuid = str.toString();
             }
             mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+            mBluetoothService.sendUuidIntent(address);
         } else if (name.equals("Paired")) {
             if (propValues[1].equals("true")) {
                 mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
@@ -528,6 +532,25 @@
         return;
     }
 
+    private void onDiscoverServicesResult(String deviceObjectPath, boolean result) {
+        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+        // We don't parse the xml here, instead just query Bluez for the properties.
+        if (result) {
+            String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
+            mBluetoothService.addRemoteDeviceProperties(address, properties);
+        }
+        mBluetoothService.sendUuidIntent(address);
+    }
+
+    private void onCreateDeviceResult(String address, boolean result) {
+        if (DBG) {
+            log("Result of onCreateDeviceResult:" + result);
+        }
+        if (!result) {
+            mBluetoothService.sendUuidIntent(address);
+        }
+    }
+
     private void onRestartRequired() {
         if (mBluetoothService.isEnabled()) {
             Log.e(TAG, "*** A serious error occured (did bluetoothd crash?) - " +
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index c0e4f34..ce62f07 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -76,10 +76,17 @@
 
     private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
     private static final int MESSAGE_FINISH_DISABLE = 2;
+    private static final int MESSAGE_UUID_INTENT = 3;
+
+    // The timeout used to sent the UUIDs Intent
+    // This timeout should be greater than the page timeout
+    private static final int UUID_INTENT_DELAY = 6000;
 
     private final Map<String, String> mAdapterProperties;
     private final HashMap <String, Map<String, String>> mDeviceProperties;
 
+    private final ArrayList <String> mUuidIntentTracker;
+
     static {
         classInitNative();
     }
@@ -104,6 +111,7 @@
         mIsDiscovering = false;
         mAdapterProperties = new HashMap<String, String>();
         mDeviceProperties = new HashMap<String, Map<String,String>>();
+        mUuidIntentTracker = new ArrayList<String>();
         registerForAirplaneMode();
     }
 
@@ -291,6 +299,11 @@
             case MESSAGE_FINISH_DISABLE:
                 finishDisable(msg.arg1 != 0);
                 break;
+            case MESSAGE_UUID_INTENT:
+                String address = (String)msg.obj;
+                if (address != null)
+                    sendUuidIntent(address);
+                break;
             }
         }
     };
@@ -976,6 +989,10 @@
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return null;
         }
+        return getUuidFromCache(address);
+    }
+
+    private ParcelUuid[] getUuidFromCache(String address) {
         String value = getRemoteDeviceProperty(address, "UUIDs");
         if (value == null) return null;
 
@@ -990,6 +1007,36 @@
         return uuids;
     }
 
+    public synchronized boolean fetchRemoteUuidsWithSdp(String address) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+            return false;
+        }
+
+        if (mUuidIntentTracker.contains(address)) {
+            // An SDP query for this address is already in progress
+            return true;
+        }
+
+        boolean ret;
+        if (getBondState(address) == BluetoothDevice.BOND_BONDED) {
+            String path = getObjectPathFromAddress(address);
+            if (path == null) return false;
+
+            // Use an empty string for the UUID pattern
+            ret = discoverServicesNative(path, "");
+        } else {
+            ret = createDeviceNative(address);
+        }
+
+        mUuidIntentTracker.add(address);
+
+        Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
+        message.obj = address;
+        mHandler.sendMessageDelayed(message, UUID_INTENT_DELAY);
+        return ret;
+    }
+
     /**
      * Gets the rfcomm channel associated with the UUID.
      *
@@ -1121,6 +1168,18 @@
                 Settings.System.AIRPLANE_MODE_ON, 0) == 1;
     }
 
+    /* Broadcast the Uuid intent */
+    /*package*/ synchronized void sendUuidIntent(String address) {
+        if (mUuidIntentTracker.contains(address)) {
+            ParcelUuid[] uuid = getUuidFromCache(address);
+            Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
+            intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
+            mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+
+            mUuidIntentTracker.remove(address);
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n");
@@ -1284,4 +1343,6 @@
     private native boolean setPairingConfirmationNative(String address, boolean confirm,
             int nativeData);
     private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
+    private native boolean createDeviceNative(String address);
+    private native boolean discoverServicesNative(String objectPath, String pattern);
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7e8ba8f..fb33561 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4517,6 +4517,8 @@
             }
         }
         if (mInZoomOverview) {
+            // Force the titlebar fully reveal in overview mode
+            if (mScrollY < getTitleHeight()) mScrollY = 0;
             zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
         } else {
             // mLastTouchX and mLastTouchY are the point in the current viewport
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 4ec597c..ed375f7 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -248,7 +248,9 @@
                                     PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
                             bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
                         } else {
-                            setDisplayName((String) cookie, null);
+                            String phoneNumber = (String) cookie;
+                            setDisplayName(phoneNumber, null);
+                            mPhotoView.assignContactFromPhone(phoneNumber, true);
                         }
                         break;
                     }
@@ -259,7 +261,9 @@
                                     EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
                             bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
                         } else {
-                            setDisplayName((String) cookie, null);
+                            String emailAddress = (String) cookie;
+                            setDisplayName(emailAddress, null);
+                            mPhotoView.assignContactFromEmail(emailAddress, true);
                         }
                         break;
                     }
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 712f1bf..750b2a9 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -70,12 +70,6 @@
     private AccelerateInterpolator mInterpolator;
 
     /**
-     * True after triggering an action if the user of {@link OnDialTriggerListener} wants to
-     * freeze the UI (until they transition to another screen).
-     */
-    private boolean mFrozen = false;
-
-    /**
      * If the user is currently dragging something.
      */
     private int mGrabbedState = NOTHING_GRABBED;
@@ -119,6 +113,9 @@
 
     private static final boolean DRAW_CENTER_DIMPLE = false;
     private int mEdgeTriggerThresh;
+    private int mDimpleWidth;
+    private int mBackgroundWidth;
+    private int mBackgroundHeight;
 
     public RotarySelector(Context context) {
         this(context, null);
@@ -155,6 +152,11 @@
         mInterpolator = new AccelerateInterpolator();
 
         mEdgeTriggerThresh = (int) (mDensity * EDGE_TRIGGER_DIP);
+
+        mDimpleWidth = mDimple.getIntrinsicWidth();
+
+        mBackgroundWidth = mBackground.getIntrinsicWidth();
+        mBackgroundHeight = mBackground.getIntrinsicHeight();
     }
 
     /**
@@ -214,7 +216,7 @@
         final int width = MeasureSpec.getSize(widthMeasureSpec);  // screen width
 
         final int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
-        final int backgroundH = mBackground.getIntrinsicHeight();
+        final int backgroundH = mBackgroundHeight;
 
         // by making the height less than arrow + bg, arrow and bg will be scrunched together,
         // overlaying somewhat (though on transparent portions of the drawable).
@@ -228,9 +230,9 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
 
-        mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimple.getIntrinsicWidth() / 2;
+        mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimpleWidth / 2;
         mRightHandleX =
-                getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimple.getIntrinsicWidth() / 2;
+                getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimpleWidth / 2;
     }
 
 //    private Paint mPaint = new Paint();
@@ -239,15 +241,14 @@
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         if (DBG) {
-            log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d," +
-                    "mFrozen=%s",
-                    mAnimating, mTouchDragOffset, mGrabbedState, mFrozen));
+            log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d",
+                    mAnimating, mTouchDragOffset, mGrabbedState));
         }
 
         final int height = getHeight();
 
         // update animating state before we draw anything
-        if (mAnimating && !mFrozen) {
+        if (mAnimating) {
             long millisLeft = mAnimationEndTime - currentAnimationTimeMillis();
             if (DBG) log("millisleft for animating: " + millisLeft);
             if (millisLeft <= 0) {
@@ -260,8 +261,8 @@
         }
 
         // Background:
-        final int backgroundW = mBackground.getIntrinsicWidth();
-        final int backgroundH = mBackground.getIntrinsicHeight();
+        final int backgroundW = mBackgroundWidth;
+        final int backgroundH = mBackgroundHeight;
         final int backgroundY = height - backgroundH;
         if (DBG) log("- Background INTRINSIC: " + backgroundW + " x " + backgroundH);
         mBackground.setBounds(0, backgroundY,
@@ -383,12 +384,12 @@
      */
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        if (mAnimating || mFrozen) {
+        if (mAnimating) {
             return true;
         }
 
         final int eventX = (int) event.getX();
-        final int hitWindow = mDimple.getIntrinsicWidth();
+        final int hitWindow = mDimpleWidth;
 
         final int action = event.getAction();
         switch (action) {
@@ -419,14 +420,29 @@
                     invalidate();
                     if (eventX >= getRight() - mEdgeTriggerThresh && !mTriggered) {
                         mTriggered = true;
-                        mFrozen = dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
+                        dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
+                        // set up "spin around animation"
+                        mAnimating = true;
+                        mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
+                        mAnimatingDelta = -mBackgroundWidth;
+                        mTouchDragOffset = 0;
+                        mGrabbedState = NOTHING_GRABBED;
+                        invalidate();
+
                     }
                 } else if (mGrabbedState == RIGHT_HANDLE_GRABBED) {
                     mTouchDragOffset = eventX - mRightHandleX;
                     invalidate();
                     if (eventX <= mEdgeTriggerThresh && !mTriggered) {
                         mTriggered = true;
-                        mFrozen = dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
+                        dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
+                        // set up "spin around animation"
+                        mAnimating = true;
+                        mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
+                        mAnimatingDelta = mBackgroundWidth;
+                        mTouchDragOffset = 0;
+                        mGrabbedState = NOTHING_GRABBED;
+                        invalidate();
                     }
                 }
                 break;
@@ -435,11 +451,13 @@
                 // handle animating back to start if they didn't trigger
                 if (mGrabbedState == LEFT_HANDLE_GRABBED
                         && Math.abs(eventX - mLeftHandleX) > 5) {
+                    // set up "snap back" animation
                     mAnimating = true;
                     mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
                     mAnimatingDelta = eventX - mLeftHandleX;
                 } else if (mGrabbedState == RIGHT_HANDLE_GRABBED
                         && Math.abs(eventX - mRightHandleX) > 5) {
+                    // set up "snap back" animation
                     mAnimating = true;
                     mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
                     mAnimatingDelta = eventX - mRightHandleX;
@@ -504,12 +522,11 @@
     /**
      * Dispatches a trigger event to our listener.
      */
-    private boolean dispatchTriggerEvent(int whichHandle) {
+    private void dispatchTriggerEvent(int whichHandle) {
         vibrate(VIBRATE_LONG);
         if (mOnDialTriggerListener != null) {
-            return mOnDialTriggerListener.onDialTrigger(this, whichHandle);
+            mOnDialTriggerListener.onDialTrigger(this, whichHandle);
         }
-        return false;
     }
 
     /**
@@ -530,22 +547,13 @@
         public static final int RIGHT_HANDLE = 2;
 
         /**
-         * @hide
-         * The center handle is currently unused.
-         */
-        public static final int CENTER_HANDLE = 3;
-
-        /**
          * Called when the dial is triggered.
          *
          * @param v The view that was triggered
          * @param whichHandle  Which "dial handle" the user grabbed,
-         *        either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}, or
-         *        {@link #CENTER_HANDLE}.
-         * @return Whether the widget should freeze (e.g when the action goes to another screen,
-         *         you want the UI to stay put until the transition occurs).
+         *        either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}.
          */
-        boolean onDialTrigger(View v, int whichHandle);
+        void onDialTrigger(View v, int whichHandle);
     }
 
 
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e703ed8..e37e832 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -48,6 +48,8 @@
 static jmethodID method_onDeviceDisconnectRequested;
 
 static jmethodID method_onCreatePairedDeviceResult;
+static jmethodID method_onCreateDeviceResult;
+static jmethodID method_onDiscoverServicesResult;
 static jmethodID method_onGetDeviceServiceChannelResult;
 
 static jmethodID method_onRequestPinCode;
@@ -92,6 +94,10 @@
 
     method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
                                                          "(Ljava/lang/String;I)V");
+    method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
+                                                         "(Ljava/lang/String;Z)V");
+    method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
+                                                         "(Ljava/lang/String;Z)V");
 
     method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
                                                "(Ljava/lang/String;Ljava/lang/String;)Z");
@@ -1097,6 +1103,54 @@
     free(user);
 }
 
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
+    LOGV(__FUNCTION__);
+
+    native_data_t *nat = (native_data_t *)n;
+    const char *address= (const char *)user;
+    DBusError err;
+    dbus_error_init(&err);
+    JNIEnv *env;
+    nat->vm->GetEnv((void**)&env, nat->envVer);
+
+    LOGV("... Address = %s", address);
+
+    bool result = JNI_TRUE;
+    if (dbus_set_error_from_message(&err, msg)) {
+        LOG_AND_FREE_DBUS_ERROR(&err);
+        result = JNI_FALSE;
+    }
+    env->CallVoidMethod(nat->me,
+                        method_onCreateDeviceResult,
+                        env->NewStringUTF(address),
+                        result);
+    free(user);
+}
+
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
+    LOGV(__FUNCTION__);
+
+    native_data_t *nat = (native_data_t *)n;
+    const char *path = (const char *)user;
+    DBusError err;
+    dbus_error_init(&err);
+    JNIEnv *env;
+    nat->vm->GetEnv((void**)&env, nat->envVer);
+
+    LOGV("... Device Path = %s", path);
+
+    bool result = JNI_TRUE;
+    if (dbus_set_error_from_message(&err, msg)) {
+        LOG_AND_FREE_DBUS_ERROR(&err);
+        result = JNI_FALSE;
+    }
+    env->CallVoidMethod(nat->me,
+                        method_onDiscoverServicesResult,
+                        env->NewStringUTF(path),
+                        result);
+    free(user);
+}
+
 void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
     LOGV(__FUNCTION__);
 
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 0b71acb..c432ed9 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -66,6 +66,8 @@
                                             DBusMessage *msg,
                                             void *data);
 void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
 
 
 /** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -757,6 +759,75 @@
 #endif
 }
 
+
+static jboolean createDeviceNative(JNIEnv *env, jobject object,
+                                                jstring address) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    native_data_t *nat = get_native_data(env, object);
+    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+    struct event_loop_native_data_t *eventLoopNat =
+            get_EventLoop_native_data(env, eventLoop);
+
+    if (nat && eventLoopNat) {
+        const char *c_address = env->GetStringUTFChars(address, NULL);
+        LOGV("... address = %s", c_address);
+        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
+        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
+
+        bool ret = dbus_func_args_async(env, nat->conn, -1,
+                                        onCreateDeviceResult,
+                                        context_address,
+                                        eventLoopNat,
+                                        get_adapter_path(env, object),
+                                        DBUS_ADAPTER_IFACE,
+                                        "CreateDevice",
+                                        DBUS_TYPE_STRING, &c_address,
+                                        DBUS_TYPE_INVALID);
+        env->ReleaseStringUTFChars(address, c_address);
+        return ret ? JNI_TRUE : JNI_FALSE;
+    }
+#endif
+    return JNI_FALSE;
+}
+
+static jboolean discoverServicesNative(JNIEnv *env, jobject object,
+                                               jstring path, jstring pattern) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    native_data_t *nat = get_native_data(env, object);
+    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+    struct event_loop_native_data_t *eventLoopNat =
+            get_EventLoop_native_data(env, eventLoop);
+
+    if (nat && eventLoopNat) {
+        const char *c_path = env->GetStringUTFChars(path, NULL);
+        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
+        int len = env->GetStringLength(path) + 1;
+        char *context_path = (char *)calloc(len, sizeof(char));
+        strlcpy(context_path, c_path, len);  // for callback
+
+        LOGV("... Object Path = %s", c_path);
+        LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
+
+        bool ret = dbus_func_args_async(env, nat->conn, -1,
+                                        onDiscoverServicesResult,
+                                        context_path,
+                                        eventLoopNat,
+                                        c_path,
+                                        DBUS_DEVICE_IFACE,
+                                        "DiscoverServices",
+                                        DBUS_TYPE_STRING, &c_pattern,
+                                        DBUS_TYPE_INVALID);
+        env->ReleaseStringUTFChars(path, c_path);
+        env->ReleaseStringUTFChars(pattern, c_pattern);
+        return ret ? JNI_TRUE : JNI_FALSE;
+    }
+#endif
+    return JNI_FALSE;
+}
+
+
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
     {"classInitNative", "()V", (void*)classInitNative},
@@ -797,6 +868,8 @@
             (void *)cancelPairingUserInputNative},
     {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
             (void *)setDevicePropertyBooleanNative},
+    {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
+    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
 };
 
 int register_android_server_BluetoothService(JNIEnv *env) {
diff --git a/core/res/res/anim/dialog_enter.xml b/core/res/res/anim/dialog_enter.xml
index 167f4bc..cc409e8 100644
--- a/core/res/res/anim/dialog_enter.xml
+++ b/core/res/res/anim/dialog_enter.xml
@@ -22,7 +22,7 @@
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="0.9" android:toXScale="1.0"
            android:fromYScale="0.9" android:toYScale="1.0"
-           android:pivotX="50%p" android:pivotY="50%p"
+           android:pivotX="50%" android:pivotY="50%"
            android:duration="@android:integer/config_shortAnimTime" />
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="@android:integer/config_shortAnimTime" />
diff --git a/core/res/res/anim/dialog_exit.xml b/core/res/res/anim/dialog_exit.xml
index d412cfb..8bf8082 100644
--- a/core/res/res/anim/dialog_exit.xml
+++ b/core/res/res/anim/dialog_exit.xml
@@ -21,7 +21,7 @@
         android:interpolator="@anim/accelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="0.9"
            android:fromYScale="1.0" android:toYScale="0.9"
-           android:pivotX="50%p" android:pivotY="50%p"
+           android:pivotX="50%" android:pivotY="50%"
            android:duration="@android:integer/config_shortAnimTime" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
             android:duration="@android:integer/config_shortAnimTime"/>
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
index deeb96b..54ae73b 100644
--- a/core/res/res/anim/recent_enter.xml
+++ b/core/res/res/anim/recent_enter.xml
@@ -21,7 +21,7 @@
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="2.0" android:toXScale="1.0"
            android:fromYScale="2.0" android:toYScale="1.0"
-           android:pivotX="50%p" android:pivotY="50%p"
+           android:pivotX="50%" android:pivotY="50%"
            android:duration="@android:integer/config_mediumAnimTime" />
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="@android:integer/config_mediumAnimTime"/>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
index fed7014..32d64a4 100644
--- a/core/res/res/anim/recent_exit.xml
+++ b/core/res/res/anim/recent_exit.xml
@@ -22,7 +22,7 @@
         android:zAdjustment="top">
     <scale android:fromXScale="1.0" android:toXScale="2.0"
            android:fromYScale="1.0" android:toYScale="2.0"
-           android:pivotX="50%p" android:pivotY="50%p"
+           android:pivotX="50%" android:pivotY="50%"
            android:duration="@android:integer/config_mediumAnimTime" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:duration="@android:integer/config_mediumAnimTime"/>
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_off.png b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..e7cb234
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_on.png b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..ce0cfab
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_off.png b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..98cfb11
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_on.png b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..691b99e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/layout/keyguard_screen_rotary_unlock.xml b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
index cf97d04..9f18124 100644
--- a/core/res/res/layout/keyguard_screen_rotary_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
@@ -83,6 +83,7 @@
         android:layout_marginTop="6dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary"
+        android:drawablePadding="4dip"
         />
 
     <TextView
@@ -94,6 +95,7 @@
         android:layout_marginTop="6dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary"
+        android:drawablePadding="4dip"
         />
 
     <TextView
@@ -108,15 +110,15 @@
         android:layout_marginTop="12dip"
         />
 
-    <!-- By having the rotary selector hang below "screen locked" text, we get a layout more
-         robust for different screen sizes.  On wvga, the widget should be flush with the bottom.-->
+    <!-- By having the rotary selector hang from the top, we get a layout more
+         robust for different screen sizes.  On hvga, the widget should be flush with the bottom.-->
     <com.android.internal.widget.RotarySelector
         android:id="@+id/rotary"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_below="@id/screenLocked"
         android:layout_centerHorizontal="true"
-        android:layout_marginTop="24dip"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="286dip"
         />
 
     <!-- emergency call button shown when sim is missing or PUKd -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index eae838a..e7b379a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -102,9 +102,9 @@
         <!-- Text color, typeface, size, and style for "small" inverse text. Defaults to secondary inverse text color. -->
         <attr name="textAppearanceSmallInverse" format="reference" />
 
-        <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
+        <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. -->
         <attr name="textAppearanceSearchResultTitle" format="reference" />
-        <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
+        <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. -->
         <attr name="textAppearanceSearchResultSubtitle" format="reference" />
 
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b710acb..7695503 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -78,6 +78,20 @@
          A value of -1 means no change in orientation by default. -->
     <integer name="config_carDockRotation">-1</integer>
 
+    <!-- Control whether being in the desk dock (and powered) always
+         keeps the screen on.  By default it doesn't.  Set to true to make it. -->
+    <bool name="config_deskDockKeepsScreenOn">false</bool>
+
+    <!-- Control whether being in the car dock (and powered) always
+         keeps the screen on.  By default it does.  Set to false to not keep on. -->
+    <bool name="config_carDockKeepsScreenOn">true</bool>
+
+    <!-- Control whether being in the desk dock should enable accelerometer based screen orientation -->
+    <bool name="config_deskDockEnablesAccelerometer">false</bool>
+
+    <!-- Control whether being in the car dock should enable accelerometer based screen orientation -->
+    <bool name="config_carDockEnablesAccelerometer">false</bool>
+
     <!-- Indicate whether the lid state impacts the accessibility of
          the physical keyboard.  0 means it doesn't, 1 means it is accessible
          when the lid is open, 2 means it is accessible when the lid is
@@ -105,5 +119,7 @@
         <item>20</item>
         <item>30</item>
     </integer-array>
-    
+
+    <bool name="config_use_strict_phone_number_comparation">false</bool>
+
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2bc2a0f..71c6ff5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1164,6 +1164,8 @@
   <public type="attr" name="restoreNeedsApplication" />
   <public type="attr" name="smallIcon" />
   <public type="attr" name="accountPreferences" />
+  <public type="attr" name="textAppearanceSearchResultSubtitle" />
+  <public type="attr" name="textAppearanceSearchResultTitle" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 4a4ad6f..b4d265d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -214,6 +214,7 @@
             Log.v(TAG, "before getduration");
             mOutputDuration = mediaPlayer.getDuration();
             Log.v(TAG, "get video dimension");
+            Thread.sleep(1000);
             mOutputVideoHeight = mediaPlayer.getVideoHeight();
             mOutputVideoWidth = mediaPlayer.getVideoWidth();
             //mOutputVideoHeight = CodecTest.videoHeight(outputFilePath);
@@ -416,7 +417,8 @@
                MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);      
         assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful);
     }
-    
+
+    @Suppress
     @LargeTest
     public void testInvalidFrameRate() throws Exception {       
         boolean isTestInvalidFrameRateSuccessful = false;
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index d4887ba..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
 #include <sys/resource.h>
 
 #include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <utils/Timers.h>
 
@@ -31,144 +31,267 @@
 
 using namespace android;
 
-static void printGLString(const char *name, GLenum s)
-{
-     fprintf(stderr, "printGLString %s, %d\n", name, s);
-#if 0 // causes hangs
-     const char *v = (const char *)glGetString(s);
-     int error = glGetError();
-     fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
-         (unsigned int)v);
-     if ((v < (const char*) 0) || (v > (const char*) 0x10000))
-         fprintf(stderr, "GL %s = %s\n", name, v);
-     else
-         fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
-#endif
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
 }
 
 static const char* eglErrorToString[] = {
-    "EGL_SUCCESS",      // 0x3000 12288
-    "EGL_NOT_INITIALIZED",
-    "EGL_BAD_ACCESS",   // 0x3002 12290
-    "EGL_BAD_ALLOC",
-    "EGL_BAD_ATTRIBUTE",
-    "EGL_BAD_CONFIG",
-    "EGL_BAD_CONTEXT",  // 0x3006 12294
-    "EGL_BAD_CURRENT_SURFACE",
-    "EGL_BAD_DISPLAY",
-    "EGL_BAD_MATCH",
-    "EGL_BAD_NATIVE_PIXMAP",
-    "EGL_BAD_NATIVE_WINDOW",
-    "EGL_BAD_PARAMETER",  // 0x300c 12300
-    "EGL_BAD_SURFACE"
-};
+        "EGL_SUCCESS", // 0x3000 12288
+        "EGL_NOT_INITIALIZED",
+        "EGL_BAD_ACCESS", // 0x3002 12290
+        "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+        "EGL_BAD_CONFIG",
+        "EGL_BAD_CONTEXT", // 0x3006 12294
+        "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+        "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+        "EGL_BAD_SURFACE" };
 
 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
     if (returnVal != EGL_TRUE) {
         fprintf(stderr, "%s() returned %d\n", op, returnVal);
     }
 
-    for(EGLint error = eglGetError();
-		error != EGL_SUCCESS;
-	error = eglGetError()) {
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
         const char* errorString = "unknown";
         if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
             errorString = eglErrorToString[error - EGL_SUCCESS];
         }
-        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
-            errorString, error);
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+                error);
     }
 }
 
-int main(int argc, char** argv)
-{
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+    "void main() {\n"
+    "  gl_Position = vPosition;\n"
+    "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+    "void main() {\n"
+    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+    "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    fprintf(stderr, "Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+            gvPositionHandle);
+
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+        0.5f, -0.5f };
+
+void renderFrame() {
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(gvPositionHandle);
+    checkGlError("glEnableVertexAttribArray");
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    checkGlError("glDrawArrays");
+}
+
+int main(int argc, char** argv) {
     EGLBoolean returnValue;
     EGLConfig configs[2];
     EGLint config_count;
 
-	EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
-    EGLint s_configAttribs[] = {
-	EGL_BUFFER_SIZE,     EGL_DONT_CARE,
-	EGL_RED_SIZE,        5,
-	EGL_GREEN_SIZE,      6,
-	EGL_BLUE_SIZE,       5,
-	EGL_DEPTH_SIZE,      8,
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-	EGL_NONE
-     };
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+            5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
 
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLSurface surface;
-     EGLint w, h;
+    EGLint s_configAttribs2[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
 
-     EGLDisplay dpy;
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
 
-     EGLNativeWindowType window = 0;
-     window = android_createDisplaySurface();
+    EGLDisplay dpy;
 
-     checkEglError("<init>");
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     checkEglError("eglGetDisplay");
-     if (dpy == EGL_NO_DISPLAY) {
-         printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
-         return 0;
-     }
-     returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
-     checkEglError("eglInitialize", returnValue);
-     fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    EGLNativeWindowType window = 0;
+    window = android_createDisplaySurface();
 
-     returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
-     checkEglError("eglGetConfigs", returnValue);
-     fprintf(stderr, "Config count: %d\n", config_count);
-     for(int i = 0; i < config_count; i++) {
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+    checkEglError("eglGetConfigs", returnValue);
+    fprintf(stderr, "Config count: %d\n", config_count);
+    for (int i = 0; i < config_count; i++) {
         fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
-     }
+    }
+
 #if 0
-     EGLConfig config;
-     EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
-     checkEglError("EGLUtils::selectConfigForNativeWindow");
+    EGLConfig config;
+    EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
 #else
-    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+            &config_count);
     checkEglError("eglChooseConfig", chooseConfigResult);
-    if (chooseConfigResult != EGL_TRUE )

-    {

+    if (chooseConfigResult != EGL_TRUE) {
         printf("eglChooseConfig failed\n");
-        return 0;

+        return 0;
     }
 #endif
 
-     surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
-     checkEglError("eglCreateWindowSurface");
-     if (surface == EGL_NO_SURFACE)
-	 {
-         printf("gelCreateWindowSurface failed.\n");
-         return 0;
-	 }
-     EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+    surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 0;
+    }
+    EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
-     context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
-     checkEglError("eglCreateContext");
-	 if (context == EGL_NO_CONTEXT)
-     {
+    context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
         printf("eglCreateContext failed\n");
         return 0;
-	 }
-     eglMakeCurrent(dpy, surface, surface, context);
-     checkEglError("eglMakeCurrent");
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     checkEglError("eglQuerySurface");
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     checkEglError("eglQuerySurface");
-     GLint dim = w<h ? w : h;
+    }
+    eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent");
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
 
-     fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
 
-     printGLString("Version", GL_VERSION);
-     printGLString("Vendor", GL_VENDOR);
-     printGLString("Renderer", GL_RENDERER);
-     printGLString("Extensions", GL_EXTENSIONS);
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
 
-     return 0;
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 0;
+    }
+
+    for (;;) {
+        renderFrame();
+        eglSwapBuffers(dpy, surface);
+    }
+
+    return 0;
 }
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 26fee89..d78d886 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -26,7 +26,6 @@
 import android.content.pm.PackageManager;
 import android.os.BatteryManager;
 import android.os.Binder;
-import android.os.Debug;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -333,16 +332,16 @@
         
         int icon = getIcon(mBatteryLevel);
 
-        intent.putExtra("status", mBatteryStatus);
-        intent.putExtra("health", mBatteryHealth);
-        intent.putExtra("present", mBatteryPresent);
-        intent.putExtra("level", mBatteryLevel);
-        intent.putExtra("scale", BATTERY_SCALE);
-        intent.putExtra("icon-small", icon);
-        intent.putExtra("plugged", mPlugType);
-        intent.putExtra("voltage", mBatteryVoltage);
-        intent.putExtra("temperature", mBatteryTemperature);
-        intent.putExtra("technology", mBatteryTechnology);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
+        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth);
+        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent);
+        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel);
+        intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
+        intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
+        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
+        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
+        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
+        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
 
         if (false) {
             Log.d(TAG, "updateBattery level:" + mBatteryLevel +
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 60195b9..8a4b45d 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,7 +16,9 @@
 
 package com.android.server;
 
+import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
@@ -44,6 +46,43 @@
     private final Context mContext;
 
     private PowerManagerService mPowerManager;
+    
+    // The broadcast receiver which receives the result of the ordered broadcast sent when
+    // the dock state changes. The original ordered broadcast is sent with an initial result
+    // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
+    // to RESULT_CANCELED, then the intent to start a dock app will not be sent.
+    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (getResultCode() != Activity.RESULT_OK) {
+                return;
+            }
+            
+            // Launch a dock activity
+            String category;
+            switch (mDockState) {
+                case Intent.EXTRA_DOCK_STATE_CAR:
+                    category = Intent.CATEGORY_CAR_DOCK;
+                    break;
+                case Intent.EXTRA_DOCK_STATE_DESK:
+                    category = Intent.CATEGORY_DESK_DOCK;
+                    break;
+                default:
+                    category = null;
+                    break;
+            }
+            if (category != null) {
+                intent = new Intent(Intent.ACTION_MAIN);
+                intent.addCategory(category);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(intent);
+                } catch (ActivityNotFoundException e) {
+                    Log.w(TAG, e.getCause());
+                }
+            }
+        }
+    };
 
     public DockObserver(Context context, PowerManagerService pm) {
         mContext = context;
@@ -111,31 +150,15 @@
                 mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
                 Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
                 intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
-                mContext.sendStickyBroadcast(intent);
-
-                // Launch a dock activity
-                String category;
-                switch (mDockState) {
-                    case Intent.EXTRA_DOCK_STATE_CAR:
-                        category = Intent.CATEGORY_CAR_DOCK;
-                        break;
-                    case Intent.EXTRA_DOCK_STATE_DESK:
-                        category = Intent.CATEGORY_DESK_DOCK;
-                        break;
-                    default:
-                        category = null;
-                        break;
-                }
-                if (category != null) {
-                    intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(category);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    try {
-                        mContext.startActivity(intent);
-                    } catch (ActivityNotFoundException e) {
-                        Log.w(TAG, e.getCause());
-                    }
-                }
+                
+                // Send the ordered broadcast; the result receiver will receive after all
+                // broadcasts have been sent. If any broadcast receiver changes the result
+                // code from the initial value of RESULT_OK, then the result receiver will
+                // not launch the corresponding dock application. This gives apps a chance
+                // to override the behavior and stay in their app even when the device is
+                // placed into a dock.
+                mContext.sendStickyOrderedBroadcast(
+                        intent, mResultReceiver, null, Activity.RESULT_OK, null, null);
             }
         }
     };
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 84250bc..656d6ba 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -304,10 +304,7 @@
                     // temporarily set mUserActivityAllowed to true so this will work
                     // even when the keyguard is on.
                     synchronized (mLocks) {
-                        boolean savedActivityAllowed = mUserActivityAllowed;
-                        mUserActivityAllowed = true;
-                        userActivity(SystemClock.uptimeMillis(), false);
-                        mUserActivityAllowed = savedActivityAllowed;
+                        forceUserActivityLocked();
                     }
                 }
             }
@@ -1714,6 +1711,13 @@
         }
     }
 
+    private void forceUserActivityLocked() {
+        boolean savedActivityAllowed = mUserActivityAllowed;
+        mUserActivityAllowed = true;
+        userActivity(SystemClock.uptimeMillis(), false);
+        mUserActivityAllowed = savedActivityAllowed;
+    }
+
     public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
         userActivity(time, noChangeLights, OTHER_EVENT, force);
@@ -2114,7 +2118,12 @@
             Log.d(TAG, "disableProximityLockLocked");
         }
         mSensorManager.unregisterListener(this);
-        mProximitySensorActive = false;
+        synchronized (mLocks) {
+            if (mProximitySensorActive) {
+                mProximitySensorActive = false;
+                forceUserActivityLocked();
+            }
+        }
     }
 
     public void onSensorChanged(SensorEvent event) {
@@ -2135,10 +2144,7 @@
                     Log.d(TAG, "onSensorChanged: proximity inactive, distance: " + distance);
                 }
                 mProximitySensorActive = false;
-                boolean savedActivityAllowed = mUserActivityAllowed;
-                mUserActivityAllowed = true;
-                userActivity(milliseconds, false);
-                mUserActivityAllowed = savedActivityAllowed;
+                forceUserActivityLocked();
             }
         }
     }
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 63bef54..cc1b697 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -295,7 +295,11 @@
         if (mWifiHandler == null) return false;
 
         synchronized (mWifiHandler) {
+            // caller may not have WAKE_LOCK permission - it's not required here
+            long ident = Binder.clearCallingIdentity();
             sWakeLock.acquire();
+            Binder.restoreCallingIdentity(ident);
+
             mLastEnableUid = Binder.getCallingUid();
             // set a flag if the user is enabling Wifi while in airplane mode
             mAirplaneModeOverwridden = (enable && isAirplaneModeOn() && isAirplaneToggleable());
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0cd5949..bbf2a24 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7319,10 +7319,11 @@
                 final Matrix tmpMatrix = mTmpMatrix;
 
                 // Compute the desired transformation.
-                tmpMatrix.setTranslate(frame.left, frame.top);
+                tmpMatrix.setTranslate(0, 0);
                 if (selfTransformation) {
                     tmpMatrix.postConcat(mTransformation.getMatrix());
                 }
+                tmpMatrix.postTranslate(frame.left, frame.top);
                 if (attachedTransformation != null) {
                     tmpMatrix.postConcat(attachedTransformation.getMatrix());
                 }
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 2672c6d..2d8afb7 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -111,6 +111,11 @@
         return c == PAUSE || c == WAIT;
     }
 
+    /** Returns true if ch is not dialable or alpha char */
+    private static boolean isSeparator(char ch) {
+        return !isDialable(ch) && !(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'));
+    }
+
     /** Extracts the phone number from an Intent.
      *
      * @param intent the intent to get the number of
@@ -293,6 +298,21 @@
     }
 
     /**
+     * Compare phone numbers a and b, return true if they're identical enough for caller ID purposes.
+     */
+    public static boolean compare(String a, String b) {
+        // We've used loose comparation at least Eclair, which may change in the future.
+        return compare(a, b, false);
+    }
+
+    /**
+     * @hide only for testing.
+     */
+    public static boolean compare(String a, String b, boolean useStrictComparation) {
+        return (useStrictComparation ? compareStrictly(a, b) : compareLoosely(a, b));
+    }
+
+    /**
      * Compare phone numbers a and b, return true if they're identical
      * enough for caller ID purposes.
      *
@@ -301,10 +321,13 @@
      * - handles common trunk prefixes and international prefixes
      *   (basically, everything except the Russian trunk prefix)
      *
-     * Tolerates nulls
+     * Note that this method does not return false even when the two phone numbers
+     * are not exactly same; rather; we can call this method "similar()", not "equals()".
+     *
+     * @hide
      */
     public static boolean
-    compare(String a, String b) {
+    compareLoosely(String a, String b) {
         int ia, ib;
         int matched;
 
@@ -391,6 +414,160 @@
     }
 
     /**
+     * @hide
+     */
+    public static boolean
+    compareStrictly(String a, String b) {
+        return compareStrictly(a, b, true);
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean
+    compareStrictly(String a, String b, boolean acceptInvalidCCCPrefix) {
+        if (a == null || b == null) {
+            return a == b;
+        } else if (a.length() == 0 && b.length() == 0) {
+            return false;
+        }
+
+        int forwardIndexA = 0;
+        int forwardIndexB = 0;
+
+        CountryCallingCodeAndNewIndex cccA =
+            tryGetCountryCallingCodeAndNewIndex(a, acceptInvalidCCCPrefix);
+        CountryCallingCodeAndNewIndex cccB =
+            tryGetCountryCallingCodeAndNewIndex(b, acceptInvalidCCCPrefix);
+        boolean bothHasCountryCallingCode = false;
+        boolean okToIgnorePrefix = true;
+        boolean trunkPrefixIsOmittedA = false;
+        boolean trunkPrefixIsOmittedB = false;
+        if (cccA != null && cccB != null) {
+            if (cccA.countryCallingCode != cccB.countryCallingCode) {
+                // Different Country Calling Code. Must be different phone number.
+                return false;
+            }
+            // When both have ccc, do not ignore trunk prefix. Without this,
+            // "+81123123" becomes same as "+810123123" (+81 == Japan)
+            okToIgnorePrefix = false;
+            bothHasCountryCallingCode = true;
+            forwardIndexA = cccA.newIndex;
+            forwardIndexB = cccB.newIndex;
+        } else if (cccA == null && cccB == null) {
+            // When both do not have ccc, do not ignore trunk prefix. Without this,
+            // "123123" becomes same as "0123123"
+            okToIgnorePrefix = false;
+        } else {
+            if (cccA != null) {
+                forwardIndexA = cccA.newIndex;
+            } else {
+                int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+                if (tmp >= 0) {
+                    forwardIndexA = tmp;
+                    trunkPrefixIsOmittedA = true;
+                }
+            }
+            if (cccB != null) {
+                forwardIndexB = cccB.newIndex;
+            } else {
+                int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+                if (tmp >= 0) {
+                    forwardIndexB = tmp;
+                    trunkPrefixIsOmittedB = true;
+                }
+            }
+        }
+
+        int backwardIndexA = a.length() - 1;
+        int backwardIndexB = b.length() - 1;
+        while (backwardIndexA >= forwardIndexA && backwardIndexB >= forwardIndexB) {
+            boolean skip_compare = false;
+            final char chA = a.charAt(backwardIndexA);
+            final char chB = b.charAt(backwardIndexB);
+            if (isSeparator(chA)) {
+                backwardIndexA--;
+                skip_compare = true;
+            }
+            if (isSeparator(chB)) {
+                backwardIndexB--;
+                skip_compare = true;
+            }
+
+            if (!skip_compare) {
+                if (chA != chB) {
+                    return false;
+                }
+                backwardIndexA--;
+                backwardIndexB--;
+            }
+        }
+
+        if (okToIgnorePrefix) {
+            if ((trunkPrefixIsOmittedA && forwardIndexA <= backwardIndexA) ||
+                !checkPrefixIsIgnorable(a, forwardIndexA, backwardIndexA)) {
+                if (acceptInvalidCCCPrefix) {
+                    // Maybe the code handling the special case for Thailand makes the
+                    // result garbled, so disable the code and try again.
+                    // e.g. "16610001234" must equal to "6610001234", but with
+                    //      Thailand-case handling code, they become equal to each other.
+                    //
+                    // Note: we select simplicity rather than adding some complicated
+                    //       logic here for performance(like "checking whether remaining
+                    //       numbers are just 66 or not"), assuming inputs are small
+                    //       enough.
+                    return compare(a, b, false);
+                } else {
+                    return false;
+                }
+            }
+            if ((trunkPrefixIsOmittedB && forwardIndexB <= backwardIndexB) ||
+                !checkPrefixIsIgnorable(b, forwardIndexA, backwardIndexB)) {
+                if (acceptInvalidCCCPrefix) {
+                    return compare(a, b, false);
+                } else {
+                    return false;
+                }
+            }
+        } else {
+            // In the US, 1-650-555-1234 must be equal to 650-555-1234,
+            // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
+            // This request exists just in US (with 1 trunk (NDD) prefix).
+            // In addition, "011 11 7005554141" must not equal to "+17005554141",
+            // while "011 1 7005554141" must equal to "+17005554141"
+            //
+            // In this comparison, we ignore the prefix '1' just once, when
+            // - at least either does not have CCC, or
+            // - the remaining non-separator number is 1
+            boolean maybeNamp = !bothHasCountryCallingCode;
+            while (backwardIndexA >= forwardIndexA) {
+                final char chA = a.charAt(backwardIndexA);
+                if (isDialable(chA)) {
+                    if (maybeNamp && tryGetISODigit(chA) == 1) {
+                        maybeNamp = false;
+                    } else {
+                        return false;
+                    }
+                }
+                backwardIndexA--;
+            }
+            while (backwardIndexB >= forwardIndexB) {
+                final char chB = b.charAt(backwardIndexB);
+                if (isDialable(chB)) {
+                    if (maybeNamp && tryGetISODigit(chB) == 1) {
+                        maybeNamp = false;
+                    } else {
+                        return false;
+                    }
+                }
+                backwardIndexB--;
+            }
+        }
+
+        return true;
+    }
+
+    /**
      * Returns the rightmost MIN_MATCH (5) characters in the network portion
      * in *reversed* order
      *
@@ -475,54 +652,6 @@
     }
 
     /**
-     * Phone numbers are stored in "lookup" form in the database
-     * as reversed strings to allow for caller ID lookup
-     *
-     * This method takes a phone number and makes a valid SQL "LIKE"
-     * string that will match the lookup form
-     *
-     */
-    /** all of a up to len must be an international prefix or
-     *  separators/non-dialing digits
-     */
-    private static boolean
-    matchIntlPrefix(String a, int len) {
-        /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
-        /*        0       1                           2 3 45               */
-
-        int state = 0;
-        for (int i = 0 ; i < len ; i++) {
-            char c = a.charAt(i);
-
-            switch (state) {
-                case 0:
-                    if      (c == '+') state = 1;
-                    else if (c == '0') state = 2;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 2:
-                    if      (c == '0') state = 3;
-                    else if (c == '1') state = 4;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 4:
-                    if      (c == '1') state = 5;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                default:
-                    if (isNonSeparator(c)) return false;
-                break;
-
-            }
-        }
-
-        return state == 1 || state == 3 || state == 5;
-    }
-
-    /**
      *  3GPP TS 24.008 10.5.4.7
      *  Called Party BCD Number
      *
@@ -835,76 +964,6 @@
         return result;
     }
 
-    /** all of 'a' up to len must match non-US trunk prefix ('0') */
-    private static boolean
-    matchTrunkPrefix(String a, int len) {
-        boolean found;
-
-        found = false;
-
-        for (int i = 0 ; i < len ; i++) {
-            char c = a.charAt(i);
-
-            if (c == '0' && !found) {
-                found = true;
-            } else if (isNonSeparator(c)) {
-                return false;
-            }
-        }
-
-        return found;
-    }
-
-    /** all of 'a' up to len must be a (+|00|011)country code)
-     *  We're fast and loose with the country code. Any \d{1,3} matches */
-    private static boolean
-    matchIntlPrefixAndCC(String a, int len) {
-        /*  [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
-        /*      0          1 2 3 45  6 7  8                 */
-
-        int state = 0;
-        for (int i = 0 ; i < len ; i++ ) {
-            char c = a.charAt(i);
-
-            switch (state) {
-                case 0:
-                    if      (c == '+') state = 1;
-                    else if (c == '0') state = 2;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 2:
-                    if      (c == '0') state = 3;
-                    else if (c == '1') state = 4;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 4:
-                    if      (c == '1') state = 5;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 1:
-                case 3:
-                case 5:
-                    if      (isISODigit(c)) state = 6;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 6:
-                case 7:
-                    if      (isISODigit(c)) state++;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                default:
-                    if (isNonSeparator(c)) return false;
-            }
-        }
-
-        return state == 6 || state == 7 || state == 8;
-    }
-
     //================ Number formatting =========================
 
     /** The current locale is unknown, look for a country code or don't format */
@@ -1553,4 +1612,317 @@
         }
         return retStr;
     }
+
+    //===== Begining of utility methods used in compareLoosely() =====
+
+    /**
+     * Phone numbers are stored in "lookup" form in the database
+     * as reversed strings to allow for caller ID lookup
+     *
+     * This method takes a phone number and makes a valid SQL "LIKE"
+     * string that will match the lookup form
+     *
+     */
+    /** all of a up to len must be an international prefix or
+     *  separators/non-dialing digits
+     */
+    private static boolean
+    matchIntlPrefix(String a, int len) {
+        /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
+        /*        0       1                           2 3 45               */
+
+        int state = 0;
+        for (int i = 0 ; i < len ; i++) {
+            char c = a.charAt(i);
+
+            switch (state) {
+                case 0:
+                    if      (c == '+') state = 1;
+                    else if (c == '0') state = 2;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 2:
+                    if      (c == '0') state = 3;
+                    else if (c == '1') state = 4;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 4:
+                    if      (c == '1') state = 5;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                default:
+                    if (isNonSeparator(c)) return false;
+                break;
+
+            }
+        }
+
+        return state == 1 || state == 3 || state == 5;
+    }
+
+    /** all of 'a' up to len must be a (+|00|011)country code)
+     *  We're fast and loose with the country code. Any \d{1,3} matches */
+    private static boolean
+    matchIntlPrefixAndCC(String a, int len) {
+        /*  [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
+        /*      0          1 2 3 45  6 7  8                 */
+
+        int state = 0;
+        for (int i = 0 ; i < len ; i++ ) {
+            char c = a.charAt(i);
+
+            switch (state) {
+                case 0:
+                    if      (c == '+') state = 1;
+                    else if (c == '0') state = 2;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 2:
+                    if      (c == '0') state = 3;
+                    else if (c == '1') state = 4;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 4:
+                    if      (c == '1') state = 5;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 1:
+                case 3:
+                case 5:
+                    if      (isISODigit(c)) state = 6;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 6:
+                case 7:
+                    if      (isISODigit(c)) state++;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                default:
+                    if (isNonSeparator(c)) return false;
+            }
+        }
+
+        return state == 6 || state == 7 || state == 8;
+    }
+
+    /** all of 'a' up to len must match non-US trunk prefix ('0') */
+    private static boolean
+    matchTrunkPrefix(String a, int len) {
+        boolean found;
+
+        found = false;
+
+        for (int i = 0 ; i < len ; i++) {
+            char c = a.charAt(i);
+
+            if (c == '0' && !found) {
+                found = true;
+            } else if (isNonSeparator(c)) {
+                return false;
+            }
+        }
+
+        return found;
+    }
+
+    //===== End of utility methods used only in compareLoosely() =====
+
+    //===== Beggining of utility methods used only in compareStrictly() ====
+
+    /*
+     * If true, the number is country calling code.
+     */
+    private static final boolean COUNTLY_CALLING_CALL[] = {
+        true, true, false, false, false, false, false, true, false, false,
+        false, false, false, false, false, false, false, false, false, false,
+        true, false, false, false, false, false, false, true, true, false,
+        true, true, true, true, true, false, true, false, false, true,
+        true, false, false, true, true, true, true, true, true, true,
+        false, true, true, true, true, true, true, true, true, false,
+        true, true, true, true, true, true, true, false, false, false,
+        false, false, false, false, false, false, false, false, false, false,
+        false, true, true, true, true, false, true, false, false, true,
+        true, true, true, true, true, true, false, false, true, false,
+    };
+    private static final int CCC_LENGTH = COUNTLY_CALLING_CALL.length;
+
+    /**
+     * @return true when input is valid Country Calling Code.
+     */
+    private static boolean isCountryCallingCode(int countryCallingCodeCandidate) {
+        return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
+                COUNTLY_CALLING_CALL[countryCallingCodeCandidate];
+    }
+
+    /**
+     * Returns interger corresponding to the input if input "ch" is
+     * ISO-LATIN characters 0-9.
+     * Returns -1 otherwise
+     */
+    private static int tryGetISODigit(char ch) {
+        if ('0' <= ch && ch <= '9') {
+            return ch - '0';
+        } else {
+            return -1;
+        }
+    }
+
+    private static class CountryCallingCodeAndNewIndex {
+        public final int countryCallingCode;
+        public final int newIndex;
+        public CountryCallingCodeAndNewIndex(int countryCode, int newIndex) {
+            this.countryCallingCode = countryCode;
+            this.newIndex = newIndex;
+        }
+    }
+
+    /*
+     * Note that this function does not strictly care the country calling code with
+     * 3 length (like Morocco: +212), assuming it is enough to use the first two
+     * digit to compare two phone numbers.
+     */
+    private static CountryCallingCodeAndNewIndex tryGetCountryCallingCodeAndNewIndex(
+        String str, boolean acceptThailandCase) {
+        // Rough regexp:
+        //  ^[^0-9*#+]*((\+|0(0|11)\d\d?|166) [^0-9*#+] $
+        //         0        1 2 3 45  6 7  89
+        //
+        // In all the states, this function ignores separator characters.
+        // "166" is the special case for the call from Thailand to the US. Uguu!
+        int state = 0;
+        int ccc = 0;
+        final int length = str.length();
+        for (int i = 0 ; i < length ; i++ ) {
+            char ch = str.charAt(i);
+            switch (state) {
+                case 0:
+                    if      (ch == '+') state = 1;
+                    else if (ch == '0') state = 2;
+                    else if (ch == '1') {
+                        if (acceptThailandCase) {
+                            state = 8;
+                        } else {
+                            return null;
+                        }
+                    } else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 2:
+                    if      (ch == '0') state = 3;
+                    else if (ch == '1') state = 4;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 4:
+                    if      (ch == '1') state = 5;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 1:
+                case 3:
+                case 5:
+                case 6:
+                case 7:
+                    {
+                        int ret = tryGetISODigit(ch);
+                        if (ret > 0) {
+                            ccc = ccc * 10 + ret;
+                            if (ccc >= 100 || isCountryCallingCode(ccc)) {
+                                return new CountryCallingCodeAndNewIndex(ccc, i + 1);
+                            }
+                            if (state == 1 || state == 3 || state == 5) {
+                                state = 6;
+                            } else {
+                                state++;
+                            }
+                        } else if (isDialable(ch)) {
+                            return null;
+                        }
+                    }
+                    break;
+                case 8:
+                    if (ch == '6') state = 9;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                    break;
+                case 9:
+                    if (ch == '6') {
+                        return new CountryCallingCodeAndNewIndex(66, i + 1);
+                    } else {
+                        return null;
+                    }
+                default:
+                    return null;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Currently this function simply ignore the first digit assuming it is
+     * trunk prefix. Actually trunk prefix is different in each country.
+     *
+     * e.g.
+     * "+79161234567" equals "89161234567" (Russian trunk digit is 8)
+     * "+33123456789" equals "0123456789" (French trunk digit is 0)
+     *
+     */
+    private static int tryGetTrunkPrefixOmittedIndex(String str, int currentIndex) {
+        int length = str.length();
+        for (int i = currentIndex ; i < length ; i++) {
+            final char ch = str.charAt(i);
+            if (tryGetISODigit(ch) >= 0) {
+                return i + 1;
+            } else if (isDialable(ch)) {
+                return -1;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
+     * that "str" has only one digit and separater characters. The one digit is
+     * assumed to be trunk prefix.
+     */
+    private static boolean checkPrefixIsIgnorable(final String str,
+            int forwardIndex, int backwardIndex) {
+        boolean trunk_prefix_was_read = false;
+        while (backwardIndex >= forwardIndex) {
+            if (tryGetISODigit(str.charAt(backwardIndex)) >= 0) {
+                if (trunk_prefix_was_read) {
+                    // More than one digit appeared, meaning that "a" and "b"
+                    // is different.
+                    return false;
+                } else {
+                    // Ignore just one digit, assuming it is trunk prefix.
+                    trunk_prefix_was_read = true;
+                }
+            } else if (isDialable(str.charAt(backwardIndex))) {
+                // Trunk prefix is a digit, not "*", "#"...
+                return false;
+            }
+            backwardIndex--;
+        }
+
+        return true;
+    }
+
+    //==== End of utility methods used only in compareStrictly() =====
 }
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index e6fd0a0..a48900a 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -15,6 +15,7 @@
  */
 
 package com.android.internal.telephony;
+import android.util.Log;
 
 /**
  * {@hide}
@@ -27,6 +28,7 @@
     public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
     public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
 
+    private static String LOG_TAG = "TelephonyConnection";
 
     public enum DisconnectCause {
         NOT_DISCONNECTED,               /* has not yet disconnected */
@@ -269,4 +271,25 @@
      */
     public abstract int getNumberPresentation();
 
+    /**
+     * Build a human representation of a connection instance, suitable for debugging.
+     * Don't log personal stuff unless in debug mode.
+     * @return a string representing the internal state of this connection.
+     */
+    public String toString() {
+        StringBuilder str = new StringBuilder(128);
+
+        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+            str.append("addr: " + getAddress())
+                    .append(" pres.: " + getNumberPresentation())
+                    .append(" dial: " + getOrigDialString())
+                    .append(" postdial: " + getRemainingPostDialString())
+                    .append(" cnap name: " + getCnapName())
+                    .append("(" + getCnapNamePresentation() + ")");
+        }
+        str.append(" incoming: " + isIncoming())
+                .append(" state: " + getState())
+                .append(" post dial state: " + getPostDialState());
+        return str.toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 3f0213b..3c2f2ed 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -383,7 +383,7 @@
          * 2. [x@y][ ]/[body]
          */
          String[] parts = messageBody.split("( /)|( )", 2);
-         if (parts.length < 1) return;
+         if (parts.length < 2) return;
          emailFrom = parts[0];
          emailBody = parts[1];
          isEmail = true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 2f4d238..bc04e02 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -221,10 +221,6 @@
         return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
     }
 
-    public String
-    toString() {
-        return (isIncoming ? "incoming" : "outgoing");
-    }
 
     public String getOrigDialString(){
         return dialString;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2091fb6..445be39 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -180,11 +180,6 @@
         return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
     }
 
-    public String
-    toString() {
-        return (isIncoming ? "incoming" : "outgoing");
-    }
-
     public String getAddress() {
         return address;
     }
diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java
index 5368526..57b22f8 100644
--- a/test-runner/android/test/mock/MockContext.java
+++ b/test-runner/android/test/mock/MockContext.java
@@ -264,6 +264,13 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         throw new UnsupportedOperationException();
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 4e7e925..1e9f573 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -1099,6 +1099,13 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        // TODO Auto-generated method stub
+    }
+    
+    @Override
     public void setTheme(int arg0) {
         // TODO Auto-generated method stub