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 
17 package com.android.systemui
18 
19 import android.graphics.Rect
20 import androidx.test.ext.junit.runners.AndroidJUnit4
21 import androidx.test.filters.SmallTest
22 import com.android.systemui.res.R
23 import com.google.common.truth.Truth.assertThat
24 import org.junit.Before
25 import org.junit.Test
26 import org.junit.runner.RunWith
27 
28 @SmallTest
29 @RunWith(AndroidJUnit4::class)
30 class CameraProtectionLoaderImplTest : SysuiTestCase() {
31 
32     private val loader = CameraProtectionLoaderImpl(context)
33 
34     @Before
setUpnull35     fun setUp() {
36         overrideResource(R.string.config_protectedCameraId, OUTER_CAMERA_LOGICAL_ID)
37         overrideResource(R.string.config_protectedPhysicalCameraId, OUTER_CAMERA_PHYSICAL_ID)
38         overrideResource(
39             R.string.config_frontBuiltInDisplayCutoutProtection,
40             OUTER_CAMERA_PROTECTION_PATH
41         )
42         overrideResource(R.string.config_protectedScreenUniqueId, OUTER_SCREEN_UNIQUE_ID)
43         overrideResource(R.string.config_protectedInnerCameraId, INNER_CAMERA_LOGICAL_ID)
44         overrideResource(R.string.config_protectedInnerPhysicalCameraId, INNER_CAMERA_PHYSICAL_ID)
45         overrideResource(
46             R.string.config_innerBuiltInDisplayCutoutProtection,
47             INNER_CAMERA_PROTECTION_PATH
48         )
49         overrideResource(R.string.config_protectedInnerScreenUniqueId, INNER_SCREEN_UNIQUE_ID)
50     }
51 
52     @Test
loadCameraProtectionInfoListnull53     fun loadCameraProtectionInfoList() {
54         val protectionList = loadProtectionList()
55 
56         assertThat(protectionList)
57             .containsExactly(OUTER_CAMERA_PROTECTION_INFO, INNER_CAMERA_PROTECTION_INFO)
58     }
59 
60     @Test
loadCameraProtectionInfoList_outerCameraIdEmpty_onlyReturnsInnerInfonull61     fun loadCameraProtectionInfoList_outerCameraIdEmpty_onlyReturnsInnerInfo() {
62         overrideResource(R.string.config_protectedCameraId, "")
63 
64         val protectionList = loadProtectionList()
65 
66         assertThat(protectionList).containsExactly(INNER_CAMERA_PROTECTION_INFO)
67     }
68 
69     @Test
loadCameraProtectionInfoList_innerCameraIdEmpty_onlyReturnsOuterInfonull70     fun loadCameraProtectionInfoList_innerCameraIdEmpty_onlyReturnsOuterInfo() {
71         overrideResource(R.string.config_protectedInnerCameraId, "")
72 
73         val protectionList = loadProtectionList()
74 
75         assertThat(protectionList).containsExactly(OUTER_CAMERA_PROTECTION_INFO)
76     }
77 
78     @Test
loadCameraProtectionInfoList_innerAndOuterCameraIdsEmpty_returnsEmptynull79     fun loadCameraProtectionInfoList_innerAndOuterCameraIdsEmpty_returnsEmpty() {
80         overrideResource(R.string.config_protectedCameraId, "")
81         overrideResource(R.string.config_protectedInnerCameraId, "")
82 
83         val protectionList = loadProtectionList()
84 
85         assertThat(protectionList).isEmpty()
86     }
87 
loadProtectionListnull88     private fun loadProtectionList() =
89         loader.loadCameraProtectionInfoList().map { it.toTestableVersion() }
90 
CameraProtectionInfonull91     private fun CameraProtectionInfo.toTestableVersion() =
92         TestableProtectionInfo(logicalCameraId, physicalCameraId, bounds, displayUniqueId)
93 
94     /**
95      * "Testable" version, because the original version contains a Path property, which doesn't
96      * implement equals.
97      */
98     private data class TestableProtectionInfo(
99         val logicalCameraId: String,
100         val physicalCameraId: String?,
101         val cutoutBounds: Rect,
102         val displayUniqueId: String?,
103     )
104 
105     companion object {
106         private const val OUTER_CAMERA_LOGICAL_ID = "1"
107         private const val OUTER_CAMERA_PHYSICAL_ID = "11"
108         private const val OUTER_CAMERA_PROTECTION_PATH = "M 0,0 H 10,10 V 10,10 H 0,10 Z"
109         private val OUTER_CAMERA_PROTECTION_BOUNDS =
110             Rect(/* left = */ 0, /* top = */ 0, /* right = */ 10, /* bottom = */ 10)
111         private const val OUTER_SCREEN_UNIQUE_ID = "111"
112         private val OUTER_CAMERA_PROTECTION_INFO =
113             TestableProtectionInfo(
114                 OUTER_CAMERA_LOGICAL_ID,
115                 OUTER_CAMERA_PHYSICAL_ID,
116                 OUTER_CAMERA_PROTECTION_BOUNDS,
117                 OUTER_SCREEN_UNIQUE_ID,
118             )
119 
120         private const val INNER_CAMERA_LOGICAL_ID = "2"
121         private const val INNER_CAMERA_PHYSICAL_ID = "22"
122         private const val INNER_CAMERA_PROTECTION_PATH = "M 0,0 H 20,20 V 20,20 H 0,20 Z"
123         private val INNER_CAMERA_PROTECTION_BOUNDS =
124             Rect(/* left = */ 0, /* top = */ 0, /* right = */ 20, /* bottom = */ 20)
125         private const val INNER_SCREEN_UNIQUE_ID = "222"
126         private val INNER_CAMERA_PROTECTION_INFO =
127             TestableProtectionInfo(
128                 INNER_CAMERA_LOGICAL_ID,
129                 INNER_CAMERA_PHYSICAL_ID,
130                 INNER_CAMERA_PROTECTION_BOUNDS,
131                 INNER_SCREEN_UNIQUE_ID,
132             )
133     }
134 }
135