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

Commit bf0d57b9 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Move WindowManager tests to WmTests

Bug: 113800711
Test: All presubmit and non-flaky tests in WmTests pass
$ tradefed.sh run commandAndExit WmTests \
        --include-annotation android.platform.test.annotations.Presubmit \
        --exclude-annotation androidx.test.filters.FlakyTest
Change-Id: I593eb03c8ee3c297eae85e39434d04138a67ab15
parent 11cf88e2
Loading
Loading
Loading
Loading
+0 −9
Original line number Original line Diff line number Diff line
@@ -143,9 +143,6 @@
        <activity android:name="com.android.server.pm.BaseShortcutManagerTest$ShortcutActivity2" />
        <activity android:name="com.android.server.pm.BaseShortcutManagerTest$ShortcutActivity2" />
        <activity android:name="com.android.server.pm.BaseShortcutManagerTest$ShortcutActivity3" />
        <activity android:name="com.android.server.pm.BaseShortcutManagerTest$ShortcutActivity3" />


        <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity"
                  android:showWhenLocked="true"/>

        <activity android:name="com.android.server.pm.ShortcutTestActivity"
        <activity android:name="com.android.server.pm.ShortcutTestActivity"
                 android:enabled="true" android:exported="true" />
                 android:enabled="true" android:exported="true" />


@@ -206,12 +203,6 @@
            </intent-filter>
            </intent-filter>
        </activity-alias>
        </activity-alias>


        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityA" />
        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityB" />
        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" />
        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" />
        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" />

        <receiver android:name="com.android.server.appwidget.DummyAppWidget">
        <receiver android:name="com.android.server.appwidget.DummyAppWidget">
            <intent-filter>
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+0 −322
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2017 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.AppOpsManager.OP_NONE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;

import static com.android.server.wm.WindowContainer.POSITION_TOP;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyFloat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.view.IApplicationToken;
import android.view.IWindow;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;

import org.mockito.invocation.InvocationOnMock;

/**
 * A collection of static functions that can be referenced by other test packages to provide access
 * to WindowManager related test functionality.
 */
public class WindowTestUtils {
    private static int sNextTaskId = 0;

    /**
     * Creates a mock instance of {@link StackWindowController}.
     */
    public static StackWindowController createMockStackWindowContainerController() {
        StackWindowController controller = mock(StackWindowController.class);
        controller.mContainer = mock(TestTaskStack.class);

        // many components rely on the {@link StackWindowController#adjustConfigurationForBounds}
        // to properly set bounds values in the configuration. We must mimick those actions here.
        doAnswer((InvocationOnMock invocationOnMock) -> {
            final Configuration config = invocationOnMock.<Configuration>getArgument(7);
            final Rect bounds = invocationOnMock.<Rect>getArgument(0);
            config.windowConfiguration.setBounds(bounds);
            return null;
        }).when(controller).adjustConfigurationForBounds(any(), any(), any(), any(),
                anyBoolean(), anyBoolean(), anyFloat(), any(), any(), anyInt());

        return controller;
    }

    /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
    public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
            int userId) {
        synchronized (service.mGlobalLock) {
            final Task newTask = new Task(sNextTaskId++, stack, userId, service, 0, false,
                    new ActivityManager.TaskDescription(), null);
            stack.addTask(newTask, POSITION_TOP);
            return newTask;
        }
    }

    /**
     * An extension of {@link TestTaskStack}, which overrides package scoped methods that would not
     * normally be mocked out.
     */
    public static class TestTaskStack extends TaskStack {
        TestTaskStack(WindowManagerService service, int stackId) {
            super(service, stackId, null);
        }

        @Override
        void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
            // Do nothing.
        }
    }

    static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
        synchronized (dc.mService.mGlobalLock) {
            return new TestAppWindowToken(dc);
        }
    }

    /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
    public static class TestAppWindowToken extends AppWindowToken {
        boolean mOnTop = false;
        private Transaction mPendingTransactionOverride;

        private TestAppWindowToken(DisplayContent dc) {
            super(dc.mService, new IApplicationToken.Stub() {
                public String getName() {return null;}
                }, new ComponentName("", ""), false, dc, true /* fillsParent */);
        }

        TestAppWindowToken(WindowManagerService service, IApplicationToken token,
                ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
                long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
                int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
                boolean launchTaskBehind, boolean alwaysFocusable, ActivityRecord activityRecord) {
            super(service, token, activityComponent, voiceInteraction, dc,
                    inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
                    orientation, rotationAnimationHint, configChanges, launchTaskBehind,
                    alwaysFocusable, activityRecord);
        }

        int getWindowsCount() {
            return mChildren.size();
        }

        boolean hasWindow(WindowState w) {
            return mChildren.contains(w);
        }

        WindowState getFirstChild() {
            return mChildren.peekFirst();
        }

        WindowState getLastChild() {
            return mChildren.peekLast();
        }

        int positionInParent() {
            return getParent().mChildren.indexOf(this);
        }

        void setIsOnTop(boolean onTop) {
            mOnTop = onTop;
        }

        @Override
        boolean isOnTop() {
            return mOnTop;
        }

        void setPendingTransaction(Transaction transaction) {
            mPendingTransactionOverride = transaction;
        }

        @Override
        public Transaction getPendingTransaction() {
            return mPendingTransactionOverride == null
                    ? super.getPendingTransaction()
                    : mPendingTransactionOverride;
        }
    }

    static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
        return createTestWindowToken(type, dc, false /* persistOnEmpty */);
    }

    static TestWindowToken createTestWindowToken(int type, DisplayContent dc,
            boolean persistOnEmpty) {
        synchronized (dc.mService.mGlobalLock) {
            return new TestWindowToken(type, dc, persistOnEmpty);
        }
    }

    /* Used so we can gain access to some protected members of the {@link WindowToken} class */
    public static class TestWindowToken extends WindowToken {

        private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
            super(dc.mService, mock(IBinder.class), type, persistOnEmpty, dc,
                    false /* ownerCanManageAppTokens */);
        }

        int getWindowsCount() {
            return mChildren.size();
        }

        boolean hasWindow(WindowState w) {
            return mChildren.contains(w);
        }
    }

    /* Used so we can gain access to some protected members of the {@link Task} class */
    public static class TestTask extends Task {
        boolean mShouldDeferRemoval = false;
        boolean mOnDisplayChangedCalled = false;
        private boolean mIsAnimating = false;

        TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service,
                int resizeMode, boolean supportsPictureInPicture,
                TaskWindowContainerController controller) {
            super(taskId, stack, userId, service, resizeMode, supportsPictureInPicture,
                    new ActivityManager.TaskDescription(), controller);
        }

        boolean shouldDeferRemoval() {
            return mShouldDeferRemoval;
        }

        int positionInParent() {
            return getParent().mChildren.indexOf(this);
        }

        @Override
        void onDisplayChanged(DisplayContent dc) {
            super.onDisplayChanged(dc);
            mOnDisplayChangedCalled = true;
        }

        @Override
        boolean isSelfAnimating() {
            return mIsAnimating;
        }

        void setLocalIsAnimating(boolean isAnimating) {
            mIsAnimating = isAnimating;
        }
    }

    /**
     * Used so we can gain access to some protected members of {@link TaskWindowContainerController}
     * class.
     */
    public static class TestTaskWindowContainerController extends TaskWindowContainerController {

        static final TaskWindowContainerListener NOP_LISTENER = new TaskWindowContainerListener() {
            @Override
            public void registerConfigurationChangeListener(
                    ConfigurationContainerListener listener) {
            }

            @Override
            public void unregisterConfigurationChangeListener(
                    ConfigurationContainerListener listener) {
            }

            @Override
            public void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
            }

            @Override
            public void requestResize(Rect bounds, int resizeMode) {
            }
        };

        TestTaskWindowContainerController(WindowTestsBase testsBase) {
            this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
        }

        TestTaskWindowContainerController(StackWindowController stackController) {
            super(sNextTaskId++, NOP_LISTENER, stackController, 0 /* userId */, null /* bounds */,
                    RESIZE_MODE_UNRESIZEABLE, false /* supportsPictureInPicture */, true /* toTop*/,
                    true /* showForAllUsers */, new ActivityManager.TaskDescription(),
                    stackController.mService);
        }

        @Override
        TestTask createTask(int taskId, TaskStack stack, int userId, int resizeMode,
                boolean supportsPictureInPicture, ActivityManager.TaskDescription taskDescription) {
            return new TestTask(taskId, stack, userId, mService, resizeMode,
                    supportsPictureInPicture, this);
        }
    }

    public static class TestIApplicationToken implements IApplicationToken {

        private final Binder mBinder = new Binder();
        @Override
        public IBinder asBinder() {
            return mBinder;
        }
        @Override
        public String getName() {
            return null;
        }
    }

    /** Used to track resize reports. */
    public static class TestWindowState extends WindowState {
        boolean resizeReported;

        TestWindowState(WindowManagerService service, Session session, IWindow window,
                WindowManager.LayoutParams attrs, WindowToken token) {
            super(service, session, window, token, null, OP_NONE, 0, attrs, 0, 0,
                    false /* ownerCanAddInternalSystemWindow */);
        }

        @Override
        void reportResized() {
            super.reportResized();
            resizeReported = true;
        }

        @Override
        public boolean isGoneForLayoutLw() {
            return false;
        }

        @Override
        void updateResizingWindowIfNeeded() {
            // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive
            // the system that it can actually update the window.
            boolean hadSurface = mHasSurface;
            mHasSurface = true;

            super.updateResizingWindowIfNeeded();

            mHasSurface = hadSurface;
        }
    }
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -34,6 +34,8 @@
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
    <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
    <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />


    <application android:debuggable="true"
    <application android:debuggable="true"
                 android:testOnly="true">
                 android:testOnly="true">
+3 −3
Original line number Original line Diff line number Diff line
@@ -19,12 +19,12 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;


import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.assertTrue;


import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.Presubmit;


import androidx.test.filters.FlakyTest;
import androidx.test.filters.FlakyTest;
Loading