Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2016 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.util.MergedConfiguration;
     20 import android.view.WindowManager;
     21 import org.junit.Test;
     22 import org.junit.runner.RunWith;
     23 
     24 import android.platform.test.annotations.Presubmit;
     25 import android.support.test.filters.SmallTest;
     26 import android.support.test.runner.AndroidJUnit4;
     27 
     28 import java.util.LinkedList;
     29 
     30 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
     31 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
     32 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
     33 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
     34 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
     35 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
     36 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
     37 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
     38 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
     39 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
     40 import static org.junit.Assert.assertEquals;
     41 import static org.junit.Assert.assertFalse;
     42 import static org.junit.Assert.assertNull;
     43 import static org.junit.Assert.assertTrue;
     44 
     45 /**
     46  * Tests for the {@link WindowState} class.
     47  *
     48  * Build/Install/Run:
     49  *  bit FrameworksServicesTests:com.android.server.wm.WindowStateTests
     50  */
     51 @SmallTest
     52 @Presubmit
     53 @RunWith(AndroidJUnit4.class)
     54 public class WindowStateTests extends WindowTestsBase {
     55 
     56     @Test
     57     public void testIsParentWindowHidden() throws Exception {
     58         final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
     59         final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
     60         final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
     61 
     62         assertFalse(parentWindow.mHidden);
     63         assertFalse(parentWindow.isParentWindowHidden());
     64         assertFalse(child1.isParentWindowHidden());
     65         assertFalse(child2.isParentWindowHidden());
     66 
     67         parentWindow.mHidden = true;
     68         assertFalse(parentWindow.isParentWindowHidden());
     69         assertTrue(child1.isParentWindowHidden());
     70         assertTrue(child2.isParentWindowHidden());
     71     }
     72 
     73     @Test
     74     public void testIsChildWindow() throws Exception {
     75         final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
     76         final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
     77         final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
     78         final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
     79 
     80         assertFalse(parentWindow.isChildWindow());
     81         assertTrue(child1.isChildWindow());
     82         assertTrue(child2.isChildWindow());
     83         assertFalse(randomWindow.isChildWindow());
     84     }
     85 
     86     @Test
     87     public void testHasChild() throws Exception {
     88         final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1");
     89         final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11");
     90         final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12");
     91         final WindowState win2 = createWindow(null, TYPE_APPLICATION, "win2");
     92         final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, "win21");
     93         final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
     94 
     95         assertTrue(win1.hasChild(win11));
     96         assertTrue(win1.hasChild(win12));
     97         assertTrue(win2.hasChild(win21));
     98 
     99         assertFalse(win1.hasChild(win21));
    100         assertFalse(win1.hasChild(randomWindow));
    101 
    102         assertFalse(win2.hasChild(win11));
    103         assertFalse(win2.hasChild(win12));
    104         assertFalse(win2.hasChild(randomWindow));
    105     }
    106 
    107     @Test
    108     public void testGetParentWindow() throws Exception {
    109         final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
    110         final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
    111         final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
    112 
    113         assertNull(parentWindow.getParentWindow());
    114         assertEquals(parentWindow, child1.getParentWindow());
    115         assertEquals(parentWindow, child2.getParentWindow());
    116     }
    117 
    118     @Test
    119     public void testGetTopParentWindow() throws Exception {
    120         final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
    121         final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
    122         final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
    123 
    124         assertEquals(root, root.getTopParentWindow());
    125         assertEquals(root, child1.getTopParentWindow());
    126         assertEquals(child1, child2.getParentWindow());
    127         assertEquals(root, child2.getTopParentWindow());
    128 
    129         // Test case were child is detached from parent.
    130         root.removeChild(child1);
    131         assertEquals(child1, child1.getTopParentWindow());
    132         assertEquals(child1, child2.getParentWindow());
    133     }
    134 
    135     @Test
    136     public void testIsOnScreen_hiddenByPolicy() {
    137         final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
    138         window.setHasSurface(true);
    139         assertTrue(window.isOnScreen());
    140         window.hideLw(false /* doAnimation */);
    141         assertFalse(window.isOnScreen());
    142     }
    143 
    144     @Test
    145     public void testCanBeImeTarget() throws Exception {
    146         final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
    147         final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
    148 
    149         // Setting FLAG_NOT_FOCUSABLE without FLAG_ALT_FOCUSABLE_IM prevents the window from being
    150         // an IME target.
    151         appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
    152         imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
    153 
    154         // Make windows visible
    155         appWindow.setHasSurface(true);
    156         imeWindow.setHasSurface(true);
    157 
    158         // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets
    159         assertFalse(appWindow.canBeImeTarget());
    160         assertFalse(imeWindow.canBeImeTarget());
    161 
    162         // Add IME target flags
    163         appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
    164         imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
    165 
    166         // Visible app window with flags can be IME target while an IME window can never be an IME
    167         // target regardless of its visibility or flags.
    168         assertTrue(appWindow.canBeImeTarget());
    169         assertFalse(imeWindow.canBeImeTarget());
    170 
    171         // Make windows invisible
    172         appWindow.hideLw(false /* doAnimation */);
    173         imeWindow.hideLw(false /* doAnimation */);
    174 
    175         // Invisible window can't be IME targets even if they have the right flags.
    176         assertFalse(appWindow.canBeImeTarget());
    177         assertFalse(imeWindow.canBeImeTarget());
    178     }
    179 
    180     @Test
    181     public void testGetWindow() throws Exception {
    182         final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
    183         final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild");
    184         final WindowState mediaOverlayChild = createWindow(root,
    185                 TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild");
    186         final WindowState attachedDialogChild = createWindow(root,
    187                 TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild");
    188         final WindowState subPanelChild = createWindow(root,
    189                 TYPE_APPLICATION_SUB_PANEL, "subPanelChild");
    190         final WindowState aboveSubPanelChild = createWindow(root,
    191                 TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild");
    192 
    193         final LinkedList<WindowState> windows = new LinkedList();
    194 
    195         root.getWindow(w -> {
    196             windows.addLast(w);
    197             return false;
    198         });
    199 
    200         // getWindow should have returned candidate windows in z-order.
    201         assertEquals(aboveSubPanelChild, windows.pollFirst());
    202         assertEquals(subPanelChild, windows.pollFirst());
    203         assertEquals(attachedDialogChild, windows.pollFirst());
    204         assertEquals(root, windows.pollFirst());
    205         assertEquals(mediaOverlayChild, windows.pollFirst());
    206         assertEquals(mediaChild, windows.pollFirst());
    207         assertTrue(windows.isEmpty());
    208     }
    209 
    210     @Test
    211     public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
    212         testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
    213         testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
    214     }
    215 
    216     private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
    217         final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
    218         root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
    219         root.mTurnOnScreen = false;
    220 
    221         root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
    222         assertTrue(root.mTurnOnScreen);
    223     }
    224 }
    225