Merge change 7854 into donut

* changes:
  Issue #1884058 (Need to only record frequency and duration for selected Google apps)
diff --git a/api/current.xml b/api/current.xml
index a088664..a1dc293 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23732,6 +23732,50 @@
  visibility="public"
 >
 </field>
+<field name="EXTRA_DATA_KEY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;intent_extra_data_key&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="INTENT_ACTION_SEARCHABLES_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.search.action.SEARCHABLES_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="INTENT_ACTION_SEARCH_SETTINGS_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.search.action.SETTINGS_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="INTENT_ACTION_WEB_SEARCH_SETTINGS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.search.action.WEB_SEARCH_SETTINGS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="MENU_KEY"
  type="char"
  transient="false"
@@ -23765,6 +23809,17 @@
  visibility="public"
 >
 </field>
+<field name="SHORTCUT_MIME_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;vnd.android.cursor.item/vnd.android.search.suggest&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_COLUMN_FORMAT"
  type="java.lang.String"
  transient="false"
@@ -23831,6 +23886,17 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_COLUMN_INTENT_EXTRA_DATA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;suggest_intent_extra_data&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_COLUMN_QUERY"
  type="java.lang.String"
  transient="false"
@@ -23842,6 +23908,28 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_COLUMN_SHORTCUT_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;suggest_shortcut_id&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;suggest_spinner_while_refreshing&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_COLUMN_TEXT_1"
  type="java.lang.String"
  transient="false"
@@ -23875,6 +23963,17 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_NEVER_MAKE_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;_-1&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_URI_PATH_QUERY"
  type="java.lang.String"
  transient="false"
@@ -23886,6 +23985,17 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_URI_PATH_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;search_suggest_shortcut&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="USER_QUERY"
  type="java.lang.String"
  transient="false"
@@ -48942,6 +49052,17 @@
  visibility="public"
 >
 </method>
+<method name="getDensityScale"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getHeight"
  return="int"
  abstract="false"
@@ -49015,6 +49136,58 @@
  visibility="public"
 >
 </method>
+<method name="getScaledHeight"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="canvas" type="android.graphics.Canvas">
+</parameter>
+</method>
+<method name="getScaledHeight"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metrics" type="android.util.DisplayMetrics">
+</parameter>
+</method>
+<method name="getScaledWidth"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="canvas" type="android.graphics.Canvas">
+</parameter>
+</method>
+<method name="getScaledWidth"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metrics" type="android.util.DisplayMetrics">
+</parameter>
+</method>
 <method name="getWidth"
  return="int"
  abstract="false"
@@ -49037,6 +49210,17 @@
  visibility="public"
 >
 </method>
+<method name="isAutoScalingEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isMutable"
  return="boolean"
  abstract="false"
@@ -49081,6 +49265,32 @@
  visibility="public"
 >
 </method>
+<method name="setAutoScalingEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoScalingEnabled" type="boolean">
+</parameter>
+</method>
+<method name="setDensityScale"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="densityScale" type="float">
+</parameter>
+</method>
 <method name="setPixel"
  return="void"
  abstract="false"
@@ -49148,6 +49358,17 @@
  visibility="public"
 >
 </field>
+<field name="DENSITY_SCALE_UNKNOWN"
+ type="float"
+ transient="false"
+ volatile="false"
+ value="-1.0f"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Bitmap.CompressFormat"
  extends="java.lang.Enum"
@@ -49367,6 +49588,27 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="res" type="android.content.res.Resources">
+</parameter>
+<parameter name="value" type="android.util.TypedValue">
+</parameter>
+<parameter name="is" type="java.io.InputStream">
+</parameter>
+<parameter name="pad" type="android.graphics.Rect">
+</parameter>
+<parameter name="opts" type="android.graphics.BitmapFactory.Options">
+</parameter>
+</method>
+<method name="decodeStream"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
 <parameter name="is" type="java.io.InputStream">
 </parameter>
 <parameter name="outPadding" type="android.graphics.Rect">
@@ -49415,6 +49657,16 @@
  visibility="public"
 >
 </method>
+<field name="inDensity"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="inDither"
  type="boolean"
  transient="false"
@@ -49475,6 +49727,16 @@
  visibility="public"
 >
 </field>
+<field name="inScaled"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="inTempStorage"
  type="byte[]"
  transient="false"
@@ -50729,6 +50991,17 @@
  visibility="public"
 >
 </method>
+<method name="getDensityScale"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getDrawFilter"
  return="android.graphics.DrawFilter"
  abstract="false"
@@ -51075,6 +51348,19 @@
 <parameter name="bitmap" type="android.graphics.Bitmap">
 </parameter>
 </method>
+<method name="setDensityScale"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="densityScale" type="float">
+</parameter>
+</method>
 <method name="setDrawFilter"
  return="void"
  abstract="false"
@@ -132969,6 +133255,50 @@
  visibility="public"
 >
 </method>
+<field name="DENSITY_DEFAULT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="160"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DENSITY_HIGH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="240"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DENSITY_LOW"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="120"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DENSITY_MEDIUM"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="160"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="density"
  type="float"
  transient="false"
@@ -135018,6 +135348,28 @@
  visibility="public"
 >
 </field>
+<field name="DENSITY_DEFAULT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DENSITY_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65535"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_ATTRIBUTE"
  type="int"
  transient="false"
@@ -135246,6 +135598,16 @@
  visibility="public"
 >
 </field>
+<field name="density"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="resourceId"
  type="int"
  transient="false"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f2814f2..76b47f1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -32,7 +32,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageParser.Component;
 import android.content.res.AssetManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 84a6085..bd72544 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -37,4 +37,5 @@
             ISearchManagerCallback searchManagerCallback,
             int ident);
     void stopSearch();
+    boolean isVisible();
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 906361c..27c6376 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -354,7 +354,6 @@
             }
             show();
         }
-
         updateUI();
         
         return true;
@@ -490,6 +489,7 @@
      */
     private void updateUI() {
         if (mSearchable != null) {
+            mDecor.setVisibility(View.VISIBLE);
             updateSearchAutoComplete();
             updateSearchButton();
             updateSearchAppIcon();
@@ -994,7 +994,7 @@
     };
 
     @Override
-    public void dismiss() {
+    public void hide() {
         if (!isShowing()) return;
 
         // We made sure the IME was displayed, so also make sure it is closed
@@ -1005,10 +1005,10 @@
             imm.hideSoftInputFromWindow(
                     getWindow().getDecorView().getWindowToken(), 0);
         }
-        
-        super.dismiss();
+
+        super.hide();
     }
-    
+
     /**
      * React to the user typing while in the suggestions list. First, check for action
      * keys. If not handled, try refocusing regular characters into the EditText. 
@@ -1234,8 +1234,8 @@
     }
 
     /**
-     * Launches an intent and dismisses the search dialog (unless the intent
-     * is one of the special intents that modifies the state of the search dialog).
+     * Launches an intent, including any special intent handling.  Doesn't dismiss the dialog
+     * since that will be handled in {@link SearchDialogWrapper#performActivityResuming}
      */
     private void launchIntent(Intent intent) {
         if (intent == null) {
@@ -1244,8 +1244,15 @@
         if (handleSpecialIntent(intent)){
             return;
         }
-        dismiss();
+        Log.d(LOG_TAG, "launching " + intent);
         getContext().startActivity(intent);
+
+        // in global search mode, SearchDialogWrapper#performActivityResuming will handle hiding
+        // the dialog when the next activity starts, but for in-app search, we still need to
+        // dismiss the dialog.
+        if (!mGlobalSearchMode) {
+            dismiss();
+        }
     }
     
     /**
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index b795a54..c98d966 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1188,8 +1188,6 @@
     /**
      * Intent extra data key: This key will be used for the extra populated by the
      * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
-     *
-     * {@hide}
      */
     public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
 
@@ -1269,16 +1267,12 @@
      * result indicates the shortcut refers to a no longer valid sugggestion.
      *
      * @see #SUGGEST_COLUMN_SHORTCUT_ID
-     * 
-     * @hide pending API council approval
      */
     public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut";
     
     /**
      * MIME type for shortcut validation.  You'll use this in your suggestions content provider
      * in the getType() function.
-     *
-     * @hide pending API council approval
      */
     public final static String SHORTCUT_MIME_TYPE = 
             "vnd.android.cursor.item/vnd.android.search.suggest";
@@ -1389,9 +1383,7 @@
      * this element exists at the given row, this is the data that will be used when
      * forming the suggestion's intent. If not provided, the Intent's extra data field will be null.
      * This column allows suggestions to provide additional arbitrary data which will be included as
-     * an extra under the key EXTRA_DATA_KEY.
-     *
-     * @hide Pending API council approval.
+     * an extra under the key {@link #EXTRA_DATA_KEY}.
      */
     public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
     /**
@@ -1425,8 +1417,6 @@
      * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
      * Otherwise, the shortcut id will be used to check back for validation via
      * {@link #SUGGEST_URI_PATH_SHORTCUT}.
-     *
-     * @hide Pending API council approval.
      */
     public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
 
@@ -1443,8 +1433,6 @@
      * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
      * that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion
      * is being refreshed.
-     * 
-     * @hide Pending API council approval.
      */
     public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING =
             "suggest_spinner_while_refreshing";
@@ -1452,8 +1440,6 @@
     /**
      * Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
      * should not be stored as a shortcut in global search.
-     *
-     * @hide Pending API council approval.
      */
     public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
 
@@ -1500,8 +1486,6 @@
      * Intent action for starting a web search provider's settings activity.
      * Web search providers should handle this intent if they have provider-specific
      * settings to implement.
-     * 
-     * @hide Pending API council approval.
      */
     public final static String INTENT_ACTION_WEB_SEARCH_SETTINGS
             = "android.search.action.WEB_SEARCH_SETTINGS";
@@ -1510,11 +1494,17 @@
      * Intent action broadcasted to inform that the searchables list or default have changed.
      * Components should handle this intent if they cache any searchable data and wish to stay
      * up to date on changes.
-     *
-     * @hide Pending API council approval.
      */
     public final static String INTENT_ACTION_SEARCHABLES_CHANGED
             = "android.search.action.SEARCHABLES_CHANGED";
+    
+    /**
+     * Intent action broadcasted to inform that the search settings have changed in some way.
+     * Either searchables have been enabled or disabled, or a different web search provider
+     * has been chosen.
+     */
+    public final static String INTENT_ACTION_SEARCH_SETTINGS_CHANGED
+            = "android.search.action.SETTINGS_CHANGED";
 
     /**
      * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
@@ -1534,7 +1524,6 @@
     private int mIdent;
     
     // package private since they are used by the inner class SearchManagerCallback
-    /* package */ boolean mIsShowing = false;
     /* package */ final Handler mHandler;
     /* package */ OnDismissListener mDismissListener = null;
     /* package */ OnCancelListener mCancelListener = null;
@@ -1600,12 +1589,9 @@
                             ComponentName launchActivity,
                             Bundle appSearchData,
                             boolean globalSearch) {
-        if (DBG) debug("startSearch(), mIsShowing=" + mIsShowing);
-        if (mIsShowing) return;
         if (mIdent == 0) throw new IllegalArgumentException(
                 "Called from outside of an Activity context");
         try {
-            mIsShowing = true;
             // activate the search manager and start it up!
             mService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
                     globalSearch, mSearchManagerCallback, mIdent);
@@ -1626,15 +1612,10 @@
      * @see #startSearch
      */
     public void stopSearch() {
-        if (DBG) debug("stopSearch(), mIsShowing=" + mIsShowing);
-        if (!mIsShowing) return;
+        if (DBG) debug("stopSearch()");
         try {
             mService.stopSearch();
-            // onDismiss will also clear this, but we do it here too since onDismiss() is
-            // called asynchronously.
-            mIsShowing = false;
         } catch (RemoteException ex) {
-            Log.e(TAG, "stopSearch() failed: " + ex);
         }
     }
 
@@ -1648,8 +1629,13 @@
      * @hide
      */
     public boolean isVisible() {
-        if (DBG) debug("isVisible(), mIsShowing=" + mIsShowing);
-        return mIsShowing;
+        if (DBG) debug("isVisible()");
+        try {
+            return mService.isVisible();
+        } catch (RemoteException e) {
+            Log.e(TAG, "isVisible() failed: " + e);
+            return false;
+        }
     }
 
     /**
@@ -1701,7 +1687,6 @@
         private final Runnable mFireOnDismiss = new Runnable() {
             public void run() {
                 if (DBG) debug("mFireOnDismiss");
-                mIsShowing = false;
                 if (mDismissListener != null) {
                     mDismissListener.onDismiss();
                 }
@@ -1711,7 +1696,6 @@
         private final Runnable mFireOnCancel = new Runnable() {
             public void run() {
                 if (DBG) debug("mFireOnCancel");
-                // doesn't need to clear mIsShowing since onDismiss() always gets called too
                 if (mCancelListener != null) {
                     mCancelListener.onCancel();
                 }
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 26712a1..f1bbede 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -64,11 +64,9 @@
         }
         else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
             Bundle extras = intent.getExtras();
-            if (extras != null) {
-                int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
-                if (appWidgetIds != null && appWidgetIds.length > 0) {
-                    this.onDeleted(context, appWidgetIds);
-                }
+            if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
+                final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
+                this.onDeleted(context, new int[] { appWidgetId });
             }
         }
         else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
index 9c760d9..9f609a3 100644
--- a/core/java/android/content/AbstractTableMerger.java
+++ b/core/java/android/content/AbstractTableMerger.java
@@ -369,30 +369,33 @@
                 // An existing server item has changed
                 // If serverSyncVersion is null, there is no edit URL;
                 // server won't let this change be written.
-                // Just hold onto it, I guess, in case the server permissions
-                // change later.
-                if (serverSyncVersion != null) {
-                    boolean recordChanged = (localSyncVersion == null) ||
-                            !serverSyncVersion.equals(localSyncVersion);
-                    if (recordChanged) {
-                        if (localSyncDirty) {
-                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                                Log.v(TAG, "remote record " + serverSyncId
-                                        + " conflicts with local _sync_id " + localSyncID
-                                        + ", local _id " + localRowId);
-                            }
-                            conflict = true;
-                        } else {
-                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                                Log.v(TAG,
-                                        "remote record " +
-                                                serverSyncId +
-                                                " updates local _sync_id " +
-                                                localSyncID + ", local _id " +
-                                                localRowId);
-                            }
-                            update = true;
+                boolean recordChanged = (localSyncVersion == null) ||
+                        (serverSyncVersion == null) ||
+                        !serverSyncVersion.equals(localSyncVersion);
+                if (recordChanged) {
+                    if (localSyncDirty) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "remote record " + serverSyncId
+                                    + " conflicts with local _sync_id " + localSyncID
+                                    + ", local _id " + localRowId);
                         }
+                        conflict = true;
+                    } else {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG,
+                                    "remote record " +
+                                            serverSyncId +
+                                            " updates local _sync_id " +
+                                            localSyncID + ", local _id " +
+                                            localRowId);
+                        }
+                        update = true;
+                    }
+                } else {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG,
+                                "Skipping update: localSyncVersion: " + localSyncVersion +
+                                ", serverSyncVersion: " + serverSyncVersion);
                     }
                 }
             } else {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 903f482..cebb696 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -979,12 +979,12 @@
         /**
          * TODO: enable this before code freeze. b/1967935
          * *
-         */
         if ((densities == null || densities.length == 0)
                 && (pkg.applicationInfo.targetSdkVersion
                         >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
             pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
         }
+         */
 
         return pkg;
     }
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 08e3a40..6e34cc8 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -85,6 +85,11 @@
     private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;
 
     /**
+     * The effective screen density we have selected for this application.
+     */
+    public final int applicationDensity;
+    
+    /**
      * Application's scale.
      */
     public final float applicationScale;
@@ -107,30 +112,36 @@
         }
         
         float packageDensityScale = -1.0f;
+        int packageDensity = 0;
         if (appInfo.supportsDensities != null) {
             int minDiff = Integer.MAX_VALUE;
             for (int density : appInfo.supportsDensities) {
-                if (density == ApplicationInfo.ANY_DENSITY) { 
+                if (density == ApplicationInfo.ANY_DENSITY) {
+                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                     packageDensityScale = 1.0f;
                     break;
                 }
-                int tmpDiff = Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
+                int tmpDiff = Math.abs(DisplayMetrics.DENSITY_DEVICE - density);
                 if (tmpDiff == 0) {
+                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                     packageDensityScale = 1.0f;
                     break;
                 }
                 // prefer higher density (appScale>1.0), unless that's only option.
                 if (tmpDiff < minDiff && packageDensityScale < 1.0f) {
-                    packageDensityScale = DisplayMetrics.DEVICE_DENSITY / (float) density;
+                    packageDensity = density;
+                    packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density;
                     minDiff = tmpDiff;
                 }
             }
         }
         if (packageDensityScale > 0.0f) {
+            applicationDensity = packageDensity;
             applicationScale = packageDensityScale;
         } else {
+            applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
             applicationScale =
-                    DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
+                    DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT;
         }
 
         applicationInvertedScale = 1.0f / applicationScale;
@@ -139,9 +150,11 @@
         }
     }
 
-    private CompatibilityInfo(int appFlags, int compFlags, float scale, float invertedScale) {
+    private CompatibilityInfo(int appFlags, int compFlags,
+            int dens, float scale, float invertedScale) {
         this.appFlags = appFlags;
         mCompatibilityFlags = compFlags;
+        applicationDensity = dens;
         applicationScale = scale;
         applicationInvertedScale = invertedScale;
     }
@@ -151,6 +164,7 @@
                 | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                 | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS,
                 EXPANDABLE | CONFIGURED_EXPANDABLE,
+                DisplayMetrics.DENSITY_DEVICE,
                 1.0f,
                 1.0f);
     }
@@ -160,7 +174,7 @@
      */
     public CompatibilityInfo copy() {
         CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
-                applicationScale, applicationInvertedScale);
+                applicationDensity, applicationScale, applicationInvertedScale);
         return info;
     }
  
@@ -210,8 +224,7 @@
             if (DBG) Log.d(TAG, "no translation required");
             return null;
         }
-        if (!isScalingRequired() ||
-            (params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
+        if (!isScalingRequired()) {
             return null;
         }
         return new Translator();
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a9aa1ee..2354519 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -87,7 +87,7 @@
     /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
     PluralRules mPluralRule;
     
-    private final CompatibilityInfo mCompatibilityInfo;
+    private CompatibilityInfo mCompatibilityInfo;
     private Display mDefaultDisplay;
 
     private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>() {
@@ -1386,6 +1386,15 @@
     }
 
     /**
+     * This is just for testing.
+     * @hide
+     */
+    public void setCompatibilityInfo(CompatibilityInfo ci) {
+        mCompatibilityInfo = ci;
+        updateConfiguration(mConfiguration, mMetrics);
+    }
+    
+    /**
      * Return a resource identifier for the given resource name.  A fully
      * qualified resource name is of the form "package:type/entry".  The first
      * two components (package and type) are optional if defType and
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 528def5..e203fd5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -508,6 +508,19 @@
     public abstract long getBatteryUptime(long curTime);
 
     /**
+     * @deprecated use getRadioDataUptime
+     */
+    public long getRadioDataUptimeMs() {
+        return getRadioDataUptime() / 1000;
+    }
+
+    /**
+     * Returns the time that the radio was on for data transfers.
+     * @return the uptime in microseconds while unplugged
+     */
+    public abstract long getRadioDataUptime();
+
+    /**
      * Returns the current battery realtime in microseconds.
      *
      * @param curTime the amount of elapsed realtime in microseconds.
@@ -1128,7 +1141,14 @@
         }
         if (!didOne) sb.append("No activity");
         pw.println(sb.toString());
-        
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Radio data uptime when unplugged: ");
+        sb.append(getRadioDataUptime() / 1000);
+        sb.append(" ms");
+        pw.println(sb.toString());
+
         sb.setLength(0);
         sb.append(prefix);
                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java
index 70c7d73..d3ef5de 100644
--- a/core/java/android/server/search/SearchDialogWrapper.java
+++ b/core/java/android/server/search/SearchDialogWrapper.java
@@ -45,8 +45,6 @@
     private static final String TAG = "SearchManagerService";
     private static final boolean DBG = false;
 
-    private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog";
-
     private static final String SEARCH_UI_THREAD_NAME = "SearchDialog";
     private static final int SEARCH_UI_THREAD_PRIORITY =
         android.os.Process.THREAD_PRIORITY_DEFAULT;
@@ -88,12 +86,11 @@
     
     // Identity of currently resumed activity.
     private int mResumedIdent = 0;
-    
-    // Allows disabling of search dialog for stress testing runs
-    private final boolean mDisabledOnBoot;
 
     // True if we have registered our receivers.
     private boolean mReceiverRegistered;
+
+    private volatile boolean mVisible = false;
     
     /**
      * Creates a new search dialog wrapper and a search UI thread. The search dialog itself will
@@ -104,8 +101,6 @@
     public SearchDialogWrapper(Context context) {
         mContext = context;
 
-        mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY));
-
         // Create the search UI thread
         HandlerThread t = new HandlerThread(SEARCH_UI_THREAD_NAME, SEARCH_UI_THREAD_PRIORITY);
         t.start();
@@ -115,6 +110,10 @@
         mSearchUiThread.sendEmptyMessage(MSG_INIT);
     }
 
+    public boolean isVisible() {
+        return mVisible;
+    }
+
     /**
      * Initializes the search UI.
      * Must be called from the search UI thread.
@@ -151,8 +150,10 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
-                if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-                performStopSearch();
+                if (!"search".equals(intent.getStringExtra("reason"))) {
+                    if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                    performStopSearch();
+                }
             } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
                 if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED);
                 performOnConfigurationChanged();
@@ -205,7 +206,7 @@
      * Can be called from any thread.
      */
     public void activityResuming(int ident) {
-        if (DBG) debug("startSearch()");
+        if (DBG) debug("activityResuming(ident=" + ident + ")");
         Message msg = Message.obtain();
         msg.what = MSG_ACTIVITY_RESUMING;
         msg.arg1 = ident;
@@ -256,20 +257,6 @@
 
     }
 
-    void updateDialogVisibility() {
-        if (mStartedIdent != 0) {
-            // mResumedIdent == 0 means we have just booted and the user
-            // hasn't yet gone anywhere.
-            if (mResumedIdent == 0 || mStartedIdent == mResumedIdent) {
-                if (DBG) Log.v(TAG, "******************* DIALOG: show");
-                mSearchDialog.show();
-            } else {
-                if (DBG) Log.v(TAG, "******************* DIALOG: hide");
-                mSearchDialog.hide();
-            }
-        }
-    }
-    
     /**
      * Actually launches the search UI.
      * This must be called on the search UI thread.
@@ -283,19 +270,20 @@
             int ident) {
         if (DBG) debug("performStartSearch()");
 
-        if (mDisabledOnBoot) {
-            Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY
-                    + " system property is set.");
-            return;
-        }
-
         registerBroadcastReceiver();
         mCallback = searchManagerCallback;
+
+        // clean up any hidden dialog that we were waiting to resume
+        if (mStartedIdent != 0) {
+            mSearchDialog.dismiss();
+        }
+
         mStartedIdent = ident;
         if (DBG) Log.v(TAG, "******************* DIALOG: start");
+
         mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
                 globalSearch);
-        updateDialogVisibility();
+        mVisible = true;
     }
 
     /**
@@ -306,6 +294,7 @@
         if (DBG) debug("performStopSearch()");
         if (DBG) Log.v(TAG, "******************* DIALOG: cancel");
         mSearchDialog.cancel();
+        mVisible = false;
         mStartedIdent = 0;
     }
 
@@ -317,7 +306,21 @@
         if (DBG) debug("performResumingActivity(): mStartedIdent="
                 + mStartedIdent + ", resuming: " + ident);
         this.mResumedIdent = ident;
-        updateDialogVisibility();
+        if (mStartedIdent != 0) {
+            if (mStartedIdent == mResumedIdent) {
+                // we are resuming into the activity where we previously hid the dialog, bring it
+                // back
+                if (DBG) Log.v(TAG, "******************* DIALOG: show");
+                mSearchDialog.show();
+                mVisible = true;
+            } else {
+                // resuming into some other activity; hide ourselves in case we ever come back
+                // so we can show ourselves quickly again
+                if (DBG) Log.v(TAG, "******************* DIALOG: hide");
+                mSearchDialog.hide();
+                mVisible = false;
+            }
+        }
     }
 
     /**
@@ -333,27 +336,38 @@
      */
     public void onDismiss(DialogInterface dialog) {
         if (DBG) debug("onDismiss()");
-        if (mCallback != null) {
-            try {
-                // should be safe to do on the search UI thread, since it's a oneway interface
-                mCallback.onDismiss();
-            } catch (DeadObjectException ex) {
-                // The process that hosted the callback has died, do nothing
-            } catch (RemoteException ex) {
-                Log.e(TAG, "onDismiss() failed: " + ex);
-            }
-            // we don't need the callback anymore, release it
-            mCallback = null;
-        }
+        mStartedIdent = 0;
+        mVisible = false;
+        callOnDismiss();
+
+        // we don't need the callback anymore, release it
+        mCallback = null;
         unregisterBroadcastReceiver();
     }
 
+
     /**
      * Called by {@link SearchDialog} when the user or activity cancels search.
      * Whenever this method is called, {@link #onDismiss} is always called afterwards.
      */
     public void onCancel(DialogInterface dialog) {
         if (DBG) debug("onCancel()");
+        callOnCancel();
+    }
+
+    private void callOnDismiss() {
+        if (mCallback == null) return;
+        try {
+            // should be safe to do on the search UI thread, since it's a oneway interface
+            mCallback.onDismiss();
+        } catch (DeadObjectException ex) {
+            // The process that hosted the callback has died, do nothing
+        } catch (RemoteException ex) {
+            Log.e(TAG, "onDismiss() failed: " + ex);
+        }
+    }
+
+    private void callOnCancel() {
         if (mCallback != null) {
             try {
                 // should be safe to do on the search UI thread, since it's a oneway interface
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index 7629912..fdeb8f9 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -238,4 +238,8 @@
         getSearchDialog().stopSearch();
     }
 
+    public boolean isVisible() {
+        return mSearchDialog != null && mSearchDialog.isVisible();
+    }
+
 }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 4794fe1..bb6b4b0 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -820,14 +820,14 @@
                 if (speechRate > 0) {
                     int rate = (int)(speechRate*100);
                     mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate);
-                    result = mITts.setSpeechRate(mPackageName, rate);
+                    // the rate is not set here, instead it is cached so it will be associated
+                    // with all upcoming utterances.
+                    if (speechRate > 0.0f) {
+                        result = TTS_SUCCESS;
+                    } else {
+                        result = TTS_ERROR;
+                    }
                 }
-            } catch (RemoteException e) {
-                // TTS died; restart it.
-                Log.e("TextToSpeech.java - setSpeechRate", "RemoteException");
-                e.printStackTrace();
-                mStarted = false;
-                initTts();
             } catch (NullPointerException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException");
@@ -907,7 +907,9 @@
      * @param loc
      *            The locale describing the language to be used.
      *
-     * @return Code indicating the support status for the locale. See the TTS_LANG_ codes.
+     * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
+     *         {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
+     *         {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
      */
     public int setLanguage(Locale loc) {
         synchronized (mStartLock) {
@@ -919,6 +921,7 @@
                 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
                 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
                 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant();
+
                 result = mITts.setLanguage(mPackageName,
                         mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
                         mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
@@ -994,8 +997,9 @@
      * @param loc
      *            The Locale describing the language to be used.
      *
-     * @return one of TTS_LANG_NOT_SUPPORTED, TTS_LANG_MISSING_DATA, TTS_LANG_AVAILABLE,
-     *         TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE.
+     * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
+     *         {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
+     *         {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
      */
     public int isLanguageAvailable(Locale loc) {
         synchronized (mStartLock) {
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 9071bf0..bfab49d 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -27,17 +27,31 @@
  */
 public class DisplayMetrics {
     /**
-     * The reference density used throughout the system.
-     * 
-     * @hide Pending API council approval
+     * Standard quantized DPI for low-density screens.
      */
-    public static final int DEFAULT_DENSITY = 160;
+    public static final int DENSITY_LOW = 120;
+
+    /**
+     * Standard quantized DPI for medium-density screens.
+     */
+    public static final int DENSITY_MEDIUM = 160;
+
+    /**
+     * Standard quantized DPI for high-density screens.
+     */
+    public static final int DENSITY_HIGH = 240;
+
+    /**
+     * The reference density used throughout the system.
+     */
+    public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
 
     /**
      * The device's density.
-     * @hide
+     * @hide becase eventually this should be able to change while
+     * running, so shouldn't be a constant.
      */
-    public static final int DEVICE_DENSITY = getDeviceDensity();
+    public static final int DENSITY_DEVICE = getDeviceDensity();
 
     /**
      * The absolute width of the display in pixels.
@@ -62,7 +76,7 @@
      * 320x480 but the screen size remained 1.5"x2" then the density would be 
      * increased (probably to 1.5).
      *
-     * @see #DEFAULT_DENSITY
+     * @see #DENSITY_DEFAULT
      */
     public float density;
     /**
@@ -95,10 +109,10 @@
     public void setToDefaults() {
         widthPixels = 0;
         heightPixels = 0;
-        density = DEVICE_DENSITY / (float) DEFAULT_DENSITY;
+        density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
         scaledDensity = density;
-        xdpi = DEVICE_DENSITY;
-        ydpi = DEVICE_DENSITY;
+        xdpi = DENSITY_DEVICE;
+        ydpi = DENSITY_DEVICE;
     }
 
     /**
@@ -176,6 +190,6 @@
         // The reason for this is that ro.sf.lcd_density is write-once and is
         // set by the init process when it parses build.prop before anything else.
         return SystemProperties.getInt("qemu.sf.lcd_density",
-                SystemProperties.getInt("ro.sf.lcd_density", DEFAULT_DENSITY));
+                SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
     }
 }
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index d4ba9e2..ed45298 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -140,12 +140,16 @@
 
     /**
      * If {@link #density} is equal to this value, then the density should be
-     * treated as the system's default density value: {@link DisplayMetrics#DEFAULT_DENSITY}.
-     *
-     * @hide Pending API council approval
+     * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
      */
     public static final int DENSITY_DEFAULT = 0;
 
+    /**
+     * If {@link #density} is equal to this value, then there is no density
+     * associated with the resource and it should not be scaled.
+     */
+    public static final int DENSITY_NONE = 0xffff;
+
     /* ------------------------------------------------------------ */
 
     /** The type held by this value, as defined by the constants here.
@@ -171,8 +175,6 @@
 
     /**
      * If the Value came from a resource, this holds the corresponding pixel density.
-     * 
-     * @hide Pending API council approval
      * */
     public int density;
 
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ff1eb53..aa701af 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -17,7 +17,6 @@
 package android.view;
 
 import android.content.Context;
-import android.content.res.CompatibilityInfo;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
@@ -256,9 +255,9 @@
     public boolean dispatchTouchEvent(MotionEvent event) {
         // SurfaceView uses pre-scaled size unless fixed size is requested. This hook
         // scales the event back to the pre-scaled coordinates for such surface.
-        if (mRequestedWidth < 0 && mTranslator != null) {
+        if (mScaled) {
             MotionEvent scaledBack = MotionEvent.obtain(event);
-            scaledBack.scale(mTranslator.applicationScale);
+            mTranslator.translateEventInScreenToAppWindow(event);
             try {
                 return super.dispatchTouchEvent(scaledBack);
             } finally {
@@ -290,12 +289,15 @@
     public void setWindowType(int type) {
         mWindowType = type;
     }
+
+    boolean mScaled = false;
     
     private void updateWindow(boolean force) {
         if (!mHaveFrame) {
             return;
         }
-        mTranslator = ((ViewRoot)getRootView().getParent()).mTranslator;
+        ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
+        mTranslator = viewRoot.mTranslator;
 
         float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
         
@@ -309,6 +311,9 @@
         if (mRequestedWidth <= 0 && mTranslator != null) {
             myWidth *= appScale;
             myHeight *= appScale;
+            mScaled = true;
+        } else {
+            mScaled = false;
         }
 
         getLocationInWindow(mLocation);
@@ -352,8 +357,10 @@
                               | WindowManager.LayoutParams.FLAG_SCALED
                               | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                               | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              | WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING
                               ;
+                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
+                    mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+                }
 
                 mLayout.memoryType = mRequestedType;
 
@@ -533,6 +540,7 @@
     private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
         
         private static final String LOG_TAG = "SurfaceHolder";
+        private int mSaveCount;
         
         public boolean isCreating() {
             return mIsCreating;
@@ -627,6 +635,10 @@
             if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
             if (c != null) {
                 mLastLockTime = SystemClock.uptimeMillis();
+                if (mScaled) {
+                    mSaveCount = c.save();
+                    mTranslator.translateCanvas(c);
+                }
                 return c;
             }
             
@@ -649,6 +661,9 @@
         }
 
         public void unlockCanvasAndPost(Canvas canvas) {
+            if (mScaled) {
+                canvas.restoreToCount(mSaveCount);
+            }
             mSurface.unlockCanvasAndPost(canvas);
             mSurfaceLock.unlock();
         }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ba3bfa7..6a26a31 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -483,19 +483,12 @@
          * {@hide} */
         public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
 
-        /** Window flag: special flag to let a window ignore the compatibility scaling.
-         * This is used by SurfaceView to pass this info into ViewRoot, and not used
-         * by WindowManager.
-         *
-         * {@hide} */
-        public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
-
         /** Window flag: special flag to limit the size of the window to be
          * original size ([320x480] x density). Used to create window for applications
          * running under compatibility mode.
          *
          * {@hide} */
-        public static final int FLAG_COMPATIBLE_WINDOW = 0x00200000;
+        public static final int FLAG_COMPATIBLE_WINDOW = 0x00100000;
 
         /** Window flag: a special option intended for system dialogs.  When
          * this flag is set, the window will demand focus unconditionally when
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 0df587f..4bc00de 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1296,11 +1296,8 @@
             }
         }
 
-        // Max height available on the screen for a popup. If this AutoCompleteTextView has
-        // the dropDownAlwaysVisible attribute, and the input method is not currently required,
-        // we then we ask for the height ignoring any bottom decorations like the input method.
-        // Otherwise we respect the input method.
-        boolean ignoreBottomDecorations = mDropDownAlwaysVisible &&
+        // Max height available on the screen for a popup.
+        boolean ignoreBottomDecorations =
                 mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
         final int maxHeight = mPopup.getMaxAvailableHeight(
                 getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index e62dda5..24c0e2a 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1295,11 +1295,8 @@
                     if (rule > 0) {
                         // The node this node depends on
                         final Node dependency = keyNodes.get(rule);
-                        if (dependency == node) {
-                            throw new IllegalStateException("A view cannot have a dependency" +
-                                    " on itself");
-                        }
-                        if (dependency == null) {
+                        // Skip unknowns and self dependencies
+                        if (dependency == null || dependency == node) {
                             continue;
                         }
                         // Add the current node as a dependent
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index a03802d..a449e5f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import android.bluetooth.BluetoothHeadset;
 import android.os.BatteryStats;
 import android.os.NetStat;
 import android.os.Parcel;
@@ -128,7 +129,10 @@
     
     boolean mBluetoothOn;
     StopwatchTimer mBluetoothOnTimer;
-    
+
+    /** Bluetooth headset object */
+    BluetoothHeadset mBtHeadset;
+
     /**
      * These provide time bases that discount the time the device is plugged
      * in to power.
@@ -160,6 +164,9 @@
     private long mRadioDataUptime;
     private long mRadioDataStart;
 
+    private int mBluetoothPingCount;
+    private int mBluetoothPingStart = -1;
+
     /*
      * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
      */
@@ -920,14 +927,18 @@
         dataTransfer[STATS_UNPLUGGED] = currentBytes;
     }
 
-    private long getCurrentRadioDataUptimeMs() {
+    /**
+     * Radio uptime in microseconds when transferring data. This value is very approximate.
+     * @return
+     */
+    private long getCurrentRadioDataUptime() {
         try {
             File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
             if (!awakeTimeFile.exists()) return 0;
             BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
             String line = br.readLine();
             br.close();
-            return Long.parseLong(line);
+            return Long.parseLong(line) * 1000;
         } catch (NumberFormatException nfe) {
             // Nothing
         } catch (IOException ioe) {
@@ -936,14 +947,44 @@
         return 0;
     }
 
+    /**
+     * @deprecated use getRadioDataUptime
+     */
     public long getRadioDataUptimeMs() {
+        return getRadioDataUptime() / 1000;
+    }
+
+    /**
+     * Returns the duration that the cell radio was up for data transfers. 
+     */
+    public long getRadioDataUptime() {
         if (mRadioDataStart == -1) {
             return mRadioDataUptime;
         } else {
-            return getCurrentRadioDataUptimeMs() - mRadioDataStart;
+            return getCurrentRadioDataUptime() - mRadioDataStart;
         }
     }
 
+    private int getCurrentBluetoothPingCount() {
+        if (mBtHeadset != null) {
+            return mBtHeadset.getBatteryUsageHint();
+        }
+        return -1;
+    }
+
+    public int getBluetoothPingCount() {
+        if (mBluetoothPingStart == -1) {
+            return mBluetoothPingCount;
+        } else if (mBtHeadset != null) {
+            return getCurrentBluetoothPingCount() - mBluetoothPingStart;
+        }
+        return -1;
+    }
+
+    public void setBtHeadset(BluetoothHeadset headset) {
+        mBtHeadset = headset;
+    }
+
     public void doUnplug(long batteryUptime, long batteryRealtime) {
         for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
             Uid u = mUidStats.valueAt(iu);
@@ -961,8 +1002,11 @@
         doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
         doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
         // Track radio awake time
-        mRadioDataStart = getCurrentRadioDataUptimeMs();
+        mRadioDataStart = getCurrentRadioDataUptime();
         mRadioDataUptime = 0;
+        // Track bt headset ping count
+        mBluetoothPingStart = getCurrentBluetoothPingCount();
+        mBluetoothPingCount = 0;
     }
 
     public void doPlug(long batteryUptime, long batteryRealtime) {
@@ -985,8 +1029,12 @@
         doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
         doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
         // Track radio awake time
-        mRadioDataUptime = getRadioDataUptimeMs();
+        mRadioDataUptime = getRadioDataUptime();
         mRadioDataStart = -1;
+
+        // Track bt headset ping count
+        mBluetoothPingCount = getBluetoothPingCount();
+        mBluetoothPingStart = -1;
     }
 
     public void noteStartGps(int uid) {
@@ -3335,6 +3383,9 @@
         mRadioDataUptime = in.readLong();
         mRadioDataStart = -1;
 
+        mBluetoothPingCount = in.readInt();
+        mBluetoothPingStart = -1;
+
         mKernelWakelockStats.clear();
         int NKW = in.readInt();
         for (int ikw = 0; ikw < NKW; ikw++) {
@@ -3415,7 +3466,9 @@
         out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
 
         // Write radio uptime for data
-        out.writeLong(getRadioDataUptimeMs());
+        out.writeLong(getRadioDataUptime());
+
+        out.writeInt(getBluetoothPingCount());
 
         out.writeInt(mKernelWakelockStats.size());
         for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 4a8d8b1..94f703a 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -87,6 +87,11 @@
     public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
 
     /**
+     * Power consumption when Bluetooth driver gets an AT command.
+     */
+    public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
+
+    /**
      * Power consumption when screen is on, not including the backlight power.
      */
     public static final String POWER_SCREEN_ON = "screen.on";
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index e9f8ea1..9053468 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -171,7 +171,8 @@
                 mCameraJObjectWeak, msgType, 0, 0, NULL);
         break;
     default:
-        LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+        // TODO: Change to LOGV
+        LOGD("dataCallback(%d, %p)", msgType, dataPtr.get());
         copyAndPost(env, dataPtr, msgType);
         break;
     }
@@ -222,6 +223,8 @@
 // finalizer is invoked later.
 static void android_hardware_Camera_release(JNIEnv *env, jobject thiz)
 {
+    // TODO: Change to LOGV
+    LOGD("release camera");
     JNICameraContext* context = NULL;
     sp<Camera> camera;
     {
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index e71e348..44a9e8c 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -212,8 +212,10 @@
     
     // failure:
 native_init_failure:
+    env->DeleteGlobalRef(lpCallbackData->audioRecord_class);
+    env->DeleteGlobalRef(lpCallbackData->audioRecord_ref);
     delete lpCallbackData;
-    
+
 native_track_failure:
     delete lpRecorder;
 
@@ -274,6 +276,8 @@
         thiz, javaAudioRecordFields.nativeCallbackCookie);
     if (lpCookie) {
         LOGV("deleting lpCookie: %x\n", (int)lpCookie);
+        env->DeleteGlobalRef(lpCookie->audioRecord_class);
+        env->DeleteGlobalRef(lpCookie->audioRecord_ref);
         delete lpCookie;
     }
 
diff --git a/core/res/res/layout/search_dropdown_app_selector.xml b/core/res/res/layout/search_dropdown_app_selector.xml
deleted file mode 100644
index f86645f..0000000
--- a/core/res/res/layout/search_dropdown_app_selector.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/layout/search_dropdown_app_selector.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-
-    <ImageView android:id="@+id/search_app_icon1"
-        android:layout_width="32dip"
-        android:layout_height="32dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="fitCenter"
-        android:src="@android:drawable/ic_search_category_default" />
-        
-    <TextView android:id="@+id/search_app_text1"
-        style="?android:attr/dropDownItemStyle"
-        android:singleLine="true"
-        android:layout_height="wrap_content"
-        android:layout_width="0dip"
-        android:layout_weight="1"
-        android:layout_gravity="center_vertical" />
-    
-</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_2line.xml b/core/res/res/layout/search_dropdown_item_2line.xml
deleted file mode 100644
index 5546b6636..0000000
--- a/core/res/res/layout/search_dropdown_item_2line.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/searchResultListItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-    
-    <TwoLineListItem
-        android:paddingTop="1dip"
-        android:paddingBottom="1dip"
-        android:gravity="center_vertical"
-        android:layout_width="0dip"
-        android:layout_weight="1"
-        android:layout_height="wrap_content"
-        android:mode="twoLine" >
-    
-        <TextView
-            android:id="@android:id/text1"
-            style="?android:attr/dropDownItemStyle"
-            android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
-            android:singleLine="true"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content" />
-    
-        <TextView
-            android:id="@android:id/text2"
-            style="?android:attr/dropDownItemStyle"
-            android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
-            android:textColor="?android:attr/textColorSecondaryInverse"
-            android:singleLine="true"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/text1"
-            android:layout_alignLeft="@android:id/text1" />
-    
-    </TwoLineListItem>
-
-</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_icons_1line.xml b/core/res/res/layout/search_dropdown_item_icons_1line.xml
deleted file mode 100644
index 4f65d74..0000000
--- a/core/res/res/layout/search_dropdown_item_icons_1line.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-    <!-- NOTE: The appearance of the inner text element must match the appearance -->
-    <!-- of the text element in apps/common/res/layout/simple_dropdown_item_1line.xml -->
-    
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:paddingLeft="4dip"
-    android:paddingRight="2dip"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/searchResultListItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-    
-    <ImageView android:id="@android:id/icon1"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside" />
-
-    <TextView android:id="@android:id/text1"
-        style="?android:attr/dropDownItemStyle"
-        android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
-        android:singleLine="true"
-        android:layout_height="wrap_content"
-        android:layout_width="0dip"
-        android:layout_weight="1"  />
-
-    <ImageView android:id="@android:id/icon2"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside" />
-
-</LinearLayout>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index e2e93eb..df659ef 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DisplayMetrics;
 
 import java.io.OutputStream;
 import java.nio.Buffer;
@@ -31,8 +32,6 @@
      *
      * @see Bitmap#getDensityScale()
      * @see Bitmap#setDensityScale(float)
-     *
-     * @hide pending API council approval
      */
     public static final float DENSITY_SCALE_UNKNOWN = -1.0f;
 
@@ -84,11 +83,9 @@
      * @see #setDensityScale(float)
      * @see #isAutoScalingEnabled()
      * @see #setAutoScalingEnabled(boolean)
-     * @see android.util.DisplayMetrics#DEFAULT_DENSITY
+     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
      * @see android.util.DisplayMetrics#density
      * @see #DENSITY_SCALE_UNKNOWN
-     *
-     * @hide pending API council approval
      */
     public float getDensityScale() {
         return mDensityScale;
@@ -106,11 +103,9 @@
      * @see #getDensityScale()
      * @see #isAutoScalingEnabled()
      * @see #setAutoScalingEnabled(boolean)
-     * @see android.util.DisplayMetrics#DEFAULT_DENSITY
+     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
      * @see android.util.DisplayMetrics#density
      * @see #DENSITY_SCALE_UNKNOWN
-     *
-     * @hide pending API council approval
      */
     public void setDensityScale(float densityScale) {
         mDensityScale = densityScale;
@@ -132,8 +127,6 @@
      * @see #setAutoScalingEnabled(boolean)
      * @see #getDensityScale()
      * @see #setDensityScale(float)
-     *
-     * @hide pending API council approval
      */
     public boolean isAutoScalingEnabled() {
         return mAutoScaling;
@@ -150,8 +143,6 @@
      * the bitmap will never be automatically scaled at drawing time.</p>
      *
      * @param autoScalingEnabled True to scale the bitmap at drawing time, false otherwise.
-     *
-     * @hide pending API council approval
      */
     public void setAutoScalingEnabled(boolean autoScalingEnabled) {
         mAutoScaling = autoScalingEnabled;
@@ -465,8 +456,8 @@
 
         // The new bitmap was created from a known bitmap source so assume that
         // they use the same density scale
-        bitmap.setDensityScale(source.getDensityScale());
-        bitmap.setAutoScalingEnabled(source.isAutoScalingEnabled());
+        bitmap.mDensityScale = source.mDensityScale;
+        bitmap.mAutoScaling = source.mAutoScaling;
 
         return bitmap;
     }
@@ -615,26 +606,60 @@
      * Convenience method that returns the width of this bitmap divided
      * by the density scale factor.
      *
+     * @param canvas The Canvas the bitmap will be drawn to.
      * @return The scaled width of this bitmap, according to the density scale factor.
-     *
-     * @hide pending API council approval
      */
-    public int getScaledWidth() {
-        final float scale = getDensityScale();
-        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getWidth() / scale);
+    public int getScaledWidth(Canvas canvas) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getWidth();
+        }
+        return (int)(getWidth() * canvas.getDensityScale() / scale);
     }
 
     /**
      * Convenience method that returns the height of this bitmap divided
      * by the density scale factor.
      *
+     * @param canvas The Canvas the bitmap will be drawn to.
      * @return The scaled height of this bitmap, according to the density scale factor.
-     *
-     * @hide pending API council approval
      */
-    public int getScaledHeight() {
-        final float scale = getDensityScale();
-        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getHeight() / scale);
+    public int getScaledHeight(Canvas canvas) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getHeight();
+        }
+        return (int)(getHeight() * canvas.getDensityScale() / scale);
+    }
+
+    /**
+     * Convenience method that returns the width of this bitmap divided
+     * by the density scale factor.
+     *
+     * @param metrics The target display metrics.
+     * @return The scaled width of this bitmap, according to the density scale factor.
+     */
+    public int getScaledWidth(DisplayMetrics metrics) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getWidth();
+        }
+        return (int)(getWidth() * metrics.density / scale);
+    }
+
+    /**
+     * Convenience method that returns the height of this bitmap divided
+     * by the density scale factor.
+     *
+     * @param metrics The target display metrics.
+     * @return The scaled height of this bitmap, according to the density scale factor.
+     */
+    public int getScaledHeight(DisplayMetrics metrics) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getHeight();
+        }
+        return (int)(getHeight() * metrics.density / scale);
     }
 
     /**
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 082e0c0..76abaa2 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -81,10 +81,8 @@
         /**
          * The desired pixel density of the bitmap.
          *
-         * @see android.util.DisplayMetrics#DEFAULT_DENSITY
+         * @see android.util.DisplayMetrics#DENSITY_DEFAULT
          * @see android.util.DisplayMetrics#density
-         *
-         * @hide pending API council approval
          */
         public int inDensity;
 
@@ -97,8 +95,6 @@
          * a non-scaled version of the bitmap. In this case,
          * {@link android.graphics.Bitmap#setAutoScalingEnabled(boolean)} can be used
          * to properly scale the bitmap at drawing time.</p>
-         *
-         * @hide pending API council approval
          */
         public boolean inScaled;
 
@@ -238,8 +234,6 @@
     /**
      * Decode a new Bitmap from an InputStream. This InputStream was obtained from
      * resources, which we pass to be able to scale the bitmap accordingly.
-     *
-     * @hide
      */
     public static Bitmap decodeStream(Resources res, TypedValue value, InputStream is,
             Rect pad, Options opts) {
@@ -251,15 +245,19 @@
         Bitmap bm = decodeStream(is, pad, opts);
 
         if (bm != null && res != null && value != null) {
+            final int density = value.density;
+            if (density == TypedValue.DENSITY_NONE) {
+                return bm;
+            }
+            
             byte[] np = bm.getNinePatchChunk();
             final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
 
-            final int density = value.density;
             if (opts.inDensity == 0) {
                 opts.inDensity = density == TypedValue.DENSITY_DEFAULT ?
-                        DisplayMetrics.DEFAULT_DENSITY : density;
+                        DisplayMetrics.DENSITY_DEFAULT : density;
             }
-            float scale = opts.inDensity / (float) DisplayMetrics.DEFAULT_DENSITY;
+            float scale = opts.inDensity / (float) DisplayMetrics.DENSITY_DEFAULT;
 
             if (opts.inScaled || isNinePatch) {
                 bm.setDensityScale(1.0f);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 4498e1a..da73597 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -184,8 +184,6 @@
      *
      * @see #setDensityScale(float)
      * @see Bitmap#getDensityScale() 
-     *
-     * @hide pending API council approval
      */
     public float getDensityScale() {
         if (mBitmap != null) {
@@ -205,8 +203,6 @@
      *
      * @see #getDensityScale()
      * @see Bitmap#setDensityScale(float) 
-     *
-     * @hide pending API council approval
      */
     public void setDensityScale(float densityScale) {
         if (mBitmap != null) {
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 93bca4a..3819335 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -825,7 +825,8 @@
     };
     
     enum {
-        DENSITY_ANY = 0
+        DENSITY_DEFAULT = 0,
+        DENSITY_NONE = 0xffff
     };
     
     union {
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 87edb01..98d450b 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -4007,7 +4007,16 @@
                         printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
                         continue;
                     }
-                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n",
+                    char density[16];
+                    uint16_t dval = dtohs(type->config.density);
+                    if (dval == ResTable_config::DENSITY_DEFAULT) {
+                        strcpy(density, "def");
+                    } else if (dval == ResTable_config::DENSITY_NONE) {
+                        strcpy(density, "non");
+                    } else {
+                        sprintf(density, "%d", (int)dval);
+                    }
+                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%s key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n",
                            (int)configIndex,
                            type->config.language[0] ? type->config.language[0] : '-',
                            type->config.language[1] ? type->config.language[1] : '-',
@@ -4015,7 +4024,7 @@
                            type->config.country[1] ? type->config.country[1] : '-',
                            type->config.orientation,
                            type->config.touchscreen,
-                           dtohs(type->config.density),
+                           density,
                            type->config.keyboard,
                            type->config.inputFlags,
                            type->config.navigation,
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index ee41021..58c04f3 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1327,10 +1327,12 @@
         }
 
         private void persistVolume(VolumeStreamState streamState) {
-            System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
-                    streamState.mIndex);
-            System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
-                    streamState.mLastAudibleIndex);
+            if (streamState.mStreamType != AudioManager.STREAM_BLUETOOTH_SCO) {
+                System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
+                        streamState.mIndex);
+                System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
+                        streamState.mLastAudibleIndex);
+            }
         }
 
         private void persistRingerMode() {
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 099c4d1..82067be 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -59,6 +59,9 @@
 // ----------------------------------------------------------------------------
 static fields_t javaTTSFields;
 
+// TODO move to synth member once we have multiple simultaneous engines running
+static Mutex engineMutex;
+
 // ----------------------------------------------------------------------------
 class SynthProxyJniStorage {
     public :
@@ -330,6 +333,8 @@
         return result;
     }
 
+    Mutex::Autolock l(engineMutex);
+
     SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
     const char *langNativeString = env->GetStringUTFChars(language, 0);
     const char *countryNativeString = env->GetStringUTFChars(country, 0);
@@ -389,6 +394,8 @@
     char buffer [bufSize];
     sprintf(buffer, "%d", speechRate);
 
+    Mutex::Autolock l(engineMutex);
+
     SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
     LOGI("setting speech rate to %d", speechRate);
 
@@ -411,6 +418,8 @@
         return result;
     }
 
+    Mutex::Autolock l(engineMutex);
+
     int bufSize = 10;
     char buffer [bufSize];
     sprintf(buffer, "%d", pitch);
@@ -443,6 +452,8 @@
         return result;
     }
 
+    Mutex::Autolock l(engineMutex);
+
     // Retrieve audio parameters before writing the file header
     AudioSystem::audio_format encoding = DEFAULT_TTS_FORMAT;
     uint32_t rate = DEFAULT_TTS_RATE;
@@ -545,10 +556,11 @@
         return result;
     }
 
+    Mutex::Autolock l(engineMutex);
+
     SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
 
     if (pSynthData->mAudioOut) {
-        pSynthData->mAudioOut->stop();
         pSynthData->mAudioOut->start();
     }
 
@@ -600,6 +612,8 @@
         return;
     }
 
+    Mutex::Autolock l(engineMutex);
+
     SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
     if (pSynthData->mNativeSynthInterface) {
         pSynthData->mNativeSynthInterface->shutdown();
@@ -608,24 +622,6 @@
 }
 
 
-// TODO add buffer format
-static void
-android_tts_SynthProxy_playAudioBuffer(JNIEnv *env, jobject thiz, jint jniData,
-        int bufferPointer, int bufferSize)
-{
-LOGI("android_tts_SynthProxy_playAudioBuffer");
-    if (jniData == 0) {
-        LOGE("android_tts_SynthProxy_playAudioBuffer(): invalid JNI data");
-        return;
-    }
-
-    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
-    short* wav = (short*) bufferPointer;
-    pSynthData->mAudioOut->write(wav, bufferSize);
-    //LOGI("AudioTrack wrote: %d bytes", bufferSize);
-}
-
-
 static jobjectArray
 android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
 {
@@ -711,10 +707,6 @@
         "(II)I",
         (void*)android_tts_SynthProxy_setPitch
     },
-    {   "native_playAudioBuffer",
-        "(III)V",
-        (void*)android_tts_SynthProxy_playAudioBuffer
-    },
     {   "native_getLanguage",
         "(I)[Ljava/lang/String;",
         (void*)android_tts_SynthProxy_getLanguage
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 41ff92a..a0814aa 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -109,13 +109,6 @@
     }
 
     /**
-     * Plays the given audio buffer.
-     */
-    public void playAudioBuffer(int bufferPointer, int bufferSize) {
-        native_playAudioBuffer(mJniData, bufferPointer, bufferSize);
-    }
-
-    /**
      * Returns the currently set language, country and variant information.
      */
     public String[] getLanguage() {
@@ -180,9 +173,6 @@
 
     private native final int native_setPitch(int jniData, int speechRate);
 
-    // TODO add buffer format
-    private native final void native_playAudioBuffer(int jniData, int bufferPointer, int bufferSize);
-
     private native final String[] native_getLanguage(int jniData);
 
     private native final int native_getRate(int jniData);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index b3b580c..cfefcb7 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -139,16 +139,18 @@
     private final ReentrantLock speechQueueLock = new ReentrantLock();
     private final ReentrantLock synthesizerLock = new ReentrantLock();
 
-    private SynthProxy nativeSynth;
+    private static SynthProxy sNativeSynth = null;
     @Override
     public void onCreate() {
         super.onCreate();
-        Log.i("TTS", "TTS starting");
+        Log.i("TtsService", "TtsService.onCreate()");
 
         mResolver = getContentResolver();
 
         String soLibPath = "/system/lib/libttspico.so";
-        nativeSynth = new SynthProxy(soLibPath);
+        if (sNativeSynth == null) {
+            sNativeSynth = new SynthProxy(soLibPath);
+        }
 
         mSelf = this;
         mIsSpeaking = false;
@@ -171,7 +173,7 @@
         // Don't hog the media player
         cleanUpPlayer();
 
-        nativeSynth.shutdown();
+        sNativeSynth.shutdown();
 
         // Unregister all callbacks.
         mCallbacks.kill();
@@ -239,36 +241,36 @@
 
     private int setSpeechRate(String callingApp, int rate) {
         if (isDefaultEnforced()) {
-            return nativeSynth.setSpeechRate(getDefaultRate());
+            return sNativeSynth.setSpeechRate(getDefaultRate());
         } else {
-            return nativeSynth.setSpeechRate(rate);
+            return sNativeSynth.setSpeechRate(rate);
         }
     }
 
 
     private int setPitch(String callingApp, int pitch) {
-        return nativeSynth.setPitch(pitch);
+        return sNativeSynth.setPitch(pitch);
     }
 
 
     private int isLanguageAvailable(String lang, String country, String variant) {
-        //Log.v("TTS", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
-        return nativeSynth.isLanguageAvailable(lang, country, variant);
+        //Log.v("TtsService", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
+        return sNativeSynth.isLanguageAvailable(lang, country, variant);
     }
 
 
     private String[] getLanguage() {
-        return nativeSynth.getLanguage();
+        return sNativeSynth.getLanguage();
     }
 
 
     private int setLanguage(String callingApp, String lang, String country, String variant) {
-        //Log.v("TTS", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
+        Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
         if (isDefaultEnforced()) {
-            return nativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
+            return sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
                     getDefaultLocVariant());
         } else {
-            return nativeSynth.setLanguage(lang, country, variant);
+            return sNativeSynth.setLanguage(lang, country, variant);
         }
     }
 
@@ -340,7 +342,7 @@
      *            engines.
      */
     private int speak(String callingApp, String text, int queueMode, ArrayList<String> params) {
-        Log.i("TTS service received", text);
+        Log.v("TtsService", "TTS service received " + text);
         if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
             stop(callingApp);
         } else if (queueMode == 2) {
@@ -390,7 +392,7 @@
             // something has gone very wrong with processSpeechQueue.
             speechQueueAvailable = speechQueueLock.tryLock(1000, TimeUnit.MILLISECONDS);
             if (speechQueueAvailable) {
-                Log.i("TTS", "Stopping");
+                Log.i("TtsService", "Stopping");
                 for (int i = mSpeechQueue.size() - 1; i > -1; i--){
                     if (mSpeechQueue.get(i).mCallingApp.equals(callingApp)){
                         mSpeechQueue.remove(i);
@@ -398,7 +400,7 @@
                 }
                 if ((mCurrentSpeechItem != null) &&
                      mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
-                    result = nativeSynth.stop();
+                    result = sNativeSynth.stop();
                     mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
@@ -412,10 +414,10 @@
                 } else {
                     result = TextToSpeech.TTS_SUCCESS;
                 }
-                Log.i("TTS", "Stopped");
+                Log.i("TtsService", "Stopped");
             }
         } catch (InterruptedException e) {
-          Log.e("TTS stop", "tryLock interrupted");
+          Log.e("TtsService", "TTS stop: tryLock interrupted");
           e.printStackTrace();
         } finally {
             // This check is needed because finally will always run; even if the
@@ -448,7 +450,7 @@
                 if ((mCurrentSpeechItem != null) &&
                     ((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
                       mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
-                    result = nativeSynth.stop();
+                    result = sNativeSynth.stop();
                     mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
@@ -462,10 +464,10 @@
                 } else {
                     result = TextToSpeech.TTS_SUCCESS;
                 }
-                Log.i("TTS", "Stopped all");
+                Log.i("TtsService", "Stopped all");
             }
         } catch (InterruptedException e) {
-          Log.e("TTS stopAll", "tryLock interrupted");
+          Log.e("TtsService", "TTS stopAll: tryLock interrupted");
           e.printStackTrace();
         } finally {
             // This check is needed because finally will always run; even if the
@@ -546,21 +548,21 @@
                     if (!synthAvailable) {
                         Thread.sleep(100);
                         Thread synth = (new Thread(new SynthThread()));
-                        synth.setPriority(Thread.MIN_PRIORITY);
+                        //synth.setPriority(Thread.MIN_PRIORITY);
                         synth.start();
                         return;
                     }
                     int streamType = DEFAULT_STREAM_TYPE;
+                    String language = "";
+                    String country = "";
+                    String variant = "";
+                    String speechRate = "";
                     if (speechItem.mParams != null){
-                        String language = "";
-                        String country = "";
-                        String variant = "";
                         for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
                             String param = speechItem.mParams.get(i);
                             if (param != null) {
                                 if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) {
-                                    setSpeechRate("",
-                                            Integer.parseInt(speechItem.mParams.get(i+1)));
+                                    speechRate = speechItem.mParams.get(i+1);
                                 } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){
                                     language = speechItem.mParams.get(i+1);
                                 } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){
@@ -579,16 +581,19 @@
                                 }
                             }
                         }
+                    }
+                    // Only do the synthesis if it has not been killed by a subsequent utterance.
+                    if (mKillList.get(speechItem) == null) {
                         if (language.length() > 0){
                             setLanguage("", language, country, variant);
                         }
-                    }
-                    // Only do the synthesis if it has not been killed by a subsequent utterance.
-                    if (mKillList.get(speechItem) == null){
-                        nativeSynth.speak(speechItem.mText, streamType);
+                        if (speechRate.length() > 0){
+                            setSpeechRate("", Integer.parseInt(speechRate));
+                        }
+                        sNativeSynth.speak(speechItem.mText, streamType);
                     }
                 } catch (InterruptedException e) {
-                    Log.e("TTS speakInternalOnly", "tryLock interrupted");
+                    Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
                     e.printStackTrace();
                 } finally {
                     // This check is needed because finally will always run;
@@ -605,7 +610,7 @@
             }
         }
         Thread synth = (new Thread(new SynthThread()));
-        synth.setPriority(Thread.MIN_PRIORITY);
+        //synth.setPriority(Thread.MIN_PRIORITY);
         synth.start();
     }
 
@@ -614,26 +619,26 @@
             public void run() {
                 boolean synthAvailable = false;
                 String utteranceId = "";
-                Log.i("TTS", "Synthesizing to " + speechItem.mFilename);
+                Log.i("TtsService", "Synthesizing to " + speechItem.mFilename);
                 try {
                     synthAvailable = synthesizerLock.tryLock();
                     if (!synthAvailable) {
                         Thread.sleep(100);
                         Thread synth = (new Thread(new SynthThread()));
-                        synth.setPriority(Thread.MIN_PRIORITY);
+                        //synth.setPriority(Thread.MIN_PRIORITY);
                         synth.start();
                         return;
                     }
+                    String language = "";
+                    String country = "";
+                    String variant = "";
+                    String speechRate = "";
                     if (speechItem.mParams != null){
-                        String language = "";
-                        String country = "";
-                        String variant = "";
                         for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
                             String param = speechItem.mParams.get(i);
-                            if (param != null){
-                                if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)){
-                                    setSpeechRate("",
-                                            Integer.parseInt(speechItem.mParams.get(i+1)));
+                            if (param != null) {
+                                if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) {
+                                    speechRate = speechItem.mParams.get(i+1);
                                 } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){
                                     language = speechItem.mParams.get(i+1);
                                 } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){
@@ -645,16 +650,19 @@
                                 }
                             }
                         }
-                        if (language.length() > 0){
-                            setLanguage("", language, country, variant);
-                        }
                     }
                     // Only do the synthesis if it has not been killed by a subsequent utterance.
                     if (mKillList.get(speechItem) == null){
-                        nativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+                        if (language.length() > 0){
+                            setLanguage("", language, country, variant);
+                        }
+                        if (speechRate.length() > 0){
+                            setSpeechRate("", Integer.parseInt(speechRate));
+                        }
+                        sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
                     }
                 } catch (InterruptedException e) {
-                    Log.e("TTS synthToFileInternalOnly", "tryLock interrupted");
+                    Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");
                     e.printStackTrace();
                 } finally {
                     // This check is needed because finally will always run;
@@ -671,7 +679,7 @@
             }
         }
         Thread synth = (new Thread(new SynthThread()));
-        synth.setPriority(Thread.MIN_PRIORITY);
+        //synth.setPriority(Thread.MIN_PRIORITY);
         synth.start();
     }
 
@@ -699,7 +707,7 @@
         if (cb == null){
             return;
         }
-        Log.i("TTS callback", "dispatch started");
+        Log.i("TtsService", "TTS callback: dispatch started");
         // Broadcast to all clients the new value.
         final int N = mCallbacks.beginBroadcast();
         try {
@@ -709,7 +717,7 @@
             // the dead object for us.
         }
         mCallbacks.finishBroadcast();
-        Log.i("TTS callback", "dispatch completed to " + N);
+        Log.i("TtsService", "TTS callback: dispatch completed to " + N);
     }
 
     private SpeechItem splitCurrentTextIfNeeded(SpeechItem currentSpeechItem){
@@ -758,7 +766,7 @@
             SoundResource sr = getSoundResource(mCurrentSpeechItem);
             // Synth speech as needed - synthesizer should call
             // processSpeechQueue to continue running the queue
-            Log.i("TTS processing: ", mCurrentSpeechItem.mText);
+            Log.i("TtsService", "TTS processing: " + mCurrentSpeechItem.mText);
             if (sr == null) {
                 if (mCurrentSpeechItem.mType == SpeechItem.TEXT) {
                     mCurrentSpeechItem = splitCurrentTextIfNeeded(mCurrentSpeechItem);
diff --git a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
index c6c9452..e4c070f 100644
--- a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
+++ b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
@@ -106,6 +106,13 @@
     @Override
     protected void performTask() throws IOException {
         String svc = mServiceName;
+        Log.d(mTag, "-----  Stop the daemon just in case: " + mServiceName);
+        SystemProperties.set(SVC_STOP_CMD, mServiceName);
+        if (!blockUntil(SVC_STATE_STOPPED, 5)) {
+            throw new IOException("cannot start service anew: " + svc
+                    + ", it is still running");
+        }
+
         Log.d(mTag, "+++++  Start: " + svc);
         SystemProperties.set(SVC_START_CMD, svc);
 
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
index cf153e3..32b8e51 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
@@ -57,6 +57,7 @@
     public void onStart (Intent intent, int startId) {
         super.onStart(intent, startId);
         setForeground(true);
+        android.util.Log.d("VpnServiceBinder", "becomes a foreground service");
     }
 
     public IBinder onBind(Intent intent) {
@@ -71,9 +72,8 @@
     }
 
     private synchronized void checkStatus(VpnProfile p) {
-        if (mService == null) broadcastConnectivity(p.getName(), VpnState.IDLE);
-
-        if (!p.getName().equals(mService.mProfile.getName())) {
+        if ((mService == null)
+                || (!p.getName().equals(mService.mProfile.getName()))) {
             broadcastConnectivity(p.getName(), VpnState.IDLE);
         } else {
             broadcastConnectivity(p.getName(), mService.getState());
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b85cf2c..d8dafb6 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4905,6 +4905,22 @@
                     pw.print("    resourcePath="); pw.println(ps.resourcePathString);
                     if (ps.pkg != null) {
                         pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
+                        pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
+                        pw.print("    densities="); pw.println(ps.pkg.supportsDensityList);
+                        ArrayList<String> screens = new ArrayList<String>();
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
+                            screens.add("medium");
+                        }
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
+                            screens.add("large");
+                        }
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
+                            screens.add("small,");
+                        }
+                        pw.print("    supportsScreens="); pw.println(screens);
                     }
                     pw.print("    timeStamp="); pw.println(ps.getTimeStampStr());
                     pw.print("    signatures="); pw.println(ps.signatures);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 5425709..2937ed0 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -27,6 +27,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
 import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -1857,7 +1858,7 @@
         // is running.
         if (!mDisplayFrozen) {
             Animation a;
-            if ((lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+            if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
                 a = new FadeInOutAnimation(enter);
                 if (DEBUG_ANIM) Log.v(TAG,
                         "applying FadeInOutAnimation for a window in compatibility mode");
@@ -5871,7 +5872,9 @@
 
             if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
                 container.intersect(mCompatibleScreenFrame);
-                display.intersect(mCompatibleScreenFrame);
+                if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
+                    display.intersect(mCompatibleScreenFrame);
+                }
             }
 
             final int pw = container.right - container.left;
@@ -6588,12 +6591,17 @@
                 return false;
             }
             final Rect frame = shownFrame ? mShownFrame : mFrame;
-            if (frame.left <= 0 && frame.top <= 0
-                    && frame.right >= screenWidth
-                    && frame.bottom >= screenHeight) {
-                return true;
+
+            if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+                return frame.left <= mCompatibleScreenFrame.left &&
+                        frame.top <= mCompatibleScreenFrame.top &&
+                        frame.right >= mCompatibleScreenFrame.right &&
+                        frame.bottom >= mCompatibleScreenFrame.bottom;
+            } else {
+                return frame.left <= 0 && frame.top <= 0
+                        && frame.right >= screenWidth
+                        && frame.bottom >= screenHeight;
             }
-            return false;
         }
 
         /**
@@ -6610,16 +6618,13 @@
                  (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
                  // only if it's visible
                  mHasDrawn && mViewVisibility == View.VISIBLE &&
-                 // and only if the application wanted to fill the screen
-                 mAttrs.width == mAttrs.FILL_PARENT &&
-                 mAttrs.height == mAttrs.FILL_PARENT &&
-                 // and only if the window is not hidden
-                 mFrame.left == mCompatibleScreenFrame.left &&
+                 // and only if the application fills the compatible screen
+                 mFrame.left <= mCompatibleScreenFrame.left &&
+                 mFrame.top <= mCompatibleScreenFrame.top &&
+                 mFrame.right >= mCompatibleScreenFrame.right &&
+                 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
                  // and starting window do not need background filler
-                 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING &&
-                 // and only if the screen is bigger
-                 ((mFrame.right - mFrame.right) < screenWidth ||
-                         (mFrame.bottom - mFrame.top) < screenHeight);
+                 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
         }
 
         boolean isFullscreen(int screenWidth, int screenHeight) {
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 39a1ee0..c834b34 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -41,7 +41,7 @@
     
     final BatteryStatsImpl mStats;
     Context mContext;
-    
+
     BatteryStatsService(String filename) {
         mStats = new BatteryStatsImpl(filename);
     }
diff --git a/tests/AndroidTests/AndroidManifest.xml b/tests/AndroidTests/AndroidManifest.xml
index 55d4d64..845f547 100644
--- a/tests/AndroidTests/AndroidManifest.xml
+++ b/tests/AndroidTests/AndroidManifest.xml
@@ -48,6 +48,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WRITE_GSERVICES" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <uses-permission android:name="com.android.unit_tests.permission.TEST_GRANTED" />
 
diff --git a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java
new file mode 100755
index 0000000..7dc1314
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests;
+
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.VpnType;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Unit test class to test VPN api
+ * Use the below command to run the vpn unit test only
+ * runtest vpntest or
+ * adb shell am instrument -e class 'com.android.unit_tests.VpnTest'
+ *   -w com.android.unit_tests/android.test.InstrumentationTestRunner
+ */
+public class VpnTest extends AndroidTestCase {
+
+    @Override
+    public void setUp() {
+    }
+
+    @Override
+    public void tearDown() {
+    }
+
+    @SmallTest
+    public void testGetType() {
+        L2tpIpsecProfile li = new L2tpIpsecProfile();
+        assertTrue(VpnType.L2TP_IPSEC== li.getType());
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
index e6639d3..a065d70 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
@@ -133,7 +133,7 @@
                 case DENSITY:
                     // this is the ratio from the standard
 
-                    mMetrics.density = (((float)value)/((float)DisplayMetrics.DEFAULT_DENSITY));
+                    mMetrics.density = (((float)value)/((float)DisplayMetrics.DENSITY_DEFAULT));
                     break;
                 default:
                     assert(false);
diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml
index 64ad7be..68ecc6e 100644
--- a/tests/DpiTest/AndroidManifest.xml
+++ b/tests/DpiTest/AndroidManifest.xml
@@ -19,10 +19,15 @@
     <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" />
     <supports-screens android:smallScreens="true" />
     <application android:label="DpiTest">
-        <activity android:name="DpiTestActivity" android:label="DpiTest">
+        <activity android:name="DpiTestActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name="DpiTestNoCompatActivity" android:label="DpiTestNoCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
diff --git a/tests/DpiTest/res/drawable-nodpi/logonodpi120.png b/tests/DpiTest/res/drawable-nodpi/logonodpi120.png
new file mode 100644
index 0000000..46bbd5b
--- /dev/null
+++ b/tests/DpiTest/res/drawable-nodpi/logonodpi120.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-nodpi/logonodpi160.png b/tests/DpiTest/res/drawable-nodpi/logonodpi160.png
new file mode 100644
index 0000000..c23b2ce
--- /dev/null
+++ b/tests/DpiTest/res/drawable-nodpi/logonodpi160.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-nodpi/logonodpi240.png b/tests/DpiTest/res/drawable-nodpi/logonodpi240.png
new file mode 100644
index 0000000..4d717a8
--- /dev/null
+++ b/tests/DpiTest/res/drawable-nodpi/logonodpi240.png
Binary files differ
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 5a9f3f5..8c69305 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -17,6 +17,8 @@
 package com.google.android.test.dpi;
 
 import android.app.Activity;
+import android.app.ActivityThread;
+import android.app.Application;
 import android.os.Bundle;
 import android.graphics.BitmapFactory;
 import android.graphics.Bitmap;
@@ -28,8 +30,42 @@
 import android.widget.ScrollView;
 import android.view.View;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.CompatibilityInfo;
+import android.util.DisplayMetrics;
 
 public class DpiTestActivity extends Activity {
+    public DpiTestActivity() {
+        super();
+        init(false);
+    }
+    
+    public DpiTestActivity(boolean noCompat) {
+        super();
+        init(noCompat);
+    }
+    
+    public void init(boolean noCompat) {
+        try {
+            // This is all a dirty hack.  Don't think a real application should
+            // be doing it.
+            Application app = ActivityThread.currentActivityThread().getApplication();
+            ApplicationInfo ai = app.getPackageManager().getApplicationInfo(
+                    "com.google.android.test.dpi",
+                    PackageManager.GET_SUPPORTS_DENSITIES);
+            if (noCompat) {
+                ai.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+                    | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
+                    | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+                ai.supportsDensities = new int[] { ApplicationInfo.ANY_DENSITY };
+                app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai));
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new RuntimeException("ouch", e);
+        }
+    }
+    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -73,6 +109,13 @@
         addLabelToRoot(root, "Autoscaled bitmap");
         addChildToRoot(root, layout);
 
+        layout = new LinearLayout(this);
+        addResourceDrawable(layout, R.drawable.logonodpi120);
+        addResourceDrawable(layout, R.drawable.logonodpi160);
+        addResourceDrawable(layout, R.drawable.logonodpi240);
+        addLabelToRoot(root, "No-dpi resource drawable");
+        addChildToRoot(root, layout);
+
         setContentView(scrollWrap(root));
     }
 
@@ -155,7 +198,10 @@
         @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            setMeasuredDimension(mBitmap.getScaledWidth(), mBitmap.getScaledHeight());
+            final DisplayMetrics metrics = getResources().getDisplayMetrics();
+            setMeasuredDimension(
+                    mBitmap.getScaledWidth(metrics),
+                    mBitmap.getScaledHeight(metrics));
         }
 
         @Override
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestNoCompatActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestNoCompatActivity.java
new file mode 100644
index 0000000..4d25e08
--- /dev/null
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestNoCompatActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.test.dpi;
+
+public class DpiTestNoCompatActivity extends DpiTestActivity {
+    public DpiTestNoCompatActivity() {
+        super(true);
+    }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index 39bbf16..ba46197 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -73,6 +73,10 @@
         runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
 
         activity.clearCache();
+        try {
+            Thread.sleep(5000);
+        } catch (InterruptedException e) {
+        }
         dumpMemoryInfo();
 
         // Kill activity
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 67af116..14cad2f 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -654,9 +654,15 @@
                                     ResTable_config* out)
 {
     if (strcmp(name, kWildcardName) == 0) {
-        if (out) out->density = 0;
+        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
         return true;
     }
+    
+    if (strcmp(name, "nodpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_NONE;
+        return true;
+    }
+    
     char* c = (char*)name;
     while (*c >= '0' && *c <= '9') {
         c++;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index d0a1c46..fd77d51 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -286,8 +286,8 @@
         }
 
         return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DEFAULT_DENSITY,
-                DisplayMetrics.DEFAULT_DENSITY, DisplayMetrics.DEFAULT_DENSITY,
+                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
+                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
                 themeName, isProjectTheme,
                 projectResources, frameworkResources, customViewLoader, logger);
     }
@@ -304,8 +304,8 @@
             Map<String, Map<String, IResourceValue>> frameworkResources,
             IProjectCallback customViewLoader, ILayoutLog logger) {
         return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DEFAULT_DENSITY,
-                DisplayMetrics.DEFAULT_DENSITY, DisplayMetrics.DEFAULT_DENSITY,
+                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
+                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
                 themeName, isProjectTheme,
                 projectResources, frameworkResources, customViewLoader, logger);
     }
@@ -340,7 +340,7 @@
         try {
             // setup the display Metrics.
             DisplayMetrics metrics = new DisplayMetrics();
-            metrics.density = density / (float) DisplayMetrics.DEFAULT_DENSITY;
+            metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT;
             metrics.scaledDensity = metrics.density;
             metrics.widthPixels = screenWidth;
             metrics.heightPixels = screenHeight;