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

Commit 17f19e44 authored by Rob Carr's avatar Rob Carr Committed by Android (Google) Code Review
Browse files

Merge "WindowManager: Emit windows from forAllWindows closer to Z-order" into pi-dev

parents e22a7bc9 9785cf30
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -1510,6 +1510,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        return (stack != null && stack.isVisible()) ? stack : null;
    }

    boolean hasSplitScreenPrimaryStack() {
        return getSplitScreenPrimaryStack() != null;
    }

    /**
     * Like {@link #getSplitScreenPrimaryStack}, but also returns the stack if it's currently
     * not visible.
@@ -1613,6 +1617,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        mService.mWindowsChanged = true;
    }

    /**
     * In split-screen mode we process the IME containers above the docked divider
     * rather than directly above their target.
     */
    private boolean skipTraverseChild(WindowContainer child) {
        if (child == mImeWindowsContainers && mService.mInputMethodTarget != null
                && !hasSplitScreenPrimaryStack()) {
            return true;
        }
        return false;
    }

    @Override
    boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
        // Special handling so we can process IME windows with #forAllImeWindows above their IME
@@ -1620,11 +1636,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (traverseTopToBottom) {
            for (int i = mChildren.size() - 1; i >= 0; --i) {
                final DisplayChildWindowContainer child = mChildren.get(i);
                if (child == mImeWindowsContainers && mService.mInputMethodTarget != null) {
                    // In this case the Ime windows will be processed above their target so we skip
                    // here.
                if (skipTraverseChild(child)) {
                    continue;
                }

                if (child.forAllWindows(callback, traverseTopToBottom)) {
                    return true;
                }
@@ -1633,11 +1648,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            final int count = mChildren.size();
            for (int i = 0; i < count; i++) {
                final DisplayChildWindowContainer child = mChildren.get(i);
                if (child == mImeWindowsContainers && mService.mInputMethodTarget != null) {
                    // In this case the Ime windows will be processed above their target so we skip
                    // here.
                if (skipTraverseChild(child)) {
                    continue;
                }

                if (child.forAllWindows(callback, traverseTopToBottom)) {
                    return true;
                }
+18 −17
Original line number Diff line number Diff line
@@ -3997,32 +3997,33 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return false;
    }

    private boolean applyInOrderWithImeWindows(ToBooleanFunction<WindowState> callback,
    private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
            boolean traverseTopToBottom) {
        if (traverseTopToBottom) {
            if (isInputMethodTarget()) {
                // This window is the current IME target, so we need to process the IME windows
                // directly above it.
        // If this window is the current IME target, so we need to process the IME windows
        // directly above it. The exception is if we are in split screen
        // in which case we process the IME at the DisplayContent level to
        // ensure it is above the docked divider.
        if (isInputMethodTarget() && !inSplitScreenWindowingMode()) {
            if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
                return true;
            }
        }
            if (callback.apply(this)) {
                return true;
        return false;
    }
        } else {
            if (callback.apply(this)) {

    private boolean applyInOrderWithImeWindows(ToBooleanFunction<WindowState> callback,
            boolean traverseTopToBottom) {
        if (traverseTopToBottom) {
            if (applyImeWindowsIfNeeded(callback, traverseTopToBottom)
                    || callback.apply(this)) {
                return true;
            }
            if (isInputMethodTarget()) {
                // This window is the current IME target, so we need to process the IME windows
                // directly above it.
                if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
        } else {
            if (callback.apply(this)
                    || applyImeWindowsIfNeeded(callback, traverseTopToBottom)) {
                return true;
            }
        }
        }

        return false;
    }

+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Matchers.eq;

import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.mockito.Mock;

import java.util.function.Consumer;

/**
 * Tests for {@link WindowContainer#forAllWindows} and various implementations.
 */
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class WindowContainerTraversalTests extends WindowTestsBase {

    @Test
    public void testDockedDividerPosition() throws Exception {
        final WindowState splitScreenWindow = createWindowOnStack(null,
                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
                mDisplayContent, "splitScreenWindow");
        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
                TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");

        sWm.mInputMethodTarget = splitScreenWindow;

        Consumer<WindowState> c = mock(Consumer.class);
        mDisplayContent.forAllWindows(c, false);

        verify(c).accept(eq(mDockedDividerWindow));
        verify(c).accept(eq(mImeWindow));
    }
}