Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a674fafb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support for WM.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR."

parents 2bccbc8e c0b0f93e
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -1422,7 +1422,7 @@ public interface WindowManager extends ViewManager {
         * this window is visible.
         * @hide
         */
        @RequiresPermission(android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
        @RequiresPermission(permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
        public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;

        /**
@@ -1442,6 +1442,15 @@ public interface WindowManager extends ViewManager {
        @RequiresPermission(permission.DEVICE_POWER)
        public static final int PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN = 0x00200000;

        /**
         * Flag to indicate that this window should be considered a screen decoration similar to the
         * nav bar and status bar. This will cause this window to affect the window insets reported
         * to other windows when it is visible.
         * @hide
         */
        @RequiresPermission(permission.STATUS_BAR_SERVICE)
        public static final int PRIVATE_FLAG_IS_SCREEN_DECOR = 0x00400000;

        /**
         * Control flags that are private to the platform.
         * @hide
@@ -1526,7 +1535,11 @@ public interface WindowManager extends ViewManager {
                @ViewDebug.FlagToString(
                        mask = PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN,
                        equals = PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN,
                        name = "ACQUIRES_SLEEP_TOKEN")
                        name = "ACQUIRES_SLEEP_TOKEN"),
                @ViewDebug.FlagToString(
                        mask = PRIVATE_FLAG_IS_SCREEN_DECOR,
                        equals = PRIVATE_FLAG_IS_SCREEN_DECOR,
                        name = "IS_SCREEN_DECOR")
        })
        @TestApi
        public int privateFlags;
+4 −3
Original line number Diff line number Diff line
@@ -758,7 +758,8 @@ public interface WindowManagerPolicy {
     * @param attrs The window layout parameters to be modified.  These values
     * are modified in-place.
     */
    public void adjustWindowParamsLw(WindowManager.LayoutParams attrs);
    public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
            boolean hasStatusBarServicePermission);

    /**
     * After the window manager has computed the current configuration based
@@ -1172,13 +1173,13 @@ public interface WindowManagerPolicy {
    /**
     * Called when layout of the windows is about to start.
     *
     * @param isDefaultDisplay true if window is on {@link Display#DEFAULT_DISPLAY}.
     * @param displayId Id of the display we are doing layout on.
     * @param displayWidth The current full width of the screen.
     * @param displayHeight The current full height of the screen.
     * @param displayRotation The current rotation being applied to the base window.
     * @param uiMode The current uiMode in configuration.
     */
    public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
    public void beginLayoutLw(int displayId, int displayWidth, int displayHeight,
                              int displayRotation, int uiMode);

    /**
+99 −6
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
@@ -198,6 +199,7 @@ import android.service.dreams.IDreamManager;
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -456,6 +458,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private AccessibilityShortcutController mAccessibilityShortcutController;

    boolean mSafeMode;
    private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
    WindowState mStatusBar = null;
    int mStatusBarHeight;
    WindowState mNavigationBar = null;
@@ -2613,7 +2616,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    @Override
    public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
    public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
            boolean hasStatusBarServicePermission) {

        final boolean isScreenDecor = (attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
        if (mScreenDecorWindows.contains(win)) {
            if (!isScreenDecor) {
                // No longer has the flag set, so remove from the set.
                mScreenDecorWindows.remove(win);
            }
        } else if (isScreenDecor && hasStatusBarServicePermission) {
            mScreenDecorWindows.add(win);
        }

        switch (attrs.type) {
            case TYPE_SYSTEM_OVERLAY:
            case TYPE_SECURE_SYSTEM_OVERLAY:
@@ -3074,6 +3089,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     */
    @Override
    public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {

        if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.STATUS_BAR_SERVICE,
                    "PhoneWindowManager");
            mScreenDecorWindows.add(win);
        }

        switch (attrs.type) {
            case TYPE_STATUS_BAR:
                mContext.enforceCallingOrSelfPermission(
@@ -3125,6 +3148,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            mNavigationBar = null;
            mNavigationBarController.setWindow(null);
        }
        mScreenDecorWindows.remove(win);
    }

    static final boolean PRINT_ANIM = false;
@@ -4395,8 +4419,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    /** {@inheritDoc} */
    @Override
    public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
    public void beginLayoutLw(int displayId, int displayWidth, int displayHeight,
            int displayRotation, int uiMode) {
        final boolean isDefaultDisplay = displayId == DEFAULT_DISPLAY;
        mDisplayRotation = displayRotation;
        final int overscanLeft, overscanTop, overscanRight, overscanBottom;
        if (isDefaultDisplay) {
@@ -4524,6 +4549,71 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                updateSystemUiVisibilityLw();
            }
        }
        layoutScreenDecorWindows(displayId, displayWidth, displayHeight, pf, df, dcf);
    }

    private void layoutScreenDecorWindows(int displayId, int displayWidth, int displayHeight,
            Rect pf, Rect df, Rect dcf) {
        if (mScreenDecorWindows.isEmpty()) {
            return;
        }

        for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {
            final WindowState w = mScreenDecorWindows.valueAt(i);
            if (w.getDisplayId() != displayId || !w.isVisibleLw()) {
                // Skip if not on the same display or not visible.
                continue;
            }

            w.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, df /* overlayFrame */,
                    df /* contentFrame */, df /* visibleFrame */, dcf /* decorFrame */,
                    df /* stableFrame */, df /* outsetFrame */);
            final Rect frame = w.getFrameLw();

            if (frame.left <= 0 && frame.top <= 0) {
                // Docked at left or top.
                if (frame.bottom >= displayHeight) {
                    // Docked left.
                    mDockLeft = Math.max(frame.right, mDockLeft);
                } else if (frame.right >= displayWidth ) {
                    // Docked top.
                    mDockTop = Math.max(frame.bottom, mDockTop);
                } else {
                    Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
                            + " not docked on left or top of display. frame=" + frame
                            + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
                }
            } else if (frame.right >= displayWidth && frame.bottom >= displayHeight) {
                // Docked at right or bottom.
                if (frame.top <= 0) {
                    // Docked right.
                    mDockRight = Math.min(frame.left, mDockRight);
                } else if (frame.left <= 0) {
                    // Docked bottom.
                    mDockBottom = Math.min(frame.top, mDockBottom);
                } else {
                    Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
                            + " not docked on right or bottom" + " of display. frame=" + frame
                            + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
                }
            } else {
                // Screen decor windows are required to be docked on one of the sides of the screen.
                Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
                        + " not docked on one of the sides of the display. frame=" + frame
                        + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
            }
        }

        mContentTop = mSystemTop = mVoiceContentTop = mCurTop = mRestrictedScreenTop = mDockTop;
        mContentLeft = mSystemLeft = mVoiceContentLeft = mCurLeft = mRestrictedScreenLeft
                = mRestrictedOverscanScreenLeft = mDockLeft;
        mContentBottom = mSystemBottom = mVoiceContentBottom = mCurBottom = mDockBottom;
        mContentRight = mSystemRight = mVoiceContentRight = mCurRight = mDockRight;

        mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft;
        mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop;
        mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft;
        mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop;
    }

    private boolean layoutStatusBar(Rect pf, Rect df, Rect of, Rect vf, Rect dcf, int sysui,
@@ -4823,9 +4913,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    /** {@inheritDoc} */
    @Override
    public void layoutWindowLw(WindowState win, WindowState attached) {
        // We've already done the navigation bar and status bar. If the status bar can receive
        // input, we need to layout it again to accomodate for the IME window.
        if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) {
        // We've already done the navigation bar, status bar, and all screen decor windows. If the
        // status bar can receive input, we need to layout it again to accommodate for the IME
        // window.
        if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar
                || mScreenDecorWindows.contains(win)) {
            return;
        }
        final WindowManager.LayoutParams attrs = win.getAttrs();
@@ -4864,6 +4956,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        if (!isDefaultDisplay) {
            // TODO: Need to fix this and above to take into account decor windows.
            if (attached != null) {
                // If this window is attached to another, our display
                // frame is the same as the one we are attached to.
+1 −2
Original line number Diff line number Diff line
@@ -2877,8 +2877,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + " dh=" + dh);
        }

        mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation,
                getConfiguration().uiMode);
        mService.mPolicy.beginLayoutLw(mDisplayId, dw, dh, mRotation, getConfiguration().uiMode);
        if (isDefaultDisplay) {
            // Not needed on non-default displays.
            mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
+10 −4
Original line number Diff line number Diff line
@@ -1320,7 +1320,10 @@ public class WindowManagerService extends IWindowManager.Stub
                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
            }

            mPolicy.adjustWindowParamsLw(win.mAttrs);
            final boolean hasStatusBarServicePermission =
                    mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
                            == PackageManager.PERMISSION_GRANTED;
            mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);
            win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));

            res = mPolicy.prepareAddWindowLw(win, attrs);
@@ -1846,8 +1849,11 @@ public class WindowManagerService extends IWindowManager.Stub
            MergedConfiguration mergedConfiguration, Surface outSurface) {
        int result = 0;
        boolean configChanged;
        boolean hasStatusBarPermission =
                mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
        final boolean hasStatusBarPermission =
                mContext.checkCallingOrSelfPermission(permission.STATUS_BAR)
                        == PackageManager.PERMISSION_GRANTED;
        final boolean hasStatusBarServicePermission =
                mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
                        == PackageManager.PERMISSION_GRANTED;

        long origId = Binder.clearCallingIdentity();
@@ -1867,7 +1873,7 @@ public class WindowManagerService extends IWindowManager.Stub
            int attrChanges = 0;
            int flagChanges = 0;
            if (attrs != null) {
                mPolicy.adjustWindowParamsLw(attrs);
                mPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission);
                // if they don't have the permission, mask out the status bar bits
                if (seq == win.mSeq) {
                    int systemUiVisibility = attrs.systemUiVisibility
Loading