Fix issue #4603422: Compatibility mode button doesn't always update

We now tell the system bar every time the top activity has changed for
it to re-evaluate its UI state.

Also fix issue #: 4607102 Low rider notifications.  It turns out this
was due to the change in the dialog asset; the notification UI was relying
on this having a lot of padding to make it sit above the status bar.
Now we have an explicitly mechanism to set how much it overlaps (or doesn't)
the status bar.

Change-Id: Iab5ebd86e620ff4fc4cd77206e18af962ec2830e
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 7f23ed5..aa9e452 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -31,7 +31,7 @@
     void animateExpand();
     void animateCollapse();
     void setLightsOn(boolean on);
-    void setMenuKeyVisible(boolean visible);
+    void topAppWindowChanged(boolean menuVisible);
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
     void setHardKeyboardStatus(boolean available, boolean enabled);
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index d6ca426..1461a7d 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License.
  */
- 
+
 package com.android.internal.statusbar;
 
 import com.android.internal.statusbar.IStatusBar;
@@ -30,7 +30,7 @@
     void setIcon(String slot, String iconPackage, int iconId, int iconLevel);
     void setIconVisibility(String slot, boolean visible);
     void removeIcon(String slot);
-    void setMenuKeyVisible(boolean visible);
+    void topAppWindowChanged(boolean menuVisible);
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
 
     // ---- Methods below are for use by the status bar policy services ----
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 88cd43c..ff979a0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -30,6 +30,8 @@
     <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
     <!-- Width of scrollable area in recents -->
     <dimen name="status_bar_recents_width">356dp</dimen>
+    <!-- Amount to offset bottom of notification peek window from top of status bar. -->
+    <dimen name="peek_window_y_offset">-12dp</dimen>
 
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index d55a7c2..07f9ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -54,7 +54,7 @@
 
     private static final int MSG_SET_LIGHTS_ON = 0x00070000;
 
-    private static final int MSG_SHOW_MENU = 0x00080000;
+    private static final int MSG_TOP_APP_WINDOW_CHANGED = 0x00080000;
     private static final int MSG_SHOW_IME_BUTTON = 0x00090000;
     private static final int MSG_SET_HARD_KEYBOARD_STATUS = 0x000a0000;
 
@@ -82,7 +82,7 @@
         public void animateExpand();
         public void animateCollapse();
         public void setLightsOn(boolean on);
-        public void setMenuKeyVisible(boolean visible);
+        public void topAppWindowChanged(boolean visible);
         public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
         public void setHardKeyboardStatus(boolean available, boolean enabled);
     }
@@ -160,10 +160,11 @@
         }
     }
 
-    public void setMenuKeyVisible(boolean visible) {
+    public void topAppWindowChanged(boolean menuVisible) {
         synchronized (mList) {
-            mHandler.removeMessages(MSG_SHOW_MENU);
-            mHandler.obtainMessage(MSG_SHOW_MENU, visible ? 1 : 0, 0, null).sendToTarget();
+            mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
+            mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0,
+                    null).sendToTarget();
         }
     }
 
@@ -240,8 +241,8 @@
                 case MSG_SET_LIGHTS_ON:
                     mCallbacks.setLightsOn(msg.arg1 != 0);
                     break;
-                case MSG_SHOW_MENU:
-                    mCallbacks.setMenuKeyVisible(msg.arg1 != 0);
+                case MSG_TOP_APP_WINDOW_CHANGED:
+                    mCallbacks.topAppWindowChanged(msg.arg1 != 0);
                     break;
                 case MSG_SHOW_IME_BUTTON:
                     mCallbacks.setImeWindowStatus((IBinder)msg.obj, msg.arg1, msg.arg2);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 23ae823..e567dc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -78,7 +78,7 @@
 
         disable(switches[0]);
         setLightsOn(switches[1] != 0);
-        setMenuKeyVisible(switches[2] != 0);
+        topAppWindowChanged(switches[2] != 0);
         // StatusBarManagerService has a back up of IME token and it's restored here.
         setImeWindowStatus(binders.get(0), switches[3], switches[4]);
         setHardKeyboardStatus(switches[5] != 0, switches[6] != 0);
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 1e46246..84ae766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1019,7 +1019,7 @@
     }
 
     // Not supported
-    public void setMenuKeyVisible(boolean visible) { }
+    public void topAppWindowChanged(boolean visible) { }
     public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { }
     @Override
     public void setHardKeyboardStatus(boolean available, boolean enabled) { }
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 4e10770..b304ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -245,11 +245,12 @@
                 512, // ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                     | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
+        lp.y = res.getDimensionPixelOffset(R.dimen.peek_window_y_offset);
         lp.setTitle("NotificationPeekWindow");
         lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
 
@@ -955,14 +956,14 @@
         mHandler.sendEmptyMessage(on ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
     }
 
-    public void setMenuKeyVisible(boolean visible) {
+    public void topAppWindowChanged(boolean windowVisible) {
         if (DEBUG) {
-            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
+            Slog.d(TAG, (windowVisible?"showing":"hiding") + " the MENU button");
         }
-        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+        mMenuButton.setVisibility(windowVisible ? View.VISIBLE : View.GONE);
 
         // See above re: lights-out policy for legacy apps.
-        if (visible) setLightsOn(true);
+        if (windowVisible) setLightsOn(true);
 
         // XXX: HACK: not sure if this is the best way to catch a new activity that might require a
         // change in compatibility features, but it's a start.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 13205e8..ca3d864 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -324,6 +324,8 @@
     static final Rect mTmpVisibleFrame = new Rect();
     
     WindowState mTopFullscreenOpaqueWindowState;
+    WindowState mTopAppWindowState;
+    WindowState mLastTopAppWindowState;
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
     boolean mHideLockScreen;
@@ -334,7 +336,6 @@
     Intent mDeskDockIntent;
     int mShortcutKeyPressed = -1;
     boolean mConsumeShortcutKeyUp;
-    boolean mShowMenuKey = false; // track FLAG_NEEDS_MENU_KEY on frontmost window
 
     // support for activating the lock screen while the screen is on
     boolean mAllowLockscreenWhenOn;
@@ -1842,12 +1843,11 @@
                     // the status bar.  They are protected by the STATUS_BAR_SERVICE
                     // permission, so they have the same privileges as the status
                     // bar itself.
-                    pf.left = df.left = cf.left = vf.left = mUnrestrictedScreenLeft;
-                    pf.top = df.top = cf.top = vf.top = mUnrestrictedScreenTop;
-                    pf.right = df.right = cf.right = vf.right
-                            = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
-                    pf.bottom = df.bottom = cf.bottom = vf.bottom
-                            = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+                    pf.left = df.left = cf.left = mRestrictedScreenLeft;
+                    pf.top = df.top = cf.top = mRestrictedScreenTop;
+                    pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
+                    pf.bottom = df.bottom = cf.bottom
+                            = mRestrictedScreenTop+mRestrictedScreenHeight;
                 } else {
                     pf.left = mContentLeft;
                     pf.top = mContentTop;
@@ -1915,6 +1915,7 @@
     /** {@inheritDoc} */
     public void beginAnimationLw(int displayWidth, int displayHeight) {
         mTopFullscreenOpaqueWindowState = null;
+        mTopAppWindowState = null;
         mForceStatusBar = false;
         
         mHideLockScreen = false;
@@ -1950,6 +1951,12 @@
                 }
             }
         }
+        if (mTopAppWindowState == null && win.isVisibleOrBehindKeyguardLw()) {
+            if (attrs.type >= FIRST_APPLICATION_WINDOW
+                    && attrs.type <= LAST_APPLICATION_WINDOW) {
+                mTopAppWindowState = win;
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -1993,22 +2000,13 @@
             }
         }
 
-        boolean topNeedsMenu = mShowMenuKey;
-        if (lp != null) {
-            topNeedsMenu = (lp.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
-        }
-
-        if (DEBUG_LAYOUT) Log.v(TAG, "Top window " 
-                + (topNeedsMenu ? "needs" : "does not need")
-                + " the MENU key");
-
         mTopIsFullscreen = topIsFullscreen;
-        final boolean changedMenu = (topNeedsMenu != mShowMenuKey);
 
-        if (changedMenu) {
-            final boolean topNeedsMenuF = topNeedsMenu;
+        if (mTopAppWindowState != null && mTopAppWindowState != mLastTopAppWindowState) {
+            mLastTopAppWindowState = mTopAppWindowState;
 
-            mShowMenuKey = topNeedsMenu;
+            final boolean topNeedsMenu = (mTopAppWindowState.getAttrs().flags
+                    & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
 
             mHandler.post(new Runnable() {
                     public void run() {
@@ -2023,9 +2021,7 @@
                         final IStatusBarService sbs = mStatusBarService;
                         if (mStatusBarService != null) {
                             try {
-                                if (changedMenu) {
-                                    sbs.setMenuKeyVisible(topNeedsMenuF);
-                                }
+                                sbs.topAppWindowChanged(topNeedsMenu);
                             } catch (RemoteException e) {
                                 // This should be impossible because we're in the same process.
                                 mStatusBarService = null;
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 8df8177..568a5e3 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -16,21 +16,16 @@
 
 package com.android.server;
 
-import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
-import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.SystemClock;
 import android.util.Slog;
 import android.view.View;
 
@@ -248,25 +243,23 @@
      * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
      * response to a window with FLAG_NEEDS_MENU_KEY set.
      */
-    public void setMenuKeyVisible(final boolean visible) {
+    public void topAppWindowChanged(final boolean menuVisible) {
         enforceStatusBar();
 
-        if (SPEW) Slog.d(TAG, (visible?"showing":"hiding") + " MENU key");
+        if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
 
         synchronized(mLock) {
-            if (mMenuVisible != visible) {
-                mMenuVisible = visible;
-                mHandler.post(new Runnable() {
-                        public void run() {
-                            if (mBar != null) {
-                                try {
-                                    mBar.setMenuKeyVisible(visible);
-                                } catch (RemoteException ex) {
-                                }
+            mMenuVisible = menuVisible;
+            mHandler.post(new Runnable() {
+                    public void run() {
+                        if (mBar != null) {
+                            try {
+                                mBar.topAppWindowChanged(menuVisible);
+                            } catch (RemoteException ex) {
                             }
                         }
-                    });
-            }
+                    }
+                });
         }
     }