Merge "Fix issue #17789629: PopupWindow overlaps with navigation bar." into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d0aae5a222
@@ -34909,6 +34909,7 @@ package android.view {
|
||||
field public static final int FLAG_HARDWARE_ACCELERATED = 16777216; // 0x1000000
|
||||
field public static final int FLAG_IGNORE_CHEEK_PRESSES = 32768; // 0x8000
|
||||
field public static final int FLAG_KEEP_SCREEN_ON = 128; // 0x80
|
||||
field public static final int FLAG_LAYOUT_ATTACHED_IN_DECOR = 1073741824; // 0x40000000
|
||||
field public static final int FLAG_LAYOUT_INSET_DECOR = 65536; // 0x10000
|
||||
field public static final int FLAG_LAYOUT_IN_OVERSCAN = 33554432; // 0x2000000
|
||||
field public static final int FLAG_LAYOUT_IN_SCREEN = 256; // 0x100
|
||||
@@ -38172,6 +38173,7 @@ package android.widget {
|
||||
method public int getSoftInputMode();
|
||||
method public int getWidth();
|
||||
method public boolean isAboveAnchor();
|
||||
method public boolean isAttachedInDecor();
|
||||
method public boolean isClippingEnabled();
|
||||
method public boolean isFocusable();
|
||||
method public boolean isOutsideTouchable();
|
||||
@@ -38179,6 +38181,7 @@ package android.widget {
|
||||
method public boolean isSplitTouchEnabled();
|
||||
method public boolean isTouchable();
|
||||
method public void setAnimationStyle(int);
|
||||
method public void setAttachedInDecor(boolean);
|
||||
method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
|
||||
method public void setClippingEnabled(boolean);
|
||||
method public void setContentView(android.view.View);
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -801,9 +800,6 @@ 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;
|
||||
dispatchWindowAttributesChanged(attrs);
|
||||
}
|
||||
@@ -814,6 +810,15 @@ public abstract class Window {
|
||||
dispatchWindowAttributesChanged(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
protected void setNeedsMenuKey(int value) {
|
||||
final WindowManager.LayoutParams attrs = getAttributes();
|
||||
attrs.needsMenuKey = value;
|
||||
dispatchWindowAttributesChanged(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
|
||||
@@ -878,9 +878,6 @@ public interface WindowManager extends ViewManager {
|
||||
*/
|
||||
public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;
|
||||
|
||||
// ----- HIDDEN FLAGS.
|
||||
// These start at the high bit and go down.
|
||||
|
||||
/**
|
||||
* Flag for a window in local focus mode.
|
||||
* Window in local focus mode can control focus independent of window manager using
|
||||
@@ -903,17 +900,12 @@ public interface WindowManager extends ViewManager {
|
||||
public static final int FLAG_SLIPPERY = 0x20000000;
|
||||
|
||||
/**
|
||||
* Flag for a window belonging to an activity that responds to {@link KeyEvent#KEYCODE_MENU}
|
||||
* and therefore needs a Menu key. For devices where Menu is a physical button this flag is
|
||||
* ignored, but on devices where the Menu key is drawn in software it may be hidden unless
|
||||
* this flag is set.
|
||||
*
|
||||
* (Note that Action Bars, when available, are the preferred way to offer additional
|
||||
* functions otherwise accessed via an options menu.)
|
||||
*
|
||||
* {@hide}
|
||||
* Window flag: When requesting layout with an attached window, the attached window may
|
||||
* overlap with the screen decorations of the parent window such as the navigation bar. By
|
||||
* including this flag, the window manager will layout the attached window within the decor
|
||||
* frame of the parent window such that it doesn't overlap with screen decorations.
|
||||
*/
|
||||
public static final int FLAG_NEEDS_MENU_KEY = 0x40000000;
|
||||
public static final int FLAG_LAYOUT_ATTACHED_IN_DECOR = 0x40000000;
|
||||
|
||||
/**
|
||||
* Flag indicating that this Window is responsible for drawing the background for the
|
||||
@@ -1056,16 +1048,6 @@ 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;
|
||||
|
||||
/** In a multiuser system if this flag is set and the owner is a system process then this
|
||||
* window will appear on all user screens. This overrides the default behavior of window
|
||||
* types that normally only appear on the owning user's screen. Refer to each window type
|
||||
@@ -1112,6 +1094,45 @@ public interface WindowManager extends ViewManager {
|
||||
*/
|
||||
public int privateFlags;
|
||||
|
||||
/**
|
||||
* Value for {@link #needsMenuKey} for a window that has not explicitly specified if it
|
||||
* needs {@link #NEEDS_MENU_SET_TRUE} or doesn't need {@link #NEEDS_MENU_SET_FALSE} a menu
|
||||
* key. For this case, we should look at windows behind it to determine the appropriate
|
||||
* value.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int NEEDS_MENU_UNSET = 0;
|
||||
|
||||
/**
|
||||
* Value for {@link #needsMenuKey} for a window that has explicitly specified it needs a
|
||||
* menu key.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int NEEDS_MENU_SET_TRUE = 1;
|
||||
|
||||
/**
|
||||
* Value for {@link #needsMenuKey} for a window that has explicitly specified it doesn't
|
||||
* needs a menu key.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int NEEDS_MENU_SET_FALSE = 2;
|
||||
|
||||
/**
|
||||
* State variable for a window belonging to an activity that responds to
|
||||
* {@link KeyEvent#KEYCODE_MENU} and therefore needs a Menu key. For devices where Menu is a
|
||||
* physical button this variable is ignored, but on devices where the Menu key is drawn in
|
||||
* software it may be hidden unless this variable is set to {@link #NEEDS_MENU_SET_TRUE}.
|
||||
*
|
||||
* (Note that Action Bars, when available, are the preferred way to offer additional
|
||||
* functions otherwise accessed via an options menu.)
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public int needsMenuKey = NEEDS_MENU_UNSET;
|
||||
|
||||
/**
|
||||
* Given a particular set of window manager flags, determine whether
|
||||
* such a window may be a target for an input method when it has
|
||||
@@ -1120,9 +1141,9 @@ public interface WindowManager extends ViewManager {
|
||||
* flags and returns true if the combination of the two corresponds
|
||||
* to a window that needs to be behind the input method so that the
|
||||
* user can type into it.
|
||||
*
|
||||
*
|
||||
* @param flags The current window manager flags.
|
||||
*
|
||||
*
|
||||
* @return Returns true if such a window should be behind/interact
|
||||
* with an input method, false if not.
|
||||
*/
|
||||
@@ -1587,14 +1608,15 @@ public interface WindowManager extends ViewManager {
|
||||
out.writeInt(surfaceInsets.top);
|
||||
out.writeInt(surfaceInsets.right);
|
||||
out.writeInt(surfaceInsets.bottom);
|
||||
out.writeInt(needsMenuKey);
|
||||
}
|
||||
|
||||
|
||||
public static final Parcelable.Creator<LayoutParams> CREATOR
|
||||
= new Parcelable.Creator<LayoutParams>() {
|
||||
public LayoutParams createFromParcel(Parcel in) {
|
||||
return new LayoutParams(in);
|
||||
}
|
||||
|
||||
|
||||
public LayoutParams[] newArray(int size) {
|
||||
return new LayoutParams[size];
|
||||
}
|
||||
@@ -1634,8 +1656,9 @@ public interface WindowManager extends ViewManager {
|
||||
surfaceInsets.top = in.readInt();
|
||||
surfaceInsets.right = in.readInt();
|
||||
surfaceInsets.bottom = in.readInt();
|
||||
needsMenuKey = in.readInt();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"PointlessBitwiseExpression"})
|
||||
public static final int LAYOUT_CHANGED = 1<<0;
|
||||
public static final int TYPE_CHANGED = 1<<1;
|
||||
@@ -1669,14 +1692,16 @@ public interface WindowManager extends ViewManager {
|
||||
/** {@hide} */
|
||||
public static final int PREFERRED_REFRESH_RATE_CHANGED = 1 << 21;
|
||||
/** {@hide} */
|
||||
public static final int NEEDS_MENU_KEY_CHANGED = 1 << 22;
|
||||
/** {@hide} */
|
||||
public static final int EVERYTHING_CHANGED = 0xffffffff;
|
||||
|
||||
// internal buffer to backup/restore parameters under compatibility mode.
|
||||
private int[] mCompatibilityParamsBackup = null;
|
||||
|
||||
|
||||
public final int copyFrom(LayoutParams o) {
|
||||
int changes = 0;
|
||||
|
||||
|
||||
if (width != o.width) {
|
||||
width = o.width;
|
||||
changes |= LAYOUT_CHANGED;
|
||||
@@ -1813,9 +1838,14 @@ public interface WindowManager extends ViewManager {
|
||||
changes |= SURFACE_INSETS_CHANGED;
|
||||
}
|
||||
|
||||
if (needsMenuKey != o.needsMenuKey) {
|
||||
needsMenuKey = o.needsMenuKey;
|
||||
changes |= NEEDS_MENU_KEY_CHANGED;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String debug(String output) {
|
||||
output += "Contents of " + this + ":";
|
||||
@@ -1919,6 +1949,10 @@ public interface WindowManager extends ViewManager {
|
||||
if (!surfaceInsets.equals(Insets.NONE)) {
|
||||
sb.append(" surfaceInsets=").append(surfaceInsets);
|
||||
}
|
||||
if (needsMenuKey != NEEDS_MENU_UNSET) {
|
||||
sb.append(" needsMenuKey=");
|
||||
sb.append(needsMenuKey);
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -97,9 +97,11 @@ public class PopupWindow {
|
||||
private boolean mAllowScrollingAnchorParent = true;
|
||||
private boolean mLayoutInsetDecor = false;
|
||||
private boolean mNotTouchModal;
|
||||
private boolean mAttachedInDecor = true;
|
||||
private boolean mAttachedInDecorSet = false;
|
||||
|
||||
private OnTouchListener mTouchInterceptor;
|
||||
|
||||
|
||||
private int mWidthMode;
|
||||
private int mWidth;
|
||||
private int mLastWidth;
|
||||
@@ -316,6 +318,7 @@ public class PopupWindow {
|
||||
mContext = contentView.getContext();
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
}
|
||||
|
||||
setContentView(contentView);
|
||||
setWidth(width);
|
||||
setHeight(height);
|
||||
@@ -373,16 +376,16 @@ public class PopupWindow {
|
||||
public int getAnimationStyle() {
|
||||
return mAnimationStyle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the flag on popup to ignore cheek press eventt; by default this flag
|
||||
* Set the flag on popup to ignore cheek press event; by default this flag
|
||||
* is set to false
|
||||
* which means the pop wont ignore cheek press dispatch events.
|
||||
*
|
||||
*
|
||||
* <p>If the popup is showing, calling this method will take effect only
|
||||
* the next time the popup is shown or through a manual call to one of
|
||||
* the {@link #update()} methods.</p>
|
||||
*
|
||||
*
|
||||
* @see #update()
|
||||
*/
|
||||
public void setIgnoreCheekPress() {
|
||||
@@ -443,6 +446,19 @@ public class PopupWindow {
|
||||
if (mWindowManager == null && mContentView != null) {
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
}
|
||||
|
||||
// Setting the default for attachedInDecor based on SDK version here
|
||||
// instead of in the constructor since we might not have the context
|
||||
// object in the constructor. We only want to set default here if the
|
||||
// app hasn't already set the attachedInDecor.
|
||||
if (mContext != null && !mAttachedInDecorSet) {
|
||||
// Attach popup window in decor frame of parent window by default for
|
||||
// {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
|
||||
// behavior of not attaching to decor frame for older SDKs.
|
||||
setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
|
||||
>= Build.VERSION_CODES.LOLLIPOP_MR1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +468,7 @@ public class PopupWindow {
|
||||
public void setTouchInterceptor(OnTouchListener l) {
|
||||
mTouchInterceptor = l;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Indicate whether the popup window can grab the focus.</p>
|
||||
*
|
||||
@@ -701,6 +717,36 @@ public class PopupWindow {
|
||||
mLayoutInScreen = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Indicates whether the popup window will be attached in the decor frame of its parent
|
||||
* window.
|
||||
*
|
||||
* @return true if the window will be attached to the decor frame of its parent window.
|
||||
*
|
||||
* @see #setAttachedInDecor(boolean)
|
||||
* @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
|
||||
*/
|
||||
public boolean isAttachedInDecor() {
|
||||
return mAttachedInDecor;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This will attach the popup window to the decor frame of the parent window to avoid
|
||||
* overlaping with screen decorations like the navigation bar. Overrides the default behavior of
|
||||
* the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
|
||||
*
|
||||
* <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
|
||||
* greater and cleared on lesser SDK versions.
|
||||
*
|
||||
* @param enabled true if the popup should be attached to the decor frame of its parent window.
|
||||
*
|
||||
* @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
|
||||
*/
|
||||
public void setAttachedInDecor(boolean enabled) {
|
||||
mAttachedInDecor = enabled;
|
||||
mAttachedInDecorSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the popup window to force the flag
|
||||
* {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
|
||||
@@ -1140,9 +1186,12 @@ public class PopupWindow {
|
||||
if (mNotTouchModal) {
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||
}
|
||||
if (mAttachedInDecor) {
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
|
||||
}
|
||||
return curFlags;
|
||||
}
|
||||
|
||||
|
||||
private int computeAnimationResource() {
|
||||
if (mAnimationStyle == -1) {
|
||||
if (mIsDropdown) {
|
||||
|
||||
@@ -3342,9 +3342,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
|
||||
final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE);
|
||||
|
||||
if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
|
||||
addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
|
||||
setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE);
|
||||
} else {
|
||||
clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
|
||||
setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
|
||||
}
|
||||
|
||||
// Non-floating windows on high end devices must put up decor beneath the system bars and
|
||||
|
||||
@@ -3181,10 +3181,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
// whether it is taking care of insetting its content. If not,
|
||||
// we need to use the parent's content frame so that the entire
|
||||
// window is positioned within that content. Otherwise we can use
|
||||
// the display frame and let the attached window take care of
|
||||
// the overscan frame and let the attached window take care of
|
||||
// positioning its content appropriately.
|
||||
if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
|
||||
cf.set(attached.getOverscanFrameLw());
|
||||
// Set the content frame of the attached window to the parent's decor frame
|
||||
// (same as content frame when IME isn't present) if specifically requested by
|
||||
// setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag.
|
||||
// Otherwise, use the overscan frame.
|
||||
cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0
|
||||
? attached.getContentFrameLw() : attached.getOverscanFrameLw());
|
||||
} else {
|
||||
// If the window is resizing, then we want to base the content
|
||||
// frame on our attached content frame to resize... however,
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Slog;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.statusbar.IStatusBar;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
@@ -295,9 +296,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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.
|
||||
* response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set
|
||||
* to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}.
|
||||
*/
|
||||
@Override
|
||||
public void topAppWindowChanged(final boolean menuVisible) {
|
||||
|
||||
@@ -704,9 +704,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
WindowState ws = this;
|
||||
WindowList windows = getWindowList();
|
||||
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 (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) {
|
||||
return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
|
||||
}
|
||||
// If we reached the bottom of the range of windows we are considering,
|
||||
// assume no menu is needed.
|
||||
|
||||
Reference in New Issue
Block a user