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.development.data.repository
18 
19 import android.content.pm.UserInfo
20 import android.os.Build
21 import android.os.UserHandle
22 import android.os.UserManager
23 import android.os.userManager
24 import android.provider.Settings
25 import androidx.test.ext.junit.runners.AndroidJUnit4
26 import androidx.test.filters.SmallTest
27 import com.android.systemui.SysuiTestCase
28 import com.android.systemui.kosmos.Kosmos
29 import com.android.systemui.kosmos.collectLastValue
30 import com.android.systemui.kosmos.testScope
31 import com.android.systemui.testKosmos
32 import com.android.systemui.util.settings.fakeGlobalSettings
33 import com.google.common.truth.Truth.assertThat
34 import kotlin.test.Test
35 import kotlinx.coroutines.test.runTest
36 import org.junit.runner.RunWith
37 import org.mockito.kotlin.doReturn
38 import org.mockito.kotlin.eq
39 import org.mockito.kotlin.stub
40 
41 @RunWith(AndroidJUnit4::class)
42 @SmallTest
43 class DevelopmentSettingRepositoryTest : SysuiTestCase() {
44 
45     private val kosmos = testKosmos()
46 
47     private val underTest = kosmos.developmentSettingRepository
48 
49     @Test
nonAdminUser_unrestricted_neverDevelopmentEnablednull50     fun nonAdminUser_unrestricted_neverDevelopmentEnabled() =
51         with(kosmos) {
52             testScope.runTest {
53                 val userInfo = nonAdminUserInfo
54                 val settingEnabled by
55                     collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
56 
57                 setUserRestriction(userInfo.userHandle, restricted = false)
58 
59                 assertThat(settingEnabled).isFalse()
60 
61                 setSettingValue(false)
62                 assertThat(settingEnabled).isFalse()
63 
64                 setSettingValue(true)
65                 assertThat(settingEnabled).isFalse()
66             }
67         }
68 
69     @Test
nonAdminUser_restricted_neverDevelopmentEnablednull70     fun nonAdminUser_restricted_neverDevelopmentEnabled() =
71         with(kosmos) {
72             testScope.runTest {
73                 val userInfo = nonAdminUserInfo
74                 val settingEnabled by
75                     collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
76 
77                 setUserRestriction(userInfo.userHandle, restricted = true)
78 
79                 assertThat(settingEnabled).isFalse()
80 
81                 setSettingValue(false)
82                 assertThat(settingEnabled).isFalse()
83 
84                 setSettingValue(true)
85                 assertThat(settingEnabled).isFalse()
86             }
87         }
88 
89     @Test
adminUser_unrestricted_defaultValueOfSettingnull90     fun adminUser_unrestricted_defaultValueOfSetting() =
91         with(kosmos) {
92             testScope.runTest {
93                 val userInfo = adminUserInfo
94                 val settingEnabled by
95                     collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
96 
97                 setUserRestriction(userInfo.userHandle, restricted = false)
98 
99                 val defaultValue = Build.TYPE == "eng"
100 
101                 assertThat(settingEnabled).isEqualTo(defaultValue)
102             }
103         }
104 
105     @Test
adminUser_unrestricted_enabledTracksSettingnull106     fun adminUser_unrestricted_enabledTracksSetting() =
107         with(kosmos) {
108             testScope.runTest {
109                 val userInfo = adminUserInfo
110                 val settingEnabled by
111                     collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
112 
113                 setUserRestriction(userInfo.userHandle, restricted = false)
114 
115                 setSettingValue(false)
116                 assertThat(settingEnabled).isFalse()
117 
118                 setSettingValue(true)
119                 assertThat(settingEnabled).isTrue()
120             }
121         }
122 
123     @Test
adminUser_restricted_neverDevelopmentEnablednull124     fun adminUser_restricted_neverDevelopmentEnabled() =
125         with(kosmos) {
126             testScope.runTest {
127                 val userInfo = adminUserInfo
128                 val settingEnabled by
129                     collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
130 
131                 setUserRestriction(userInfo.userHandle, restricted = true)
132 
133                 assertThat(settingEnabled).isFalse()
134 
135                 setSettingValue(false)
136                 assertThat(settingEnabled).isFalse()
137 
138                 setSettingValue(true)
139                 assertThat(settingEnabled).isFalse()
140             }
141         }
142 
143     private companion object {
144         const val USER_RESTRICTION = UserManager.DISALLOW_DEBUGGING_FEATURES
145         const val SETTING_NAME = Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
146 
147         val adminUserInfo =
148             UserInfo(
149                 /* id= */ 10,
150                 /* name= */ "",
151                 /* flags */ UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
152             )
153         val nonAdminUserInfo =
154             UserInfo(/* id= */ 11, /* name= */ "", /* flags */ UserInfo.FLAG_FULL)
155 
setUserRestrictionnull156         fun Kosmos.setUserRestriction(userHandle: UserHandle, restricted: Boolean) {
157             userManager.stub {
158                 on { hasUserRestrictionForUser(eq(USER_RESTRICTION), eq(userHandle)) } doReturn
159                     restricted
160             }
161         }
162 
setSettingValuenull163         fun Kosmos.setSettingValue(enabled: Boolean) {
164             fakeGlobalSettings.putInt(SETTING_NAME, if (enabled) 1 else 0)
165         }
166     }
167 }
168