1 /* 2 * Copyright (C) 2021 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 static android.view.Display.DEFAULT_DISPLAY; 20 import static android.view.Display.FLAG_PRESENTATION; 21 import static android.view.Surface.ROTATION_0; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.anyInt; 26 import static org.mockito.Mockito.when; 27 28 import android.graphics.Rect; 29 import android.platform.test.annotations.Presubmit; 30 import android.util.ArraySet; 31 import android.view.DisplayInfo; 32 33 import androidx.test.filters.MediumTest; 34 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 39 import java.util.ArrayList; 40 import java.util.List; 41 import java.util.Set; 42 43 44 /** 45 * Tests for {@link PossibleDisplayInfoMapper}. 46 * 47 * Build/Install/Run: 48 * atest WmTests:PossibleDisplayInfoMapperTests 49 */ 50 @MediumTest 51 @Presubmit 52 @RunWith(WindowTestRunner.class) 53 public class PossibleDisplayInfoMapperTests extends WindowTestsBase { 54 55 private PossibleDisplayInfoMapper mDisplayInfoMapper; 56 private final Set<DisplayInfo> mPossibleDisplayInfo = new ArraySet<>(); 57 private DisplayInfo mDefaultDisplayInfo; 58 private DisplayInfo mSecondDisplayInfo; 59 60 @Before setUp()61 public void setUp() throws Exception { 62 mDisplayInfoMapper = mWm.mPossibleDisplayInfoMapper; 63 final DisplayInfo baseDisplayInfo = mWm.mRoot.getDisplayContent( 64 DEFAULT_DISPLAY).getDisplayInfo(); 65 when(mWm.mDisplayManagerInternal.getPossibleDisplayInfo(anyInt())).thenReturn( 66 mPossibleDisplayInfo); 67 68 mDefaultDisplayInfo = new DisplayInfo(baseDisplayInfo); 69 initializeDisplayInfo(mDefaultDisplayInfo, DEFAULT_DISPLAY, new Rect(0, 0, 500, 800)); 70 mSecondDisplayInfo = new DisplayInfo(baseDisplayInfo); 71 // Use the same display id for any display in the same group, due to the assumption that 72 // any display in the same grouped can be swapped out for each other (while maintaining the 73 // display id). 74 initializeDisplayInfo(mSecondDisplayInfo, DEFAULT_DISPLAY, new Rect(0, 0, 600, 1600)); 75 mSecondDisplayInfo.flags |= FLAG_PRESENTATION; 76 } 77 78 @Test testInitialization_isEmpty()79 public void testInitialization_isEmpty() { 80 // Empty after initializing. 81 assertThat(mDisplayInfoMapper.getPossibleDisplayInfos(DEFAULT_DISPLAY)).isEmpty(); 82 83 // Still empty after updating. 84 mDisplayInfoMapper.updatePossibleDisplayInfos(DEFAULT_DISPLAY); 85 assertThat(mDisplayInfoMapper.getPossibleDisplayInfos(DEFAULT_DISPLAY)).isEmpty(); 86 } 87 88 @Test testUpdatePossibleDisplayInfos_singleDisplay()89 public void testUpdatePossibleDisplayInfos_singleDisplay() { 90 mPossibleDisplayInfo.add(mDefaultDisplayInfo); 91 mDisplayInfoMapper.updatePossibleDisplayInfos(DEFAULT_DISPLAY); 92 93 List<DisplayInfo> displayInfos = mDisplayInfoMapper.getPossibleDisplayInfos( 94 DEFAULT_DISPLAY); 95 // An entry for rotation 0, for a display that can be in a single state. 96 assertThat(displayInfos.size()).isEqualTo(1); 97 assertPossibleDisplayInfoEntries(displayInfos, mDefaultDisplayInfo); 98 } 99 100 @Test testUpdatePossibleDisplayInfos_secondDisplayAdded_sameGroup()101 public void testUpdatePossibleDisplayInfos_secondDisplayAdded_sameGroup() { 102 mPossibleDisplayInfo.add(mDefaultDisplayInfo); 103 mDisplayInfoMapper.updatePossibleDisplayInfos(DEFAULT_DISPLAY); 104 105 assertThat(mDisplayInfoMapper.getPossibleDisplayInfos(DEFAULT_DISPLAY).size()).isEqualTo(1); 106 107 // Add another display layout to the set of supported states. 108 mPossibleDisplayInfo.add(mSecondDisplayInfo); 109 mDisplayInfoMapper.updatePossibleDisplayInfos(DEFAULT_DISPLAY); 110 111 List<DisplayInfo> displayInfos = mDisplayInfoMapper.getPossibleDisplayInfos( 112 DEFAULT_DISPLAY); 113 List<DisplayInfo> defaultDisplayInfos = new ArrayList<>(); 114 List<DisplayInfo> secondDisplayInfos = new ArrayList<>(); 115 for (DisplayInfo di : displayInfos) { 116 if ((di.flags & FLAG_PRESENTATION) != 0) { 117 secondDisplayInfos.add(di); 118 } else { 119 defaultDisplayInfos.add(di); 120 } 121 } 122 // An entry for rotation 0, for the default display. 123 assertThat(defaultDisplayInfos).hasSize(1); 124 assertPossibleDisplayInfoEntries(defaultDisplayInfos, mDefaultDisplayInfo); 125 126 // An entry for rotation 0, for the second display. 127 assertThat(secondDisplayInfos).hasSize(1); 128 assertPossibleDisplayInfoEntries(secondDisplayInfos, mSecondDisplayInfo); 129 } 130 131 @Test testUpdatePossibleDisplayInfos_secondDisplayAdded_differentGroup()132 public void testUpdatePossibleDisplayInfos_secondDisplayAdded_differentGroup() { 133 mPossibleDisplayInfo.add(mDefaultDisplayInfo); 134 mDisplayInfoMapper.updatePossibleDisplayInfos(DEFAULT_DISPLAY); 135 136 assertThat(mDisplayInfoMapper.getPossibleDisplayInfos(DEFAULT_DISPLAY).size()).isEqualTo(1); 137 138 // Add another display to a different group. 139 mSecondDisplayInfo.displayId = DEFAULT_DISPLAY + 1; 140 mSecondDisplayInfo.displayGroupId = mDefaultDisplayInfo.displayGroupId + 1; 141 mPossibleDisplayInfo.add(mSecondDisplayInfo); 142 mDisplayInfoMapper.updatePossibleDisplayInfos(mSecondDisplayInfo.displayId); 143 144 List<DisplayInfo> displayInfos = mDisplayInfoMapper.getPossibleDisplayInfos( 145 DEFAULT_DISPLAY); 146 // An entry for rotation 0, for the default display. 147 assertThat(displayInfos).hasSize(1); 148 assertPossibleDisplayInfoEntries(displayInfos, mDefaultDisplayInfo); 149 150 List<DisplayInfo> secondStateEntries = 151 mDisplayInfoMapper.getPossibleDisplayInfos(mSecondDisplayInfo.displayId); 152 // An entry for rotation 0, for the second display. 153 assertThat(secondStateEntries).hasSize(1); 154 assertPossibleDisplayInfoEntries(secondStateEntries, mSecondDisplayInfo); 155 } 156 initializeDisplayInfo(DisplayInfo outDisplayInfo, int displayId, Rect logicalBounds)157 private static void initializeDisplayInfo(DisplayInfo outDisplayInfo, int displayId, 158 Rect logicalBounds) { 159 outDisplayInfo.displayId = displayId; 160 outDisplayInfo.rotation = ROTATION_0; 161 outDisplayInfo.logicalWidth = logicalBounds.width(); 162 outDisplayInfo.logicalHeight = logicalBounds.height(); 163 } 164 assertPossibleDisplayInfoEntries(List<DisplayInfo> displayInfos, DisplayInfo expectedDisplayInfo)165 private static void assertPossibleDisplayInfoEntries(List<DisplayInfo> displayInfos, 166 DisplayInfo expectedDisplayInfo) { 167 for (DisplayInfo displayInfo : displayInfos) { 168 assertThat(displayInfo.displayId).isEqualTo(expectedDisplayInfo.displayId); 169 assertThat(displayInfo.logicalWidth).isEqualTo(expectedDisplayInfo.logicalWidth); 170 assertThat(displayInfo.logicalHeight).isEqualTo(expectedDisplayInfo.logicalHeight); 171 } 172 } 173 } 174