Merge "Revert "Updated volume rocker assets for ring notification icon"" into ics-mr0
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index 448b2c0..acc8549 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -43,7 +43,7 @@
  * @hide
  */
 public class ChooseAccountTypeActivity extends Activity {
-    private static final String TAG = "AccountManager";
+    private static final String TAG = "AccountChooser";
 
     private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
     private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
@@ -52,6 +52,11 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
+                    + savedInstanceState + ")");
+        }
+
         // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
         Set<String> setOfAllowableAccountTypes = null;
         String[] validAccountTypes = getIntent().getStringArrayExtra(
@@ -111,8 +116,10 @@
         Bundle bundle = new Bundle();
         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
         setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-        Log.d(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
-                + "selected account type " + type);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
+                    + "selected account type " + type);
+        }
         finish();
     }
 
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 8cc2002..5f38eb4 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -47,7 +47,7 @@
  */
 public class ChooseTypeAndAccountActivity extends Activity
         implements AccountManagerCallback<Bundle> {
-    private static final String TAG = "AccountManager";
+    private static final String TAG = "AccountChooser";
 
     /**
      * A Parcelable ArrayList of Account objects that limits the choosable accounts to those
@@ -100,13 +100,39 @@
     public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE =
             "descriptionTextOverride";
 
+    public static final int REQUEST_NULL = 0;
+    public static final int REQUEST_CHOOSE_TYPE = 1;
+    public static final int REQUEST_ADD_ACCOUNT = 2;
+
+    private static final String KEY_INSTANCE_STATE_PENDING_REQUEST = "pendingRequest";
+    private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
+
     private ArrayList<AccountInfo> mAccountInfos;
+    private int mPendingRequest = REQUEST_NULL;
+    private Parcelable[] mExistingAccounts = null;
+    private Parcelable[] mSavedAccounts = null;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState="
+                    + savedInstanceState + ")");
+        }
+
         setContentView(R.layout.choose_type_and_account);
 
+        if (savedInstanceState != null) {
+            mPendingRequest = savedInstanceState.getInt(KEY_INSTANCE_STATE_PENDING_REQUEST);
+            mSavedAccounts =
+                    savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS);
+            mExistingAccounts = null;
+        } else {
+            mPendingRequest = REQUEST_NULL;
+            mSavedAccounts = null;
+            mExistingAccounts = null;
+        }
+
         // save some items we use frequently
         final AccountManager accountManager = AccountManager.get(this);
         final Intent intent = getIntent();
@@ -171,20 +197,6 @@
                     account.equals(selectedAccount)));
         }
 
-        // If there are no allowable accounts go directly to add account
-        if (mAccountInfos.isEmpty()) {
-            startChooseAccountTypeActivity();
-            return;
-        }
-
-        // if there is only one allowable account return it
-        if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
-                && mAccountInfos.size() == 1) {
-            Account account = mAccountInfos.get(0).account;
-            setResultAndFinish(account.name, account.type);
-            return;
-        }
-
         // there is more than one allowable account. initialize the list adapter to allow
         // the user to select an account.
         ListView list = (ListView) findViewById(android.R.id.list);
@@ -204,6 +216,37 @@
                 startChooseAccountTypeActivity();
             }
         });
+
+        if (mPendingRequest == REQUEST_NULL) {
+            // If there are no allowable accounts go directly to add account
+            if (mAccountInfos.isEmpty()) {
+                startChooseAccountTypeActivity();
+                return;
+            }
+
+            // if there is only one allowable account return it
+            if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
+                    && mAccountInfos.size() == 1) {
+                Account account = mAccountInfos.get(0).account;
+                setResultAndFinish(account.name, account.type);
+                return;
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onDestroy()");
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onSaveInstanceState(final Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(KEY_INSTANCE_STATE_PENDING_REQUEST, mPendingRequest);
+        outState.putParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS, mExistingAccounts);
     }
 
     // Called when the choose account type activity (for adding an account) returns.
@@ -212,20 +255,75 @@
     @Override
     protected void onActivityResult(final int requestCode, final int resultCode,
             final Intent data) {
-        if (resultCode == RESULT_OK && data != null) {
-            String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
-            if (accountType != null) {
-                runAddAccountForAuthenticator(accountType);
-                return;
-            }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            if (data != null && data.getExtras() != null) data.getExtras().keySet();
+            Bundle extras = data != null ? data.getExtras() : null;
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult(reqCode=" + requestCode
+                    + ", resCode=" + resultCode + ", extras=" + extras + ")");
         }
-        Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+
+        // we got our result, so clear the fact that we had a pending request
+        mPendingRequest = REQUEST_NULL;
+        mExistingAccounts = null;
+
+        if (resultCode == RESULT_CANCELED) {
+            return;
+        }
+
+        if (resultCode == RESULT_OK) {
+            if (requestCode == REQUEST_CHOOSE_TYPE) {
+                if (data != null) {
+                    String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+                    if (accountType != null) {
+                        runAddAccountForAuthenticator(accountType);
+                        return;
+                    }
+                }
+                Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find account "
+                        + "type, pretending the request was canceled");
+            } else if (requestCode == REQUEST_ADD_ACCOUNT) {
+                String accountName = null;
+                String accountType = null;
+
+                if (data != null) {
+                    accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
+                    accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+                }
+
+                if (accountName == null || accountType == null) {
+                    Account[] currentAccounts = AccountManager.get(this).getAccounts();
+                    Set<Account> preExistingAccounts = new HashSet<Account>();
+                    for (Parcelable accountParcel : mSavedAccounts) {
+                        preExistingAccounts.add((Account) accountParcel);
+                    }
+                    for (Account account : currentAccounts) {
+                        if (!preExistingAccounts.contains(account)) {
+                            accountName = account.name;
+                            accountType = account.type;
+                            break;
+                        }
+                    }
+                }
+
+                if (accountName != null || accountType != null) {
+                    setResultAndFinish(accountName, accountType);
+                    return;
+                }
+            }
+            Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find added "
+                    + "account, pretending the request was canceled");
+        }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+        }
         setResult(Activity.RESULT_CANCELED);
         finish();
     }
 
     protected void runAddAccountForAuthenticator(String type) {
-        Log.d(TAG, "selected account type " + type);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "runAddAccountForAuthenticator: " + type);
+        }
         final Bundle options = getIntent().getBundleExtra(
                 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE);
         final String[] requiredFeatures = getIntent().getStringArrayExtra(
@@ -233,20 +331,19 @@
         final String authTokenType = getIntent().getStringExtra(
                 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING);
         AccountManager.get(this).addAccount(type, authTokenType, requiredFeatures,
-                options, this, this, null /* Handler */);
+                options, null /* activity */, this /* callback */, null /* Handler */);
     }
 
     public void run(final AccountManagerFuture<Bundle> accountManagerFuture) {
         try {
             final Bundle accountManagerResult = accountManagerFuture.getResult();
-            final String name = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME);
-            final String type = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE);
-            if (name != null && type != null) {
-                final Bundle bundle = new Bundle();
-                bundle.putString(AccountManager.KEY_ACCOUNT_NAME, name);
-                bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
-                setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-                finish();
+            final Intent intent = (Intent)accountManagerResult.getParcelable(
+                    AccountManager.KEY_INTENT);
+            if (intent != null) {
+                mPendingRequest = REQUEST_ADD_ACCOUNT;
+                mExistingAccounts = AccountManager.get(this).getAccounts();
+                intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
                 return;
             }
         } catch (OperationCanceledException e) {
@@ -297,12 +394,17 @@
         bundle.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
         setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-        Log.d(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
-                + "selected account " + accountName + ", " + accountType);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
+                    + "selected account " + accountName + ", " + accountType);
+        }
         finish();
     }
 
     private void startChooseAccountTypeActivity() {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.startChooseAccountTypeActivity()");
+        }
         final Intent intent = new Intent(this, ChooseAccountTypeActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
         intent.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
@@ -313,7 +415,8 @@
                 getIntent().getStringArrayExtra(EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY));
         intent.putExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
                 getIntent().getStringExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING));
-        startActivityForResult(intent, 0);
+        startActivityForResult(intent, REQUEST_CHOOSE_TYPE);
+        mPendingRequest = REQUEST_CHOOSE_TYPE;
     }
 
     private static class AccountInfo {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index ca64c88..c5ee48d 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -40,15 +40,20 @@
     public static final int DISABLE_NOTIFICATION_TICKER
             = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
     public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
-    public static final int DISABLE_NAVIGATION = View.STATUS_BAR_DISABLE_NAVIGATION;
+    public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
+    public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
     public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
     public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
 
+    @Deprecated
+    public static final int DISABLE_NAVIGATION = 
+            View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;
+
     public static final int DISABLE_NONE = 0x00000000;
 
     public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
             | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
-            | DISABLE_SYSTEM_INFO| DISABLE_NAVIGATION | DISABLE_BACK | DISABLE_CLOCK;
+            | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK;
 
     private Context mContext;
     private IStatusBarService mService;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 86be28a..73e5026 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1891,12 +1891,10 @@
      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
      * out of the public fields to keep the undefined bits out of the developer's way.
      *
-     * Flag to hide only the navigation buttons.  Don't use this
+     * Flag to hide only the home button.  Don't use this
      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
-     *
-     * THIS DOES NOT DISABLE THE BACK BUTTON
      */
-    public static final int STATUS_BAR_DISABLE_NAVIGATION = 0x00200000;
+    public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
 
     /**
      * @hide
@@ -1904,7 +1902,7 @@
      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
      * out of the public fields to keep the undefined bits out of the developer's way.
      *
-     * Flag to hide only the back button.  Don't use this
+     * Flag to hide only the back button. Don't use this
      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
      */
     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
@@ -1922,6 +1920,28 @@
 
     /**
      * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the recent apps button. Don't use this
+     * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
+     */
+    public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility, etc. etc.
+     *
+     * This hides HOME and RECENT and is provided for compatibility with interim implementations.
+     */
+    @Deprecated
+    public static final int STATUS_BAR_DISABLE_NAVIGATION = 
+            STATUS_BAR_DISABLE_HOME | STATUS_BAR_DISABLE_RECENT;
+
+    /**
+     * @hide
      */
     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
 
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 9c44138..f1c2bde 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -211,6 +211,7 @@
     private ZoomDensity     mDefaultZoom = ZoomDensity.MEDIUM;
     private RenderPriority  mRenderPriority = RenderPriority.NORMAL;
     private int             mOverrideCacheMode = LOAD_DEFAULT;
+    private int             mDoubleTapZoom = 100;
     private boolean         mSaveFormData = true;
     private boolean         mAutoFillEnabled = false;
     private boolean         mSavePassword = true;
@@ -769,6 +770,27 @@
     }
 
     /**
+     * Set the double-tap zoom of the page in percent. Default is 100.
+     * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
+     * @hide
+     */
+    public void setDoubleTapZoom(int doubleTapZoom) {
+        if (mDoubleTapZoom != doubleTapZoom) {
+            mDoubleTapZoom = doubleTapZoom;
+            mWebView.updateDoubleTapZoom();
+        }
+    }
+
+    /**
+     * Get the double-tap zoom of the page in percent.
+     * @return A percent value describing the double-tap zoom.
+     * @hide
+     */
+    public int getDoubleTapZoom() {
+        return mDoubleTapZoom;
+    }
+
+    /**
      * Set the default zoom density of the page. This should be called from UI
      * thread.
      * @param zoom A ZoomDensity value
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9648cd0..8da1820 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2986,6 +2986,13 @@
         return false;
     }
 
+    /**
+     * Update the double-tap zoom.
+     */
+    /* package */ void updateDoubleTapZoom() {
+        mZoomManager.updateDoubleTapZoom();
+    }
+
     private int computeRealHorizontalScrollRange() {
         if (mDrawHistory) {
             return mHistoryWidth;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7f526e7..206142a 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -145,11 +145,11 @@
     private float mInvDefaultScale;
 
     /*
-     * The scale factor that is used to determine the zoom level for reading text.
-     * The value is initially set to equal the display density.
-     * TODO: Support changing this in WebSettings
+     * The logical density of the display. This is a scaling factor for the
+     * Density Independent Pixel unit, where one DIP is one pixel on an
+     * approximately 160 dpi screen (see android.util.DisplayMetrics.density)
      */
-    private float mReadingLevelScale;
+    private float mDisplayDensity;
 
     /*
      * The scale factor that is used as the minimum increment when going from
@@ -233,11 +233,11 @@
     public void init(float density) {
         assert density > 0;
 
+        mDisplayDensity = density;
         setDefaultZoomScale(density);
         mActualScale = density;
         mInvActualScale = 1 / density;
-        mReadingLevelScale = density;
-        mTextWrapScale = density;
+        mTextWrapScale = getReadingLevelScale();
     }
 
     /**
@@ -310,8 +310,11 @@
         return mInitialScale > 0 ? mInitialScale : mDefaultScale;
     }
 
+    /**
+     * Returns the zoom scale used for reading text on a double-tap.
+     */
     public final float getReadingLevelScale() {
-        return mReadingLevelScale;
+        return mDisplayDensity * mWebView.getSettings().getDoubleTapZoom() / 100.0f;
     }
 
     public final float getInvDefaultScale() {
@@ -510,6 +513,13 @@
         return mZoomScale != 0 || mInHWAcceleratedZoom;
     }
 
+    public void updateDoubleTapZoom() {
+        if (mInZoomOverview) {
+            mTextWrapScale = getReadingLevelScale();
+            refreshZoomScale(true);
+        }
+    }
+
     public void refreshZoomScale(boolean reflowText) {
         setZoomScale(mActualScale, reflowText, true);
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 475b8ee..bdaf89e 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -335,7 +335,9 @@
                     mTouchDownX = event.getX();
                 } else {
                     setPressed(true);
-                    invalidate(mThumb.getBounds()); // This may be within the padding region
+                    if (mThumb != null) {
+                        invalidate(mThumb.getBounds()); // This may be within the padding region
+                    }
                     onStartTrackingTouch();
                     trackTouchEvent(event);
                     attemptClaimDrag();
@@ -349,7 +351,9 @@
                     final float x = event.getX();
                     if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
                         setPressed(true);
-                        invalidate(mThumb.getBounds()); // This may be within the padding region
+                        if (mThumb != null) {
+                            invalidate(mThumb.getBounds()); // This may be within the padding region
+                        }
                         onStartTrackingTouch();
                         trackTouchEvent(event);
                         attemptClaimDrag();
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
index 81c52b0..3e00747 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
index 15500c3..c760936 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
index f3aaa27..8148ab8 100644
--- a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index a9af4a8..c63ca94 100644
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
index 85f3cb2..baa5427 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
index 77f92fb..8e6a93f 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
index 747cb97..b7e2a6a 100644
--- a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index e8c6374..ec7ef0c 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
index 16632b1..7aa8750 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
index 6e007c7..d4e4d81 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
index 6bb7512..0dbae57 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 3ac1b88..6938ab4 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/layout/volume_adjust_item.xml b/core/res/res/layout/volume_adjust_item.xml
index fb900f7..d3fa7e9 100644
--- a/core/res/res/layout/volume_adjust_item.xml
+++ b/core/res/res/layout/volume_adjust_item.xml
@@ -27,7 +27,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:padding="16dip"
-        android:layout_marginLeft="8dip"
         android:background="?attr/selectableItemBackground"
         />
 
@@ -38,8 +37,6 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:padding="16dip"
-        android:layout_marginRight="8dip" />
+        android:layout_marginRight="16dip" />
 
 </LinearLayout>
-
-
diff --git a/docs/html/guide/developing/devices/emulator.jd b/docs/html/guide/developing/devices/emulator.jd
index fe00531..8211275 100644
--- a/docs/html/guide/developing/devices/emulator.jd
+++ b/docs/html/guide/developing/devices/emulator.jd
@@ -32,6 +32,12 @@
         </ol>
       </li>
     </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a></li>
+    <li><a href="{@docRoot}guide/developing/devices/managing-avds.html">Managing AVDs with AVD Manager</a></li>
+  </ol>
 </div>
 </div>
 
@@ -63,8 +69,6 @@
 
 
 
-
-
 <h2  id="overview">Overview</h2>
 
 <p>The Android emulator is a QEMU-based application that provides a virtual ARM
@@ -166,7 +170,8 @@
 
 <p>To stop an emulator instance, just close the emulator's window.</p>
 
-
+<p>For a reference of the emulator's startup commands and keyboard mapping, see
+the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> document.</p>
 
 
 
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index ff667f2..5151ec1 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -3,6 +3,25 @@
 parent.link=index.html
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>In this document</h2>
+  <ol>
+    <li><a href="#startup-options">Emulator Startup Options</a></li>
+    <li><a href="#KeyMapping">Emulator Keyboard Mapping</a></li>
+  </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}guide/developing/devices/emulator.html">Using the Android Emulator</a></li>
+    <li><a href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a></li>
+  </ol>
+
+</div>
+</div>
+
+
 <p>The Android SDK includes a mobile device emulator &mdash; a virtual mobile device 
 that runs on your computer. The emulator lets you develop and test
 Android applications without using a physical device.</p>
@@ -451,7 +470,10 @@
   <td>See comments for <code>-skin</code>, above.</td></tr>
 </table>
 
-<h2>Emulator Keyboard Mapping</h2>
+
+
+<h2 id="KeyMapping">Emulator Keyboard Mapping</h2>
+
 <p>The table below summarizes the mappings between the emulator keys and and 
 the keys of your keyboard. </p>
 <p class="table-caption"><strong>Table 2.</strong> Emulator keyboard mapping</p>
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index 8f7ac55..619c907 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -71,7 +71,12 @@
   <div class="toggle-content-toggleme" style="padding-left:2em;">
 
 <dl>
-<dt>Initial release. SDK Tools r14 or higher is recommended.</dt>
+<dt>Initial release. SDK Tools r14 or higher is required.
+<p class="note"><strong>Important:</strong> To download the new Android
+4.0 system components from the Android SDK Manager, you must first update the
+SDK tools to revision 14 and restart the Android SDK Manager. If you do not,
+the Android 4.0 system components will not be available for download.</p>
+</dt>
 </dl>
 
   </div>
@@ -165,7 +170,7 @@
 
 <p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows you to
 invoke an action that indicates the user wants to add a contact to a social network that understand
-this intent and use it to invite the contact specified in the contact to that social network.</p> 
+this intent and use it to invite the contact specified in the contact to that social network.</p>
 
 <p>Apps that use a sync adapter to provide information about contacts can register with the system
 to
@@ -290,7 +295,7 @@
 located</li>
 </ul>
 
-  
+
 <h4>Focus and Metering Areas</h4>
 
 <p>Camera apps can now control the areas that the camera uses for focus and when metering white
@@ -334,7 +339,7 @@
 <h4>Camera Broadcast Intents</h4>
 
 <ul>
-<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE} 
+<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE}
 This indicates that the user has captured a new photo. The built-in camera app invokes this
 broadcast after a photo is captured and third-party camera apps should also broadcast this intent
 after capturing a photo.</li>
@@ -344,10 +349,10 @@
 after capturing a video.</li>
 </ul>
 
-  
-  
 
-  
+
+
+
 <h3 id="Multimedia">Multimedia</h3>
 
 <p>Android 4.0 adds several new APIs for applications that interact with media such as photos,
@@ -476,7 +481,7 @@
 function). You may provide multiple mipmap levels. If the output texture has not been bound to a
 texture image, it will be automatically bound by the effect as a {@link
 android.opengl.GLES20#GL_TEXTURE_2D}. It will contain one mipmap level (0), which will have the same
-size as the input.</p> 
+size as the input.</p>
 
 
 
@@ -844,9 +849,9 @@
   onInitializeAccessibilityEvent()} - This method collects information about the view. If your
   application has specific requirements for accessibility, you should extend this method to add that
   information to the {@link android.view.accessibility.AccessibilityEvent}.</li>
-  
+
   <li>{@link
- 
+
 android.view.View#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
   dispatchPopulateAccessibilityEvent()} is called by the framework to request text information for
   this view and its children. This method calls {@link
@@ -890,7 +895,7 @@
 the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
 AccessibilityEvent.getRecord()} to retrieve new accessibility information about the state of the
 view.</li>
-<li>From the {@link android.view.accessibility.AccessibilityRecord}, call {@link 
+<li>From the {@link android.view.accessibility.AccessibilityRecord}, call {@link
 android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
 android.view.accessibility.AccessibilityNodeInfo} object.</li>
 <li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, call {@link
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 333efa2..dab5b29 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
 page.title=ADT Plugin for Eclipse
 adt.zip.version=14.0.0
 adt.zip.download=ADT-14.0.0.zip
-adt.zip.bytes=6745584
-adt.zip.checksum=a645330d90fd9dae6187662bb1c3c644
+adt.zip.bytes=6745047
+adt.zip.checksum=014312e1553e3b8da55cb6a24e33e432
 
 @jd:body
 
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 065f41b..67be5c9 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,20 +2,20 @@
 sdk.redirect=0
 
 sdk.win_installer=installer_r14-windows.exe
-sdk.win_installer_bytes=33860145
-sdk.win_installer_checksum=7a563491bf4671d09b9da0dcde85f212
+sdk.win_installer_bytes=33860326
+sdk.win_installer_checksum=6d4f76385daaee766ad901699cdae6cc
 
 sdk.win_download=android-sdk_r14-windows.zip
-sdk.win_bytes=33852972
-sdk.win_checksum=d1381a0cc8e6f9358174aa6d051ba379
+sdk.win_bytes=33853090
+sdk.win_checksum=0c39628e296d6176ed928cc64498ba04
 
 sdk.mac_download=android-sdk_r14-macosx.zip
-sdk.mac_bytes=30426052
-sdk.mac_checksum=df0a5c5b5327ffcaf256ce735998e12a
+sdk.mac_bytes=30426431
+sdk.mac_checksum=189ce3e26dfb46298a7def21d3bdf271
 
 sdk.linux_download=android-sdk_r14-linux.tgz
-sdk.linux_bytes=26083315
-sdk.linux_checksum=2049d5c1a164fcae47a5e93c52200752
+sdk.linux_bytes=26082867
+sdk.linux_checksum=500483f8acd0d3cae94c68c3dcefbb98
 
 @jd:body
 
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 2d044ed..6cb246c 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -66,7 +66,12 @@
   <a href="#" onclick="return toggleDiv(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
     width="9px" />SDK Tools, Revision 14</a> <em>(October 2011)</em>
+
   <div class="toggleme">
+    <p class="note"><strong>Important:</strong> To download the new Android
+    4.0 system components from the Android SDK Manager, you must first update the
+    SDK tools to revision 14 and restart the Android SDK Manager. If you do not,
+    the Android 4.0 system components will not be available for download.</p>
   <dl>
 <dt>Dependencies:</dt>
 <dd>
@@ -81,6 +86,9 @@
 <dt>General notes:</dt>
 <dd>
   <ul>
+    <li>Added webcam support to Android 4.0 or later platforms to emulate rear-facing cameras when one webcam is present,
+    and to emulate both rear-facing and front-facing cameras when two webcams are present. Webcam suport is for Windows and Linux only.
+    Mac support will come in a later release.</li>
      <li>Changed <code>default.properties</code> to <code>project.properties</code> and
     <code>build.properties</code> to <code>ant.properties</code>. Any existing
     projects that you build with Ant must be updated with the <code>android update project</code>
@@ -90,7 +98,6 @@
 commands, see the
 <a href="{@docRoot}guide/developing/building/building-cmdline.html#AntReference">Ant Command
 Reference</a>.</li>
-
     <li>Changed how library projects are built.</a></li>
     <li>Improved incremental builds, so that resource compilation runs less frequently. Builds no
     longer run when you edit strings or layouts (unless you add a new <code>id</code>) and no longer
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index a9b539b..dc6c011 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -947,7 +947,12 @@
 
     if (mSendObjectFileSize - initialData > 0) {
         mfr.offset = initialData;
-        mfr.length = mSendObjectFileSize - initialData;
+        if (mSendObjectFileSize == 0xFFFFFFFF) {
+            // tell driver to read until it receives a short packet
+            mfr.length = 0xFFFFFFFF;
+        } else {
+            mfr.length = mSendObjectFileSize - initialData;
+        }
 
         LOGV("receiving %s\n", (const char *)mSendObjectFilePath);
         // transfer the file
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 3adcbec..4a1d37e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
index d7a591c..9378fac 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
index 277dcb8..6e84546 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
index edc1760..c56905e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
index fbc6b99..11ffbde 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
index fb938e8..2bb923e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
index 2d35517..783ad175 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
index fe68c3c..e499f9d 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 49411bd..39e3df0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
index 77924f0..b4920c3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
index 000e98b..31c0936 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
index 62b940a..7e9b752 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
index 5beb543..3209234d 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
index f70d315..95c56ed 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
index be9953f..11b9a93 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
index de20bdd..0f85ca0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
index 8a3d90c..3d67766 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
index 45dda51c..b74e070 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
index 18e019c..24485e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
index cb8ed3a..390d500 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
index ab4ad05..78998f9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
index 956b6c1..c539615 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
index 9d95f17..5c38d45 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
index e68d57d..6a79695 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
index 4ac361d9..99dbe1b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
index 5e7ecdc..6a73a89 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
index 462fad4..7042f2b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
index d284c02..3da781e 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
index 4a5e701..cf63e24 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
index 9a08949..8f68e1f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
index 314f422..894c63b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
index 4e0a48a..1ec5b49 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
index 4eeae1d..9ca3ca8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
index 1a6f1ef..74241e0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index d853993..faeee29 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
index 2e6e3ac..f7e7102 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
index 2864ec3..cc9c49f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
index 0bb0c72..5a313c5 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
index f23dd60..373a4a4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
index b1c3168..d299daf 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
index 5e41470..dcfdb7b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
index 639842b..fb8125a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 5b4c33e..d3c4a61 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -483,7 +483,8 @@
         } else {
             Intent intent = ad.intent;
             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME
+                    | Intent.FLAG_ACTIVITY_NEW_TASK);
             if (DEBUG) Log.v(TAG, "Starting activity " + intent);
             context.startActivity(intent);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index e3a64a8..694da20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -116,15 +116,13 @@
 
         mDisabledFlags = disabledFlags;
 
-        final boolean disableNavigation = ((disabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) != 0);
+        final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+        final boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
         final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
 
         getBackButton()   .setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
-        getHomeButton()   .setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
-        getRecentsButton().setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
- 
-        getMenuButton()   .setVisibility((disableNavigation || !mShowMenu)
-                                                           ? View.INVISIBLE : View.VISIBLE);
+        getHomeButton()   .setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
+        getRecentsButton().setVisibility(disableRecent     ? View.INVISIBLE : View.VISIBLE);
     }
 
     public void setMenuVisibility(final boolean show) {
@@ -136,9 +134,7 @@
 
         mShowMenu = show;
 
-        getMenuButton().setVisibility(
-            (0 != (mDisabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) || !mShowMenu)
-                ? View.INVISIBLE : View.VISIBLE);
+        getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
     }
 
     public void setLowProfile(final boolean lightsOut) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e54de59..9c8c229 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -300,18 +300,6 @@
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
-
-                sb.setOnSystemUiVisibilityChangeListener(
-                    new View.OnSystemUiVisibilityChangeListener() {
-                        @Override
-                        public void onSystemUiVisibilityChange(int visibility) {
-                            if (DEBUG) {
-                                Slog.d(TAG, "systemUi: " + visibility);
-                            }
-                            boolean hide = (0 != (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION));
-                            mNavigationBarView.setHidden(hide);
-                        }
-                    });
             }
         } catch (Resources.NotFoundException ex) {
             // no nav bar for you
@@ -1064,10 +1052,12 @@
         flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "NAVIGATION" : "navigation");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
         flagdbg.append(">");
@@ -1083,11 +1073,13 @@
             }
         }
 
-        if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
-            // the nav bar will take care of DISABLE_NAVIGATION and DISABLE_BACK
+        if ((diff & (StatusBarManager.DISABLE_HOME 
+                        | StatusBarManager.DISABLE_RECENT 
+                        | StatusBarManager.DISABLE_BACK)) != 0) {
+            // the nav bar will take care of these
             if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
 
-            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+            if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
                 // close recents if it's visible
                 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
                 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 271e508..415a9a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -964,34 +964,24 @@
                 mTicker.halt();
             }
         }
-        if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
-            setNavigationVisibility(state &
-                    (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK));
+        if ((diff & (StatusBarManager.DISABLE_RECENT 
+                        | StatusBarManager.DISABLE_BACK 
+                        | StatusBarManager.DISABLE_HOME)) != 0) {
+            setNavigationVisibility(state);
         }
     }
 
     private void setNavigationVisibility(int visibility) {
-        boolean disableNavigation = ((visibility & StatusBarManager.DISABLE_NAVIGATION) != 0);
+        boolean disableHome = ((visibility & StatusBarManager.DISABLE_HOME) != 0);
+        boolean disableRecent = ((visibility & StatusBarManager.DISABLE_RECENT) != 0);
         boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
 
-        Slog.i(TAG, "DISABLE_BACK: " + (disableBack ? "yes" : "no"));
-        Slog.i(TAG, "DISABLE_NAVIGATION: " + (disableNavigation ? "yes" : "no"));
+        mBackButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
+        mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+        mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
 
-        if (disableNavigation && disableBack) {
-            mNavigationArea.setVisibility(View.INVISIBLE);
-        } else {
-            int backVisiblity = (disableBack ? View.INVISIBLE : View.VISIBLE);
-            int navVisibility = (disableNavigation ? View.INVISIBLE : View.VISIBLE);
-
-            mBackButton.setVisibility(backVisiblity);
-            mHomeButton.setVisibility(navVisibility);
-            mRecentButton.setVisibility(navVisibility);
-            // don't change menu button visibility here
-
-            mNavigationArea.setVisibility(View.VISIBLE);
-        }
-
-        mInputMethodSwitchButton.setScreenLocked(disableNavigation);
+        mInputMethodSwitchButton.setScreenLocked(
+                (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);
     }
 
     private boolean hasTicker(Notification n) {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 8569143..11b6c15 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -57,8 +56,6 @@
 
     private static final String TAG = "GlobalActions";
 
-    private StatusBarManager mStatusBar;
-
     private final Context mContext;
     private final AudioManager mAudioManager;
 
@@ -103,13 +100,12 @@
         mKeyguardShowing = keyguardShowing;
         mDeviceProvisioned = isDeviceProvisioned;
         if (mDialog == null) {
-            mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);
             mDialog = createDialog();
         }
         prepareDialog();
 
-        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
         mDialog.show();
+        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
     }
 
     /**
@@ -249,7 +245,6 @@
 
     /** {@inheritDoc} */
     public void onDismiss(DialogInterface dialog) {
-        mStatusBar.disable(StatusBarManager.DISABLE_NONE);
     }
 
     /** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 59b546d..de156c9 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -50,8 +50,6 @@
     public KeyguardViewBase(Context context) {
         super(context);
 
-        setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
-
         // This is a faster way to draw the background on devices without hardware acceleration
         setBackgroundDrawable(new Drawable() {
             @Override
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 90972da..2fd165a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -171,6 +171,17 @@
             }
         }
 
+        // Disable aspects of the system/status/navigation bars that are not appropriate or
+        // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
+        // Other disabled bits are handled by the KeyguardViewMediator talking directly to the
+        // status bar service.
+        int visFlags =
+                ( View.STATUS_BAR_DISABLE_BACK
+                | View.STATUS_BAR_DISABLE_HOME
+                | View.STATUS_BAR_DISABLE_CLOCK
+                );
+        mKeyguardHost.setSystemUiVisibility(visFlags);
+
         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
         mKeyguardHost.setVisibility(View.VISIBLE);
         mKeyguardView.requestFocus();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index c25e3ca..bbfc513 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -1188,19 +1188,12 @@
                 }
             }
 
+            // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+            // windows that appear on top, ever
             int flags = StatusBarManager.DISABLE_NONE;
             if (mShowing) {
-                // disable navigation status bar components if lock screen is up
-                flags |= StatusBarManager.DISABLE_NAVIGATION;
-                if (!mHidden) {
-                    // showing lockscreen exclusively (no activities in front of it)
-                    // disable back button too
-                    flags |= StatusBarManager.DISABLE_BACK;
-                    if (mUpdateMonitor.isClockVisible()) {
-                        // lockscreen showing a clock, so hide statusbar clock
-                        flags |= StatusBarManager.DISABLE_CLOCK;
-                    }
-                }
+                // disable navigation status bar components (home, recents) if lock screen is up
+                flags |= StatusBarManager.DISABLE_RECENT;
                 if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
                     // showing secure lockscreen; disable expanding.
                     flags |= StatusBarManager.DISABLE_EXPAND;
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index a010ba1..0c44e45 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -117,9 +117,14 @@
     private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
     private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
 
-    // Long enough to stay black while dialer comes up
-    // Short enough to not be black if the user goes back immediately
-    private final int FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT = 1000;
+    // Long enough to stay visible while dialer comes up
+    // Short enough to not be visible if the user goes back immediately
+    private final int FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
+
+    // Long enough to stay visible while the service starts
+    // Short enough to not have to wait long for backup if service fails to start or crashes
+    // The service can take a couple of seconds to start on the first try after boot
+    private final int FACELOCK_VIEW_AREA_SERVICE_TIMEOUT = 3000;
 
     /**
      * The current {@link KeyguardScreen} will use this to communicate back to us.
@@ -328,9 +333,8 @@
                 // FaceLock must be stopped if it is running when emergency call is pressed
                 stopAndUnbindFromFaceLock();
 
-                // Delay hiding FaceLock area so unlock doesn't display while dialer is coming up
-                mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW,
-                        FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT);
+                // Continue showing FaceLock area until dialer comes up
+                showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
 
                 pokeWakelock(EMERGENCY_CALL_TIMEOUT);
                 if (TelephonyManager.getDefault().getCallState()
@@ -529,11 +533,11 @@
         if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
                 && transportInvisible) {
             bindToFaceLock();
-            //Eliminate the black background so that the lockpattern will be visible
-            //If FaceUnlock is cancelled
-            mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, 4000);
+            // Show FaceLock area, but only for a little bit so lockpattern will become visible if
+            // FaceLock fails to start or crashes
+            showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
         } else {
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
@@ -563,7 +567,7 @@
         }
         if(!hasWindowFocus) {
             stopAndUnbindFromFaceLock();
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         } else if (runFaceLock) {
             //Don't activate facelock while the user is calling 911!
             if(mEmergencyCall) mEmergencyCall = false;
@@ -583,9 +587,9 @@
 
         if (mLockPatternUtils.usingBiometricWeak() &&
                 mLockPatternUtils.isBiometricWeakInstalled()) {
-            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+            showFaceLockArea();
         } else {
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
@@ -652,7 +656,7 @@
         if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
         if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
             stopAndUnbindFromFaceLock();
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
@@ -1085,6 +1089,32 @@
         return true;
     }
 
+    // Removes show and hide messages from the message queue
+    private void removeFaceLockAreaDisplayMessages() {
+        mHandler.removeMessages(MSG_SHOW_FACELOCK_AREA_VIEW);
+        mHandler.removeMessages(MSG_HIDE_FACELOCK_AREA_VIEW);
+    }
+
+    // Shows the FaceLock area immediately
+    private void showFaceLockArea() {
+        // Remove messages to prevent a delayed hide message from undo-ing the show
+        removeFaceLockAreaDisplayMessages();
+        mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+    }
+
+    // Hides the FaceLock area immediately
+    private void hideFaceLockArea() {
+        // Remove messages to prevent a delayed show message from undo-ing the hide
+        removeFaceLockAreaDisplayMessages();
+        mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+    }
+
+    // Shows the FaceLock area for a period of time
+    private void showFaceLockAreaWithTimeout(long timeoutMillis) {
+        showFaceLockArea();
+        mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, timeoutMillis);
+    }
+
     // Binds to FaceLock service, but does not tell it to start
     public void bindToFaceLock() {
         if (mLockPatternUtils.usingBiometricWeak() &&
@@ -1130,7 +1160,10 @@
             try {
                 mFaceLockService.registerCallback(mFaceLockCallback);
             } catch (RemoteException e) {
-                throw new RuntimeException("Remote exception");
+                Log.e(TAG, "Caught exception connecting to FaceLock: " + e.toString());
+                mFaceLockService = null;
+                mBoundToFaceLockService = false;
+                return;
             }
 
             if (mFaceLockAreaView != null) {
@@ -1147,6 +1180,7 @@
                 mFaceLockService = null;
                 mFaceLockServiceRunning = false;
             }
+            mBoundToFaceLockService = false;
             Log.w(TAG, "Unexpected disconnect from FaceLock service");
         }
     };
@@ -1162,7 +1196,8 @@
                     try {
                         mFaceLockService.startUi(windowToken, x, y, h, w);
                     } catch (RemoteException e) {
-                        throw new RuntimeException("Remote exception");
+                        Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
+                        return;
                     }
                     mFaceLockServiceRunning = true;
                 } else {
@@ -1186,7 +1221,7 @@
                         if (DEBUG) Log.d(TAG, "Stopping FaceLock");
                         mFaceLockService.stopUi();
                     } catch (RemoteException e) {
-                        throw new RuntimeException("Remote exception");
+                        Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString());
                     }
                     mFaceLockServiceRunning = false;
                 }
@@ -1201,7 +1236,7 @@
         @Override
         public void unlock() {
             if (DEBUG) Log.d(TAG, "FaceLock unlock()");
-            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW); // Keep fallback covered
+            showFaceLockArea(); // Keep fallback covered
             stopFaceLock();
 
             mKeyguardScreenCallback.keyguardDone(true);
@@ -1213,7 +1248,7 @@
         @Override
         public void cancel() {
             if (DEBUG) Log.d(TAG, "FaceLock cancel()");
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); // Expose fallback
+            hideFaceLockArea(); // Expose fallback
             stopFaceLock();
         }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3eb04cb..aac3209 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -128,7 +128,6 @@
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.KeyCharacterMap.FallbackAction;
-import android.view.WindowManagerPolicy.WindowManagerFuncs;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -180,26 +179,26 @@
     static final int PRIORITY_PHONE_LAYER = 7;
     // like the ANR / app crashed dialogs
     static final int SYSTEM_ALERT_LAYER = 8;
-    // system-level error dialogs
-    static final int SYSTEM_ERROR_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_LAYER = 10;
+    static final int INPUT_METHOD_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_DIALOG_LAYER = 11;
+    static final int INPUT_METHOD_DIALOG_LAYER = 10;
     // the keyguard; nothing on top of these can take focus, since they are
     // responsible for power management when displayed.
-    static final int KEYGUARD_LAYER = 12;
-    static final int KEYGUARD_DIALOG_LAYER = 13;
-    static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
-    static final int STATUS_BAR_LAYER = 15;
-    static final int STATUS_BAR_PANEL_LAYER = 16;
+    static final int KEYGUARD_LAYER = 11;
+    static final int KEYGUARD_DIALOG_LAYER = 12;
+    static final int STATUS_BAR_SUB_PANEL_LAYER = 13;
+    static final int STATUS_BAR_LAYER = 14;
+    static final int STATUS_BAR_PANEL_LAYER = 15;
     // the on-screen volume indicator and controller shown when the user
     // changes the device volume
-    static final int VOLUME_OVERLAY_LAYER = 17;
+    static final int VOLUME_OVERLAY_LAYER = 16;
     // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 18;
+    static final int SYSTEM_OVERLAY_LAYER = 17;
     // the navigation bar, if available, shows atop most things
-    static final int NAVIGATION_BAR_LAYER = 19;
+    static final int NAVIGATION_BAR_LAYER = 18;
+    // system-level error dialogs
+    static final int SYSTEM_ERROR_LAYER = 19;
     // the drag layer: input for drag-and-drop is associated with this window,
     // which sits above all other focusable windows
     static final int DRAG_LAYER = 20;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index dd649e7..eb75ebc 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -16,24 +16,6 @@
 
 package com.android.server;
 
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.impl.SimpleLog;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
@@ -42,9 +24,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.Intent.FilterComparison;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.Intent.FilterComparison;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -58,7 +40,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -68,20 +49,37 @@
 import android.util.TypedValue;
 import android.util.Xml;
 import android.widget.RemoteViews;
-import android.widget.RemoteViewsService;
 
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.os.AtomicFile;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
 class AppWidgetService extends IAppWidgetService.Stub
 {
     private static final String TAG = "AppWidgetService";
 
     private static final String SETTINGS_FILENAME = "appwidgets.xml";
-    private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
     private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
 
     /*
@@ -1159,70 +1157,46 @@
 
     // only call from initialization -- it assumes that the data structures are all empty
     void loadStateLocked() {
-        File temp = savedStateTempFile();
-        File real = savedStateRealFile();
+        AtomicFile file = savedStateFile();
+        try {
+            FileInputStream stream = file.openRead();
+            readStateFromFileLocked(stream);
 
-        // prefer the real file.  If it doesn't exist, use the temp one, and then copy it to the
-        // real one.  if there is both a real file and a temp one, assume that the temp one isn't
-        // fully written and delete it.
-        if (real.exists()) {
-            readStateFromFileLocked(real);
-            if (temp.exists()) {
-                //noinspection ResultOfMethodCallIgnored
-                temp.delete();
+            if (stream != null) {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to close state FileInputStream " + e);
+                }
             }
-        } else if (temp.exists()) {
-            readStateFromFileLocked(temp);
-            //noinspection ResultOfMethodCallIgnored
-            temp.renameTo(real);
+        } catch (FileNotFoundException e) {
+            Slog.w(TAG, "Failed to read state: " + e);
         }
     }
-    
+
     void saveStateLocked() {
-        File temp = savedStateTempFile();
-        File real = savedStateRealFile();
-
-        if (!real.exists()) {
-            // If the real one doesn't exist, it's either because this is the first time
-            // or because something went wrong while copying them.  In this case, we can't
-            // trust anything that's in temp.  In order to have the loadState code not
-            // use the temporary one until it's fully written, create an empty file
-            // for real, which will we'll shortly delete.
-            try {
-                //noinspection ResultOfMethodCallIgnored
-                real.createNewFile();
-            } catch (IOException e) {
-                // Ignore
+        AtomicFile file = savedStateFile();
+        FileOutputStream stream;
+        try {
+            stream = file.startWrite();
+            if (writeStateToFileLocked(stream)) {
+                file.finishWrite(stream);
+            } else {
+                file.failWrite(stream);
+                Slog.w(TAG, "Failed to save state, restoring backup.");
             }
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed open state file for write: " + e);
         }
-
-        if (temp.exists()) {
-            //noinspection ResultOfMethodCallIgnored
-            temp.delete();
-        }
-
-        if (!writeStateToFileLocked(temp)) {
-            Slog.w(TAG, "Failed to persist new settings");
-            return;
-        }
-
-        //noinspection ResultOfMethodCallIgnored
-        real.delete();
-        //noinspection ResultOfMethodCallIgnored
-        temp.renameTo(real);
     }
 
-    boolean writeStateToFileLocked(File file) {
-        FileOutputStream stream = null;
+    boolean writeStateToFileLocked(FileOutputStream stream) {
         int N;
 
         try {
-            stream = new FileOutputStream(file, false);
             XmlSerializer out = new FastXmlSerializer();
             out.setOutput(stream, "utf-8");
             out.startDocument(null, true);
-
-            
             out.startTag(null, "gs");
 
             int providerIndex = 0;
@@ -1264,31 +1238,17 @@
             out.endTag(null, "gs");
 
             out.endDocument();
-            stream.close();
             return true;
         } catch (IOException e) {
-            try {
-                if (stream != null) {
-                    stream.close();
-                }
-            } catch (IOException ex) {
-                // Ignore
-            }
-            if (file.exists()) {
-                //noinspection ResultOfMethodCallIgnored
-                file.delete();
-            }
+            Slog.w(TAG, "Failed to write state: " + e);
             return false;
         }
     }
 
-    void readStateFromFileLocked(File file) {
-        FileInputStream stream = null;
-
+    void readStateFromFileLocked(FileInputStream stream) {
         boolean success = false;
 
         try {
-            stream = new FileInputStream(file);
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(stream, null);
 
@@ -1390,22 +1350,15 @@
             } while (type != XmlPullParser.END_DOCUMENT);
             success = true;
         } catch (NullPointerException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (NumberFormatException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (XmlPullParserException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (IOException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (IndexOutOfBoundsException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
-        }
-        try {
-            if (stream != null) {
-                stream.close();
-            }
-        } catch (IOException e) {
-            // Ignore
+            Slog.w(TAG, "failed parsing " + e);
         }
 
         if (success) {
@@ -1416,6 +1369,8 @@
             }
         } else {
             // failed reading, clean up
+            Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
+
             mAppWidgetIds.clear();
             mHosts.clear();
             final int N = mInstalledProviders.size();
@@ -1425,14 +1380,8 @@
         }
     }
 
-    File savedStateTempFile() {
-        return new File("/data/system/" + SETTINGS_TMP_FILENAME);
-        //return new File(mContext.getFilesDir(), SETTINGS_FILENAME);
-    }
-
-    File savedStateRealFile() {
-        return new File("/data/system/" + SETTINGS_FILENAME);
-        //return new File(mContext.getFilesDir(), SETTINGS_TMP_FILENAME);
+    AtomicFile savedStateFile() {
+        return new AtomicFile(new File("/data/system/" + SETTINGS_FILENAME));
     }
 
     BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 1941c6a..994201b 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1698,11 +1698,6 @@
                     // make sure button and key backlights are off too
                     mButtonLight.turnOff();
                     mKeyboardLight.turnOff();
-                    // clear current value so we will update based on the new conditions
-                    // when the sensor is reenabled.
-                    mLightSensorValue = -1;
-                    // reset our highest light sensor value when the screen turns off
-                    mHighestLightSensorValue = -1;
                 }
             }
         }
@@ -2472,6 +2467,7 @@
         synchronized (mLocks) {
             mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
             if (mIsDocked) {
+                // allow brightness to decrease when docked
                 mHighestLightSensorValue = -1;
             }
             if ((mPowerState & SCREEN_ON_BIT) != 0) {
@@ -3047,11 +3043,21 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 if (enable) {
+                    // reset our highest value when reenabling
+                    mHighestLightSensorValue = -1;
+                    // force recompute of backlight values
+                    if (mLightSensorValue >= 0) {
+                        int value = (int)mLightSensorValue;
+                        mLightSensorValue = -1;
+                        handleLightSensorValue(value);
+                    }
                     mSensorManager.registerListener(mLightListener, mLightSensor,
                             SensorManager.SENSOR_DELAY_NORMAL);
                 } else {
                     mSensorManager.unregisterListener(mLightListener);
                     mHandler.removeCallbacks(mAutoBrightnessTask);
+                    mLightSensorPendingDecrease = false;
+                    mLightSensorPendingIncrease = false;
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3103,43 +3109,45 @@
         }
     };
 
+    private void handleLightSensorValue(int value) {
+        long milliseconds = SystemClock.elapsedRealtime();
+        if (mLightSensorValue == -1 ||
+                milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
+            // process the value immediately if screen has just turned on
+            mHandler.removeCallbacks(mAutoBrightnessTask);
+            mLightSensorPendingDecrease = false;
+            mLightSensorPendingIncrease = false;
+            lightSensorChangedLocked(value);
+        } else {
+            if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
+                    (value < mLightSensorValue && mLightSensorPendingIncrease) ||
+                    (value == mLightSensorValue) ||
+                    (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
+                // delay processing to debounce the sensor
+                mHandler.removeCallbacks(mAutoBrightnessTask);
+                mLightSensorPendingDecrease = (value < mLightSensorValue);
+                mLightSensorPendingIncrease = (value > mLightSensorValue);
+                if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
+                    mLightSensorPendingValue = value;
+                    mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
+                }
+            } else {
+                mLightSensorPendingValue = value;
+            }
+        }
+    }
+
     SensorEventListener mLightListener = new SensorEventListener() {
         public void onSensorChanged(SensorEvent event) {
+            if (mDebugLightSensor) {
+                Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
+            }
             synchronized (mLocks) {
                 // ignore light sensor while screen is turning off
                 if (isScreenTurningOffLocked()) {
                     return;
                 }
-
-                int value = (int)event.values[0];
-                long milliseconds = SystemClock.elapsedRealtime();
-                if (mDebugLightSensor) {
-                    Slog.d(TAG, "onSensorChanged: light value: " + value);
-                }
-                if (mLightSensorValue == -1 ||
-                        milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
-                    // process the value immediately if screen has just turned on
-                    mHandler.removeCallbacks(mAutoBrightnessTask);
-                    mLightSensorPendingDecrease = false;
-                    mLightSensorPendingIncrease = false;
-                    lightSensorChangedLocked(value);
-                } else {
-                    if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
-                            (value < mLightSensorValue && mLightSensorPendingIncrease) ||
-                            (value == mLightSensorValue) ||
-                            (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
-                        // delay processing to debounce the sensor
-                        mHandler.removeCallbacks(mAutoBrightnessTask);
-                        mLightSensorPendingDecrease = (value < mLightSensorValue);
-                        mLightSensorPendingIncrease = (value > mLightSensorValue);
-                        if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
-                            mLightSensorPendingValue = value;
-                            mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
-                        }
-                    } else {
-                        mLightSensorPendingValue = value;
-                    }
-                }
+                handleLightSensorValue((int)event.values[0]);
             }
         }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d038d76..55fb371 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3427,8 +3427,10 @@
                     ac.removePackage(name);
                 }
             }
-            mMainStack.resumeTopActivityLocked(null);
-            mMainStack.scheduleIdleLocked();
+            if (mBooted) {
+                mMainStack.resumeTopActivityLocked(null);
+                mMainStack.scheduleIdleLocked();
+            }
         }
         
         return didSomething;
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index a769c05..57e11cf 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -24,6 +24,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Slog;
+import android.view.WindowManager;
 
 class AppErrorDialog extends BaseErrorDialog {
     private final static String TAG = "AppErrorDialog";
@@ -73,6 +74,9 @@
         setTitle(res.getText(com.android.internal.R.string.aerr_title));
         getWindow().addFlags(FLAG_SYSTEM_ERROR);
         getWindow().setTitle("Application Error: " + app.info.processName);
+        if (app.persistent) {
+            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        }
 
         // After the timeout, pretend the user clicked the quit button
         mHandler.sendMessageDelayed(
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0a9ef3d..68f0e66 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -167,6 +167,7 @@
     static final boolean DEBUG_DRAG = false;
     static final boolean DEBUG_SCREEN_ON = false;
     static final boolean DEBUG_SCREENSHOT = false;
+    static final boolean DEBUG_BOOT = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4728,6 +4729,14 @@
 
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mSystemBooted) {
                 return;
             }
@@ -4745,6 +4754,14 @@
     }
 
     void enableScreenIfNeededLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mDisplayEnabled) {
             return;
         }
@@ -4767,6 +4784,14 @@
 
     public void performEnableScreen() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mDisplayEnabled) {
                 return;
             }
@@ -4780,10 +4805,22 @@
                 boolean haveBootMsg = false;
                 boolean haveApp = false;
                 boolean haveWallpaper = false;
-                boolean haveKeyguard = false;
+                boolean haveKeyguard = true;
                 final int N = mWindows.size();
                 for (int i=0; i<N; i++) {
                     WindowState w = mWindows.get(i);
+                    if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+                        // Only if there is a keyguard attached to the window manager
+                        // will we consider ourselves as having a keyguard.  If it
+                        // isn't attached, we don't know if it wants to be shown or
+                        // hidden.  If it is attached, we will say we have a keyguard
+                        // if the window doesn't want to be visible, because in that
+                        // case it explicitly doesn't want to be shown so we should
+                        // not delay turning the screen on for it.
+                        boolean vis = w.mViewVisibility == View.VISIBLE
+                                && w.mPolicyVisibility;
+                        haveKeyguard = !vis;
+                    }
                     if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
                         return;
                     }
@@ -4800,7 +4837,7 @@
                     }
                 }
 
-                if (DEBUG_SCREEN_ON) {
+                if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
                     Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
                             + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
                             + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
@@ -4821,7 +4858,7 @@
             }
 
             mDisplayEnabled = true;
-            if (DEBUG_SCREEN_ON) Slog.i(TAG, "******************** ENABLING SCREEN!");
+            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
             if (false) {
                 StringWriter sw = new StringWriter();
                 PrintWriter pw = new PrintWriter(sw);
@@ -4852,6 +4889,14 @@
     public void showBootMessage(final CharSequence msg, final boolean always) {
         boolean first = false;
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
+                        + " mAllowBootMessages=" + mAllowBootMessages
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (!mAllowBootMessages) {
                 return;
             }
@@ -4873,6 +4918,14 @@
     }
 
     public void hideBootMessagesLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mShowingBootMessages) {
             mShowingBootMessages = false;
             mPolicy.hideBootMessages();
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 7c94c2d..94ad620 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -114,9 +114,9 @@
 //                v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
 //            }
 //        },
-        new Test("systemUiVisibility: STATUS_BAR_DISABLE_NAVIGATION") {
+        new Test("systemUiVisibility: STATUS_BAR_DISABLE_HOME") {
             public void run() {
-                mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
+                mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
             }
         },
         new Test("Double Remove") {
@@ -227,16 +227,21 @@
                     }, 3000);
             }
         },
-        new Test("Disable Navigation") {
+        new Test("Disable Home (StatusBarManager)") {
             public void run() {
-                mStatusBarManager.disable(StatusBarManager.DISABLE_NAVIGATION);
+                mStatusBarManager.disable(StatusBarManager.DISABLE_HOME);
             }
         },
-        new Test("Disable Back") {
+        new Test("Disable Back (StatusBarManager)") {
             public void run() {
                 mStatusBarManager.disable(StatusBarManager.DISABLE_BACK);
             }
         },
+        new Test("Disable Recent (StatusBarManager)") {
+            public void run() {
+                mStatusBarManager.disable(StatusBarManager.DISABLE_RECENT);
+            }
+        },
         new Test("Disable Clock") {
             public void run() {
                 mStatusBarManager.disable(StatusBarManager.DISABLE_CLOCK);