diff options
7 files changed, 52 insertions, 2 deletions
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index d0841dd..a99ac03 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -743,6 +743,9 @@ public abstract class Window { public void setFlags(int flags, int mask) { final WindowManager.LayoutParams attrs = getAttributes(); attrs.flags = (attrs.flags&~mask) | (flags&mask); + if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) { + attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; + } mForcedWindowFlags |= mask; if (mCallback != null) { mCallback.onWindowAttributesChanged(attrs); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index e74fec6..c0eb65b 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -824,6 +824,16 @@ public interface WindowManager extends ViewManager { public static final int PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS = 0x00000004; /** + * This is set for a window that has explicitly specified its + * FLAG_NEEDS_MENU_KEY, so we know the value on this window is the + * appropriate one to use. If this is not set, we should look at + * windows behind it to determine the appropriate value. + * + * @hide + */ + public static final int PRIVATE_FLAG_SET_NEEDS_MENU_KEY = 0x00000008; + + /** * Control flags that are private to the platform. * @hide */ diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 2e19bf6..924cb53 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -238,6 +238,14 @@ public interface WindowManagerPolicy { public WindowManager.LayoutParams getAttrs(); /** + * Return whether this window needs the menu key shown. Must be called + * with window lock held, because it may need to traverse down through + * window list to determine the result. + * @param bottom The bottom-most window to consider when determining this. + */ + public boolean getNeedsMenuLw(WindowState bottom); + + /** * Retrieve the current system UI visibility flags associated with * this window. */ diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java index 0499cfa..ff8d5ac 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java @@ -138,6 +138,7 @@ public class KeyguardViewManager implements KeyguardWindowController { lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; } + lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; lp.setTitle("Keyguard"); mWindowLayoutParams = lp; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 535f039..f1fe43b 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -2582,6 +2582,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) { addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); + } else { + clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); } if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 7510e04..0b223c1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -3707,8 +3707,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { & ~mResettingSystemUiFlags & ~mForceClearedSystemUiFlags; int diff = visibility ^ mLastSystemUiFlags; - final boolean needsMenu = (mFocusedWindow.getAttrs().flags - & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; + final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); if (diff == 0 && mLastFocusNeedsMenu == needsMenu && mFocusedApp == mFocusedWindow.getAppToken()) { return 0; diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index aa7bf2d..75bda41 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -562,6 +562,33 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAttrs; } + public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { + int index = -1; + WindowState ws = this; + while (true) { + if ((ws.mAttrs.privateFlags + & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) { + return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; + } + // If we reached the bottom of the range of windows we are considering, + // assume no menu is needed. + if (ws == bottom) { + return false; + } + // The current window hasn't specified whether menu key is needed; + // look behind it. + // First, we may need to determine the starting position. + if (index < 0) { + index = mService.mWindows.indexOf(ws); + } + index--; + if (index < 0) { + return false; + } + ws = mService.mWindows.get(index); + } + } + public int getSystemUiVisibility() { return mSystemUiVisibility; } |