Merge change 7819 into donut

* changes:
  Fix NullPointer in VpnServiceBinder.checkStatus().
diff --git a/api/current.xml b/api/current.xml
index afba894..bb932e6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -32173,6 +32173,39 @@
  visibility="public"
 >
 </field>
+<field name="ACTION_TTS_CHECK_TTS_DATA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.CHECK_TTS_DATA&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_TTS_INSTALL_TTS_DATA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.INSTALL_TTS_DATA&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_TTS_QUEUE_PROCESSING_COMPLETED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTION_UID_REMOVED"
  type="java.lang.String"
  transient="false"
@@ -48909,6 +48942,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"
@@ -48982,6 +49026,28 @@
  visibility="public"
 >
 </method>
+<method name="getScaledHeight"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getScaledWidth"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getWidth"
  return="int"
  abstract="false"
@@ -49004,6 +49070,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"
@@ -49048,6 +49125,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"
@@ -49115,6 +49218,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"
@@ -49334,6 +49448,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">
@@ -49382,6 +49517,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"
@@ -49442,6 +49587,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"
@@ -50696,6 +50851,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"
@@ -51042,6 +51208,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"
@@ -132936,6 +133115,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"
@@ -134985,6 +135208,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"
@@ -135213,6 +135458,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/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index ec7714d..ba6cc32 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1068,6 +1068,23 @@
             unregisterActivityWatcher(watcher);
             return true;
         }
+        
+        case START_ACTIVITY_IN_PACKAGE_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            int uid = data.readInt();
+            Intent intent = Intent.CREATOR.createFromParcel(data);
+            String resolvedType = data.readString();
+            IBinder resultTo = data.readStrongBinder();
+            String resultWho = data.readString();    
+            int requestCode = data.readInt();
+            boolean onlyIfNeeded = data.readInt() != 0;
+            int result = startActivityInPackage(uid, intent, resolvedType,
+                    resultTo, resultWho, requestCode, onlyIfNeeded);
+            reply.writeNoException();
+            reply.writeInt(result);
+            return true;
+        }
         }
         
         return super.onTransact(code, data, reply, flags);
@@ -2330,5 +2347,27 @@
         reply.recycle();
     }
     
+    public int startActivityInPackage(int uid,
+            Intent intent, String resolvedType, IBinder resultTo,
+            String resultWho, int requestCode, boolean onlyIfNeeded)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(uid);
+        intent.writeToParcel(data, 0);
+        data.writeString(resolvedType);
+        data.writeStrongBinder(resultTo);
+        data.writeString(resultWho);
+        data.writeInt(requestCode);
+        data.writeInt(onlyIfNeeded ? 1 : 0);
+        mRemote.transact(START_ACTIVITY_IN_PACKAGE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+        
     private IBinder mRemote;
 }
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/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ee1b69b..95b376c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -262,6 +262,11 @@
     public void unregisterActivityWatcher(IActivityWatcher watcher)
             throws RemoteException;
 
+    public int startActivityInPackage(int uid,
+            Intent intent, String resolvedType, IBinder resultTo,
+            String resultWho, int requestCode, boolean onlyIfNeeded)
+            throws RemoteException;
+        
     /*
      * Private non-Binder interfaces
      */
@@ -415,4 +420,5 @@
     int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
     int REGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
     int UNREGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
+    int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index bfd9923..906361c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -139,8 +139,8 @@
     
     // A weak map of drawables we've gotten from other packages, so we don't load them
     // more than once.
-    private final WeakHashMap<String, Drawable> mOutsideDrawablesCache =
-            new WeakHashMap<String, Drawable>();
+    private final WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache =
+            new WeakHashMap<String, Drawable.ConstantState>();
 
     // Last known IME options value for the search edit text.
     private int mSearchAutoCompleteImeOptions;
@@ -1042,6 +1042,8 @@
                 mSearchAutoComplete.setSelection(selPoint);
                 mSearchAutoComplete.setListSelection(0);
                 mSearchAutoComplete.clearListSelection();
+                mSearchAutoComplete.ensureImeVisible();
+                
                 return true;
             }
             
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index dc5e864..593b7b7 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -40,6 +40,7 @@
 import android.widget.ImageView;
 import android.widget.ResourceCursorAdapter;
 import android.widget.TextView;
+import android.widget.Filter;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -60,8 +61,8 @@
     private SearchDialog mSearchDialog;
     private SearchableInfo mSearchable;
     private Context mProviderContext;
-    private WeakHashMap<String, Drawable> mOutsideDrawablesCache;
-    private SparseArray<Drawable> mBackgroundsCache;
+    private WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache;
+    private SparseArray<Drawable.ConstantState> mBackgroundsCache;
     private boolean mGlobalSearchMode;
 
     // Cached column indexes, updated when the cursor changes.
@@ -90,8 +91,16 @@
     private final Runnable mStartSpinnerRunnable;
     private final Runnable mStopSpinnerRunnable;
 
-    public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable,
-            WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) {
+    /**
+     * The amount of time we delay in the filter when the user presses the delete key.
+     * @see Filter#setDelayer(android.widget.Filter.Delayer).
+     */
+    private static final long DELETE_KEY_POST_DELAY = 500L;
+
+    public SuggestionsAdapter(Context context, SearchDialog searchDialog,
+            SearchableInfo searchable,
+            WeakHashMap<String, Drawable.ConstantState> outsideDrawablesCache,
+            boolean globalSearchMode) {
         super(context,
                 com.android.internal.R.layout.search_dropdown_item_icons_2line,
                 null,   // no initial cursor
@@ -105,7 +114,7 @@
         mProviderContext = mSearchable.getProviderContext(mContext, activityContext);
 
         mOutsideDrawablesCache = outsideDrawablesCache;
-        mBackgroundsCache = new SparseArray<Drawable>();
+        mBackgroundsCache = new SparseArray<Drawable.ConstantState>();
         mGlobalSearchMode = globalSearchMode;
 
         mStartSpinnerRunnable = new Runnable() {
@@ -119,6 +128,18 @@
                 mSearchDialog.setWorking(false);
             }
         };
+
+        // delay 500ms when deleting
+        getFilter().setDelayer(new Filter.Delayer() {
+
+            private int mPreviousLength = 0;
+
+            public long getPostingDelay(CharSequence constraint) {
+                long delay = constraint.length() < mPreviousLength ? DELETE_KEY_POST_DELAY : 0;
+                mPreviousLength = constraint.length();
+                return delay;
+            }
+        });
     }
 
     /**
@@ -326,11 +347,10 @@
         if (backgroundColor == 0) {
             return null;
         } else {
-            Drawable cachedBg = mBackgroundsCache.get(backgroundColor);
+            Drawable.ConstantState cachedBg = mBackgroundsCache.get(backgroundColor);
             if (cachedBg != null) {
                 if (DBG) Log.d(LOG_TAG, "Background cache hit for color " + backgroundColor);
-                // copy the drawable so that they don't share states
-                return cachedBg.getConstantState().newDrawable();
+                return cachedBg.newDrawable();
             }
             if (DBG) Log.d(LOG_TAG, "Creating new background for color " + backgroundColor);
             ColorDrawable transparent = new ColorDrawable(0);
@@ -339,7 +359,7 @@
             newBg.addState(new int[]{android.R.attr.state_selected}, transparent);
             newBg.addState(new int[]{android.R.attr.state_pressed}, transparent);
             newBg.addState(new int[]{}, background);
-            mBackgroundsCache.put(backgroundColor, newBg);
+            mBackgroundsCache.put(backgroundColor, newBg.getConstantState());
             return newBg;
         }
     }
@@ -504,12 +524,13 @@
         }
 
         // First, check the cache.
-        Drawable drawable = mOutsideDrawablesCache.get(drawableId);
-        if (drawable != null) {
+        Drawable.ConstantState cached = mOutsideDrawablesCache.get(drawableId);
+        if (cached != null) {
             if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + drawableId);
-            return drawable;
+            return cached.newDrawable();
         }
 
+        Drawable drawable = null;
         try {
             // Not cached, try using it as a plain resource ID in the provider's context.
             int resourceId = Integer.parseInt(drawableId);
@@ -541,7 +562,7 @@
             // If we got a drawable for this resource id, then stick it in the
             // map so we don't do this lookup again.
             if (drawable != null) {
-                mOutsideDrawablesCache.put(drawableId, drawable);
+                mOutsideDrawablesCache.put(drawableId, drawable.getConstantState());
             }
         } catch (Resources.NotFoundException nfe) {
             if (DBG) Log.d(LOG_TAG, "Icon resource not found: " + drawableId);
@@ -596,12 +617,14 @@
         String componentIconKey = component.flattenToShortString();
         // Using containsKey() since we also store null values.
         if (mOutsideDrawablesCache.containsKey(componentIconKey)) {
-            return mOutsideDrawablesCache.get(componentIconKey);
+            Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey);
+            return cached == null ? null : cached.newDrawable();
         }
         // Then try the activity or application icon
         Drawable drawable = getActivityIcon(component);
         // Stick it in the cache so we don't do this lookup again.
-        mOutsideDrawablesCache.put(componentIconKey, drawable);
+        Drawable.ConstantState toCache = drawable == null ? null : drawable.getConstantState();
+        mOutsideDrawablesCache.put(componentIconKey, toCache);
         return drawable;
     }
 
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/Intent.java b/core/java/android/content/Intent.java
index 9202b9a..b0dbfcb 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1683,10 +1683,47 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_REBOOT =
             "android.intent.action.REBOOT";
+    /**
+     * Broadcast Action: Triggers the platform Text-To-Speech engine to
+     * start the activity that installs the resource files on the device
+     * that are required for TTS to be operational. Since the installation
+     * of the data can be interrupted or declined by the user, the application
+     * shouldn't expect successful installation upon return from that intent,
+     * and if need be, should check installation status with 
+     * {@link #ACTION_TTS_CHECK_TTS_DATA}.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_TTS_INSTALL_TTS_DATA =
+            "android.intent.action.INSTALL_TTS_DATA";
 
     /**
-     * @hide
-     * TODO: This will be unhidden in a later CL.
+     * Broadcast Action: Starts the activity from the platform Text-To-Speech
+     * engine to verify the proper installation and availability of the
+     * resource files on the system. Upon completion, the activity will
+     * return one of the following codes: 
+     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_PASS},
+     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_FAIL},
+     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_BAD_DATA},
+     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_DATA}, or
+     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_VOLUME}.
+     * <p> Moreover, the data received in the activity result will contain the following
+     * fields:
+     * <ul>
+     *   <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_ROOT_DIRECTORY} which
+     *       indicates the path to the location of the resource files</li>,
+     *   <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES} which contains
+     *       the list of all the resource files</li>,
+     *   <li>and {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES_INFO} which
+     *       contains, for each resource file, the description of the language covered by
+     *       the file in the xxx-YYY format, where xxx is the 3-letter ISO language code,
+     *       and YYY is the 3-letter ISO country code.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_TTS_CHECK_TTS_DATA =
+            "android.intent.action.CHECK_TTS_DATA";
+
+    /**
      * Broadcast Action: The TextToSpeech synthesizer has completed processing 
      * all of the text in the speech queue.
      */
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index ebe556e..d4e2507 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -38,7 +38,12 @@
     private static final String TAG = "CompatibilityInfo";
     
     /** default compatibility info object for compatible applications */
-    public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo(); 
+    public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo() {
+        @Override
+        public void setExpandable(boolean expandable) {
+            throw new UnsupportedOperationException("trying to change default compatibility info");
+        }
+    };
 
     /**
      * The default width of the screen in portrait mode. 
@@ -109,14 +114,14 @@
                     packageDensityScale = 1.0f;
                     break;
                 }
-                int tmpDiff = Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
+                int tmpDiff = Math.abs(DisplayMetrics.DENSITY_DEVICE - density);
                 if (tmpDiff == 0) {
                     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;
+                    packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density;
                     minDiff = tmpDiff;
                 }
             }
@@ -125,7 +130,7 @@
             applicationScale = packageDensityScale;
         } else {
             applicationScale =
-                    DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
+                    DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT;
         }
 
         applicationInvertedScale = 1.0f / applicationScale;
@@ -191,7 +196,7 @@
     @Override
     public String toString() {
         return "CompatibilityInfo{scale=" + applicationScale +
-                ", compatibility flag=" + mCompatibilityFlags + "}"; 
+                ", supports screen=" + supportsScreen() + "}";
     }
 
     /**
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/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..28c1fe1fe 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,7 +255,7 @@
     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);
             try {
@@ -290,6 +289,8 @@
     public void setWindowType(int type) {
         mWindowType = type;
     }
+
+    boolean mScaled = false;
     
     private void updateWindow(boolean force) {
         if (!mHaveFrame) {
@@ -309,6 +310,9 @@
         if (mRequestedWidth <= 0 && mTranslator != null) {
             myWidth *= appScale;
             myHeight *= appScale;
+            mScaled = true;
+        } else {
+            mScaled = false;
         }
 
         getLocationInWindow(mLocation);
@@ -533,6 +537,7 @@
     private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
         
         private static final String LOG_TAG = "SurfaceHolder";
+        private int mSaveCount;
         
         public boolean isCreating() {
             return mIsCreating;
@@ -627,6 +632,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 +658,9 @@
         }
 
         public void unlockCanvasAndPost(Canvas canvas) {
+            if (mScaled) {
+                canvas.restoreToCount(mSaveCount);
+            }
             mSurface.unlockCanvasAndPost(canvas);
             mSurfaceLock.unlock();
         }
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index eab3799..301d604 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -497,8 +497,12 @@
     void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
         synchronized (this) {
             int oldSoftInputMode = mWindowAttributes.softInputMode;
+            // preserve compatible window flag if exists.
+            int compatibleWindowFlag =
+                mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
             mWindowAttributes.copyFrom(attrs);
-
+            mWindowAttributes.flags |= compatibleWindowFlag;
+            
             if (newView) {
                 mSoftInputMode = attrs.softInputMode;
                 requestLayout();
@@ -1301,7 +1305,8 @@
                 if (DEBUG_DRAW) {
                     Context cxt = mView.getContext();
                     Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
-                            ", metrics=" + mView.getContext().getResources().getDisplayMetrics());
+                            ", metrics=" + cxt.getResources().getDisplayMetrics() +
+                            ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
                 }
                 int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
                 try {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e96a15b..ba3bfa7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -986,6 +986,9 @@
                 sb.append(" or=");
                 sb.append(screenOrientation);
             }
+            if ((flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+                sb.append(" compatible=true");
+            }
             sb.append('}');
             return sb.toString();
         }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f9ca8cb..777beed 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -720,7 +720,7 @@
     @Override
     public void getFocusedRect(Rect r) {
         View view = getSelectedView();
-        if (view != null) {
+        if (view != null && view.getParent() == this) {
             // the focused rectangle of the selected view offset into the
             // coordinate space of this view.
             view.getFocusedRect(r);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 9eef98c..0df587f 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -210,8 +210,7 @@
         if (mDropDownAlwaysVisible
                 && mPopup.isShowing()
                 && mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED) {
-            mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
-            showDropDown();
+            ensureImeVisible();
         }
     }
 
@@ -1086,11 +1085,21 @@
     /**
      * Issues a runnable to show the dropdown as soon as possible.
      *
-     * @hide internal used only by Search Dialog
+     * @hide internal used only by SearchDialog
      */
     public void showDropDownAfterLayout() {
         post(mShowDropDownRunnable);
     }
+    
+    /**
+     * Ensures that the drop down is not obscuring the IME.
+     * 
+     * @hide internal used only here and SearchDialog
+     */
+    public void ensureImeVisible() {
+        mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+        showDropDown();
+    }
 
     /**
      * <p>Displays the drop down on screen.</p>
diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java
index bdecf62..d901540 100644
--- a/core/java/android/widget/Filter.java
+++ b/core/java/android/widget/Filter.java
@@ -46,6 +46,8 @@
     private Handler mThreadHandler;
     private Handler mResultHandler;
 
+    private Delayer mDelayer;
+
     private final Object mLock = new Object();
 
     /**
@@ -56,6 +58,20 @@
     }
 
     /**
+     * Provide an interface that decides how long to delay the message for a given query.  Useful
+     * for heuristics such as posting a delay for the delete key to avoid doing any work while the
+     * user holds down the delete key.
+     *
+     * @param delayer The delayer.
+     * @hide
+     */
+    public void setDelayer(Delayer delayer) {
+        synchronized (mLock) {
+            mDelayer = delayer;
+        }
+    }
+
+    /**
      * <p>Starts an asynchronous filtering operation. Calling this method
      * cancels all previous non-executed filtering requests and posts a new
      * filtering request that will be executed later.</p>
@@ -90,6 +106,8 @@
                 thread.start();
                 mThreadHandler = new RequestHandler(thread.getLooper());
             }
+
+            final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint);
             
             Message message = mThreadHandler.obtainMessage(FILTER_TOKEN);
     
@@ -102,7 +120,7 @@
     
             mThreadHandler.removeMessages(FILTER_TOKEN);
             mThreadHandler.removeMessages(FINISH_TOKEN);
-            mThreadHandler.sendMessage(message);
+            mThreadHandler.sendMessageDelayed(message, delay);
         }
     }
 
@@ -289,4 +307,17 @@
          */
         FilterResults results;
     }
+
+    /**
+     * @hide
+     */
+    public interface Delayer {
+
+        /**
+         * @param constraint The constraint passed to {@link Filter#filter(CharSequence)}
+         * @return The delay that should be used for
+         *         {@link Handler#sendMessageDelayed(android.os.Message, long)}
+         */
+        long getPostingDelay(CharSequence constraint);
+    }
 }
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index af8ecf5..3fb07a7 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -224,7 +224,7 @@
     SkBitmap bitmap;

 

     bitmap.setConfig(config, width, height);

-    if (!GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL)) {

+    if (!GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL, true)) {

         return NULL;

     }

 

@@ -240,7 +240,7 @@
 static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,

                            SkBitmap::Config dstConfig, jboolean isMutable) {

     SkBitmap            result;

-    JavaPixelAllocator  allocator(env);

+    JavaPixelAllocator  allocator(env, true);

 

     if (!src->copyTo(&result, dstConfig, &allocator)) {

         return NULL;

@@ -356,7 +356,7 @@
         }

     }

 

-    if (!GraphicsJNI::setJavaPixelRef(env, bitmap, ctable)) {

+    if (!GraphicsJNI::setJavaPixelRef(env, bitmap, ctable, true)) {

         ctable->safeUnref();

         delete bitmap;

         return NULL;

diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 137707f..0c84265 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -23,6 +23,7 @@
 static jfieldID gOptions_ditherFieldID;
 static jfieldID gOptions_purgeableFieldID;
 static jfieldID gOptions_shareableFieldID;
+static jfieldID gOptions_nativeAllocFieldID;
 static jfieldID gOptions_widthFieldID;
 static jfieldID gOptions_heightFieldID;
 static jfieldID gOptions_mimeFieldID;
@@ -300,6 +301,11 @@
             env->GetBooleanField(options, gOptions_shareableFieldID);
 }
 
+static bool optionsReportSizeToVM(JNIEnv* env, jobject options) {
+    return NULL == options ||
+            !env->GetBooleanField(options, gOptions_nativeAllocFieldID);
+}
+
 static jobject nullObjectReturn(const char msg[]) {
     if (msg) {
         SkDebugf("--- %s\n", msg);
@@ -330,6 +336,7 @@
     SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
     bool doDither = true;
     bool isPurgeable = allowPurgeable && optionsPurgeable(env, options);
+    bool reportSizeToVM = optionsReportSizeToVM(env, options);
     
     if (NULL != options) {
         sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
@@ -355,7 +362,7 @@
     decoder->setDitherImage(doDither);
 
     NinePatchPeeker     peeker;
-    JavaPixelAllocator  javaAllocator(env);
+    JavaPixelAllocator  javaAllocator(env, reportSizeToVM);
     SkBitmap*           bitmap = new SkBitmap;
     Res_png_9patch      dummy9Patch;
 
@@ -699,6 +706,7 @@
     gOptions_ditherFieldID = getFieldIDCheck(env, gOptions_class, "inDither", "Z");
     gOptions_purgeableFieldID = getFieldIDCheck(env, gOptions_class, "inPurgeable", "Z");
     gOptions_shareableFieldID = getFieldIDCheck(env, gOptions_class, "inInputShareable", "Z");
+    gOptions_nativeAllocFieldID = getFieldIDCheck(env, gOptions_class, "inNativeAlloc", "Z");
     gOptions_widthFieldID = getFieldIDCheck(env, gOptions_class, "outWidth", "I");
     gOptions_heightFieldID = getFieldIDCheck(env, gOptions_class, "outHeight", "I");
     gOptions_mimeFieldID = getFieldIDCheck(env, gOptions_class, "outMimeType", "Ljava/lang/String;");
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 6eebbdc..6e159a8 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -5,6 +5,7 @@
 #include "SkRegion.h"
 #include <android_runtime/AndroidRuntime.h>
 
+//#define REPORT_SIZE_TO_JVM
 //#define TRACK_LOCK_COUNT
 
 void doThrow(JNIEnv* env, const char* exc, const char* msg) {
@@ -444,7 +445,7 @@
 };
 
 bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
-                                  SkColorTable* ctable) {
+                                  SkColorTable* ctable, bool reportSizeToVM) {
     Sk64 size64 = bitmap->getSize64();
     if (size64.isNeg() || !size64.is32()) {
         doThrow(env, "java/lang/IllegalArgumentException",
@@ -453,35 +454,41 @@
     }
     
     size_t size = size64.get32();
-    //    SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
     jlong jsize = size;  // the VM wants longs for the size
-    bool r = env->CallBooleanMethod(gVMRuntime_singleton,
-                                     gVMRuntime_trackExternalAllocationMethodID,
-                                     jsize);
-    if (GraphicsJNI::hasException(env)) {
-        return false;
+    if (reportSizeToVM) {
+        //    SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
+        bool r = env->CallBooleanMethod(gVMRuntime_singleton,
+                                    gVMRuntime_trackExternalAllocationMethodID,
+                                    jsize);
+        if (GraphicsJNI::hasException(env)) {
+            return false;
+        }
+        if (!r) {
+            LOGE("VM won't let us allocate %zd bytes\n", size);
+            doThrowOOME(env, "bitmap size exceeds VM budget");
+            return false;
+        }
     }
-    if (!r) {
-        LOGE("VM won't let us allocate %zd bytes\n", size);
-        doThrowOOME(env, "bitmap size exceeds VM budget");
-        return false;
-    }
-    
     // call the version of malloc that returns null on failure
     void* addr = sk_malloc_flags(size, 0);
     if (NULL == addr) {
-        //        SkDebugf("-------------- inform VM we're releasing %d bytes which we couldn't allocate\n", size);
-        // we didn't actually allocate it, so inform the VM
-        env->CallVoidMethod(gVMRuntime_singleton,
-                             gVMRuntime_trackExternalFreeMethodID,
-                             jsize);
-        if (!GraphicsJNI::hasException(env)) {
-            doThrowOOME(env, "bitmap size too large for malloc");
+        if (reportSizeToVM) {
+            //        SkDebugf("-------------- inform VM we're releasing %d bytes which we couldn't allocate\n", size);
+            // we didn't actually allocate it, so inform the VM
+            env->CallVoidMethod(gVMRuntime_singleton,
+                                 gVMRuntime_trackExternalFreeMethodID,
+                                 jsize);
+            if (!GraphicsJNI::hasException(env)) {
+                doThrowOOME(env, "bitmap size too large for malloc");
+            }
         }
         return false;
     }
     
-    bitmap->setPixelRef(new AndroidPixelRef(env, addr, size, ctable))->unref();
+    SkPixelRef* pr = reportSizeToVM ?
+                        new AndroidPixelRef(env, addr, size, ctable) :
+                        new SkMallocPixelRef(addr, size, ctable);
+    bitmap->setPixelRef(pr)->unref();
     // since we're already allocated, we lockPixels right away
     // HeapAllocator behaves this way too
     bitmap->lockPixels();
@@ -490,12 +497,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) : fEnv(env)
-{
-}
+JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM)
+    : fEnv(env), fReportSizeToVM(reportSizeToVM) {}
     
 bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
-    return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable);
+    return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable, fReportSizeToVM);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index e2dc9ac..16925e4 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -59,7 +59,8 @@
         Returns true on success. If it returns false, then it failed, and the
         appropriate exception will have been raised.
     */
-    static bool setJavaPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable);
+    static bool setJavaPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable,
+                                bool reportSizeToVM);
 
     /** Copy the colors in colors[] to the bitmap, convert to the correct
         format along the way.
@@ -71,12 +72,13 @@
 
 class JavaPixelAllocator : public SkBitmap::Allocator {
 public:
-    JavaPixelAllocator(JNIEnv* env);
+    JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM);
     // overrides
     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
     
 private:
     JNIEnv* fEnv;
+    bool fReportSizeToVM;
 };
 
 class AutoJavaFloatArray {
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/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index e7d4694..fd92fbe 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -75,6 +75,9 @@
         int                        mStreamType;
 
     AudioTrackJniStorage() {
+        mCallbackData.audioTrack_class = 0;
+        mCallbackData.audioTrack_ref = 0;
+        mStreamType = AudioSystem::DEFAULT;
     }
 
     ~AudioTrackJniStorage() {
@@ -318,6 +321,8 @@
     env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0);
     
 native_track_failure:
+    env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_class);
+    env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref);
     delete lpJniStorage;
     env->SetIntField(thiz, javaAudioTrackFields.jniData, 0);
     return AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
@@ -415,6 +420,9 @@
     AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetIntField(
         thiz, javaAudioTrackFields.jniData);
     if (pJniStorage) {
+        // delete global refs created in native_setup
+        env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_class);
+        env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_ref);
         //LOGV("deleting pJniStorage: %x\n", (int)pJniStorage);
         delete pJniStorage;
     }
diff --git a/core/res/res/drawable/light_header.9.png b/core/res/res/drawable/light_header.9.png
new file mode 100644
index 0000000..ad5dce1
--- /dev/null
+++ b/core/res/res/drawable/light_header.9.png
Binary files differ
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 7d235ec..8eda12e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -348,7 +348,8 @@
     </style>
 
     <style name="Widget.TextView.ListSeparator.White">
-        <item name="android:textColor">?textColorSecondaryInverse</item>
+        <item name="android:textColor">?textColorPrimaryInverse</item>
+        <item name="android:background">@android:drawable/light_header</item>
     </style>
 
     <style name="Widget.EditText">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index be836eb..e3fffb7 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -325,6 +325,32 @@
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
         <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+
+        <item name="textAppearance">@android:style/TextAppearance</item>
+        <item name="textAppearanceInverse">@android:style/TextAppearance.Inverse</item>
+
+        <item name="textColorPrimary">@android:color/primary_text_dark</item>
+        <item name="textColorSecondary">@android:color/secondary_text_dark</item>
+        <item name="textColorTertiary">@android:color/tertiary_text_dark</item>
+        <item name="textColorPrimaryInverse">@android:color/primary_text_light</item>
+        <item name="textColorSecondaryInverse">@android:color/secondary_text_light</item>
+        <item name="textColorTertiaryInverse">@android:color/tertiary_text_light</item>
+        <item name="textColorPrimaryDisableOnly">@android:color/primary_text_dark_disable_only</item>
+        <item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_light_disable_only</item>
+        <item name="textColorPrimaryNoDisable">@android:color/primary_text_dark_nodisable</item>
+        <item name="textColorSecondaryNoDisable">@android:color/secondary_text_dark_nodisable</item>
+        <item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_light_nodisable</item>
+        <item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_light_nodisable</item>
+        <item name="textColorHint">@android:color/hint_foreground_dark</item>
+        <item name="textColorHintInverse">@android:color/hint_foreground_light</item>
+        <item name="textColorSearchUrl">@android:color/search_url_text</item>
+
+        <item name="textAppearanceLarge">@android:style/TextAppearance.Large</item>
+        <item name="textAppearanceMedium">@android:style/TextAppearance.Medium</item>
+        <item name="textAppearanceSmall">@android:style/TextAppearance.Small</item>
+        <item name="textAppearanceLargeInverse">@android:style/TextAppearance.Large.Inverse</item>
+        <item name="textAppearanceMediumInverse">@android:style/TextAppearance.Medium.Inverse</item>
+        <item name="textAppearanceSmallInverse">@android:style/TextAppearance.Small.Inverse</item>
     </style>
 
     <!-- Default theme for alert dialog windows, which is used by the
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index e2e93eb..141553e 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -31,8 +31,6 @@
      *
      * @see Bitmap#getDensityScale()
      * @see Bitmap#setDensityScale(float)
-     *
-     * @hide pending API council approval
      */
     public static final float DENSITY_SCALE_UNKNOWN = -1.0f;
 
@@ -84,11 +82,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 +102,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 +126,6 @@
      * @see #setAutoScalingEnabled(boolean)
      * @see #getDensityScale()
      * @see #setDensityScale(float)
-     *
-     * @hide pending API council approval
      */
     public boolean isAutoScalingEnabled() {
         return mAutoScaling;
@@ -150,8 +142,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 +455,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;
     }
@@ -616,11 +606,9 @@
      * by the density scale factor.
      *
      * @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();
+        final float scale = mDensityScale;
         return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getWidth() / scale);
     }
 
@@ -629,11 +617,9 @@
      * by the density scale factor.
      *
      * @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();
+        final float scale = mDensityScale;
         return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getHeight() / scale);
     }
 
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index e5a9aab..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;
 
@@ -129,6 +125,19 @@
         public boolean inInputShareable;
 
         /**
+         * Normally bitmap allocations count against the dalvik heap, which
+         * means they help trigger GCs when a lot have been allocated. However,
+         * in rare cases, the caller may want to allocate the bitmap outside of
+         * that heap. To request that, set inNativeAlloc to true. In these
+         * rare instances, it is solely up to the caller to ensure that OOM is
+         * managed explicitly by calling bitmap.recycle() as soon as such a
+         * bitmap is no longer needed.
+         *
+         * @hide pending API council approval
+         */
+        public boolean inNativeAlloc;
+
+        /**
          * The resulting width of the bitmap, set independent of the state of
          * inJustDecodeBounds. However, if there is an error trying to decode,
          * outWidth will be set to -1.
@@ -225,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) {
@@ -238,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/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index 26d22ae..c96cd4f 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -16,11 +16,19 @@
 
 package android.security;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
 import android.content.Context;
 import android.content.Intent;
 import android.security.Keystore;
 import android.text.TextUtils;
-
+import android.util.Log;
 
 /**
  * The CertTool class provides the functions to list the certs/keys,
@@ -41,12 +49,12 @@
     public static final String KEY_NAMESPACE = "namespace";
     public static final String KEY_DESCRIPTION = "description";
 
-    private static final String TAG = "CertTool";
+    public static final String TITLE_CA_CERT = "CA Certificate";
+    public static final String TITLE_USER_CERT = "User Certificate";
+    public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
+    public static final String TITLE_PRIVATE_KEY = "Private Key";
 
-    private static final String TITLE_CA_CERT = "CA Certificate";
-    private static final String TITLE_USER_CERT = "User Certificate";
-    private static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
-    private static final String TITLE_PRIVATE_KEY = "Private Key";
+    private static final String TAG = "CertTool";
     private static final String UNKNOWN = "Unknown";
     private static final String ISSUER_NAME = "Issuer Name:";
     private static final String DISTINCT_NAME = "Distinct Name:";
@@ -58,6 +66,11 @@
     private static final String KEYNAME_DELIMITER = "_";
     private static final Keystore sKeystore = Keystore.getInstance();
 
+    private native int getPkcs12Handle(byte[] data, String password);
+    private native String getPkcs12Certificate(int handle);
+    private native String getPkcs12PrivateKey(int handle);
+    private native String popPkcs12CertificateStack(int handle);
+    private native void freePkcs12Handle(int handle);
     private native String generateCertificateRequest(int bits, String subject);
     private native boolean isPkcs12Keystore(byte[] data);
     private native int generateX509Certificate(byte[] data);
@@ -130,10 +143,35 @@
         intent.putExtra(KEY_NAMESPACE + "1", namespace);
     }
 
+    public int addPkcs12Keystore(byte[] p12Data, String password,
+            String keyname) {
+        int handle, i = 0;
+        String pemData;
+        Log.i("CertTool", "addPkcs12Keystore()");
+
+        if ((handle = getPkcs12Handle(p12Data, password)) == 0) return -1;
+        if ((pemData = getPkcs12Certificate(handle)) != null) {
+            sKeystore.put(USER_CERTIFICATE, keyname, pemData);
+        }
+        if ((pemData = getPkcs12PrivateKey(handle)) != null) {
+            sKeystore.put(USER_KEY, keyname, pemData);
+        }
+        while ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
+            if (i++ > 0) {
+                sKeystore.put(CA_CERTIFICATE, keyname + i, pemData);
+            } else {
+                sKeystore.put(CA_CERTIFICATE, keyname, pemData);
+            }
+        }
+        freePkcs12Handle(handle);
+        return 0;
+    }
+
     public synchronized void addCertificate(byte[] data, Context context) {
         int handle;
         Intent intent = null;
 
+        Log.i("CertTool", "addCertificate()");
         if (isPkcs12Keystore(data)) {
             intent = prepareIntent(TITLE_PKCS12_KEYSTORE, data, USER_KEY,
                     UNKNOWN, UNKNOWN);
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
index cc36b84..0db28fd 100644
--- a/keystore/jni/cert.c
+++ b/keystore/jni/cert.c
@@ -136,30 +136,126 @@
     return ret_code;
 }
 
-int is_pkcs12(const char *buf, int bufLen)
+PKCS12 *get_p12_handle(const char *buf, int bufLen)
 {
-    int ret = 0;
     BIO *bp = NULL;
     PKCS12  *p12 = NULL;
 
-    if (!buf || bufLen < 1) goto err;
+    if (!buf || (bufLen < 1) || (buf[0] != 48)) goto err;
 
     bp = BIO_new(BIO_s_mem());
     if (!bp) goto err;
 
-    if (buf[0] != 48) goto err; // it is not DER.
-
     if (!BIO_write(bp, buf, bufLen)) goto err;
 
-    if ((p12 = d2i_PKCS12_bio(bp, NULL)) != NULL) {
-        PKCS12_free(p12);
-        ret = 1;
-    }
+    p12 = d2i_PKCS12_bio(bp, NULL);
+
 err:
     if (bp) BIO_free(bp);
+    return p12;
+}
+
+PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
+                                            const char *passwd)
+{
+    PKCS12_KEYSTORE *p12store = NULL;
+    EVP_PKEY *pkey = NULL;
+    X509 *cert = NULL;
+    STACK_OF(X509) *certs = NULL;
+    PKCS12  *p12 = get_p12_handle(buf, bufLen);
+
+    if (p12 == NULL) return NULL;
+    if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
+        LOGE("Can not parse PKCS12 content");
+        PKCS12_free(p12);
+        return NULL;
+    }
+    if ((p12store = malloc(sizeof(PKCS12_KEYSTORE))) == NULL) {
+        if (cert) X509_free(cert);
+        if (pkey) EVP_PKEY_free(pkey);
+        if (certs) sk_X509_free(certs);
+    }
+    p12store->p12 = p12;
+    p12store->pkey = pkey;
+    p12store->cert = cert;
+    p12store->certs = certs;
+    return p12store;
+}
+
+void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store)
+{
+    if (p12store != NULL) {
+        if (p12store->cert) X509_free(p12store->cert);
+        if (p12store->pkey) EVP_PKEY_free(p12store->pkey);
+        if (p12store->certs) sk_X509_free(p12store->certs);
+        free(p12store);
+    }
+}
+
+int is_pkcs12(const char *buf, int bufLen)
+{
+    int ret = 0;
+    PKCS12  *p12 = get_p12_handle(buf, bufLen);
+    if (p12 != NULL) ret = 1;
+    PKCS12_free(p12);
     return ret;
 }
 
+static int convert_to_pem(void *data, int is_cert, char *buf, int size)
+{
+    int len = 0;
+    BIO *bio = NULL;
+
+    if (data == NULL) return -1;
+
+    if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
+    if (is_cert) {
+        if ((len = PEM_write_bio_X509(bio, (X509*)data)) == 0) {
+            goto err;
+        }
+    } else {
+        if ((len = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *)data, NULL,
+                                            NULL, 0, NULL, NULL)) == 0) {
+            goto err;
+        }
+    }
+    if (len < size && (len = BIO_read(bio, buf, size - 1)) > 0) {
+        buf[len] = 0;
+    }
+err:
+    if (bio) BIO_free(bio);
+    return (len == 0) ? -1 : 0;
+}
+
+int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+    if ((p12store != NULL) && (p12store->cert != NULL)) {
+        return convert_to_pem((void*)p12store->cert, 1, buf, size);
+    }
+    return -1;
+}
+
+int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+    if ((p12store != NULL) && (p12store->pkey != NULL)) {
+        return convert_to_pem((void*)p12store->pkey, 0, buf, size);
+    }
+    return -1;
+}
+
+int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+    X509 *cert = NULL;
+
+    if ((p12store != NULL) && (p12store->certs != NULL) &&
+        ((cert = sk_X509_pop(p12store->certs)) != NULL)) {
+        int ret = convert_to_pem((void*)cert, 1, buf, size);
+        X509_free(cert);
+        return ret;
+    }
+    return -1;
+}
+
 X509* parse_cert(const char *buf, int bufLen)
 {
     X509 *cert = NULL;
diff --git a/keystore/jni/cert.h b/keystore/jni/cert.h
index a9807b1..aaa7602 100644
--- a/keystore/jni/cert.h
+++ b/keystore/jni/cert.h
@@ -41,6 +41,13 @@
     int key_len;
 } PKEY_STORE;
 
+typedef struct {
+    PKCS12  *p12;
+    EVP_PKEY *pkey;
+    X509 *cert;
+    STACK_OF(X509) *certs;
+} PKCS12_KEYSTORE;
+
 #define PKEY_STORE_free(x) { \
     if(x.pkey) EVP_PKEY_free(x.pkey); \
     if(x.public_key) free(x.public_key); \
@@ -49,8 +56,14 @@
 #define nelem(x) (sizeof (x) / sizeof *(x))
 
 int gen_csr(int bits, const char *organizations, char reply[REPLY_MAX]);
+PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
+                                            const char *passwd);
+int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size);
+int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size);
+int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size);
+void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store);
 int is_pkcs12(const char *buf, int bufLen);
-X509*    parse_cert(const char *buf, int bufLen);
+X509 *parse_cert(const char *buf, int bufLen);
 int get_cert_name(X509 *cert, char *buf, int size);
 int get_issuer_name(X509 *cert, char *buf, int size);
 int is_ca_cert(X509 *cert);
diff --git a/keystore/jni/certtool.c b/keystore/jni/certtool.c
index fabf5cd..1ae8dab 100644
--- a/keystore/jni/certtool.c
+++ b/keystore/jni/certtool.c
@@ -19,10 +19,13 @@
 #include <string.h>
 #include <jni.h>
 #include <cutils/log.h>
+#include <openssl/pkcs12.h>
 #include <openssl/x509v3.h>
 
 #include "cert.h"
 
+typedef int PKCS12_KEYSTORE_FUNC(PKCS12_KEYSTORE *store, char *buf, int size);
+
 jstring
 android_security_CertTool_generateCertificateRequest(JNIEnv* env,
                                                      jobject thiz,
@@ -42,12 +45,88 @@
                                            jobject thiz,
                                            jbyteArray data)
 {
-    char buf[REPLY_MAX];
     int len = (*env)->GetArrayLength(env, data);
 
-    if (len > REPLY_MAX) return 0;
-    (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-    return (jboolean) is_pkcs12(buf, len);
+    if (len > 0) {
+        PKCS12 *handle = NULL;
+        char buf[len];
+
+        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
+        return (jboolean)is_pkcs12(buf, len);
+    } else {
+        return 0;
+    }
+}
+
+jint
+android_security_CertTool_getPkcs12Handle(JNIEnv* env,
+                                          jobject thiz,
+                                          jbyteArray data,
+                                          jstring jPassword)
+{
+    jboolean bIsCopy;
+    int len = (*env)->GetArrayLength(env, data);
+    const char* passwd = (*env)->GetStringUTFChars(env, jPassword , &bIsCopy);
+
+    if (len > 0) {
+        PKCS12_KEYSTORE *handle = NULL;
+        char buf[len];
+
+        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
+        handle = get_pkcs12_keystore_handle(buf, len, passwd);
+        (*env)->ReleaseStringUTFChars(env, jPassword, passwd);
+        return (jint)handle;
+    } else {
+        return 0;
+    }
+}
+
+jstring call_pkcs12_ks_func(PKCS12_KEYSTORE_FUNC *func,
+                            JNIEnv* env,
+                            jobject thiz,
+                            jint phandle)
+{
+    char buf[REPLY_MAX];
+
+    if (phandle == 0) return NULL;
+    if (func((PKCS12_KEYSTORE*)phandle, buf, sizeof(buf)) == 0) {
+        return (*env)->NewStringUTF(env, buf);
+    }
+    return NULL;
+}
+
+jstring
+android_security_CertTool_getPkcs12Certificate(JNIEnv* env,
+                                               jobject thiz,
+                                               jint phandle)
+{
+    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_certificate,
+                               env, thiz, phandle);
+}
+
+jstring
+android_security_CertTool_getPkcs12PrivateKey(JNIEnv* env,
+                                              jobject thiz,
+                                              jint phandle)
+{
+    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_private_key,
+                               env, thiz, phandle);
+}
+
+jstring
+android_security_CertTool_popPkcs12CertificateStack(JNIEnv* env,
+                                                    jobject thiz,
+                                                    jint phandle)
+{
+    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)pop_pkcs12_certs_stack,
+                               env, thiz, phandle);
+}
+
+void android_security_CertTool_freePkcs12Handle(JNIEnv* env,
+                                                jobject thiz,
+                                                jint handle)
+{
+    if (handle != 0) free_pkcs12_keystore((PKCS12_KEYSTORE*)handle);
 }
 
 jint
@@ -117,6 +196,16 @@
         (void*)android_security_CertTool_generateCertificateRequest},
     {"isPkcs12Keystore", "([B)Z",
         (void*)android_security_CertTool_isPkcs12Keystore},
+    {"getPkcs12Handle", "([BLjava/lang/String;)I",
+        (void*)android_security_CertTool_getPkcs12Handle},
+    {"getPkcs12Certificate", "(I)Ljava/lang/String;",
+        (void*)android_security_CertTool_getPkcs12Certificate},
+    {"getPkcs12PrivateKey", "(I)Ljava/lang/String;",
+        (void*)android_security_CertTool_getPkcs12PrivateKey},
+    {"popPkcs12CertificateStack", "(I)Ljava/lang/String;",
+        (void*)android_security_CertTool_popPkcs12CertificateStack},
+    {"freePkcs12Handle", "(I)V",
+        (void*)android_security_CertTool_freePkcs12Handle},
     {"generateX509Certificate", "([B)I",
         (void*)android_security_CertTool_generateX509Certificate},
     {"isCaCertificate", "(I)Z",
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/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
index 5df94cb..9138878 100644
--- a/libs/utils/ZipUtils.cpp
+++ b/libs/utils/ZipUtils.cpp
@@ -210,7 +210,7 @@
             LOGV("+++ reading %ld bytes (%ld left)\n",
                 getSize, compRemaining);
 
-            int cc = fread(readBuf, getSize, 1, fp);
+            int cc = fread(readBuf, 1, getSize, fp);
             if (cc != (int) getSize) {
                 LOGD("inflate read failed (%d vs %ld)\n",
                     cc, getSize);
@@ -341,4 +341,3 @@
 
     return true;
 }
-
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 6de7bc1..95f3680 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -657,7 +657,7 @@
 
             ContentValues values = toValues();
             String title = values.getAsString(MediaStore.MediaColumns.TITLE);
-            if (TextUtils.isEmpty(title)) {
+            if (title == null || TextUtils.isEmpty(title.trim())) {
                 title = values.getAsString(MediaStore.MediaColumns.DATA);
                 // extract file name after last slash
                 int lastSlash = title.lastIndexOf('/');
diff --git a/media/sdutils/sdutil.cpp b/media/sdutils/sdutil.cpp
index a9aabf0..06120f5 100644
--- a/media/sdutils/sdutil.cpp
+++ b/media/sdutils/sdutil.cpp
@@ -88,7 +88,7 @@
     String16 string(path);
     gMountService->mountMedia(string);
     
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < 60; i++) {
         if (isMounted(path)) {
             return 0;
         }
@@ -103,7 +103,7 @@
     String16 string(path);
     gMountService->unmountMedia(string);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < 20; i++) {
         if (!isMounted(path)) {
             return 0;
         }
diff --git a/packages/SettingsProvider/etc/bookmarks.xml b/packages/SettingsProvider/etc/bookmarks.xml
index 5fb6608..5af416a 100644
--- a/packages/SettingsProvider/etc/bookmarks.xml
+++ b/packages/SettingsProvider/etc/bookmarks.xml
@@ -53,6 +53,6 @@
         shortcut="s" />
     <bookmark
         package="com.google.android.youtube"
-        class="com.google.android.youtube.HomePage"
+        class="com.google.android.youtube.HomeActivity"
         shortcut="y" />
-</bookmarks>
\ No newline at end of file
+</bookmarks>
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 64cdb5b..80eb3cb 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -286,6 +286,7 @@
 {
     if (jniData) {
         SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+        env->DeleteGlobalRef(pSynthData->tts_ref);
         delete pSynthData;
     }
 }
@@ -607,24 +608,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)
 {
@@ -710,10 +693,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 7c4996e..b3b580c 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -130,6 +130,8 @@
     private HashMap<String, SoundResource> mUtterances;
     private MediaPlayer mPlayer;
     private SpeechItem mCurrentSpeechItem;
+    private HashMap<SpeechItem, Boolean> mKillList; // Used to ensure that in-flight synth calls
+                                                    // are killed when stop is used.
     private TtsService mSelf;
 
     private ContentResolver mResolver;
@@ -158,6 +160,7 @@
         mSpeechQueue = new ArrayList<SpeechItem>();
         mPlayer = null;
         mCurrentSpeechItem = null;
+        mKillList = new HashMap<SpeechItem, Boolean>();
 
         setDefaultSettings();
     }
@@ -396,6 +399,7 @@
                 if ((mCurrentSpeechItem != null) &&
                      mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
                     result = nativeSynth.stop();
+                    mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
                             mPlayer.stop();
@@ -445,6 +449,7 @@
                     ((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
                       mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
                     result = nativeSynth.stop();
+                    mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
                             mPlayer.stop();
@@ -578,7 +583,10 @@
                             setLanguage("", language, country, variant);
                         }
                     }
-                    nativeSynth.speak(speechItem.mText, streamType);
+                    // Only do the synthesis if it has not been killed by a subsequent utterance.
+                    if (mKillList.get(speechItem) == null){
+                        nativeSynth.speak(speechItem.mText, streamType);
+                    }
                 } catch (InterruptedException e) {
                     Log.e("TTS speakInternalOnly", "tryLock interrupted");
                     e.printStackTrace();
@@ -641,7 +649,10 @@
                             setLanguage("", language, country, variant);
                         }
                     }
-                    nativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+                    // 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);
+                    }
                 } catch (InterruptedException e) {
                     Log.e("TTS synthToFileInternalOnly", "tryLock interrupted");
                     e.printStackTrace();
diff --git a/services/java/com/android/server/MountListener.java b/services/java/com/android/server/MountListener.java
index 2e430c8..3e53585 100644
--- a/services/java/com/android/server/MountListener.java
+++ b/services/java/com/android/server/MountListener.java
@@ -202,6 +202,7 @@
             byte[] buffer = new byte[100];
 
             writeCommand(VOLD_CMD_SEND_UMS_STATUS);
+            mountMedia(Environment.getExternalStorageDirectory().getAbsolutePath());
             
             while (true) {
                 int count = inputStream.read(buffer);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b038a64..aa1a5cf 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -52,6 +52,7 @@
 class ServerThread extends Thread {
     private static final String TAG = "SystemServer";
     private final static boolean INCLUDE_DEMO = false;
+    private final static boolean INCLUDE_BACKUP = false;
 
     private static final int LOG_BOOT_PROGRESS_SYSTEM_RUN = 3010;
 
@@ -318,8 +319,10 @@
             }
 
             try {
-                Log.i(TAG, "Starting Backup Service");
-                ServiceManager.addService(Context.BACKUP_SERVICE, new BackupManagerService(context));
+                if (INCLUDE_BACKUP) {
+                    Log.i(TAG, "Starting Backup Service");
+                    ServiceManager.addService(Context.BACKUP_SERVICE, new BackupManagerService(context));
+                }
             } catch (Throwable e) {
                 Log.e(TAG, "Failure starting Backup Service", e);
             }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 4baf202..5425709 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1891,7 +1891,7 @@
                         break;
                     case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
                         animAttr = enter
-                        ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
+                                ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
                                 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
                         break;
                 }
@@ -7232,17 +7232,27 @@
 
     public static WindowManager.LayoutParams findAnimations(
             ArrayList<AppWindowToken> order,
-            ArrayList<AppWindowToken> tokenList1,
-            ArrayList<AppWindowToken> tokenList2) {
+            ArrayList<AppWindowToken> openingTokenList1,
+            ArrayList<AppWindowToken> closingTokenList2) {
         // We need to figure out which animation to use...
+
+        // First, check if there is a compatible window in opening/closing
+        // apps, and use it if exists.
         WindowManager.LayoutParams animParams = null;
         int animSrc = 0;
-
+        animParams = findCompatibleWindowParams(openingTokenList1);
+        if (animParams == null) {
+            animParams = findCompatibleWindowParams(closingTokenList2);
+        }
+        if (animParams != null) {
+            return animParams;
+        }
+        
         //Log.i(TAG, "Looking for animations...");
         for (int i=order.size()-1; i>=0; i--) {
             AppWindowToken wtoken = order.get(i);
             //Log.i(TAG, "Token " + wtoken + " with " + wtoken.windows.size() + " windows");
-            if (tokenList1.contains(wtoken) || tokenList2.contains(wtoken)) {
+            if (openingTokenList1.contains(wtoken) || closingTokenList2.contains(wtoken)) {
                 int j = wtoken.windows.size();
                 while (j > 0) {
                     j--;
@@ -7270,6 +7280,21 @@
         return animParams;
     }
 
+    private static LayoutParams findCompatibleWindowParams(ArrayList<AppWindowToken> tokenList) {
+        for (int appCount = tokenList.size() - 1; appCount >= 0; appCount--) {
+            AppWindowToken wtoken = tokenList.get(appCount);
+            // Just checking one window is sufficient as all windows have the compatible flag 
+            // if the application is in compatibility mode.
+            if (wtoken.windows.size() > 0) {
+                WindowManager.LayoutParams params = wtoken.windows.get(0).mAttrs;
+                if ((params.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+                    return params;
+                }
+            }
+        }
+        return null;
+    }
+
     // -------------------------------------------------------------
     // DummyAnimation
     // -------------------------------------------------------------
@@ -9277,16 +9302,10 @@
             // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
             mWidth = width;
         }
-        
-        @Override
-        public boolean willChangeTransformationMatrix() {
-            return true;
-        }
 
         @Override
-        public boolean willChangeBounds() {
-            return true;
+        public int getZAdjustment() {
+            return Animation.ZORDER_TOP;
         }
     }
 }
-
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 442e9ce..d9c40ec 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3522,8 +3522,6 @@
         intent = new Intent(intent);
 
         // Collect information about the target of the Intent.
-        // Must do this before locking, because resolving the intent
-        // may require launching a process to run its content provider.
         ActivityInfo aInfo;
         try {
             ResolveInfo rInfo =
@@ -3657,17 +3655,24 @@
         }
     }
 
-    final int startActivityInPackage(int uid,
+    public final int startActivityInPackage(int uid,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, boolean onlyIfNeeded) {
+        
+        // This is so super not safe, that only the system (or okay root)
+        // can do it.
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != 0 && callingUid != Process.myUid()) {
+            throw new SecurityException(
+                    "startActivityInPackage only available to the system");
+        }
+        
         final boolean componentSpecified = intent.getComponent() != null;
         
         // Don't modify the client's object!
         intent = new Intent(intent);
 
         // Collect information about the target of the Intent.
-        // Must do this before locking, because resolving the intent
-        // may require launching a process to run its content provider.
         ActivityInfo aInfo;
         try {
             ResolveInfo rInfo =
@@ -11834,10 +11839,12 @@
             config.reqTouchScreen = mConfiguration.touchscreen;
             config.reqKeyboardType = mConfiguration.keyboard;
             config.reqNavigation = mConfiguration.navigation;
-            if (mConfiguration.navigation != Configuration.NAVIGATION_NONAV) {
+            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
+                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
             }
-            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED) {
+            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
+                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
             }
         }
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 7a8d4e5e..a4b47b5 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -626,7 +626,9 @@
                         && mBatteryThreshold > BATTERY_THRESHOLD_WARNING))) {
             // Broadcast the low battery warning
             mSentLowBatteryBroadcast = true;
-            mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_LOW));
+            Intent batIntent = new Intent(Intent.ACTION_BATTERY_LOW);
+            batIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+            mContext.sendBroadcast(batIntent);
 
             if (SHOW_LOW_BATTERY_WARNING) {
                 if (false) {
@@ -644,7 +646,9 @@
         } else if (mBatteryThreshold < BATTERY_THRESHOLD_WARNING) {
             if (mSentLowBatteryBroadcast == true) {
                 mSentLowBatteryBroadcast = false;
-                mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_OKAY));
+                Intent batIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
+                batIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                mContext.sendBroadcast(batIntent);
             }
             if (SHOW_LOW_BATTERY_WARNING) {
                 if (mLowBatteryDialog != null) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 0ab9d34..23eedfe 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -18,17 +18,23 @@
 
 import android.app.ActivityManagerNative;
 import android.content.Context;
+import android.content.ContentValues;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.content.SharedPreferences;
+import android.database.SQLException;
+import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.provider.Telephony;
 import android.telephony.CellLocation;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
@@ -41,6 +47,10 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.DataConnection;
+// TODO(Moto): need to move MccTable from telephony.gsm to telephony
+// since there is no difference between CDMA and GSM for MccTable and
+// CDMA uses gsm's MccTable is not good.
+import com.android.internal.telephony.gsm.MccTable;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccException;
 import com.android.internal.telephony.IccFileHandler;
@@ -56,6 +66,10 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
+
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -154,6 +168,23 @@
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
         mIsPhoneInECMState = inEcm.equals("true");
 
+        // Sets operator alpha property by retrieving from build-time system property
+        String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha");
+        setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, operatorAlpha);
+
+        // Sets operator numeric property by retrieving from build-time system property
+        String operatorNumeric = SystemProperties.get("ro.cdma.home.operator.numeric");
+        setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operatorNumeric);
+
+        // Sets iso country property by retrieving from build-time system property
+        setIsoCountryProperty(operatorNumeric);
+
+        // Sets current entry in the telephony carrier table
+        updateCurrentCarrierInProvider(operatorNumeric);
+
+        // Updates MCC MNC device configuration information
+        updateMccMncConfiguration(operatorNumeric);
+
         // Notify voicemails.
         notifier.notifyMessageWaitingChanged(this);
     }
@@ -427,13 +458,7 @@
     }
 
     public String getSubscriberId() {
-        // Subscriber ID is the combination of MCC+MNC+MIN as CDMA IMSI
-        // TODO(Moto): Replace with call to mRuimRecords.getIMSI_M() when implemented.
-        if ((getServiceState().getOperatorNumeric() != null) && (getCdmaMIN() != null)) {
-            return (getServiceState().getOperatorNumeric() + getCdmaMIN());
-        } else {
-            return null;
-        }
+        return mSST.getImsi();
     }
 
     public boolean canConference() {
@@ -1244,4 +1269,66 @@
         editor.commit();
     }
 
+    /**
+     * Sets PROPERTY_ICC_OPERATOR_ISO_COUNTRY property
+     *
+     */
+    private void setIsoCountryProperty(String operatorNumeric) {
+        if (TextUtils.isEmpty(operatorNumeric)) {
+            setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
+        } else {
+            String iso = "";
+            try {
+                iso = MccTable.countryCodeForMcc(Integer.parseInt(
+                        operatorNumeric.substring(0,3)));
+            } catch (NumberFormatException ex) {
+                Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
+            } catch (StringIndexOutOfBoundsException ex) {
+                Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
+            }
+
+            setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
+        }
+    }
+
+    /**
+     * Sets the "current" field in the telephony provider according to the build-time
+     * operator numeric property
+     *
+     * @return true for success; false otherwise.
+     */
+    // TODO(Moto): move this method into PhoneBase, since it looks identical to
+    // the one in GsmPhone
+    private boolean updateCurrentCarrierInProvider(String operatorNumeric) {
+        if (!TextUtils.isEmpty(operatorNumeric)) {
+            try {
+                Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
+                ContentValues map = new ContentValues();
+                map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
+                getContext().getContentResolver().insert(uri, map);
+                return true;
+            } catch (SQLException e) {
+                Log.e(LOG_TAG, "Can't store current operator", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Updates MCC and MNC device configuration information for application retrieving
+     * correct version of resources
+     *
+     */
+    private void updateMccMncConfiguration(String operatorNumeric) {
+        if (operatorNumeric.length() >= 5) {
+            Configuration config = new Configuration();
+            config.mcc = Integer.parseInt(operatorNumeric.substring(0,3));
+            config.mnc = Integer.parseInt(operatorNumeric.substring(3));
+            try {
+                ActivityManagerNative.getDefault().updateConfiguration(config);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "Can't update configuration", e);
+            }
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index abb4a43..23a0520 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -19,11 +19,8 @@
 import android.app.AlarmManager;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContentValues;
 import android.content.Intent;
 import android.database.ContentObserver;
-import android.database.SQLException;
-import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -35,7 +32,6 @@
 import android.provider.Checkin;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
-import android.provider.Telephony;
 import android.provider.Telephony.Intents;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -64,6 +60,7 @@
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
 
 import java.util.Arrays;
 import java.util.Date;
@@ -634,27 +631,6 @@
                     } else {
                         newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
                     }
-
-                    if (!(opNames[2].equals(currentCarrier))) {
-                        // TODO(Moto): jsh asks, "This uses the MCC+MNC of the current registered
-                        // network to set the "current" entry in the APN table. But the correct
-                        // entry should be the MCC+MNC that matches the subscribed operator
-                        // (eg, phone issuer). These can be different when roaming."
-                        try {
-                            // Set the current field of the telephony provider according to
-                            // the CDMA's operator
-                            Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
-                            ContentValues map = new ContentValues();
-                            map.put(Telephony.Carriers.NUMERIC, opNames[2]);
-                            cr.insert(uri, map);
-                            // save current carrier for the next time check
-                            currentCarrier = opNames[2];
-                        } catch (SQLException e) {
-                            Log.e(LOG_TAG, "Can't store current operator", e);
-                        }
-                    } else {
-                        Log.i(LOG_TAG, "current carrier is not changed");
-                    }
                 } else {
                     Log.w(LOG_TAG, "error parsing opNames");
                 }
@@ -1444,4 +1420,19 @@
          return mMin;
     }
 
+    /**
+     * Returns IMSI as MCC + MNC + MIN
+     */
+    /*package*/ String getImsi() {
+        // TODO(Moto): When RUIM is enabled, IMSI will come from RUIM
+        // not build-time props. Moto will provide implementation
+        // for RUIM-ready case later.
+        String operatorNumeric = SystemProperties.get(PROPERTY_ICC_OPERATOR_NUMERIC, "");
+
+        if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) {
+            return (operatorNumeric + getCdmaMin());
+        } else {
+            return null;
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 4d888f6..55f48b1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -123,21 +123,12 @@
 
         adnCache.reset();
 
-        phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, null);
-        phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
-
         // recordsRequested is set to false indicating that the SIM
         // read requests made so far are not valid. This is set to
         // true only when fresh set of read requests are made.
         recordsRequested = false;
     }
 
-    /** Returns null if RUIM is not yet ready */
-    public String getIMSI_M() {
-        // TODO(Moto): mImsi is not initialized, fix.
-        return mImsi;
-    }
-
     public String getMdnNumber() {
         return mMyMobileNumber;
     }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/activity/ServiceTest.java b/tests/AndroidTests/src/com/android/unit_tests/activity/ServiceTest.java
index db523dc..95f6e36 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/activity/ServiceTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/activity/ServiceTest.java
@@ -27,10 +27,14 @@
 import android.os.Parcel;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
 // These test binders purport to support an interface whose canonical
 // interface name is ServiceTest.SERVICE_LOCAL
+// Temporarily suppress, this test is causing unit test suite run to fail
+// TODO: remove this suppress
+@Suppress
 public class ServiceTest extends ActivityTestsBase {
 
     public static final String SERVICE_LOCAL =
@@ -131,7 +135,7 @@
             mSetReporter = setReporter;
             mMonitor = !setReporter;
         }
-        
+
         void setMonitor(boolean v) {
             mMonitor = v;
         }
@@ -148,7 +152,7 @@
                 }
                 data.recycle();
             }
-            
+
             if (mMonitor) {
                 mCount++;
                 if (mStartState == STATE_START_1) {
@@ -260,7 +264,7 @@
         waitForResultOrThrow(5 * 1000, "existing connection to lose service");
 
         getContext().unbindService(conn);
-        
+
         conn = new TestConnection(true, true);
         success = false;
         try {
@@ -290,7 +294,7 @@
         waitForResultOrThrow(5 * 1000, "existing connection to lose service");
 
         getContext().unbindService(conn);
-        
+
         conn = new TestConnection(true, true);
         success = false;
         try {
@@ -318,12 +322,12 @@
         mStartState = STATE_UNBIND_ONLY;
         getContext().unbindService(conn);
         waitForResultOrThrow(5 * 1000, "existing connection to unbind service");
-        
+
         // Expect to see the service rebound.
         mStartState = STATE_REBIND;
         getContext().bindService(service, conn, 0);
         waitForResultOrThrow(5 * 1000, "existing connection to rebind service");
-        
+
         // Expect to see the service unbind and then destroyed.
         mStartState = STATE_UNBIND;
         getContext().stopService(service);
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..ea355a4 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="DpiTestActivityNoCompat" android:label="DpiTestCompat">
+            <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..9169025 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -28,8 +28,38 @@
 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;
 
 public class DpiTestActivity extends Activity {
+    public DpiTestActivity() {
+        super();
+        init(false);
+    }
+    
+    public DpiTestActivity(boolean noCompat) {
+        super();
+        init(noCompat);
+    }
+    
+    public void init(boolean noCompat) {
+        try {
+            ApplicationInfo ai = 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 };
+            }
+            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 +103,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));
     }
 
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;