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.permissioncontroller.permission.util 18 19 import android.Manifest.permission.READ_CONTACTS 20 import android.Manifest.permission_group.ACTIVITY_RECOGNITION 21 import android.Manifest.permission_group.CALENDAR 22 import android.Manifest.permission_group.CALL_LOG 23 import android.Manifest.permission_group.CAMERA 24 import android.Manifest.permission_group.CONTACTS 25 import android.Manifest.permission_group.LOCATION 26 import android.Manifest.permission_group.MICROPHONE 27 import android.Manifest.permission_group.NEARBY_DEVICES 28 import android.Manifest.permission_group.PHONE 29 import android.Manifest.permission_group.READ_MEDIA_AURAL 30 import android.Manifest.permission_group.READ_MEDIA_VISUAL 31 import android.Manifest.permission_group.SENSORS 32 import android.Manifest.permission_group.SMS 33 import android.Manifest.permission_group.STORAGE 34 import android.Manifest.permission_group.UNDEFINED 35 import android.content.ComponentName 36 import android.content.Context 37 import android.content.Intent 38 import android.content.SharedPreferences 39 import android.content.pm.PackageManager.NameNotFoundException 40 import android.content.res.Resources 41 import androidx.test.platform.app.InstrumentationRegistry 42 import com.android.permissioncontroller.Constants.EXTRA_SESSION_ID 43 import com.android.permissioncontroller.Constants.INVALID_SESSION_ID 44 import com.android.permissioncontroller.R 45 import com.android.permissioncontroller.permission.utils.Utils 46 import com.android.permissioncontroller.privacysources.WorkPolicyInfo 47 import com.google.common.truth.Truth.assertThat 48 import kotlin.test.assertFailsWith 49 import org.junit.Ignore 50 import org.junit.Test 51 52 class UtilsTest { 53 private val context = InstrumentationRegistry.getInstrumentation().targetContext as Context 54 55 @Test getAbsoluteTimeString_zero_returnsNullnull56 fun getAbsoluteTimeString_zero_returnsNull() { 57 assertThat(Utils.getAbsoluteTimeString(context, 0)).isNull() 58 } 59 60 @Test getAbsoluteTimeString_currentTime_returnsTimeFormatStringnull61 fun getAbsoluteTimeString_currentTime_returnsTimeFormatString() { 62 val time = Utils.getAbsoluteTimeString(context, System.currentTimeMillis()) 63 assertThat(time).isNotNull() 64 if (time != null) { 65 if (time.contains(":")) { 66 val times = time.split(":") 67 assertThat(times.size).isEqualTo(2) 68 val isTime = times[1].contains("am", true) || times[1].contains("pm", true) 69 assertThat(isTime).isTrue() 70 } else { 71 assertThat(time.contains(".")).isTrue() 72 val times = time.split(".") 73 assertThat(times.size).isEqualTo(3) 74 } 75 } 76 } 77 78 @Test getAbsoluteTimeString_previousDateTime_returnsDateFormatStringnull79 fun getAbsoluteTimeString_previousDateTime_returnsDateFormatString() { 80 val lastAccessTime = 1680739840723L 81 val time = Utils.getAbsoluteTimeString(context, lastAccessTime) 82 assertThat(time == "Apr 5, 2023" || time == "Apr 6, 2023").isTrue() 83 } 84 85 @Test getBlockedIcon_invalidGroupName_returnsMinusOnenull86 fun getBlockedIcon_invalidGroupName_returnsMinusOne() { 87 assertThat(Utils.getBlockedIcon(INVALID_GROUP_NAME)).isEqualTo(-1) 88 } 89 90 @Test getBlockedIcon_validGroupNamenull91 fun getBlockedIcon_validGroupName() { 92 assertThat(Utils.getBlockedIcon(CAMERA)).isEqualTo(R.drawable.ic_camera_blocked) 93 } 94 95 @Test getBlockedTitle_invalidGroupName_returnsMinusOnenull96 fun getBlockedTitle_invalidGroupName_returnsMinusOne() { 97 assertThat(Utils.getBlockedTitle(INVALID_GROUP_NAME)).isEqualTo(-1) 98 } 99 @Test getBlockedTitle_validGroupNamenull100 fun getBlockedTitle_validGroupName() { 101 assertThat(Utils.getBlockedTitle(CAMERA)).isEqualTo(R.string.blocked_camera_title) 102 } 103 104 @Test getDeviceProtectedSharedPreferencesnull105 fun getDeviceProtectedSharedPreferences() { 106 assertThat(Utils.getDeviceProtectedSharedPreferences(context)) 107 .isInstanceOf(SharedPreferences::class.java) 108 } 109 110 @Test 111 @Ignore("b/277782895") getEnterpriseStringnull112 fun getEnterpriseString() { 113 assertThat( 114 Utils.getEnterpriseString( 115 context, 116 WorkPolicyInfo.WORK_POLICY_TITLE, 117 R.string.work_policy_title 118 ) 119 ) 120 .isInstanceOf(String::class.java) 121 } 122 123 @Test getOneTimePermissionsTimeout_returnsNonNegativeTimeoutnull124 fun getOneTimePermissionsTimeout_returnsNonNegativeTimeout() { 125 assertThat(Utils.getOneTimePermissionsTimeout()).isGreaterThan(0L) 126 } 127 128 @Test getOneTimePermissionsKilledDelaySelfRevokednull129 fun getOneTimePermissionsKilledDelaySelfRevoked() { 130 assertThat(Utils.getOneTimePermissionsKilledDelay(true)).isEqualTo(0) 131 } 132 133 @Test getOneTimePermissionsKilledDelayNonSelfRevokednull134 fun getOneTimePermissionsKilledDelayNonSelfRevoked() { 135 assertThat(Utils.getOneTimePermissionsKilledDelay(false)).isAtLeast(0L) 136 } 137 138 @Test getPackageInfoForComponentName_NonExistComponent_throwsNameNotFoundExceptionnull139 fun getPackageInfoForComponentName_NonExistComponent_throwsNameNotFoundException() { 140 val testComponent = ComponentName("com.test.package", "TestClass") 141 assertFailsWith<NameNotFoundException> { 142 Utils.getPackageInfoForComponentName(context, testComponent) 143 } 144 } 145 146 @Test getPermissionGroupDescriptionString_undefinedPermissionGroupnull147 fun getPermissionGroupDescriptionString_undefinedPermissionGroup() { 148 val description = "test permission group description" 149 val resultString = 150 context.getString(R.string.permission_description_summary_generic, description) 151 assertThat(Utils.getPermissionGroupDescriptionString(context, UNDEFINED, description)) 152 .isEqualTo(resultString) 153 } 154 155 @Test getPermissionGroupDescriptionString_validPermissionGroupnull156 fun getPermissionGroupDescriptionString_validPermissionGroup() { 157 val permissionGroupNames = 158 listOf( 159 ACTIVITY_RECOGNITION, 160 CALENDAR, 161 CALL_LOG, 162 CAMERA, 163 CONTACTS, 164 LOCATION, 165 MICROPHONE, 166 NEARBY_DEVICES, 167 PHONE, 168 READ_MEDIA_AURAL, 169 READ_MEDIA_VISUAL, 170 SENSORS, 171 SMS, 172 STORAGE 173 ) 174 for (permissionGroupName in permissionGroupNames) { 175 assertThat(Utils.getPermissionGroupDescriptionString(context, permissionGroupName, "")) 176 .isNotNull() 177 } 178 } 179 180 @Test getPermissionLastAccessSummaryTimestamp_lastAccessSummaryTimestampIsNullnull181 fun getPermissionLastAccessSummaryTimestamp_lastAccessSummaryTimestampIsNull() { 182 val result = Utils.getPermissionLastAccessSummaryTimestamp(null, context, LOCATION) 183 assertThat(result.first).isEqualTo("") 184 assertThat(result.second).isEqualTo(Utils.NOT_IN_LAST_7D) 185 assertThat(result.third).isEqualTo("") 186 } 187 188 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsTodaynull189 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsToday() { 190 val result = 191 Utils.getPermissionLastAccessSummaryTimestamp( 192 System.currentTimeMillis(), 193 context, 194 LOCATION 195 ) 196 assertThat(result.first).isNotEmpty() 197 assertThat(result.second).isEqualTo(Utils.LAST_24H_SENSOR_TODAY) 198 assertThat(result.third).isNotEmpty() 199 } 200 201 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsYesterdaynull202 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsYesterday() { 203 val result = 204 Utils.getPermissionLastAccessSummaryTimestamp( 205 System.currentTimeMillis() - 24 * 60 * 60 * 1000, 206 context, 207 LOCATION 208 ) 209 assertThat(result.first).isNotEmpty() 210 assertThat(result.second).isEqualTo(Utils.LAST_24H_SENSOR_YESTERDAY) 211 assertThat(result.third).isNotEmpty() 212 } 213 214 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsLast7Daysnull215 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsLast7Days() { 216 val result = 217 Utils.getPermissionLastAccessSummaryTimestamp( 218 System.currentTimeMillis() - 5 * 24 * 60 * 60 * 1000, 219 context, 220 LOCATION 221 ) 222 assertThat(result.first).isNotEmpty() 223 assertThat(result.second).isEqualTo(Utils.LAST_7D_SENSOR) 224 assertThat(result.third).isNotEmpty() 225 } 226 227 @Test getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIsLast24Hrsnull228 fun getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIsLast24Hrs() { 229 val result = 230 Utils.getPermissionLastAccessSummaryTimestamp( 231 System.currentTimeMillis(), 232 context, 233 STORAGE 234 ) 235 assertThat(result.first).isNotEmpty() 236 assertThat(result.second).isEqualTo(Utils.LAST_24H_CONTENT_PROVIDER) 237 assertThat(result.third).isNotEmpty() 238 } 239 240 @Test getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIs7Daysnull241 fun getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIs7Days() { 242 val result = 243 Utils.getPermissionLastAccessSummaryTimestamp( 244 System.currentTimeMillis() - 5 * 60 * 60 * 24 * 1000, 245 context, 246 STORAGE 247 ) 248 assertThat(result.first).isNotEmpty() 249 assertThat(result.second).isEqualTo(Utils.LAST_7D_CONTENT_PROVIDER) 250 assertThat(result.third).isNotEmpty() 251 } 252 253 @Test getOrGenerateSessionId_validSessionIdnull254 fun getOrGenerateSessionId_validSessionId() { 255 val intent = Intent() 256 intent.putExtra(EXTRA_SESSION_ID, VALID_SESSION_ID) 257 val sessionId = Utils.getOrGenerateSessionId(intent) 258 assertThat(sessionId).isEqualTo(VALID_SESSION_ID) 259 } 260 261 @Test getOrGenerateSessionId_invalidSessionIdnull262 fun getOrGenerateSessionId_invalidSessionId() { 263 val intent = Intent() 264 val sessionId = Utils.getOrGenerateSessionId(intent) 265 assertThat(sessionId).isNotEqualTo(INVALID_SESSION_ID) 266 } 267 268 @Test getGroupPermissionInfos_validGroupName_returnsGroupPermissionsnull269 fun getGroupPermissionInfos_validGroupName_returnsGroupPermissions() { 270 val permissionInfos = Utils.getGroupPermissionInfos(CONTACTS, context) 271 assertThat(permissionInfos).isNotNull() 272 val permissions = mutableListOf<String>() 273 for (permissionInfo in permissionInfos!!) { 274 permissions.add(permissionInfo.name) 275 } 276 assertThat(permissions.contains(READ_CONTACTS)).isTrue() 277 } 278 279 @Test getGroupPermissionInfos_inValidGroup_returnsNullnull280 fun getGroupPermissionInfos_inValidGroup_returnsNull() { 281 assertThat(Utils.getGroupPermissionInfos(INVALID_GROUP_NAME, context)).isNull() 282 } 283 284 @Test getGroupPermissionInfos_undefinedGroup_returnsAllSystemPermissionsnull285 fun getGroupPermissionInfos_undefinedGroup_returnsAllSystemPermissions() { 286 val permissionInfos = Utils.getGroupPermissionInfos(UNDEFINED, context) 287 assertThat(permissionInfos).isNotNull() 288 } 289 290 @Test getGroupPermissionInfo_permissionName_returnsSamePermissionnull291 fun getGroupPermissionInfo_permissionName_returnsSamePermission() { 292 val permissionInfos = Utils.getGroupPermissionInfos(READ_CONTACTS, context) 293 assertThat(permissionInfos).isNotNull() 294 assertThat(permissionInfos!!.size).isEqualTo(1) 295 assertThat(permissionInfos[0].name).isEqualTo(READ_CONTACTS) 296 } 297 298 @Test getColorResId_validId_returnsNonZeronull299 fun getColorResId_validId_returnsNonZero() { 300 assertThat(Utils.getColorResId(context, android.R.attr.colorPrimary)) 301 .isNotEqualTo(Resources.ID_NULL) 302 } 303 304 @Test getColorResId_inValidId_returnsZeronull305 fun getColorResId_inValidId_returnsZero() { 306 assertThat(Utils.getColorResId(context, INVALID_ATTR_ID)).isEqualTo(Resources.ID_NULL) 307 } 308 309 companion object { 310 private const val INVALID_ATTR_ID = 1000 311 private const val VALID_SESSION_ID = 10000L 312 private const val INVALID_GROUP_NAME = "invalid group name" 313 } 314 } 315