Clean up status bar, system bar, navigation bar management.

The status bar and navigation bar are two completely separate
elements, with their own semantics.  The system bar now classifies
itself as a navigation bar, since that is really how it behaves.

This required rewriting the HDMI resizing code, so that it is
all done by PhoneWindowManager since that is what is responsible
for the size of the navigation bar (and thus now system bar).  This
actually gets rid of a fair amount of code, and means we can also
do the same thing for a pure navigation bar.

Likewise the system bar now has the navigation bar ability to be
hidden when requested by system UI flags.  To get the behavior
we want on Xoom, we only allow the nav bar to be hidden when it
will help provide a better aspect ratio for showing widescreen
videos.

Finally the nav/system bar now animates when hidden and shown.

Change-Id: Ie927154b68376a0b61802f99171ff56b8da92e7a
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..7a2e94b 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 e5f049d..565d7d2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1125,6 +1125,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" />
@@ -1150,7 +1158,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/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