1 /* 2 * Copyright (C) 2024 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 package com.android.wallpaper.util 17 18 import android.content.Context 19 import android.content.res.Configuration 20 import android.graphics.Point 21 import com.android.wallpaper.module.InjectorProvider 22 import com.android.wallpaper.testing.FakeDisplaysProvider 23 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.FOLDABLE_FOLDED 24 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.FOLDABLE_UNFOLDED_LAND 25 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.FOLDABLE_UNFOLDED_PORT 26 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.HANDHELD 27 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.TABLET_LAND 28 import com.android.wallpaper.testing.FakeDisplaysProvider.Companion.TABLET_PORT 29 import com.android.wallpaper.testing.TestInjector 30 import com.google.common.truth.Truth.assertThat 31 import dagger.hilt.android.qualifiers.ApplicationContext 32 import dagger.hilt.android.testing.HiltAndroidRule 33 import dagger.hilt.android.testing.HiltAndroidTest 34 import javax.inject.Inject 35 import org.junit.Before 36 import org.junit.Rule 37 import org.junit.Test 38 import org.junit.runner.RunWith 39 import org.robolectric.RobolectricTestRunner 40 import org.robolectric.annotation.Config 41 import org.robolectric.shadows.ShadowDisplayManager 42 43 @HiltAndroidTest 44 @RunWith(RobolectricTestRunner::class) 45 @Config(shadows = [ShadowDisplayManager::class]) 46 class DisplayUtilsTest { 47 @get:Rule var hiltRule = HiltAndroidRule(this) 48 49 @Inject @ApplicationContext lateinit var appContext: Context 50 @Inject lateinit var displaysProvider: FakeDisplaysProvider 51 @Inject lateinit var displayUtils: DisplayUtils 52 @Inject lateinit var testInjector: TestInjector 53 54 @Before setUpnull55 fun setUp() { 56 hiltRule.inject() 57 InjectorProvider.setInjector(testInjector) 58 } 59 60 @Test hasMultiInternalDisplays_oneDisplay_returnsFalsenull61 fun hasMultiInternalDisplays_oneDisplay_returnsFalse() { 62 val displays = listOf(HANDHELD) 63 displaysProvider.setDisplays(displays) 64 65 assertThat(displayUtils.hasMultiInternalDisplays()).isFalse() 66 } 67 68 @Test hasMultiInternalDisplays_twoDisplays_returnsTruenull69 fun hasMultiInternalDisplays_twoDisplays_returnsTrue() { 70 val displays = listOf(FOLDABLE_FOLDED, FOLDABLE_UNFOLDED_LAND) 71 displaysProvider.setDisplays(displays) 72 73 assertThat(displayUtils.hasMultiInternalDisplays()).isTrue() 74 } 75 76 @Test getWallpaperDisplay_oneDisplay_returnsDefaultDisplaynull77 fun getWallpaperDisplay_oneDisplay_returnsDefaultDisplay() { 78 val displays = listOf(HANDHELD) 79 displaysProvider.setDisplays(displays) 80 81 assertThat(displayUtils.getWallpaperDisplay()) 82 .isEqualTo(displaysProvider.getInternalDisplays()[0]) 83 } 84 85 @Test getWallpaperDisplay_twoDisplays_returnsLargestDisplaynull86 fun getWallpaperDisplay_twoDisplays_returnsLargestDisplay() { 87 val displays = listOf(FOLDABLE_FOLDED, FOLDABLE_UNFOLDED_LAND) 88 displaysProvider.setDisplays(displays) 89 90 assertThat(displayUtils.getWallpaperDisplay()) 91 .isEqualTo(displaysProvider.getInternalDisplays()[1]) 92 } 93 94 @Test isUnfoldedHorizontalHinge_handheld_returnsFalsenull95 fun isUnfoldedHorizontalHinge_handheld_returnsFalse() { 96 val displays = listOf(HANDHELD) 97 displaysProvider.setDisplays(displays) 98 val displayContext = 99 appContext.createDisplayContext(displaysProvider.getInternalDisplays()[0]) 100 101 assertThat(displayUtils.isUnfoldedHorizontalHinge(displayContext)).isFalse() 102 } 103 104 @Test isUnfoldedHorizontalHinge_foldableFolded_returnsFalsenull105 fun isUnfoldedHorizontalHinge_foldableFolded_returnsFalse() { 106 val displays = listOf(FOLDABLE_FOLDED, FOLDABLE_UNFOLDED_PORT) 107 displaysProvider.setDisplays(displays) 108 val displayContext = 109 appContext.createDisplayContext(displaysProvider.getInternalDisplays()[0]) 110 111 assertThat(displayUtils.isUnfoldedHorizontalHinge(displayContext)).isFalse() 112 } 113 114 @Test isUnfoldedHorizontalHinge_foldableUnfoldedLandscape_returnsFalsenull115 fun isUnfoldedHorizontalHinge_foldableUnfoldedLandscape_returnsFalse() { 116 val displays = listOf(FOLDABLE_UNFOLDED_LAND, FOLDABLE_FOLDED) 117 displaysProvider.setDisplays(displays) 118 val displayContext = 119 appContext.createDisplayContext(displaysProvider.getInternalDisplays()[0]) 120 121 assertThat(displayUtils.isUnfoldedHorizontalHinge(displayContext)).isFalse() 122 } 123 124 @Test isUnfoldedHorizontalHinge_foldableUnfoldedPortrait_returnsTruenull125 fun isUnfoldedHorizontalHinge_foldableUnfoldedPortrait_returnsTrue() { 126 val displays = listOf(FOLDABLE_UNFOLDED_PORT, FOLDABLE_FOLDED) 127 displaysProvider.setDisplays(displays) 128 val displayContext = 129 appContext.createDisplayContext(displaysProvider.getInternalDisplays()[0]) 130 131 assertThat(displayUtils.isUnfoldedHorizontalHinge(displayContext)).isTrue() 132 } 133 134 @Test isUnfoldedHorizontalHinge_tabletPortrait_returnsFalsenull135 fun isUnfoldedHorizontalHinge_tabletPortrait_returnsFalse() { 136 val displays = listOf(TABLET_PORT) 137 displaysProvider.setDisplays(displays) 138 val displayContext = 139 appContext.createDisplayContext(displaysProvider.getInternalDisplays()[0]) 140 141 assertThat(displayUtils.isUnfoldedHorizontalHinge(displayContext)).isFalse() 142 } 143 144 @Test getMaxDisplaysDimension_oneDisplay_returnsDisplayDimensionsnull145 fun getMaxDisplaysDimension_oneDisplay_returnsDisplayDimensions() { 146 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 147 val displays = listOf(displayConfig1) 148 displaysProvider.setDisplays(displays) 149 150 assertThat(displayUtils.getMaxDisplaysDimension()).isEqualTo(Point(250, 500)) 151 } 152 153 @Test getMaxDisplaysDimension_noRotation_returnsMaxOfEachDimensionnull154 fun getMaxDisplaysDimension_noRotation_returnsMaxOfEachDimension() { 155 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 156 val displayConfig2 = FakeDisplaysProvider.FakeDisplayConfig(Point(300, 400)) 157 val displays = listOf(displayConfig1, displayConfig2) 158 displaysProvider.setDisplays(displays) 159 160 assertThat(displayUtils.getMaxDisplaysDimension()).isEqualTo(Point(300, 500)) 161 } 162 163 @Test getMaxDisplaysDimension_withRotation_returnsMaxPostRotationnull164 fun getMaxDisplaysDimension_withRotation_returnsMaxPostRotation() { 165 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 166 // Display size of config 2 becomes Point(400, 300) with rotation. 167 val displayConfig2 = 168 FakeDisplaysProvider.FakeDisplayConfig( 169 displaySize = Point(300, 400), 170 orientation = Configuration.ORIENTATION_LANDSCAPE, 171 ) 172 val displays = listOf(displayConfig1, displayConfig2) 173 displaysProvider.setDisplays(displays) 174 175 assertThat(displayUtils.getMaxDisplaysDimension()).isEqualTo(Point(400, 500)) 176 } 177 178 @Test getMaxDisplaysDimension_foldable_returnsMaxOfEachDimensionnull179 fun getMaxDisplaysDimension_foldable_returnsMaxOfEachDimension() { 180 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 181 val displayConfig2 = FakeDisplaysProvider.FakeDisplayConfig(Point(300, 400)) 182 val displayConfig3 = FakeDisplaysProvider.FakeDisplayConfig(Point(600, 300)) 183 val displays = listOf(displayConfig1, displayConfig2, displayConfig3) 184 displaysProvider.setDisplays(displays) 185 186 assertThat(displayUtils.getMaxDisplaysDimension()).isEqualTo(Point(600, 500)) 187 } 188 189 @Test isLargeScreenDevice_handheld_returnsFalsenull190 fun isLargeScreenDevice_handheld_returnsFalse() { 191 val displays = listOf(HANDHELD) 192 displaysProvider.setDisplays(displays) 193 194 assertThat(displayUtils.isLargeScreenDevice()).isFalse() 195 } 196 197 @Test isLargeScreenDevice_foldedFoldable_returnsTruenull198 fun isLargeScreenDevice_foldedFoldable_returnsTrue() { 199 val displays = listOf(FOLDABLE_FOLDED, FOLDABLE_UNFOLDED_LAND) 200 displaysProvider.setDisplays(displays) 201 202 assertThat(displayUtils.isLargeScreenDevice()).isTrue() 203 } 204 205 @Test isLargeScreenDevice_unfoldedFoldable_returnsTruenull206 fun isLargeScreenDevice_unfoldedFoldable_returnsTrue() { 207 val displays = listOf(FOLDABLE_UNFOLDED_LAND, FOLDABLE_FOLDED) 208 displaysProvider.setDisplays(displays) 209 210 assertThat(displayUtils.isLargeScreenDevice()).isTrue() 211 } 212 213 @Test isLargeScreenDevice_tablet_returnsTruenull214 fun isLargeScreenDevice_tablet_returnsTrue() { 215 val displays = listOf(TABLET_LAND) 216 displaysProvider.setDisplays(displays) 217 218 assertThat(displayUtils.isLargeScreenDevice()).isTrue() 219 } 220 221 @Test getSmallerDisplay_oneDisplay_returnsDefaultDisplaynull222 fun getSmallerDisplay_oneDisplay_returnsDefaultDisplay() { 223 val displays = listOf(HANDHELD) 224 displaysProvider.setDisplays(displays) 225 226 assertThat(displayUtils.getSmallerDisplay()) 227 .isEqualTo(displaysProvider.getInternalDisplays()[0]) 228 } 229 230 @Test getSmallerDisplay_twoDisplays_returnsSmallestDisplaynull231 fun getSmallerDisplay_twoDisplays_returnsSmallestDisplay() { 232 val displays = listOf(FOLDABLE_UNFOLDED_LAND, FOLDABLE_FOLDED) 233 displaysProvider.setDisplays(displays) 234 235 assertThat(displayUtils.getSmallerDisplay()) 236 .isEqualTo(displaysProvider.getInternalDisplays()[1]) 237 } 238 239 @Test getInternalDisplaySizes_noRotation_returnsSizesAsIsnull240 fun getInternalDisplaySizes_noRotation_returnsSizesAsIs() { 241 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 242 val displayConfig2 = FakeDisplaysProvider.FakeDisplayConfig(Point(300, 400)) 243 val displays = listOf(displayConfig1, displayConfig2) 244 displaysProvider.setDisplays(displays) 245 246 val displaySizes = displayUtils.getInternalDisplaySizes() 247 assertThat(displaySizes.size).isEqualTo(displays.size) 248 assertThat(displaySizes).contains(Point(250, 500)) 249 assertThat(displaySizes).contains(Point(300, 400)) 250 } 251 252 @Test getInternalDisplaySizes_withRotation_returnsSizesPostRotationnull253 fun getInternalDisplaySizes_withRotation_returnsSizesPostRotation() { 254 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 255 // Display size of config 2 becomes Point(400, 300) with rotation. 256 val displayConfig2 = 257 FakeDisplaysProvider.FakeDisplayConfig( 258 displaySize = Point(300, 400), 259 orientation = Configuration.ORIENTATION_LANDSCAPE, 260 ) 261 val displays = listOf(displayConfig1, displayConfig2) 262 displaysProvider.setDisplays(displays) 263 264 val displaySizes = displayUtils.getInternalDisplaySizes() 265 assertThat(displaySizes.size).isEqualTo(displays.size) 266 assertThat(displaySizes).contains(Point(250, 500)) 267 assertThat(displaySizes).contains(Point(400, 300)) 268 } 269 270 @Test getInternalDisplaySizes_allDimensions_returnsSizesAndRotatedSizesnull271 fun getInternalDisplaySizes_allDimensions_returnsSizesAndRotatedSizes() { 272 val displayConfig1 = FakeDisplaysProvider.FakeDisplayConfig(Point(250, 500)) 273 val displayConfig2 = FakeDisplaysProvider.FakeDisplayConfig(Point(300, 400)) 274 val displays = listOf(displayConfig1, displayConfig2) 275 displaysProvider.setDisplays(displays) 276 277 val displaySizes = displayUtils.getInternalDisplaySizes(true) 278 assertThat(displaySizes.size).isEqualTo(displays.size * 2) 279 assertThat(displaySizes).contains(Point(250, 500)) 280 assertThat(displaySizes).contains(Point(300, 400)) 281 assertThat(displaySizes).contains(Point(500, 250)) 282 assertThat(displaySizes).contains(Point(400, 300)) 283 } 284 } 285