1 /*
2  * Copyright (C) 2023 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.settings.applications.specialaccess
18 
19 import android.content.Context
20 import android.content.pm.ApplicationInfo
21 import android.content.res.Resources
22 import android.net.NetworkPolicyManager
23 import android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND
24 import androidx.test.core.app.ApplicationProvider
25 import androidx.test.ext.junit.runners.AndroidJUnit4
26 import com.android.settings.R
27 import com.android.settings.applications.specialaccess.DataSaverController.Companion.getUnrestrictedSummary
28 import com.android.settings.core.BasePreferenceController.AVAILABLE
29 import com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE
30 import com.android.settingslib.spaprivileged.model.app.AppListRepository
31 import com.google.common.truth.Truth.assertThat
32 import kotlinx.coroutines.flow.Flow
33 import kotlinx.coroutines.flow.flowOf
34 import kotlinx.coroutines.test.runTest
35 import org.junit.Before
36 import org.junit.Rule
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.mockito.Mock
40 import org.mockito.Spy
41 import org.mockito.junit.MockitoJUnit
42 import org.mockito.junit.MockitoRule
43 import org.mockito.Mockito.`when` as whenever
44 
45 @RunWith(AndroidJUnit4::class)
46 class DataSaverControllerTest {
47     @get:Rule
48     val mockito: MockitoRule = MockitoJUnit.rule()
49 
50     @Spy
51     private val context: Context = ApplicationProvider.getApplicationContext()
52 
53     @Spy
54     private val resources: Resources = context.resources
55 
56     @Mock
57     private lateinit var networkPolicyManager: NetworkPolicyManager
58 
59     @Mock
60     private lateinit var dataSaverController: DataSaverController
61 
62     @Before
setUpnull63     fun setUp() {
64         whenever(context.applicationContext).thenReturn(context)
65         whenever(context.resources).thenReturn(resources)
66         whenever(NetworkPolicyManager.from(context)).thenReturn(networkPolicyManager)
67 
68         dataSaverController = DataSaverController(context, "key")
69     }
70 
71     @Test
getAvailabilityStatus_whenConfigOn_availablenull72     fun getAvailabilityStatus_whenConfigOn_available() {
73         whenever(resources.getBoolean(R.bool.config_show_data_saver)).thenReturn(true)
74         assertThat(dataSaverController.availabilityStatus).isEqualTo(AVAILABLE)
75     }
76 
77     @Test
getAvailabilityStatus_whenConfigOff_unsupportedOnDevicenull78     fun getAvailabilityStatus_whenConfigOff_unsupportedOnDevice() {
79         whenever(resources.getBoolean(R.bool.config_show_data_saver)).thenReturn(false)
80         assertThat(dataSaverController.availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE)
81     }
82 
83     @Test
<lambda>null84     fun getUnrestrictedSummary_whenTwoAppsAllowed() = runTest {
85         whenever(
86             networkPolicyManager.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND)
87         ).thenReturn(intArrayOf(APP1.uid, APP2.uid))
88 
89         val summary =
90             getUnrestrictedSummary(context = context, appListRepository = FakeAppListRepository)
91 
92         assertThat(summary)
93             .isEqualTo("2 apps allowed to use unrestricted mobile data when Data Saver is on")
94     }
95 
96     @Test
<lambda>null97     fun getUnrestrictedSummary_whenNoAppsAllowed() = runTest {
98         whenever(
99             networkPolicyManager.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND)
100         ).thenReturn(intArrayOf())
101 
102         val summary =
103             getUnrestrictedSummary(context = context, appListRepository = FakeAppListRepository)
104 
105         assertThat(summary)
106             .isEqualTo("0 apps allowed to use unrestricted mobile data when Data Saver is on")
107     }
108 
109     private companion object {
<lambda>null110         val APP1 = ApplicationInfo().apply { uid = 10001 }
<lambda>null111         val APP2 = ApplicationInfo().apply { uid = 10002 }
<lambda>null112         val APP3 = ApplicationInfo().apply { uid = 10003 }
113 
114         object FakeAppListRepository : AppListRepository {
loadAppsnull115             override suspend fun loadApps(
116                 userId: Int,
117                 loadInstantApps: Boolean,
118                 matchAnyUserForAdmin: Boolean,
119             ) = emptyList<ApplicationInfo>()
120 
121             override fun showSystemPredicate(
122                 userIdFlow: Flow<Int>,
123                 showSystemFlow: Flow<Boolean>,
124             ): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { false }
125 
getSystemPackageNamesBlockingnull126             override fun getSystemPackageNamesBlocking(userId: Int): Set<String> = emptySet()
127 
128             override suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean) =
129                 listOf(APP1, APP2, APP3)
130         }
131     }
132 }