Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.server.wm;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.Context;
     21 import android.content.res.Configuration;
     22 import android.graphics.Rect;
     23 import android.os.Binder;
     24 import android.os.IBinder;
     25 import android.view.IApplicationToken;
     26 import android.view.IWindow;
     27 import android.view.WindowManager;
     28 
     29 import static android.app.AppOpsManager.OP_NONE;
     30 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
     31 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     32 import static android.content.res.Configuration.EMPTY;
     33 import static com.android.server.wm.WindowContainer.POSITION_TOP;
     34 import static org.mockito.Mockito.mock;
     35 
     36 /**
     37  * A collection of static functions that can be referenced by other test packages to provide access
     38  * to WindowManager related test functionality.
     39  */
     40 public class WindowTestUtils {
     41     public static int sNextTaskId = 0;
     42 
     43     /**
     44      * Retrieves an instance of {@link WindowManagerService}, creating it if necessary.
     45      */
     46     public static WindowManagerService getWindowManagerService(Context context) {
     47         return TestWindowManagerPolicy.getWindowManagerService(context);
     48     }
     49 
     50     /**
     51      * Retrieves an instance of a mock {@link WindowManagerService}.
     52      */
     53     public static WindowManagerService getMockWindowManagerService() {
     54         return mock(WindowManagerService.class);
     55     }
     56 
     57     /**
     58      * Creates a mock instance of {@link StackWindowController}.
     59      */
     60     public static StackWindowController createMockStackWindowContainerController() {
     61         StackWindowController controller = mock(StackWindowController.class);
     62         controller.mContainer = mock(TestTaskStack.class);
     63         return controller;
     64     }
     65 
     66     /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
     67     public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
     68             int userId) {
     69         final Task newTask = new Task(sNextTaskId++, stack, userId, service, null, EMPTY, 0, false,
     70                 false, new ActivityManager.TaskDescription(), null);
     71         stack.addTask(newTask, POSITION_TOP);
     72         return newTask;
     73     }
     74 
     75     /**
     76      * An extension of {@link TestTaskStack}, which overrides package scoped methods that would not
     77      * normally be mocked out.
     78      */
     79     public static class TestTaskStack extends TaskStack {
     80         TestTaskStack(WindowManagerService service, int stackId) {
     81             super(service, stackId);
     82         }
     83 
     84         @Override
     85         void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
     86             // Do nothing.
     87         }
     88     }
     89 
     90     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
     91     public static class TestAppWindowToken extends AppWindowToken {
     92 
     93         TestAppWindowToken(DisplayContent dc) {
     94             super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */,
     95                     null /* overrideConfig */, null /* bounds */);
     96         }
     97 
     98         TestAppWindowToken(WindowManagerService service, IApplicationToken token,
     99                 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
    100                 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
    101                 int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
    102                 boolean alwaysFocusable, AppWindowContainerController controller,
    103                 Configuration overrideConfig, Rect bounds) {
    104             super(service, token, voiceInteraction, dc, inputDispatchingTimeoutNanos, fullscreen,
    105                     showForAllUsers, targetSdk, orientation, rotationAnimationHint, configChanges,
    106                     launchTaskBehind, alwaysFocusable, controller, overrideConfig, bounds);
    107         }
    108 
    109         int getWindowsCount() {
    110             return mChildren.size();
    111         }
    112 
    113         boolean hasWindow(WindowState w) {
    114             return mChildren.contains(w);
    115         }
    116 
    117         WindowState getFirstChild() {
    118             return mChildren.peekFirst();
    119         }
    120 
    121         WindowState getLastChild() {
    122             return mChildren.peekLast();
    123         }
    124 
    125         int positionInParent() {
    126             return getParent().mChildren.indexOf(this);
    127         }
    128     }
    129 
    130     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
    131     public static class TestWindowToken extends WindowToken {
    132         int adj = 0;
    133 
    134         TestWindowToken(int type, DisplayContent dc) {
    135             this(type, dc, false /* persistOnEmpty */);
    136         }
    137 
    138         TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
    139             super(dc.mService, mock(IBinder.class), type, persistOnEmpty, dc,
    140                     false /* ownerCanManageAppTokens */);
    141         }
    142 
    143         int getWindowsCount() {
    144             return mChildren.size();
    145         }
    146 
    147         boolean hasWindow(WindowState w) {
    148             return mChildren.contains(w);
    149         }
    150 
    151         @Override
    152         int getAnimLayerAdjustment() {
    153             return adj;
    154         }
    155     }
    156 
    157     /* Used so we can gain access to some protected members of the {@link Task} class */
    158     public static class TestTask extends Task {
    159         boolean mShouldDeferRemoval = false;
    160         boolean mOnDisplayChangedCalled = false;
    161         private boolean mUseLocalIsAnimating = false;
    162         private boolean mIsAnimating = false;
    163 
    164         TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
    165                 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
    166                 boolean homeTask, TaskWindowContainerController controller) {
    167             super(taskId, stack, userId, service, bounds, overrideConfig, resizeMode,
    168                     supportsPictureInPicture, homeTask, new ActivityManager.TaskDescription(),
    169                     controller);
    170         }
    171 
    172         boolean shouldDeferRemoval() {
    173             return mShouldDeferRemoval;
    174         }
    175 
    176         int positionInParent() {
    177             return getParent().mChildren.indexOf(this);
    178         }
    179 
    180         @Override
    181         void onDisplayChanged(DisplayContent dc) {
    182             super.onDisplayChanged(dc);
    183             mOnDisplayChangedCalled = true;
    184         }
    185 
    186         @Override
    187         boolean isAnimating() {
    188             return mUseLocalIsAnimating ? mIsAnimating : super.isAnimating();
    189         }
    190 
    191         void setLocalIsAnimating(boolean isAnimating) {
    192             mUseLocalIsAnimating = true;
    193             mIsAnimating = isAnimating;
    194         }
    195     }
    196 
    197     /**
    198      * Used so we can gain access to some protected members of {@link TaskWindowContainerController}
    199      * class.
    200      */
    201     public static class TestTaskWindowContainerController extends TaskWindowContainerController {
    202 
    203         TestTaskWindowContainerController(WindowTestsBase testsBase) {
    204             this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
    205         }
    206 
    207         TestTaskWindowContainerController(StackWindowController stackController) {
    208             super(sNextTaskId++, new TaskWindowContainerListener() {
    209                         @Override
    210                         public void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
    211 
    212                         }
    213 
    214                         @Override
    215                         public void requestResize(Rect bounds, int resizeMode) {
    216 
    217                         }
    218                     }, stackController, 0 /* userId */, null /* bounds */,
    219                     EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE,
    220                     false /* supportsPictureInPicture */, false /* homeTask*/, true /* toTop*/,
    221                     true /* showForAllUsers */, new ActivityManager.TaskDescription(),
    222                     stackController.mService);
    223         }
    224 
    225         @Override
    226         TestTask createTask(int taskId, TaskStack stack, int userId, Rect bounds,
    227                 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
    228                 boolean homeTask, ActivityManager.TaskDescription taskDescription) {
    229             return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
    230                     supportsPictureInPicture, homeTask, this);
    231         }
    232     }
    233 
    234     public static class TestAppWindowContainerController extends AppWindowContainerController {
    235 
    236         final IApplicationToken mToken;
    237 
    238         TestAppWindowContainerController(TestTaskWindowContainerController taskController) {
    239             this(taskController, new TestIApplicationToken());
    240         }
    241 
    242         TestAppWindowContainerController(TestTaskWindowContainerController taskController,
    243                 IApplicationToken token) {
    244             super(taskController, token, null /* listener */, 0 /* index */,
    245                     SCREEN_ORIENTATION_UNSPECIFIED, true /* fullscreen */,
    246                     true /* showForAllUsers */, 0 /* configChanges */, false /* voiceInteraction */,
    247                     false /* launchTaskBehind */, false /* alwaysFocusable */,
    248                     0 /* targetSdkVersion */, 0 /* rotationAnimationHint */,
    249                     0 /* inputDispatchingTimeoutNanos */, taskController.mService,
    250                     null /* overrideConfig */, null /* bounds */);
    251             mToken = token;
    252         }
    253 
    254         @Override
    255         AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
    256                 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
    257                 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
    258                 int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
    259                 boolean alwaysFocusable, AppWindowContainerController controller,
    260                 Configuration overrideConfig, Rect bounds) {
    261             return new TestAppWindowToken(service, token, voiceInteraction, dc,
    262                     inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
    263                     orientation,
    264                     rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
    265                     controller, overrideConfig, bounds);
    266         }
    267 
    268         AppWindowToken getAppWindowToken(DisplayContent dc) {
    269             return (AppWindowToken) dc.getWindowToken(mToken.asBinder());
    270         }
    271     }
    272 
    273     public static class TestIApplicationToken implements IApplicationToken {
    274 
    275         private final Binder mBinder = new Binder();
    276         @Override
    277         public IBinder asBinder() {
    278             return mBinder;
    279         }
    280     }
    281 
    282     /** Used to track resize reports. */
    283     public static class TestWindowState extends WindowState {
    284         boolean resizeReported;
    285 
    286         TestWindowState(WindowManagerService service, Session session, IWindow window,
    287                 WindowManager.LayoutParams attrs, WindowToken token) {
    288             super(service, session, window, token, null, OP_NONE, 0, attrs, 0, 0,
    289                     false /* ownerCanAddInternalSystemWindow */);
    290         }
    291 
    292         @Override
    293         void reportResized() {
    294             super.reportResized();
    295             resizeReported = true;
    296         }
    297 
    298         @Override
    299         public boolean isGoneForLayoutLw() {
    300             return false;
    301         }
    302 
    303         @Override
    304         void updateResizingWindowIfNeeded() {
    305             // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive
    306             // the system that it can actually update the window.
    307             boolean hadSurface = mHasSurface;
    308             mHasSurface = true;
    309 
    310             super.updateResizingWindowIfNeeded();
    311 
    312             mHasSurface = hadSurface;
    313         }
    314     }
    315 }
    316