Merge "TaskStackBuilder and Activity navigation features for framework"
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 8335459..f80dae4 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -114,6 +114,10 @@
             if (activity.getWindow().isDestroyed()) {
                 throw new IllegalStateException("activity is already destroyed");
             }
+            // Check if activity is resumed right now, as we will not
+            // immediately get a callback for that.
+            resumed = activity.isResumed();
+
             this.activity = activity;
             registerApplication(activity.getApplication());
         }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 14cd48f..eb030de 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -62,8 +62,8 @@
     void setForcedDisplaySize(int longDimen, int shortDimen);
     void clearForcedDisplaySize();
 
-    // Is device configured with a hideable status bar or a tablet system bar?
-    boolean canStatusBarHide();
+    // Is the device configured to have a full system bar for larger screens?
+    boolean hasSystemNavBar();
 
     // These can only be called when injecting events to your own window,
     // or by holding the INJECT_EVENTS permission.  These methods may block
@@ -171,8 +171,10 @@
      * @param alwaysSendConfiguration Flag to force a new configuration to
      * be evaluated.  This can be used when there are other parameters in
      * configuration that are changing.
+     * @param forceRelayout If true, the window manager will always do a relayout
+     * of its windows even if the rotation hasn't changed.
      */
-    void updateRotation(boolean alwaysSendConfiguration);
+    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
 
     /**
      * Retrieve the current screen orientation, constants as per
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index b9924c7..9d06145 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -315,7 +315,7 @@
         if (!sHasPermanentMenuKeySet) {
             IWindowManager wm = Display.getWindowManager();
             try {
-                sHasPermanentMenuKey = wm.canStatusBarHide() && !wm.hasNavigationBar();
+                sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar();
                 sHasPermanentMenuKeySet = true;
             } catch (RemoteException ex) {
                 sHasPermanentMenuKey = false;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 75267bb..cf9cafc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -326,6 +326,11 @@
          * Returns true if {@link #hideLw} was last called for the window.
          */
         public boolean showLw(boolean doAnimation);
+
+        /**
+         * Check whether the process hosting this window is currently alive.
+         */
+        public boolean isAlive();
     }
 
     /**
@@ -447,7 +452,7 @@
      * Called by window manager once it has the initial, default native
      * display dimensions.
      */
-    public void setInitialDisplaySize(int width, int height);
+    public void setInitialDisplaySize(Display display, int width, int height);
 
     /**
      * Check permissions when adding a window.
@@ -514,10 +519,10 @@
     public int getMaxWallpaperLayer();
     
     /**
-     * Return true if the policy allows the status bar to hide.  Otherwise,
-     * it is a tablet-style system bar.
+     * Return true if the policy desires a full unified system nav bar.  Otherwise,
+     * it is a phone-style status bar with optional nav bar.
      */
-    public boolean canStatusBarHide();
+    public boolean hasSystemNavBar();
 
     /**
      * Return the display width available after excluding any screen
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
similarity index 77%
rename from packages/SystemUI/res/anim/status_bar_enter.xml
rename to core/res/res/anim/dock_bottom_enter.xml
index f1c1301..7a2e94be 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the bottom of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromYDelta="75%" android:toYDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_bottom_exit.xml
index 46462e2..c2fd15c 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the bottom of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromYDelta="0" android:toYDelta="75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_left_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_left_enter.xml
index f1c1301..b057f67 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_left_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the left of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromXDelta="-75%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_left_exit.xml
similarity index 78%
rename from packages/SystemUI/res/anim/status_bar_exit.xml
rename to core/res/res/anim/dock_left_exit.xml
index 46462e2..576b1aa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_left_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromXDelta="0" android:toXDelta="-75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_right_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_right_enter.xml
index f1c1301..e1bd190 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_right_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromXDelta="75%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_right_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_right_exit.xml
index 46462e2..6d778fa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_right_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromXDelta="0" android:toXDelta="75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_top_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_top_enter.xml
index f1c1301..f2e4cae 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the top of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromYDelta="-75%" android:toYDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_top_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_top_exit.xml
index 46462e2..7373695 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
 ** you may not use this file except in compliance with the License. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the top of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromYDelta="0" android:toYDelta="-75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6d6b86b..0442be8 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -32,11 +32,9 @@
     <dimen name="toast_y_offset">64dip</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">25dip</dimen>
-    <!-- Height of the system bar (combined status + navigation, used on large screens) -->
-    <dimen name="system_bar_height">48dip</dimen>
-    <!-- Height of the horizontal navigation bar on devices that require it -->
+    <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_height">48dp</dimen>
-    <!-- Width of the vertical navigation bar on devices that require it -->
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
     <dimen name="navigation_bar_width">42dp</dimen>
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">24dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 87482d7..72cb73b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1128,6 +1128,14 @@
   <!-- From android.policy -->
   <java-symbol type="anim" name="app_starting_exit" />
   <java-symbol type="anim" name="lock_screen_behind_enter" />
+  <java-symbol type="anim" name="dock_top_enter" />
+  <java-symbol type="anim" name="dock_top_exit" />
+  <java-symbol type="anim" name="dock_bottom_enter" />
+  <java-symbol type="anim" name="dock_bottom_exit" />
+  <java-symbol type="anim" name="dock_left_enter" />
+  <java-symbol type="anim" name="dock_left_exit" />
+  <java-symbol type="anim" name="dock_right_enter" />
+  <java-symbol type="anim" name="dock_right_exit" />
   <java-symbol type="array" name="config_keyboardTapVibePattern" />
   <java-symbol type="array" name="config_longPressVibePattern" />
   <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
@@ -1153,7 +1161,6 @@
   <java-symbol type="dimen" name="navigation_bar_height" />
   <java-symbol type="dimen" name="navigation_bar_width" />
   <java-symbol type="dimen" name="status_bar_height" />
-  <java-symbol type="dimen" name="system_bar_height" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 82dd308..c7e71eb 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -903,9 +903,18 @@
      * @hide
      */
     public void setMasterMute(boolean state) {
+        setMasterMute(state, FLAG_SHOW_UI);
+    }
+
+    /**
+     * set master mute state with optional flags.
+     *
+     * @hide
+     */
+    public void setMasterMute(boolean state, int flags) {
         IAudioService service = getService();
         try {
-            service.setMasterMute(state, mICallBack);
+            service.setMasterMute(state, flags, mICallBack);
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setMasterMute", e);
         }
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f59848f..2e456f0 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -827,13 +827,13 @@
     }
 
     /** @see AudioManager#setMasterMute(boolean, IBinder) */
-    public void setMasterMute(boolean state, IBinder cb) {
+    public void setMasterMute(boolean state, int flags, IBinder cb) {
         if (state != AudioSystem.getMasterMute()) {
             AudioSystem.setMasterMute(state);
             // Post a persist master volume msg
             sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME_MUTE, SENDMSG_REPLACE, state ? 1
                     : 0, 0, null, PERSIST_DELAY);
-            sendMasterMuteUpdate(state, AudioManager.FLAG_SHOW_UI);
+            sendMasterMuteUpdate(state, flags);
         }
     }
 
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 17d8e4d..b775095 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -45,7 +45,7 @@
 
     boolean isStreamMute(int streamType);
 
-    void setMasterMute(boolean state, IBinder cb);
+    void setMasterMute(boolean state, int flags, IBinder cb);
 
     boolean isMasterMute();
 
diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml
deleted file mode 100644
index 79fe5f1..0000000
--- a/packages/SystemUI/res/anim/status_bar_in.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromYDelta="100%p" android:toYDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml
deleted file mode 100644
index 80863cf..0000000
--- a/packages/SystemUI/res/anim/status_bar_out.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toYDelta="100%p" android:fromYDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dc5c540..02411d4 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -67,8 +67,6 @@
 
     <!-- Standard animations for hiding and showing the status bar. -->
     <style name="Animation.StatusBar">
-        <item name="android:windowEnterAnimation">@anim/status_bar_enter</item>
-        <item name="android:windowExitAnimation">@anim/status_bar_exit</item>
     </style>
 
     <style name="Animation.StatusBar.IntruderAlert">
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index d7a5056..1ae15be 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -69,9 +69,9 @@
         IWindowManager wm = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         try {
-            SERVICES[0] = wm.canStatusBarHide()
-                    ? R.string.config_statusBarComponent
-                    : R.string.config_systemBarComponent;
+            SERVICES[0] = wm.hasSystemNavBar()
+                    ? R.string.config_systemBarComponent
+                    : R.string.config_statusBarComponent;
         } catch (RemoteException e) {
             Slog.w(TAG, "Failing checking whether status bar can hide", e);
         }
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 12c05ed..5ba72c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1766,11 +1766,6 @@
                 // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
                 PixelFormat.RGB_565);
 
-        // the status bar should be in an overlay if possible
-        final Display defaultDisplay
-            = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-
         // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
         // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
         // for the status bar, we prevent the GPU from having to wake up just to do these small
@@ -1779,9 +1774,7 @@
         lp.gravity = getStatusBarGravity();
         lp.setTitle("StatusBar");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar;
         WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp);
-
     }
     
     void addExpandedWindow() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
deleted file mode 100644
index 3e9a9d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tablet;
-
-import java.util.ArrayList;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.Slog;
-import android.view.Display;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
-import android.view.WindowManagerPolicy;
-
-public class HeightReceiver extends BroadcastReceiver {
-    private static final String TAG = "StatusBar.HeightReceiver";
-
-    public interface OnBarHeightChangedListener {
-        public void onBarHeightChanged(int height);
-    }
-
-    Context mContext;
-    ArrayList<OnBarHeightChangedListener> mListeners = new ArrayList<OnBarHeightChangedListener>();
-    WindowManager mWindowManager;
-    int mHeight;
-    boolean mPlugged;
-
-    public HeightReceiver(Context context) {
-        mContext = context;
-        mWindowManager = WindowManagerImpl.getDefault();
-    }
-
-    public void addOnBarHeightChangedListener(OnBarHeightChangedListener l) {
-        mListeners.add(l);
-        l.onBarHeightChanged(mHeight);
-    }
-
-    public void removeOnBarHeightChangedListener(OnBarHeightChangedListener l) {
-        mListeners.remove(l);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final boolean plugged
-                = intent.getBooleanExtra(WindowManagerPolicy.EXTRA_HDMI_PLUGGED_STATE, false);
-        setPlugged(plugged);
-    }
-
-    public void registerReceiver() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(WindowManagerPolicy.ACTION_HDMI_PLUGGED);
-        final Intent val = mContext.registerReceiver(this, filter);
-        onReceive(mContext, val);
-    }
-
-    private void setPlugged(boolean plugged) {
-        mPlugged = plugged;
-        updateHeight();
-    }
-
-    public void updateHeight() {
-        final Resources res = mContext.getResources();
-
-        int height = -1;
-        if (mPlugged) {
-            final DisplayMetrics metrics = new DisplayMetrics();
-            Display display = mWindowManager.getDefaultDisplay();
-            display.getRealMetrics(metrics);
-
-            //Slog.i(TAG, "updateHeight: display metrics=" + metrics);
-            final int shortSide = Math.min(metrics.widthPixels, metrics.heightPixels);
-            final int externalShortSide = Math.min(display.getRawExternalWidth(),
-                    display.getRawExternalHeight());
-            height = shortSide - externalShortSide;
-        }
-
-        final int minHeight
-                = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-        if (height < minHeight) {
-            height = minHeight;
-        }
-        Slog.i(TAG, "Resizing status bar plugged=" + mPlugged + " height="
-                + height + " old=" + mHeight);
-        mHeight = height;
-
-        final int N = mListeners.size();
-        for (int i=0; i<N; i++) {
-            mListeners.get(i).onBarHeightChanged(height);
-        }
-    }
-
-    public int getHeight() {
-        return mHeight;
-    }
-}
-
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 7325a37..49b1a14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -87,7 +87,6 @@
 import com.android.systemui.statusbar.policy.Prefs;
 
 public class TabletStatusBar extends BaseStatusBar implements
-        HeightReceiver.OnBarHeightChangedListener,
         InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
         RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
     public static final boolean DEBUG = false;
@@ -162,7 +161,6 @@
 
     ViewGroup mPile;
 
-    HeightReceiver mHeightReceiver;
     BatteryController mBatteryController;
     BluetoothController mBluetoothController;
     LocationController mLocationController;
@@ -204,12 +202,11 @@
     
     private void addStatusBarWindow() {
         final View sb = makeStatusBarView();
-        final int height = getStatusBarHeight();
 
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
-                height,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
@@ -218,20 +215,14 @@
                 // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
                 PixelFormat.RGB_565);
 
-        // the status bar should be in an overlay if possible
-        final Display defaultDisplay
-            = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-
         // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
         // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
         // for the status bar, we prevent the GPU from having to wake up just to do these small
         // updates, which should help keep power consumption down.
 
         lp.gravity = getStatusBarGravity();
-        lp.setTitle("StatusBar");
+        lp.setTitle("SystemBar");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar;
         WindowManagerImpl.getDefault().addView(sb, lp);
     }
 
@@ -414,7 +405,6 @@
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
-        mHeightReceiver.updateHeight(); // display size may have changed
         loadDimens();
         mNotificationPanelParams.height = getNotificationPanelHeight();
         WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
@@ -426,7 +416,7 @@
         final Resources res = mContext.getResources();
 
         mNaturalBarHeight = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.system_bar_height);
+                com.android.internal.R.dimen.navigation_bar_height);
 
         int newIconSize = res.getDimensionPixelSize(
             com.android.internal.R.dimen.system_bar_icon_size);
@@ -478,10 +468,6 @@
         mWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
 
-        // This guy will listen for HDMI plugged broadcasts so we can resize the
-        // status bar as appropriate.
-        mHeightReceiver = new HeightReceiver(mContext);
-        mHeightReceiver.registerReceiver();
         loadDimens();
 
         final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
@@ -637,8 +623,6 @@
         // set the initial view visibility
         setAreThereNotifications();
 
-        mHeightReceiver.addOnBarHeightChangedListener(this);
-
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -674,7 +658,9 @@
     }
 
     public int getStatusBarHeight() {
-        return mHeightReceiver.getHeight();
+        return mStatusBarView != null ? mStatusBarView.getHeight()
+                : mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.navigation_bar_height);
     }
 
     protected int getStatusBarGravity() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fb1e106..c3cac6e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -72,6 +71,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.IApplicationToken;
@@ -299,11 +299,13 @@
     boolean mHeadless;
     boolean mSafeMode;
     WindowState mStatusBar = null;
-    boolean mStatusBarCanHide;
+    boolean mHasSystemNavBar;
     int mStatusBarHeight;
     final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
     WindowState mNavigationBar = null;
     boolean mHasNavigationBar = false;
+    boolean mCanHideNavigationBar = false;
+    boolean mNavigationBarOnBottom = true;
     int mNavigationBarWidth = 0, mNavigationBarHeight = 0;
 
     WindowState mKeyguard = null;
@@ -329,6 +331,8 @@
     boolean mSystemReady;
     boolean mSystemBooted;
     boolean mHdmiPlugged;
+    int mExternalDisplayWidth;
+    int mExternalDisplayHeight;
     int mUiMode;
     int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
     int mLidOpenRotation;
@@ -464,6 +468,8 @@
     // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
     int mIncallPowerBehavior;
 
+    Display mDisplay;
+
     int mLandscapeRotation = 0;  // default landscape rotation
     int mSeascapeRotation = 0;   // "other" landscape rotation, 180 degrees from mLandscapeRotation
     int mPortraitRotation = 0;   // default portrait rotation
@@ -927,10 +933,13 @@
         }
     }
 
-    public void setInitialDisplaySize(int width, int height) {
-        int shortSize;
+    public void setInitialDisplaySize(Display display, int width, int height) {
+        mDisplay = display;
+
+        int shortSize, longSize;
         if (width > height) {
             shortSize = height;
+            longSize = width;
             mLandscapeRotation = Surface.ROTATION_0;
             mSeascapeRotation = Surface.ROTATION_180;
             if (mContext.getResources().getBoolean(
@@ -943,6 +952,7 @@
             }
         } else {
             shortSize = width;
+            longSize = height;
             mPortraitRotation = Surface.ROTATION_0;
             mUpsideDownRotation = Surface.ROTATION_180;
             if (mContext.getResources().getBoolean(
@@ -955,36 +965,61 @@
             }
         }
 
+        mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+        mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+
+        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_height);
+        mNavigationBarWidth = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_width);
+
         // Determine whether the status bar can hide based on the size
         // of the screen.  We assume sizes > 600dp are tablets where we
         // will use the system bar.
         int shortSizeDp = shortSize
                 * DisplayMetrics.DENSITY_DEFAULT
                 / DisplayMetrics.DENSITY_DEVICE;
-        mStatusBarCanHide = shortSizeDp < 600;
-        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
-                mStatusBarCanHide
-                ? com.android.internal.R.dimen.status_bar_height
-                : com.android.internal.R.dimen.system_bar_height);
+        mHasSystemNavBar = shortSizeDp > 600;
 
-        mHasNavigationBar = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_showNavigationBar);
-        // Allow a system property to override this. Used by the emulator.
-        // See also hasNavigationBar().
-        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
-        if (! "".equals(navBarOverride)) {
-            if      (navBarOverride.equals("1")) mHasNavigationBar = false;
-            else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+        if (!mHasSystemNavBar) {
+            mHasNavigationBar = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_showNavigationBar);
+            // Allow a system property to override this. Used by the emulator.
+            // See also hasNavigationBar().
+            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+            if (! "".equals(navBarOverride)) {
+                if      (navBarOverride.equals("1")) mHasNavigationBar = false;
+                else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+            }
+        } else {
+            mHasNavigationBar = false;
         }
 
-        mNavigationBarHeight = mHasNavigationBar
-                ? mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_height)
-                : 0;
-        mNavigationBarWidth = mHasNavigationBar
-                ? mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_width)
-                : 0;
+        if (mHasSystemNavBar) {
+            // The system bar is always at the bottom.  If you are watching
+            // a video in landscape, we don't need to hide it if we can still
+            // show a 16:9 aspect ratio with it.
+            int longSizeDp = longSize
+                    * DisplayMetrics.DENSITY_DEFAULT
+                    / DisplayMetrics.DENSITY_DEVICE;
+            int barHeightDp = mNavigationBarHeight
+                    * DisplayMetrics.DENSITY_DEFAULT
+                    / DisplayMetrics.DENSITY_DEVICE;
+            int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
+            // We have computed the aspect ratio with the bar height taken
+            // out to be 16:aspect.  If this is less than 9, then hiding
+            // the navigation bar will provide more useful space for wide
+            // screen movies.
+            mCanHideNavigationBar = aspect < 9;
+        } else if (mHasNavigationBar) {
+            // The navigation bar is at the right in landscape; it seems always
+            // useful to hide it for showing a video.
+            mCanHideNavigationBar = true;
+        } else {
+            mCanHideNavigationBar = false;
+        }
 
         if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
             mHdmiRotation = mPortraitRotation;
@@ -1318,13 +1353,13 @@
         return STATUS_BAR_LAYER;
     }
 
-    public boolean canStatusBarHide() {
-        return mStatusBarCanHide;
+    public boolean hasSystemNavBar() {
+        return mHasSystemNavBar;
     }
 
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
         // Assumes that the navigation bar appears on the side of the display in landscape.
-        if (fullWidth > fullHeight) {
+        if (mHasNavigationBar && fullWidth > fullHeight) {
             return fullWidth - mNavigationBarWidth;
         }
         return fullWidth;
@@ -1333,8 +1368,8 @@
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
         // Assumes the navigation bar appears on the bottom of the display in portrait.
         return fullHeight
-            - (mStatusBarCanHide ? 0 : mStatusBarHeight)
-            - ((fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
+            - (mHasSystemNavBar ? mNavigationBarHeight : 0)
+            - ((mHasNavigationBar && fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
     }
 
     public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
@@ -1348,7 +1383,7 @@
         // exclude it since applications can't generally use that part of the
         // screen.
         return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation)
-                - (mStatusBarCanHide ? mStatusBarHeight : 0);
+                - (mHasSystemNavBar ? 0 : mStatusBarHeight);
     }
 
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1357,6 +1392,7 @@
     
     public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
         return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
+                && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                 && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
     }
     
@@ -1495,10 +1531,10 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
-                // TODO: Need to handle the race condition of the status bar proc
-                // dying and coming back before the removeWindowLw cleanup has happened.
                 if (mStatusBar != null) {
-                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    if (mStatusBar.isAlive()) {
+                        return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    }
                 }
                 mStatusBar = win;
                 break;
@@ -1506,6 +1542,11 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
+                if (mNavigationBar != null) {
+                    if (mNavigationBar.isAlive()) {
+                        return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    }
+                }
                 mNavigationBar = win;
                 if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
@@ -1550,7 +1591,28 @@
     public int selectAnimationLw(WindowState win, int transit) {
         if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
               + ": transit=" + transit);
-        if (transit == TRANSIT_PREVIEW_DONE) {
+        if (win == mStatusBar) {
+            if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                return R.anim.dock_top_exit;
+            } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                return R.anim.dock_top_enter;
+            }
+        } else if (win == mNavigationBar) {
+            // This can be on either the bottom or the right.
+            if (mNavigationBarOnBottom) {
+                if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                    return R.anim.dock_bottom_exit;
+                } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                    return R.anim.dock_bottom_enter;
+                }
+            } else {
+                if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                    return R.anim.dock_right_exit;
+                } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                    return R.anim.dock_right_enter;
+                }
+            }
+        } if (transit == TRANSIT_PREVIEW_DONE) {
             if (win.hasAppShownWindows()) {
                 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
                 return com.android.internal.R.anim.app_starting_exit;
@@ -2036,7 +2098,8 @@
         if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
                 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
             int availRight, availBottom;
-            if ((attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
+            if (mCanHideNavigationBar &&
+                    (attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
                 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
                 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
             } else {
@@ -2082,8 +2145,9 @@
         pf.right = df.right = vf.right = mDockRight;
         pf.bottom = df.bottom = vf.bottom = mDockBottom;
 
-        final boolean navVisible = (mNavigationBar == null || mNavigationBar.isVisibleLw()) &&
-                (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+        // For purposes of putting out fake window up to steal focus, we will
+        // drive nav being hidden only by whether it is requested.
+        boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
 
         // When the navigation bar isn't visible, we put up a fake
         // input window to catch all touch events.  This way we can
@@ -2101,57 +2165,71 @@
                     0, false, false, true);
         }
 
-        // decide where the status bar goes ahead of time
-        if (mStatusBar != null) {
-            if (mNavigationBar != null) {
-                // Force the navigation bar to its appropriate place and
-                // size.  We need to do this directly, instead of relying on
-                // it to bubble up from the nav bar, because this needs to
-                // change atomically with screen rotations.
-                if (displayWidth < displayHeight) {
-                    // Portrait screen; nav bar goes on bottom.
-                    mTmpNavigationFrame.set(0, displayHeight-mNavigationBarHeight,
-                            displayWidth, displayHeight);
-                    mStableBottom = mTmpNavigationFrame.top;
-                    if (navVisible) {
-                        mDockBottom = mTmpNavigationFrame.top;
-                        mRestrictedScreenHeight = mDockBottom - mDockTop;
-                    } else {
-                        // We currently want to hide the navigation UI.  Do this by just
-                        // moving it off the screen, so it can still receive input events
-                        // to know when to be re-shown.
-                        mTmpNavigationFrame.offset(0, mNavigationBarHeight);
-                    }
-                } else {
-                    // Landscape screen; nav bar goes to the right.
-                    mTmpNavigationFrame.set(displayWidth-mNavigationBarWidth, 0,
-                            displayWidth, displayHeight);
-                    mStableRight = mTmpNavigationFrame.left;
-                    if (navVisible) {
-                        mDockRight = mTmpNavigationFrame.left;
-                        mRestrictedScreenWidth = mDockRight - mDockLeft;
-                    } else {
-                        // We currently want to hide the navigation UI.  Do this by just
-                        // moving it off the screen, so it can still receive input events
-                        // to know when to be re-shown.
-                        mTmpNavigationFrame.offset(mNavigationBarWidth, 0);
+        // For purposes of positioning and showing the nav bar, if we have
+        // decided that it can't be hidden (because of the screen aspect ratio),
+        // then take that into account.
+        navVisible |= !mCanHideNavigationBar;
+
+        if (mNavigationBar != null) {
+            // Force the navigation bar to its appropriate place and
+            // size.  We need to do this directly, instead of relying on
+            // it to bubble up from the nav bar, because this needs to
+            // change atomically with screen rotations.
+            mNavigationBarOnBottom = !mHasNavigationBar || displayWidth < displayHeight;
+            if (mNavigationBarOnBottom) {
+                // It's a system nav bar or a portrait screen; nav bar goes on bottom.
+                int top = displayHeight - mNavigationBarHeight;
+                if (mHdmiPlugged) {
+                    if (top > mExternalDisplayHeight) {
+                        top = mExternalDisplayHeight;
                     }
                 }
-                // Make sure the content and current rectangles are updated to
-                // account for the restrictions from the navigation bar.
-                mContentTop = mCurTop = mDockTop;
-                mContentBottom = mCurBottom = mDockBottom;
-                mContentLeft = mCurLeft = mDockLeft;
-                mContentRight = mCurRight = mDockRight;
-                // And compute the final frame.
-                mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
-                        mTmpNavigationFrame, mTmpNavigationFrame);
-                if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+                mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
+                mStableBottom = mTmpNavigationFrame.top;
+                if (navVisible) {
+                    mNavigationBar.showLw(true);
+                    mDockBottom = mTmpNavigationFrame.top;
+                    mRestrictedScreenHeight = mDockBottom - mDockTop;
+                } else {
+                    // We currently want to hide the navigation UI.
+                    mNavigationBar.hideLw(true);
+                }
+            } else {
+                // Landscape screen; nav bar goes to the right.
+                int left = displayWidth - mNavigationBarWidth;
+                if (mHdmiPlugged) {
+                    if (left > mExternalDisplayWidth) {
+                        left = mExternalDisplayWidth;
+                    }
+                }
+                mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
+                mStableRight = mTmpNavigationFrame.left;
+                if (navVisible) {
+                    mNavigationBar.showLw(true);
+                    mDockRight = mTmpNavigationFrame.left;
+                    mRestrictedScreenWidth = mDockRight - mDockLeft;
+                } else {
+                    // We currently want to hide the navigation UI.
+                    mNavigationBar.hideLw(true);
+                }
             }
-            if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
-                    mDockLeft, mDockTop, mDockRight, mDockBottom));
+            // Make sure the content and current rectangles are updated to
+            // account for the restrictions from the navigation bar.
+            mContentTop = mCurTop = mDockTop;
+            mContentBottom = mCurBottom = mDockBottom;
+            mContentLeft = mCurLeft = mDockLeft;
+            mContentRight = mCurRight = mDockRight;
+            // And compute the final frame.
+            mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
+                    mTmpNavigationFrame, mTmpNavigationFrame);
+            if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+        }
+        if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
+                mDockLeft, mDockTop, mDockRight, mDockBottom));
 
-            // apply navigation bar insets
+        // decide where the status bar goes ahead of time
+        if (mStatusBar != null) {
+            // apply any navigation bar insets
             pf.left = df.left = vf.left = mDockLeft;
             pf.top = df.top = vf.top = mDockTop;
             pf.right = df.right = vf.right = mDockRight;
@@ -2161,57 +2239,29 @@
             final Rect r = mStatusBar.getFrameLw();
 
             // Compute the stable dimensions whether or not the status bar is hidden.
-            if (mStatusBarCanHide) {
-                if (mDockTop == r.top) mStableTop = r.bottom;
-                else if (mDockBottom == r.bottom) mStableBottom = r.top;
-            } else {
-                if (mStableTop == r.top) {
-                    mStableTop = r.bottom;
-                } else if (mStableBottom == r.bottom) {
-                    mStableBottom = r.top;
-                }
-            }
+            if (mDockTop == r.top) mStableTop = r.bottom;
+            else if (mDockBottom == r.bottom) mStableBottom = r.top;
 
+            // If the status bar is hidden, we don't want to cause
+            // windows behind it to scroll.
             if (mStatusBar.isVisibleLw()) {
-                // If the status bar is hidden, we don't want to cause
-                // windows behind it to scroll.
-                if (mStatusBarCanHide) {
-                    // Status bar may go away, so the screen area it occupies
-                    // is available to apps but just covering them when the
-                    // status bar is visible.
-                    if (mDockTop == r.top) mDockTop = r.bottom;
-                    else if (mDockBottom == r.bottom) mDockBottom = r.top;
-                    
-                    mContentTop = mCurTop = mDockTop;
-                    mContentBottom = mCurBottom = mDockBottom;
-                    mContentLeft = mCurLeft = mDockLeft;
-                    mContentRight = mCurRight = mDockRight;
+                // Status bar may go away, so the screen area it occupies
+                // is available to apps but just covering them when the
+                // status bar is visible.
+                if (mDockTop == r.top) mDockTop = r.bottom;
+                else if (mDockBottom == r.bottom) mDockBottom = r.top;
+                
+                mContentTop = mCurTop = mDockTop;
+                mContentBottom = mCurBottom = mDockBottom;
+                mContentLeft = mCurLeft = mDockLeft;
+                mContentRight = mCurRight = mDockRight;
 
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
-                        String.format(
-                            "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
-                            mDockLeft, mDockTop, mDockRight, mDockBottom,
-                            mContentLeft, mContentTop, mContentRight, mContentBottom,
-                            mCurLeft, mCurTop, mCurRight, mCurBottom));
-                } else {
-                    // Status bar can't go away; the part of the screen it
-                    // covers does not exist for anything behind it.
-                    if (mRestrictedScreenTop == r.top) {
-                        mRestrictedScreenTop = r.bottom;
-                        mRestrictedScreenHeight -= (r.bottom-r.top);
-                    } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
-                        mRestrictedScreenHeight -= (r.bottom-r.top);
-                    }
-
-                    mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
-                    mContentBottom = mCurBottom = mDockBottom
-                            = mRestrictedScreenTop + mRestrictedScreenHeight;
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: ("
-                            + mRestrictedScreenLeft + ","
-                            + mRestrictedScreenTop + ","
-                            + (mRestrictedScreenLeft + mRestrictedScreenWidth) + ","
-                            + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")");
-                }
+                if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
+                    String.format(
+                        "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
+                        mDockLeft, mDockTop, mDockRight, mDockBottom,
+                        mContentLeft, mContentTop, mContentRight, mContentBottom,
+                        mCurLeft, mCurTop, mCurRight, mCurBottom));
             }
         }
     }
@@ -2333,7 +2383,8 @@
                                         "Laying out status bar window: (%d,%d - %d,%d)",
                                         pf.left, pf.top, pf.right, pf.bottom));
                         }
-                    } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+                    } else if (mCanHideNavigationBar
+                            && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
                             && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                             && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                         // Asking for layout as if the nav bar is hidden, lets the
@@ -2426,7 +2477,8 @@
                     pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = cf.bottom
                             = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
-                } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+                } else if (mCanHideNavigationBar
+                        && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
                         && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                         && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                     // Asking for layout as if the nav bar is hidden, lets the
@@ -2623,19 +2675,17 @@
                 // has the FLAG_FULLSCREEN set.  Not sure if there is another way that to be the
                 // case though.
                 if (topIsFullscreen) {
-                    if (mStatusBarCanHide) {
-                        if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
-                        if (mStatusBar.hideLw(true)) {
-                            changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                    if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
+                    if (mStatusBar.hideLw(true)) {
+                        changes |= FINISH_LAYOUT_REDO_LAYOUT;
 
-                            mHandler.post(new Runnable() { public void run() {
-                                if (mStatusBarService != null) {
-                                    try {
-                                        mStatusBarService.collapse();
-                                    } catch (RemoteException ex) {}
-                                }
-                            }});
-                        }
+                        mHandler.post(new Runnable() { public void run() {
+                            if (mStatusBarService != null) {
+                                try {
+                                    mStatusBarService.collapse();
+                                } catch (RemoteException ex) {}
+                            }
+                        }});
                     } else if (DEBUG_LAYOUT) {
                         Log.v(TAG, "Preventing status bar from hiding by policy");
                     }
@@ -2699,29 +2749,23 @@
             // behind it.
             return false;
         }
-        if (false) {
-            // Don't do this on the tablet, since the system bar never completely
-            // covers the screen, and with all its transparency this will
-            // incorrectly think it does cover it when it doesn't.  We'll revisit
-            // this later when we re-do the phone status bar.
-            if (mStatusBar != null && mStatusBar.isVisibleLw()) {
-                RectF rect = new RectF(mStatusBar.getShownFrameLw());
-                for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
-                    WindowState w = mStatusBarPanels.get(i);
-                    if (w.isVisibleLw()) {
-                        rect.union(w.getShownFrameLw());
-                    }
+        if (mStatusBar != null && mStatusBar.isVisibleLw()) {
+            RectF rect = new RectF(mStatusBar.getShownFrameLw());
+            for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
+                WindowState w = mStatusBarPanels.get(i);
+                if (w.isVisibleLw()) {
+                    rect.union(w.getShownFrameLw());
                 }
-                final int insetw = mRestrictedScreenWidth/10;
-                final int inseth = mRestrictedScreenHeight/10;
-                if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
-                            mRestrictedScreenHeight-inseth)) {
-                    // All of the status bar windows put together cover the
-                    // screen, so the app can't be seen.  (Note this test doesn't
-                    // work if the rects of these windows are at off offsets or
-                    // sizes, causing gaps in the rect union we have computed.)
-                    return false;
-                }
+            }
+            final int insetw = mRestrictedScreenWidth/10;
+            final int inseth = mRestrictedScreenHeight/10;
+            if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
+                        mRestrictedScreenHeight-inseth)) {
+                // All of the status bar windows put together cover the
+                // screen, so the app can't be seen.  (Note this test doesn't
+                // work if the rects of these windows are at odd offsets or
+                // sizes, causing gaps in the rect union we have computed.)
+                return false;
             }
         }
         return true;
@@ -2776,7 +2820,11 @@
     void setHdmiPlugged(boolean plugged) {
         if (mHdmiPlugged != plugged) {
             mHdmiPlugged = plugged;
-            updateRotation(true);
+            if (plugged && mDisplay != null) {
+                mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+                mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+            }
+            updateRotation(true, true);
             Intent intent = new Intent(ACTION_HDMI_PLUGGED);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
@@ -3871,7 +3919,16 @@
     void updateRotation(boolean alwaysSendConfiguration) {
         try {
             //set orientation on WindowManager
-            mWindowManager.updateRotation(alwaysSendConfiguration);
+            mWindowManager.updateRotation(alwaysSendConfiguration, false);
+        } catch (RemoteException e) {
+            // Ignore
+        }
+    }
+
+    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+        try {
+            //set orientation on WindowManager
+            mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
         } catch (RemoteException e) {
             // Ignore
         }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 7eca401..654cfdf 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5109,7 +5109,7 @@
         mPolicy.enableScreenAfterBoot();
 
         // Make sure the last requested orientation has been applied.
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -5383,7 +5383,7 @@
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
                 rotation == -1 ? mRotation : rotation);
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     /**
@@ -5399,7 +5399,7 @@
         if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     /**
@@ -5409,8 +5409,8 @@
      * such that the current rotation might need to be updated, such as when the
      * device is docked or rotated into a new posture.
      */
-    public void updateRotation(boolean alwaysSendConfiguration) {
-        updateRotationUnchecked(alwaysSendConfiguration);
+    public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+        updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
     }
 
     /**
@@ -5440,8 +5440,7 @@
         }
     }
 
-    public void updateRotationUnchecked(
-            boolean alwaysSendConfiguration) {
+    public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
         if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
                    + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
 
@@ -5449,6 +5448,10 @@
         boolean changed;
         synchronized(mWindowMap) {
             changed = updateRotationUncheckedLocked(false);
+            if (!changed || forceRelayout) {
+                mLayoutNeeded = true;
+                performLayoutAndPlaceSurfacesLocked();
+            }
         }
 
         if (changed || alwaysSendConfiguration) {
@@ -6641,7 +6644,7 @@
             mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
                     mDisplay.getRawWidth(), mDisplay.getRawHeight(),
                     mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
-            mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight);
+            mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight);
         }
 
         try {
@@ -7361,7 +7364,7 @@
             mBaseDisplayWidth = width;
             mBaseDisplayHeight = height;
         }
-        mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
+        mPolicy.setInitialDisplaySize(mDisplay, mBaseDisplayWidth, mBaseDisplayHeight);
 
         mLayoutNeeded = true;
 
@@ -7393,8 +7396,8 @@
         }
     }
 
-    public boolean canStatusBarHide() {
-        return mPolicy.canStatusBarHide();
+    public boolean hasSystemNavBar() {
+        return mPolicy.hasSystemNavBar();
     }
 
     // -------------------------------------------------------------
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 05797a4..a4708d3 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -870,6 +870,7 @@
         return true;
     }
 
+    @Override
     public boolean hideLw(boolean doAnimation) {
         return hideLw(doAnimation, true);
     }
@@ -912,6 +913,11 @@
         return true;
     }
 
+    @Override
+    public boolean isAlive() {
+        return mClient.asBinder().isBinderAlive();
+    }
+
     private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
         outRegion.set(
                 frame.left + inset.left, frame.top + inset.top,
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index c3ac22c..58f65be 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -412,7 +412,7 @@
     @SmallTest
     public void testSET_ORIENTATION() {
         try {
-            mWm.updateRotation(true);
+            mWm.updateRotation(true, false);
             mWm.getSwitchState(0);
             fail("IWindowManager.updateRotation did not throw SecurityException as"
                     + " expected");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 8b1d41a..0755670 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -88,7 +88,7 @@
     // ---- unused implementation of IWindowManager ----
 
     @Override
-    public boolean canStatusBarHide() throws RemoteException {
+    public boolean hasSystemNavBar() throws RemoteException {
         // TODO Auto-generated method stub
         return false;
     }
@@ -468,9 +468,8 @@
     }
 
     @Override
-    public void updateRotation(boolean arg0) throws RemoteException {
+    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
         // TODO Auto-generated method stub
-
     }
 
     @Override