Merge "Fix focused application handle. (DO NOT MERGE)" into honeycomb-mr2
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 36b9d72..51f1e3d 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -35,6 +35,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Resources;
 import android.database.DatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
@@ -78,6 +79,7 @@
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
+import android.view.Display;
 import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityManager;
 import android.view.inputmethod.InputMethodManager;
@@ -423,7 +425,11 @@
 
         registerService(WINDOW_SERVICE, new ServiceFetcher() {
                 public Object getService(ContextImpl ctx) {
-                    return WindowManagerImpl.getDefault();
+                    RuntimeException e = new RuntimeException("foo");
+                    e.fillInStackTrace();
+                    Log.i(TAG, "Getting window manager", e);
+                    CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo();
+                    return WindowManagerImpl.getDefault(ci);
                 }});
     }
 
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index cd278be..3d4c966 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1045,7 +1045,7 @@
             }
         }
         
-        activity.onCreate(icicle);
+        activity.performCreate(icicle);
         
         if (mActivityMonitors != null) {
             synchronized (mSync) {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 8bcb005..854d410 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -125,14 +125,16 @@
         if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
             compatFlags |= XLARGE_SCREENS | EXPANDABLE;
         }
-        if (!forceCompat) {
+        if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
+            compatFlags |= EXPANDABLE;
+        }
+
+        if (forceCompat) {
             // If we are forcing compatibility mode, then ignore an app that
             // just says it is resizable for screens.  We'll only have it fill
             // the screen if it explicitly says it supports the screen size we
             // are running in.
-            if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
-                compatFlags |= EXPANDABLE;
-            }
+            compatFlags &= ~EXPANDABLE;
         }
 
         boolean supportsScreen = false;
@@ -155,12 +157,10 @@
                 break;
         }
 
-        if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) == 0) {
+        if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) {
             if ((compatFlags&EXPANDABLE) != 0) {
                 supportsScreen = true;
-            }
-            if ((compatFlags&EXPANDABLE) == 0 &&
-                    (appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) {
+            } else if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) {
                 compatFlags |= ALWAYS_COMPAT;
             }
         }
@@ -382,6 +382,9 @@
             // This is a larger screen device and the app is not
             // compatible with large screens, so diddle it.
             CompatibilityInfo.updateCompatibleScreenFrame(inoutDm, null, inoutDm);
+        } else {
+            inoutDm.widthPixels = inoutDm.realWidthPixels;
+            inoutDm.heightPixels = inoutDm.realHeightPixels;
         }
 
         if (isScalingRequired()) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 51a7115..d476997 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -316,10 +316,11 @@
         StringBuilder sb = new StringBuilder(128);
         sb.append("{");
         sb.append(fontScale);
-        sb.append("x imsi=");
+        sb.append(" ");
         sb.append(mcc);
-        sb.append("/");
+        sb.append("mcc");
         sb.append(mnc);
+        sb.append("mnc");
         if (locale != null) {
             sb.append(" ");
             sb.append(locale);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a072e94..e63e7eb 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -115,7 +115,6 @@
     private NativePluralRules mPluralRule;
     
     private CompatibilityInfo mCompatibilityInfo;
-    private Display mDefaultDisplay;
 
     private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>(0) {
         @Override
@@ -1426,6 +1425,15 @@
             }
             if (metrics != null) {
                 mMetrics.setTo(metrics);
+                // NOTE: We should re-arrange this code to create a Display
+                // with the CompatibilityInfo that is used everywhere we deal
+                // with the display in relation to this app, rather than
+                // doing the conversion here.  This impl should be okay because
+                // we make sure to return a compatible display in the places
+                // where there are public APIs to retrieve the display...  but
+                // it would be cleaner and more maintainble to just be
+                // consistently dealing with a compatible display everywhere in
+                // the framework.
                 mCompatibilityInfo.applyToDisplayMetrics(mMetrics);
             }
             mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
@@ -2121,24 +2129,6 @@
                 + Integer.toHexString(id));
     }
 
-    /**
-     * Returns the display adjusted for the Resources' metrics.
-     * @hide
-     */
-    public Display getDefaultDisplay(Display defaultDisplay) {
-        if (mDefaultDisplay == null) {
-            if (!mCompatibilityInfo.isScalingRequired() && mCompatibilityInfo.supportsScreen()) {
-                // the app supports the display. just use the default one.
-                mDefaultDisplay = defaultDisplay;
-            } else {
-                // display needs adjustment.
-                mDefaultDisplay = Display.createMetricsBasedDisplay(
-                        defaultDisplay.getDisplayId(), mMetrics);
-            }
-        }
-        return mDefaultDisplay;
-    }
-
     private TypedArray getCachedStyledAttributes(int len) {
         synchronized (mTmpValue) {
             TypedArray attrs = mCachedStyledAttributes;
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index d68e6fb..bc6e993 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -36,6 +36,11 @@
     private final int mMtpReserveSpace;
     private int mStorageId;
 
+    // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
+    // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
+    // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
+    public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
+
     public StorageVolume(String path, String description,
             boolean removable, boolean emulated, int mtpReserveSpace) {
         mPath = path;
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 7d37e5b..93114ad 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -470,11 +470,15 @@
         
         final View layout = layoutInflater.inflate(mLayoutResId, parent, false); 
         
-        if (mWidgetLayoutResId != 0) {
-            final ViewGroup widgetFrame = (ViewGroup)layout.findViewById(com.android.internal.R.id.widget_frame);
-            layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);
+        final ViewGroup widgetFrame = (ViewGroup) layout
+                .findViewById(com.android.internal.R.id.widget_frame);
+        if (widgetFrame != null) {
+            if (mWidgetLayoutResId != 0) {
+                layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);
+            } else {
+                widgetFrame.setVisibility(View.GONE);
+            }
         }
-
         return layout;
     }
     
@@ -510,16 +514,20 @@
                 }
             }
         }
-        
+
         ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
-        if (imageView != null && (mIconResId != 0 || mIcon != null)) {
-            if (mIcon == null) {
-                mIcon = getContext().getResources().getDrawable(mIconResId);
+        if (imageView != null) {
+            if (mIconResId != 0 || mIcon != null) {
+                if (mIcon == null) {
+                    mIcon = getContext().getResources().getDrawable(mIconResId);
+                }
+                if (mIcon != null) {
+                    imageView.setImageDrawable(mIcon);
+                }
             }
-            if (mIcon != null) {
-                imageView.setImageDrawable(mIcon);
-            }
+            imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
         }
+
         if (mShouldDisableView) {
             setEnabledStateOnViews(view, isEnabled());
         }
@@ -618,6 +626,7 @@
     public void setIcon(Drawable icon) {
         if ((icon == null && mIcon != null) || (icon != null && mIcon != icon)) {
             mIcon = icon;
+
             notifyChanged();
         }
     }
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index ad0bc84..8535bd4 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -18,9 +18,6 @@
 
 import com.android.internal.util.XmlUtils;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.app.ActionBar;
 import android.app.Fragment;
 import android.app.FragmentBreadCrumbs;
@@ -44,8 +41,8 @@
 import android.util.Xml;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.View.OnClickListener;
 import android.widget.AbsListView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
@@ -58,6 +55,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 /**
  * This is the base class for an activity to show a hierarchy of preferences
  * to the user.  Prior to {@link android.os.Build.VERSION_CODES#HONEYCOMB}
@@ -641,17 +641,9 @@
      * enough.
      */
     public boolean onIsMultiPane() {
-        Configuration config = getResources().getConfiguration();
-        if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
-                == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
-            return true;
-        }
-        if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
-                == Configuration.SCREENLAYOUT_SIZE_LARGE
-                && config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            return true;
-        }
-        return false;
+        boolean preferMultiPane = getResources().getBoolean(
+                com.android.internal.R.bool.preferences_prefer_dual_pane);
+        return preferMultiPane;
     }
 
     /**
@@ -992,7 +984,7 @@
         if (mFragmentBreadCrumbs == null) {
             View crumbs = findViewById(android.R.id.title);
             // For screens with a different kind of title, don't create breadcrumbs.
-            if (!(crumbs instanceof FragmentBreadCrumbs)) return;
+            if (crumbs != null && !(crumbs instanceof FragmentBreadCrumbs)) return;
             mFragmentBreadCrumbs = (FragmentBreadCrumbs) findViewById(android.R.id.title);
             if (mFragmentBreadCrumbs == null) {
                 mFragmentBreadCrumbs = new FragmentBreadCrumbs(this);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6deb5a0..fbdc0ba 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2545,6 +2545,13 @@
             "lock_screen_owner_info_enabled";
 
         /**
+         * The saved value for WindowManagerService.setForcedDisplaySize().
+         * Two integers separated by a comma.  If unset, then use the real display size.
+         * @hide
+         */
+        public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
+
+        /**
          * Whether assisted GPS should be enabled or not.
          * @hide
          */
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 1d60066..b5d36d9 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.content.res.CompatibilityInfo;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.RemoteException;
@@ -37,7 +38,7 @@
      * Display gives you access to some information about a particular display
      * connected to the device.
      */
-    Display(int display) {
+    Display(int display, CompatibilityInfo compatInfo) {
         // initalize the statics when this class is first instansiated. This is
         // done here instead of in the static block because Zygote
         synchronized (sStaticInit) {
@@ -46,6 +47,12 @@
                 sInitialized = true;
             }
         }
+        if (compatInfo != null && (compatInfo.isScalingRequired()
+                || !compatInfo.supportsScreen())) {
+            mCompatibilityInfo = compatInfo;
+        } else {
+            mCompatibilityInfo = null;
+        }
         mDisplay = display;
         init(display);
     }
@@ -82,6 +89,16 @@
                 // system process before the window manager is up.
                 outSize.y = getRealHeight();
             }
+            if (mCompatibilityInfo != null) {
+                synchronized (mTmpMetrics) {
+                    mTmpMetrics.realWidthPixels = outSize.x;
+                    mTmpMetrics.realHeightPixels = outSize.y;
+                    mTmpMetrics.density = mDensity;
+                    mCompatibilityInfo.applyToDisplayMetrics(mTmpMetrics);
+                    outSize.x = mTmpMetrics.widthPixels;
+                    outSize.y = mTmpMetrics.heightPixels;
+                }
+            }
         } catch (RemoteException e) {
             Slog.w("Display", "Unable to get display size", e);
         }
@@ -206,6 +223,10 @@
             outMetrics.heightPixels = mTmpPoint.y;
         }
         getNonSizeMetrics(outMetrics);
+
+        if (mCompatibilityInfo != null) {
+            mCompatibilityInfo.applyToDisplayMetrics(outMetrics);
+        }
     }
 
     /**
@@ -249,7 +270,8 @@
     
     private native void init(int display);
 
-    private int         mDisplay;
+    private final CompatibilityInfo mCompatibilityInfo;
+    private final int   mDisplay;
     // Following fields are initialized from native code
     private int         mPixelFormat;
     private float       mRefreshRate;
@@ -258,6 +280,7 @@
     private float       mDpiY;
     
     private final Point mTmpPoint = new Point();
+    private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
     private float mLastGetTime;
 
     private static final Object sStaticInit = new Object();
@@ -268,27 +291,8 @@
      * Returns a display object which uses the metric's width/height instead.
      * @hide
      */
-    public static Display createMetricsBasedDisplay(int displayId, DisplayMetrics metrics) {
-        return new CompatibleDisplay(displayId, metrics);
-    }
-
-    private static class CompatibleDisplay extends Display {
-        private final DisplayMetrics mMetrics;
-
-        private CompatibleDisplay(int displayId, DisplayMetrics metrics) {
-            super(displayId);
-            mMetrics = metrics;
-        }
-
-        @Override
-        public int getWidth() {
-            return mMetrics.widthPixels;
-        }
-
-        @Override
-        public int getHeight() {
-            return mMetrics.heightPixels;
-        }
+    public static Display createCompatibleDisplay(int displayId, CompatibilityInfo compat) {
+        return new Display(displayId, compat);
     }
 }
 
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 83f9119..c913bb3 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -20,7 +20,6 @@
 import android.graphics.*;
 import android.os.Parcelable;
 import android.os.Parcel;
-import android.util.DisplayMetrics;
 import android.util.Log;
 
 /**
@@ -174,9 +173,9 @@
     private int mSurfaceGenerationId;
     private String mName;
 
-    // The display metrics used to provide the pseudo canvas size for applications
-    // running in compatibility mode. This is set to null for non compatibility mode.
-    private DisplayMetrics mCompatibleDisplayMetrics;
+    // The Translator for density compatibility mode.  This is used for scaling
+    // the canvas to perform the appropriate density transformation.
+    private Translator mCompatibilityTranslator;
 
     // A matrix to scale the matrix set by application. This is set to null for
     // non compatibility mode.
@@ -263,14 +262,20 @@
 
         @Override
         public int getWidth() {
-            return mCompatibleDisplayMetrics == null ?
-                    super.getWidth() : mCompatibleDisplayMetrics.widthPixels;
+            int w = super.getWidth();
+            if (mCompatibilityTranslator != null) {
+                w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f);
+            }
+            return w;
         }
 
         @Override
         public int getHeight() {
-            return mCompatibleDisplayMetrics == null ?
-                    super.getHeight() : mCompatibleDisplayMetrics.heightPixels;
+            int h = super.getHeight();
+            if (mCompatibilityTranslator != null) {
+                h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f);
+            }
+            return h;
         }
 
         @Override
@@ -297,10 +302,9 @@
     }
 
     /**
-     * Sets the display metrics used to provide canvas's width/height in compatibility mode.
+     * Sets the translator used to scale canvas's width/height in compatibility mode.
      */
-    void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
-        mCompatibleDisplayMetrics = metrics;
+    void setCompatibilityTranslator(Translator translator) {
         if (translator != null) {
             float appScale = translator.applicationScale;
             mCompatibleMatrix = new Matrix();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 87b3d79..3efc799 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -21,7 +21,6 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
@@ -433,9 +432,8 @@
             mTranslator = viewRoot.mTranslator;
         }
 
-        Resources res = getContext().getResources();
-        if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
-            mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
+        if (mTranslator != null) {
+            mSurface.setCompatibilityTranslator(mTranslator);
         }
         
         int myWidth = mRequestedWidth;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a4aeed8..5ad0b6b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -373,9 +373,8 @@
                 CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
                 mTranslator = compatibilityInfo.getTranslator();
 
-                if (mTranslator != null || !compatibilityInfo.supportsScreen()) {
-                    mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics(),
-                            mTranslator);
+                if (mTranslator != null) {
+                    mSurface.setCompatibilityTranslator(mTranslator);
                 }
 
                 boolean restore = false;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2095a93..5236a9e 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.content.Context;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.PixelFormat;
@@ -462,13 +463,11 @@
         mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);
     }
 
-    private class LocalWindowManager implements WindowManager {
-        private boolean mHardwareAccelerated;
+    private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper {
+        private final boolean mHardwareAccelerated;
 
         LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) {
-            mWindowManager = wm;
-            mDefaultDisplay = mContext.getResources().getDefaultDisplay(
-                    mWindowManager.getDefaultDisplay());
+            super(wm, mContext.getResources().getCompatibilityInfo());
             mHardwareAccelerated = hardwareAccelerated;
         }
 
@@ -523,28 +522,8 @@
             if (mHardwareAccelerated) {
                 wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
             }
-            mWindowManager.addView(view, params);
+            super.addView(view, params);
         }
-
-        public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
-            mWindowManager.updateViewLayout(view, params);
-        }
-
-        public final void removeView(View view) {
-            mWindowManager.removeView(view);
-        }
-
-        public final void removeViewImmediate(View view) {
-            mWindowManager.removeViewImmediate(view);
-        }
-
-        public Display getDefaultDisplay() {
-            return mDefaultDisplay;
-        }
-        
-        private final WindowManager mWindowManager;
-
-        private final Display mDefaultDisplay;
     }
 
     /**
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index a4c4544..9cae75c 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import java.util.HashMap;
+
+import android.content.res.CompatibilityInfo;
 import android.graphics.PixelFormat;
 import android.os.IBinder;
 import android.util.AndroidRuntimeException;
@@ -75,9 +78,92 @@
     public static final int ADD_MULTIPLE_SINGLETON = -7;
     public static final int ADD_PERMISSION_DENIED = -8;
 
-    public static WindowManagerImpl getDefault()
-    {
-        return mWindowManager;
+    private View[] mViews;
+    private ViewRoot[] mRoots;
+    private WindowManager.LayoutParams[] mParams;
+
+    private final static Object sLock = new Object();
+    private final static WindowManagerImpl sWindowManager = new WindowManagerImpl();
+    private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers
+            = new HashMap<CompatibilityInfo, WindowManager>();
+
+    static class CompatModeWrapper implements WindowManager {
+        private final WindowManager mWindowManager;
+        private final Display mDefaultDisplay;
+
+        CompatModeWrapper(WindowManager wm, CompatibilityInfo ci) {
+            mWindowManager = wm;
+
+            // Use the original display if there is no compatibility mode
+            // to apply, or the underlying window manager is already a
+            // compatibility mode wrapper.  (We assume that if it is a
+            // wrapper, it is applying the same compatibility mode.)
+            if (ci == null || wm instanceof CompatModeWrapper
+                    || (!ci.isScalingRequired() && ci.supportsScreen())) {
+                mDefaultDisplay = mWindowManager.getDefaultDisplay();
+            } else {
+                //mDefaultDisplay = mWindowManager.getDefaultDisplay();
+                mDefaultDisplay = Display.createCompatibleDisplay(
+                        mWindowManager.getDefaultDisplay().getDisplayId(), ci);
+            }
+        }
+
+        @Override
+        public void addView(View view, android.view.ViewGroup.LayoutParams params) {
+            mWindowManager.addView(view, params);
+        }
+
+        @Override
+        public void updateViewLayout(View view, android.view.ViewGroup.LayoutParams params) {
+            mWindowManager.updateViewLayout(view, params);
+
+        }
+
+        @Override
+        public void removeView(View view) {
+            mWindowManager.removeView(view);
+        }
+
+        @Override
+        public Display getDefaultDisplay() {
+            return mDefaultDisplay;
+        }
+
+        @Override
+        public void removeViewImmediate(View view) {
+            mWindowManager.removeViewImmediate(view);
+        }
+
+        @Override
+        public boolean isHardwareAccelerated() {
+            return mWindowManager.isHardwareAccelerated();
+        }
+
+    }
+
+    public static WindowManagerImpl getDefault() {
+        return sWindowManager;
+    }
+
+    public static WindowManager getDefault(CompatibilityInfo compatInfo) {
+        if (compatInfo == null || (!compatInfo.isScalingRequired()
+                && compatInfo.supportsScreen())) {
+            return sWindowManager;
+        }
+
+        synchronized (sLock) {
+            // NOTE: It would be cleaner to move the implementation of
+            // WindowManagerImpl into a static inner class, and have this
+            // public impl just call into that.  Then we can make multiple
+            // instances of WindowManagerImpl for compat mode rather than
+            // having to make wrappers.
+            WindowManager wm = sCompatWindowManagers.get(compatInfo);
+            if (wm == null) {
+                wm = new CompatModeWrapper(sWindowManager, compatInfo);
+                sCompatWindowManagers.put(compatInfo, wm);
+            }
+            return wm;
+        }
     }
     
     public boolean isHardwareAccelerated() {
@@ -341,13 +427,9 @@
     }
     
     public Display getDefaultDisplay() {
-        return new Display(Display.DEFAULT_DISPLAY);
+        return new Display(Display.DEFAULT_DISPLAY, null);
     }
 
-    private View[] mViews;
-    private ViewRoot[] mRoots;
-    private WindowManager.LayoutParams[] mParams;
-
     private static void removeItem(Object[] dst, Object[] src, int index)
     {
         if (dst.length > 0) {
@@ -376,6 +458,4 @@
             return -1;
         }
     }
-
-    private static WindowManagerImpl mWindowManager = new WindowManagerImpl();
 }
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 12391df..5b78586 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -16,6 +16,7 @@
 
 package android.webkit;
 
+import android.net.ProxyProperties;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -294,6 +295,20 @@
         mContentUriToFilePathMap.put(contentUri, path);
     }
 
+    public void updateProxy(ProxyProperties proxyProperties) {
+        if (proxyProperties == null) {
+            nativeUpdateProxy("", "");
+            return;
+        }
+
+        String host = proxyProperties.getHost();
+        int port = proxyProperties.getPort();
+        if (port != 0)
+            host += ":" + port;
+
+        nativeUpdateProxy(host, proxyProperties.getExclusionList());
+    }
+
     private native void nativeConstructor();
     private native void nativeFinalize();
     private native void sharedTimerFired();
@@ -304,5 +319,5 @@
     public native void addPackageNames(Set<String> packageNames);
     public native void addPackageName(String packageName);
     public native void removePackageName(String packageName);
-    public native void updateProxy(String newProxy);
+    public native void nativeUpdateProxy(String newProxy, String exclusionList);
 }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 2b507fd..b884853 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
@@ -139,6 +138,9 @@
         OFF
     }
 
+    // TODO: Keep this up to date
+    private static final String PREVIOUS_VERSION = "3.1";
+
     // WebView associated with this WebSettings.
     private WebView mWebView;
     // BrowserFrame used to access the native frame pointer.
@@ -358,10 +360,9 @@
     }
 
     // User agent strings.
-    private static final String DESKTOP_USERAGENT =
-            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us)"
-            + " AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0"
-            + " Safari/530.17";
+    private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
+        "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
+        "Chrome/11.0.696.34 Safari/534.24";
     private static final String IPHONE_USERAGENT =
             "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)"
             + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0"
@@ -471,7 +472,14 @@
         // Add version
         final String version = Build.VERSION.RELEASE;
         if (version.length() > 0) {
-            buffer.append(version);
+            if (Character.isDigit(version.charAt(0))) {
+                // Release is a version, eg "3.1"
+                buffer.append(version);
+            } else {
+                // Release is a codename, eg "Honeycomb"
+                // In this case, use the previous release's version
+                buffer.append(PREVIOUS_VERSION);
+            }
         } else {
             // default to "1.0"
             buffer.append("1.0");
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index cf83456..0d34ff6 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1045,20 +1045,10 @@
     private static void handleProxyBroadcast(Intent intent) {
         ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
         if (proxyProperties == null || proxyProperties.getHost() == null) {
-            WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, "");
+            WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, null);
             return;
         }
-
-        String host = proxyProperties.getHost();
-        int port = proxyProperties.getPort();
-        if (port != 0)
-            host += ":" + port;
-
-        // TODO: Handle exclusion list
-        // The plan is to make an AndroidProxyResolver, and handle the blacklist
-        // there
-        String exclusionList = proxyProperties.getExclusionList();
-        WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, host);
+        WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, proxyProperties);
     }
 
     /*
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 0271695..e73c9d0 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -24,6 +24,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.media.MediaFile;
+import android.net.ProxyProperties;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
@@ -705,7 +706,7 @@
                                     throw new IllegalStateException(
                                             "No WebView has been created in this process!");
                                 }
-                                BrowserFrame.sJavaBridge.updateProxy((String) msg.obj);
+                                BrowserFrame.sJavaBridge.updateProxy((ProxyProperties)msg.obj);
                                 break;
                         }
                     }
@@ -2016,7 +2017,8 @@
         if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start");
         draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mContentSize);
         if (draw.mBaseLayer == 0) {
-            if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort");
+            if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, resending draw message");
+            mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
             return;
         }
         webkitDraw(draw);
diff --git a/core/res/res/layout-xlarge/preference_list_content_single.xml b/core/res/res/layout-w600dp/preference_list_content_single.xml
similarity index 100%
rename from core/res/res/layout-xlarge/preference_list_content_single.xml
rename to core/res/res/layout-w600dp/preference_list_content_single.xml
diff --git a/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
new file mode 100644
index 0000000..9b81497
--- /dev/null
+++ b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent">
+    <android.app.FragmentBreadCrumbs
+            android:id="@android:id/title"
+            android:layout_height="72dip"
+            android:layout_width="match_parent"
+            android:paddingTop="16dip"
+            android:paddingBottom="8dip"
+            android:gravity="center_vertical|left"
+            android:layout_marginLeft="@dimen/preference_breadcrumb_paddingLeft"
+            android:layout_marginRight="@dimen/preference_breadcrumb_paddingRight"
+        />
+
+    <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:paddingLeft="@dimen/preference_breadcrumb_paddingLeft"
+            android:paddingRight="@dimen/preference_breadcrumb_paddingRight"
+            android:src="#404040"
+        />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/breadcrumbs_in_fragment.xml b/core/res/res/layout/breadcrumbs_in_fragment.xml
new file mode 100644
index 0000000..98fffb7
--- /dev/null
+++ b/core/res/res/layout/breadcrumbs_in_fragment.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<!-- This layout disables breadcrumbs in the fragment area and causes PreferenceActivity to
+    put the breadcrumbs in the action bar. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_height="@dimen/preference_fragment_padding_side"
+        android:layout_width="match_parent">
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/locale_picker_item.xml b/core/res/res/layout/locale_picker_item.xml
index b63f5ab..19c0dee 100644
--- a/core/res/res/layout/locale_picker_item.xml
+++ b/core/res/res/layout/locale_picker_item.xml
@@ -20,11 +20,14 @@
     android:layout_width="match_parent"
     android:gravity="center_vertical"
     android:minHeight="?android:attr/listPreferredItemHeight"
-    android:padding="5dip">
+    android:paddingLeft="16dp"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp"
+    android:paddingRight="16dp">
 
     <TextView android:id="@+id/locale"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textAppearance="?android:attr/textAppearanceMedium"
     />
 </LinearLayout >
diff --git a/core/res/res/layout/preference_category_holo.xml b/core/res/res/layout/preference_category_holo.xml
index 5fe8b28..a4e20d2 100644
--- a/core/res/res/layout/preference_category_holo.xml
+++ b/core/res/res/layout/preference_category_holo.xml
@@ -18,5 +18,5 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     style="?android:attr/listSeparatorTextViewStyle"
     android:id="@+android:id/title"
-    android:paddingLeft="32dp"
+    android:paddingLeft="16dp"
 />
diff --git a/core/res/res/layout/preference_child_holo.xml b/core/res/res/layout/preference_child_holo.xml
index 2e70d77..06c846b 100644
--- a/core/res/res/layout/preference_child_holo.xml
+++ b/core/res/res/layout/preference_child_holo.xml
@@ -26,7 +26,7 @@
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:minWidth="@dimen/preference_widget_width"
+        android:minWidth="@dimen/preference_icon_minWidth"
         android:gravity="center"
         android:orientation="horizontal">
         <ImageView
@@ -40,6 +40,7 @@
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="32dip"
         android:layout_marginRight="6dip"
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index c448f64..e5ed33c 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -27,21 +27,23 @@
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:minWidth="@dimen/preference_widget_width"
         android:gravity="center"
+        android:minWidth="@dimen/preference_icon_minWidth"
         android:orientation="horizontal">
         <ImageView
             android:id="@+android:id/icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
+            android:minWidth="48dp"
             />
     </LinearLayout>
 
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="6dip"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="8dip"
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
         android:layout_weight="1">
diff --git a/core/res/res/layout/preference_information_holo.xml b/core/res/res/layout/preference_information_holo.xml
index d6cc063..d15cd7b 100644
--- a/core/res/res/layout/preference_information_holo.xml
+++ b/core/res/res/layout/preference_information_holo.xml
@@ -24,13 +24,24 @@
     android:gravity="center_vertical"
     android:paddingRight="?android:attr/scrollbarSize">
 
-    <View
-        android:layout_width="@dimen/preference_widget_width"
-        android:layout_height="match_parent" />
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:minWidth="@dimen/preference_icon_minWidth"
+        android:gravity="center"
+        android:orientation="horizontal">
+        <ImageView
+            android:id="@+android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            />
+    </LinearLayout>
 
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="16dip"
         android:layout_marginRight="6sp"
         android:layout_marginTop="6sp"
         android:layout_marginBottom="6sp"
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 5d034a5..5a345c6 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -27,6 +27,8 @@
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="0px"
+        android:layout_marginTop="@dimen/preference_screen_top_margin"
+        android:layout_marginBottom="@dimen/preference_screen_bottom_margin"
         android:layout_weight="1">
 
         <LinearLayout
@@ -36,14 +38,15 @@
             android:layout_height="match_parent"
             android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
             android:layout_marginLeft="@dimen/preference_screen_side_margin"
-            android:layout_marginTop="32dp"
-            android:layout_marginBottom="32dp"
-            android:layout_weight="10">
+            android:layout_weight="@integer/preferences_left_pane_weight">
 
             <ListView android:id="@android:id/list"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp"
+
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
@@ -60,39 +63,22 @@
                 android:id="@+id/prefs_frame"
                 android:layout_width="0px"
                 android:layout_height="match_parent"
-                android:layout_weight="20"
+                android:layout_weight="@integer/preferences_right_pane_weight"
                 android:layout_marginLeft="@dimen/preference_screen_side_margin"
                 android:layout_marginRight="@dimen/preference_screen_side_margin"
-                android:layout_marginTop="16dp"
-                android:layout_marginBottom="16dp"
                 android:background="?attr/detailsElementBackground"
                 android:orientation="vertical"
                 android:visibility="gone" >
 
-            <!-- Breadcrumb inserted here -->
-            <android.app.FragmentBreadCrumbs
-                android:id="@android:id/title"
-                android:layout_height="72dip"
-                android:layout_width="match_parent"
-                android:paddingTop="16dip"
-                android:paddingBottom="8dip"
-                android:gravity="center_vertical|left"
-                android:layout_marginLeft="48dip"
-                android:layout_marginRight="48dip"
-                />
+            <!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
+                empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
+                the action bar. -->
+            <include layout="@layout/breadcrumbs_in_fragment" />
 
-            <ImageView
-                    android:layout_width="match_parent"
-                    android:layout_height="1dip"
-                    android:paddingLeft="32dip"
-                    android:paddingRight="32dip"
-                    android:src="#404040"
-                />
             <android.preference.PreferenceFrameLayout android:id="@+id/prefs"
                     android:layout_width="match_parent"
                     android:layout_height="0dip"
                     android:layout_weight="1"
-                    android:layout_marginTop="-1dip"
                 />
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 393cecf..986536e 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -29,9 +29,9 @@
         android:layout_height="0px"
         android:layout_weight="1"
         android:paddingTop="0dip"
-        android:paddingBottom="48dip"
-        android:paddingLeft="32dip"
-        android:paddingRight="32dip"
+        android:paddingBottom="@dimen/preference_fragment_padding_bottom"
+        android:paddingLeft="@dimen/preference_fragment_padding_side"
+        android:paddingRight="@dimen/preference_fragment_padding_side"
         android:clipToPadding="false"
         android:drawSelectorOnTop="false"
         android:cacheColorHint="@android:color/transparent"
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index face8b2..99fdf5b 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -33,8 +33,8 @@
         android:layout_gravity="center_vertical"
         android:layout_marginBottom="2dip"
         android:drawablePadding="0dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/textColorPrimaryInverse"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorPrimary"
         android:visibility="gone"
     />
 
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 7f43946..c09cb5b 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -21,4 +21,10 @@
     <dimen name="alert_dialog_title_height">54dip</dimen>
     <!-- Dialog button bar height -->
     <dimen name="alert_dialog_button_bar_height">54dip</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">16dp</dimen>
+    <!-- Preference activity top margin -->
+    <dimen name="preference_screen_top_margin">16dp</dimen>
+    <!-- Preference activity bottom margin -->
+    <dimen name="preference_screen_bottom_margin">16dp</dimen>
 </resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index fbfc3bf..b0a11a6 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -21,7 +21,7 @@
 <resources>
     <dimen name="password_keyboard_key_height">47dip</dimen>
     <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
-    <dimen name="preference_screen_side_margin">96dp</dimen>
-    <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
+    <dimen name="preference_screen_side_margin">16dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-20dp</dimen>
     <dimen name="preference_widget_width">72dp</dimen>
 </resources>
diff --git a/core/res/res/values-large/styles.xml b/core/res/res/values-large/styles.xml
new file mode 100644
index 0000000..79b524d
--- /dev/null
+++ b/core/res/res/values-large/styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <style name="PreferencePanel">
+        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginTop">48dip</item>
+        <item name="android:layout_marginBottom">48dip</item>
+        <item name="android:background">?attr/detailsElementBackground</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
new file mode 100644
index 0000000..734031f
--- /dev/null
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <bool name="preferences_prefer_dual_pane">true</bool>
+</resources>
diff --git a/core/res/res/values-w1280dp/dimens.xml b/core/res/res/values-w1280dp/dimens.xml
new file mode 100644
index 0000000..e67b3a9
--- /dev/null
+++ b/core/res/res/values-w1280dp/dimens.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+<resources>
+    <dimen name="preference_screen_side_margin">96dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
+    <dimen name="preference_widget_width">64dp</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">48dp</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">48dp</dimen>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">48dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">48dp</dimen>
+</resources>
+
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
index a74c41c..45b5c25 100644
--- a/core/res/res/values-w720dp/dimens.xml
+++ b/core/res/res/values-w720dp/dimens.xml
@@ -21,4 +21,18 @@
     <!-- Size of the padding on either side of the app-supplied image
          in the action bar home section. -->
     <dimen name="action_bar_home_image_padding">16dip</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">32dp</dimen>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">32dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">32dp</dimen>
+    <!-- Weight of the left pane in a multi-pane preference layout. -->
+    <integer name="preferences_left_pane_weight">1</integer>
+    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 1:2 -->
+    <integer name="preferences_right_pane_weight">2</integer>
+    <!-- Minimum space to allocate to the left of a preference item for an icon.
+        This helps in aligning titles when some items have icons and some don't. When space is
+        at a premium, we don't pre-allocate any space. -->
+    <dimen name="preference_icon_minWidth">48dp</dimen>
 </resources>
diff --git a/core/res/res/values-xlarge/styles.xml b/core/res/res/values-xlarge/styles.xml
index dd78920..9b2e126 100644
--- a/core/res/res/values-xlarge/styles.xml
+++ b/core/res/res/values-xlarge/styles.xml
@@ -35,13 +35,5 @@
     <style name="TextAppearance.StatusBar.EventContent.Title">
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
-
-    <style name="PreferencePanel">
-        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginTop">48dip</item>
-        <item name="android:layout_marginBottom">48dip</item>
-        <item name="android:background">?attr/detailsElementBackground</item>
-    </style>
 </resources>
 
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
new file mode 100644
index 0000000..cd55122
--- /dev/null
+++ b/core/res/res/values/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<resources>
+    <bool name="preferences_prefer_dual_pane">false</bool>
+</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 1782f02..77ba33e 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -54,9 +54,28 @@
     <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
     <dimen name="preference_screen_side_margin_negative">0dp</dimen>
+    <!-- Preference activity top margin -->
+    <dimen name="preference_screen_top_margin">0dp</dimen>
+    <!-- Preference activity bottom margin -->
+    <dimen name="preference_screen_bottom_margin">0dp</dimen>
     <!-- Preference widget area width (to the left of the text) -->
-    <dimen name="preference_widget_width">56dp</dimen>
-
+    <dimen name="preference_widget_width">48dp</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">0dp</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">0dp</dimen>
+    <!-- Weight of the left pane in a multi-pane preference layout. -->
+    <integer name="preferences_left_pane_weight">4</integer>
+    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 40:60 -->
+    <integer name="preferences_right_pane_weight">6</integer>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">0dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">0dp</dimen>
+    <!-- Minimum space to allocate to the left of a preference item for an icon.
+        This helps in aligning titles when some items have icons and some don't. When space is
+        at a premium, we don't pre-allocate any space. -->
+    <dimen name="preference_icon_minWidth">0dp</dimen>
     <!-- The platform's desired minimum size for a dialog's width when it
          is along the major axis (that is the screen is landscape).  This may
          be either a fraction or a dimension. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 08a3024..74f0d6b 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2183,8 +2183,8 @@
 
     <style name="Widget.Holo.PreferenceFrameLayout">
         <item name="android:borderTop">0dip</item>
-        <item name="android:borderBottom">48dip</item>
-        <item name="android:borderLeft">32dip</item>
-        <item name="android:borderRight">32dip</item>
+        <item name="android:borderBottom">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
     </style>
 </resources>
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 83a1eaa..26eda0c 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -45,8 +45,7 @@
 static Mutex gWVMutex;
 
 WVMExtractor::WVMExtractor(const sp<DataSource> &source)
-    : mDataSource(source),
-      mUseAdaptiveStreaming(false) {
+    : mDataSource(source) {
     {
         Mutex::Autolock autoLock(gWVMutex);
         if (gVendorLibHandle == NULL) {
@@ -59,13 +58,12 @@
         }
     }
 
-    typedef MediaExtractor *(*GetInstanceFunc)(sp<DataSource>);
+    typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
     GetInstanceFunc getInstanceFunc =
         (GetInstanceFunc) dlsym(gVendorLibHandle,
                 "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
 
     if (getInstanceFunc) {
-        LOGD("Calling GetInstanceFunc");
         mImpl = (*getInstanceFunc)(source);
         CHECK(mImpl != NULL);
     } else {
@@ -102,19 +100,17 @@
 }
 
 int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
-    // TODO: Fill this with life.
+    if (mImpl == NULL) {
+        return 0;
+    }
 
-    *finalStatus = OK;
-
-    return 0;
+    return mImpl->getCachedDurationUs(finalStatus);
 }
 
 void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
-    mUseAdaptiveStreaming = adaptive;
-}
-
-bool WVMExtractor::getAdaptiveStreamingMode() const {
-    return mUseAdaptiveStreaming;
+    if (mImpl != NULL) {
+        mImpl->setAdaptiveStreamingMode(adaptive);
+    }
 }
 
 } //namespace android
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index 62e5aa5..deecd25 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -25,6 +25,15 @@
 
 class DataSource;
 
+class WVMLoadableExtractor : public MediaExtractor {
+public:
+    WVMLoadableExtractor() {}
+    virtual ~WVMLoadableExtractor() {}
+
+    virtual int64_t getCachedDurationUs(status_t *finalStatus) = 0;
+    virtual void setAdaptiveStreamingMode(bool adaptive) = 0;
+};
+
 class WVMExtractor : public MediaExtractor {
 public:
     WVMExtractor(const sp<DataSource> &source);
@@ -49,20 +58,15 @@
     // is used.
     void setAdaptiveStreamingMode(bool adaptive);
 
-    // Retrieve the adaptive streaming mode used by the WV component.
-    bool getAdaptiveStreamingMode() const;
-
 protected:
     virtual ~WVMExtractor();
 
 private:
     sp<DataSource> mDataSource;
-    sp<MediaExtractor> mImpl;
-    bool mUseAdaptiveStreaming;
+    sp<WVMLoadableExtractor> mImpl;
 
     WVMExtractor(const WVMExtractor &);
     WVMExtractor &operator=(const WVMExtractor &);
-
 };
 
 }  // namespace android
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index df2cd1b..92d76be 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -134,18 +134,43 @@
         final DeviceAdminInfo info;
 
         int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-        int minimumPasswordLength = 0;
-        int passwordHistoryLength = 0;
-        int minimumPasswordUpperCase = 0;
-        int minimumPasswordLowerCase = 0;
-        int minimumPasswordLetters = 1;
-        int minimumPasswordNumeric = 1;
-        int minimumPasswordSymbols = 1;
-        int minimumPasswordNonLetter = 0;
-        long maximumTimeToUnlock = 0;
-        int maximumFailedPasswordsForWipe = 0;
-        long passwordExpirationTimeout = 0L;
-        long passwordExpirationDate = 0L;
+
+        static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
+        int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH;
+
+        static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
+        int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
+
+        static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
+        int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE;
+
+        static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
+        int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE;
+
+        static final int DEF_MINIMUM_PASSWORD_LETTERS = 1;
+        int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LOWER_CASE;
+
+        static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1;
+        int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC;
+
+        static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1;
+        int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS;
+
+        static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0;
+        int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER;
+
+        static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
+        long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
+
+        static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
+        int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
+
+        static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0;
+        long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT;
+
+        static final long DEF_PASSWORD_EXPIRATION_DATE = 0;
+        long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
+
         boolean encryptionRequested = false;
 
         // TODO: review implementation decisions with frameworks team
@@ -168,53 +193,53 @@
                 out.startTag(null, "password-quality");
                 out.attribute(null, "value", Integer.toString(passwordQuality));
                 out.endTag(null, "password-quality");
-                if (minimumPasswordLength > 0) {
+                if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) {
                     out.startTag(null, "min-password-length");
                     out.attribute(null, "value", Integer.toString(minimumPasswordLength));
                     out.endTag(null, "min-password-length");
                 }
-                if(passwordHistoryLength > 0) {
+                if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
                     out.startTag(null, "password-history-length");
                     out.attribute(null, "value", Integer.toString(passwordHistoryLength));
                     out.endTag(null, "password-history-length");
                 }
-                if (minimumPasswordUpperCase > 0) {
+                if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
                     out.startTag(null, "min-password-uppercase");
                     out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
                     out.endTag(null, "min-password-uppercase");
                 }
-                if (minimumPasswordLowerCase > 0) {
+                if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
                     out.startTag(null, "min-password-lowercase");
                     out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
                     out.endTag(null, "min-password-lowercase");
                 }
-                if (minimumPasswordLetters > 0) {
+                if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) {
                     out.startTag(null, "min-password-letters");
                     out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
                     out.endTag(null, "min-password-letters");
                 }
-                if (minimumPasswordNumeric > 0) {
+                if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
                     out.startTag(null, "min-password-numeric");
                     out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
                     out.endTag(null, "min-password-numeric");
                 }
-                if (minimumPasswordSymbols > 0) {
+                if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
                     out.startTag(null, "min-password-symbols");
                     out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
                     out.endTag(null, "min-password-symbols");
                 }
-                if (minimumPasswordNonLetter > 0) {
+                if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
                     out.startTag(null, "min-password-nonletter");
                     out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter));
                     out.endTag(null, "min-password-nonletter");
                 }
             }
-            if (maximumTimeToUnlock != 0) {
+            if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
                 out.startTag(null, "max-time-to-unlock");
                 out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
                 out.endTag(null, "max-time-to-unlock");
             }
-            if (maximumFailedPasswordsForWipe != 0) {
+            if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
                 out.startTag(null, "max-failed-password-wipe");
                 out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
                 out.endTag(null, "max-failed-password-wipe");
@@ -234,12 +259,12 @@
                     out.endTag(null, "global-proxy-exclusion-list");
                 }
             }
-            if (passwordExpirationTimeout != 0L) {
+            if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) {
                 out.startTag(null, "password-expiration-timeout");
                 out.attribute(null, "value", Long.toString(passwordExpirationTimeout));
                 out.endTag(null, "password-expiration-timeout");
             }
-            if (passwordExpirationDate != 0L) {
+            if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) {
                 out.startTag(null, "password-expiration-date");
                 out.attribute(null, "value", Long.toString(passwordExpirationDate));
                 out.endTag(null, "password-expiration-date");
@@ -399,6 +424,7 @@
                 }
                 if (removed) {
                     validatePasswordOwnerLocked();
+                    saveSettingsLocked();
                 }
             }
         }
@@ -509,12 +535,21 @@
     }
 
     void sendAdminCommandLocked(ActiveAdmin admin, String action) {
+        sendAdminCommandLocked(admin, action, null);
+    }
+
+    void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) {
         Intent intent = new Intent(action);
         intent.setComponent(admin.info.getComponent());
         if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
             intent.putExtra("expiration", admin.passwordExpirationDate);
         }
-        mContext.sendBroadcast(intent);
+        if (result != null) {
+            mContext.sendOrderedBroadcast(intent, null, result, mHandler,
+                    Activity.RESULT_OK, null, null);
+        } else {
+            mContext.sendBroadcast(intent);
+        }
     }
 
     void sendAdminCommandLocked(String action, int reqPolicy) {
@@ -529,20 +564,27 @@
         }
     }
 
-    void removeActiveAdminLocked(ComponentName adminReceiver) {
-        ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
+    void removeActiveAdminLocked(final ComponentName adminReceiver) {
+        final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
         if (admin != null) {
-            boolean doProxyCleanup =
-                admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
             sendAdminCommandLocked(admin,
-                    DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED);
-            // XXX need to wait for it to complete.
-            mAdminList.remove(admin);
-            mAdminMap.remove(adminReceiver);
-            validatePasswordOwnerLocked();
-            if (doProxyCleanup) {
-                resetGlobalProxy();
-            }
+                    DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED,
+                    new BroadcastReceiver() {
+                        @Override
+                        public void onReceive(Context context, Intent intent) {
+                            synchronized (this) {
+                                boolean doProxyCleanup = admin.info.usesPolicy(
+                                        DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
+                                mAdminList.remove(admin);
+                                mAdminMap.remove(adminReceiver);
+                                validatePasswordOwnerLocked();
+                                if (doProxyCleanup) {
+                                    resetGlobalProxy();
+                                }
+                                saveSettingsLocked();
+                            }
+                        }
+            });
         }
     }
 
@@ -1749,7 +1791,6 @@
 
             // Scan through active admins and find if anyone has already
             // set the global proxy.
-            final int N = mAdminList.size();
             Set<ComponentName> compSet = mAdminMap.keySet();
             for  (ComponentName component : compSet) {
                 ActiveAdmin ap = mAdminMap.get(component);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 347d70a..1f2ac2b 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -159,6 +159,7 @@
     private final ArrayList<StorageVolume>        mVolumes = new ArrayList<StorageVolume>();
     private StorageVolume                         mPrimaryVolume;
     private final HashMap<String, String>         mVolumeStates = new HashMap<String, String>();
+    private final HashMap<String, StorageVolume>  mVolumeMap = new HashMap<String, StorageVolume>();
     private String                                mExternalStoragePath;
     private PackageManagerService                 mPms;
     private boolean                               mUmsEnabling;
@@ -669,8 +670,6 @@
      * Callback from NativeDaemonConnector
      */
     public boolean onEvent(int code, String raw, String[] cooked) {
-        Intent in = null;
-
         if (DEBUG_EVENTS) {
             StringBuilder builder = new StringBuilder();
             builder.append("onEvent::");
@@ -705,6 +704,7 @@
             // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>)
             // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>)
             // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>)
+            String action = null;
             final String label = cooked[2];
             final String path = cooked[3];
             int major = -1;
@@ -743,32 +743,31 @@
                 /* Send the media unmounted event first */
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending unmounted event first");
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-                in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
-                mContext.sendBroadcast(in);
+                sendStorageIntent(Environment.MEDIA_UNMOUNTED, path);
 
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending media removed");
                 updatePublicVolumeState(path, Environment.MEDIA_REMOVED);
-                in = new Intent(Intent.ACTION_MEDIA_REMOVED, Uri.parse("file://" + path));
+                action = Intent.ACTION_MEDIA_REMOVED;
             } else if (code == VoldResponseCode.VolumeBadRemoval) {
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending unmounted event first");
                 /* Send the media unmounted event first */
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-                in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
-                mContext.sendBroadcast(in);
+                action = Intent.ACTION_MEDIA_UNMOUNTED;
 
                 if (DEBUG_EVENTS) Slog.i(TAG, "Sending media bad removal");
                 updatePublicVolumeState(path, Environment.MEDIA_BAD_REMOVAL);
-                in = new Intent(Intent.ACTION_MEDIA_BAD_REMOVAL, Uri.parse("file://" + path));
+                action = Intent.ACTION_MEDIA_BAD_REMOVAL;
             } else {
                 Slog.e(TAG, String.format("Unknown code {%d}", code));
             }
+
+            if (action != null) {
+                sendStorageIntent(action, path);
+            }
         } else {
             return false;
         }
 
-        if (in != null) {
-            mContext.sendBroadcast(in);
-        }
         return true;
     }
 
@@ -776,12 +775,11 @@
         String vs = getVolumeState(path);
         if (DEBUG_EVENTS) Slog.i(TAG, "notifyVolumeStateChanged::" + vs);
 
-        Intent in = null;
+        String action = null;
 
         if (oldState == VolumeState.Shared && newState != oldState) {
             if (LOCAL_LOGD) Slog.d(TAG, "Sending ACTION_MEDIA_UNSHARED intent");
-            mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_UNSHARED,
-                                                Uri.parse("file://" + path)));
+            sendStorageIntent(Intent.ACTION_MEDIA_UNSHARED,  path);
         }
 
         if (newState == VolumeState.Init) {
@@ -798,31 +796,29 @@
                                     Environment.MEDIA_UNMOUNTABLE) && !getUmsEnabling()) {
                 if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state for media bad removal nofs and unmountable");
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-                in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
+                action = Intent.ACTION_MEDIA_UNMOUNTED;
             }
         } else if (newState == VolumeState.Pending) {
         } else if (newState == VolumeState.Checking) {
             if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state checking");
             updatePublicVolumeState(path, Environment.MEDIA_CHECKING);
-            in = new Intent(Intent.ACTION_MEDIA_CHECKING, Uri.parse("file://" + path));
+            action = Intent.ACTION_MEDIA_CHECKING;
         } else if (newState == VolumeState.Mounted) {
             if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state mounted");
             updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);
-            in = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + path));
-            in.putExtra("read-only", false);
+            action = Intent.ACTION_MEDIA_MOUNTED;
         } else if (newState == VolumeState.Unmounting) {
-            in = new Intent(Intent.ACTION_MEDIA_EJECT, Uri.parse("file://" + path));
+            action = Intent.ACTION_MEDIA_EJECT;
         } else if (newState == VolumeState.Formatting) {
         } else if (newState == VolumeState.Shared) {
             if (DEBUG_EVENTS) Slog.i(TAG, "Updating volume state media mounted");
             /* Send the media unmounted event first */
             updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
-            in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
-            mContext.sendBroadcast(in);
+            sendStorageIntent(Intent.ACTION_MEDIA_UNMOUNTED, path);
 
             if (DEBUG_EVENTS) Slog.i(TAG, "Updating media shared");
             updatePublicVolumeState(path, Environment.MEDIA_SHARED);
-            in = new Intent(Intent.ACTION_MEDIA_SHARED, Uri.parse("file://" + path));
+            action = Intent.ACTION_MEDIA_SHARED;
             if (LOCAL_LOGD) Slog.d(TAG, "Sending ACTION_MEDIA_SHARED intent");
         } else if (newState == VolumeState.SharedMnt) {
             Slog.e(TAG, "Live shared mounts not supported yet!");
@@ -831,8 +827,8 @@
             Slog.e(TAG, "Unhandled VolumeState {" + newState + "}");
         }
 
-        if (in != null) {
-            mContext.sendBroadcast(in);
+        if (action != null) {
+            sendStorageIntent(action, path);
         }
     }
 
@@ -882,7 +878,7 @@
             /*
              * Mount failed for some reason
              */
-            Intent in = null;
+            String action = null;
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedNoMedia) {
                 /*
@@ -895,7 +891,7 @@
                  * Media is blank or does not contain a supported filesystem
                  */
                 updatePublicVolumeState(path, Environment.MEDIA_NOFS);
-                in = new Intent(Intent.ACTION_MEDIA_NOFS, Uri.parse("file://" + path));
+                action = Intent.ACTION_MEDIA_NOFS;
                 rc = StorageResultCode.OperationFailedMediaBlank;
             } else if (code == VoldResponseCode.OpFailedMediaCorrupt) {
                 if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state media corrupt");
@@ -903,7 +899,7 @@
                  * Volume consistency check failed
                  */
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTABLE);
-                in = new Intent(Intent.ACTION_MEDIA_UNMOUNTABLE, Uri.parse("file://" + path));
+                action = Intent.ACTION_MEDIA_UNMOUNTABLE;
                 rc = StorageResultCode.OperationFailedMediaCorrupt;
             } else {
                 rc = StorageResultCode.OperationFailedInternalError;
@@ -912,8 +908,8 @@
             /*
              * Send broadcast intent (if required for the failure)
              */
-            if (in != null) {
-                mContext.sendBroadcast(in);
+            if (action != null) {
+                sendStorageIntent(action, path);
             }
         }
 
@@ -1070,6 +1066,14 @@
         }
     }
 
+    private void sendStorageIntent(String action, String path) {
+        Intent intent = new Intent(action, Uri.parse("file://" + path));
+        // add StorageVolume extra
+        intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, mVolumeMap.get(path));
+        Slog.d(TAG, "sendStorageIntent " + intent);
+        mContext.sendBroadcast(intent);
+    }
+
     private void sendUmsIntent(boolean c) {
         mContext.sendBroadcast(
                 new Intent((c ? Intent.ACTION_UMS_CONNECTED : Intent.ACTION_UMS_DISCONNECTED)));
@@ -1121,7 +1125,8 @@
                     if (path == null || description == null) {
                         Slog.e(TAG, "path or description is null in readStorageList");
                     } else {
-                        StorageVolume volume = new StorageVolume(path.toString(),
+                        String pathString = path.toString();
+                        StorageVolume volume = new StorageVolume(pathString,
                                 description.toString(), removable, emulated, mtpReserve);
                         if (primary) {
                             if (mPrimaryVolume == null) {
@@ -1136,6 +1141,7 @@
                         } else {
                             mVolumes.add(volume);
                         }
+                        mVolumeMap.put(pathString, volume);
                     }
                     a.recycle();
                 }
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 3561862..f3a2a62 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -282,8 +282,8 @@
     private final SparseIntArray mClientUids = new SparseIntArray();
 
     // how often to request NTP time, in milliseconds
-    // current setting 4 hours
-    private static final long NTP_INTERVAL = 4*60*60*1000;
+    // current setting 24 hours
+    private static final long NTP_INTERVAL = 24*60*60*1000;
     // how long to wait if we have a network error in NTP or XTRA downloading
     // current setting - 5 minutes
     private static final long RETRY_INTERVAL = 5*60*1000;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 5c49ef09..31977e4 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5996,8 +5996,12 @@
             mActivityManager.updateConfiguration(null);
         } catch (RemoteException e) {
         }
-        
+
         mPolicy.systemReady();
+
+        synchronized (mWindowMap) {
+            readForcedDisplaySizeLocked();
+        }
     }
 
     // This is an animation that does nothing: it just immediately finishes
@@ -6513,6 +6517,8 @@
                         ? shortDimen : mInitialDisplayHeight;
             }
             setForcedDisplaySizeLocked(width, height);
+            Settings.Secure.putString(mContext.getContentResolver(),
+                    Settings.Secure.DISPLAY_SIZE_FORCED, width + "," + height);
         }
     }
 
@@ -6559,7 +6565,29 @@
         }
     }
 
+    private void readForcedDisplaySizeLocked() {
+        final String str = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.DISPLAY_SIZE_FORCED);
+        if (str == null || str.length() == 0) {
+            return;
+        }
+        final int pos = str.indexOf(',');
+        if (pos <= 0 || str.lastIndexOf(',') != pos) {
+            return;
+        }
+        int width, height;
+        try {
+            width = Integer.parseInt(str.substring(0, pos));
+            height = Integer.parseInt(str.substring(pos+1));
+        } catch (NumberFormatException ex) {
+            return;
+        }
+        setForcedDisplaySizeLocked(width, height);
+    }
+
     private void setForcedDisplaySizeLocked(int width, int height) {
+        Slog.i(TAG, "Using new display size: " + width + "x" + height);
+
         mBaseDisplayWidth = width;
         mBaseDisplayHeight = height;
         mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
@@ -6589,6 +6617,8 @@
     public void clearForcedDisplaySize() {
         synchronized(mWindowMap) {
             setForcedDisplaySizeLocked(mInitialDisplayWidth, mInitialDisplayHeight);
+            Settings.Secure.putString(mContext.getContentResolver(),
+                    Settings.Secure.DISPLAY_SIZE_FORCED, "");
         }
     }