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 org.junit.Ignore 49 import org.junit.Test 50 import kotlin.test.assertFailsWith 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(Utils.getEnterpriseString(context, WorkPolicyInfo.WORK_POLICY_TITLE, 114 R.string.work_policy_title)).isInstanceOf(String::class.java) 115 } 116 117 @Test getOneTimePermissionsTimeout_returnsNonNegativeTimeoutnull118 fun getOneTimePermissionsTimeout_returnsNonNegativeTimeout() { 119 assertThat(Utils.getOneTimePermissionsTimeout()).isGreaterThan(0L) 120 } 121 122 @Test getOneTimePermissionsKilledDelaySelfRevokednull123 fun getOneTimePermissionsKilledDelaySelfRevoked() { 124 assertThat(Utils.getOneTimePermissionsKilledDelay(true)).isEqualTo(0) 125 } 126 127 @Test getOneTimePermissionsKilledDelayNonSelfRevokednull128 fun getOneTimePermissionsKilledDelayNonSelfRevoked() { 129 assertThat(Utils.getOneTimePermissionsKilledDelay(false)).isAtLeast(0L) 130 } 131 132 @Test getPackageInfoForComponentName_NonExistComponent_throwsNameNotFoundExceptionnull133 fun getPackageInfoForComponentName_NonExistComponent_throwsNameNotFoundException() { 134 val testComponent = ComponentName("com.test.package", "TestClass") 135 assertFailsWith<NameNotFoundException> { 136 Utils.getPackageInfoForComponentName(context, testComponent) 137 } 138 } 139 140 @Test getPermissionGroupDescriptionString_undefinedPermissionGroupnull141 fun getPermissionGroupDescriptionString_undefinedPermissionGroup() { 142 val description = "test permission group description" 143 val resultString = 144 context.getString(R.string.permission_description_summary_generic, description) 145 assertThat(Utils.getPermissionGroupDescriptionString(context, UNDEFINED, description)) 146 .isEqualTo(resultString) 147 } 148 149 @Test getPermissionGroupDescriptionString_validPermissionGroupnull150 fun getPermissionGroupDescriptionString_validPermissionGroup() { 151 val permissionGroupNames = listOf(ACTIVITY_RECOGNITION, CALENDAR, CALL_LOG, 152 CAMERA, CONTACTS, LOCATION, MICROPHONE, NEARBY_DEVICES, PHONE, READ_MEDIA_AURAL, 153 READ_MEDIA_VISUAL, SENSORS, SMS, STORAGE) 154 for (permissionGroupName in permissionGroupNames) { 155 assertThat(Utils.getPermissionGroupDescriptionString(context, permissionGroupName, "")) 156 .isNotNull() 157 } 158 } 159 160 @Test getPermissionLastAccessSummaryTimestamp_lastAccessSummaryTimestampIsNullnull161 fun getPermissionLastAccessSummaryTimestamp_lastAccessSummaryTimestampIsNull() { 162 val result = Utils.getPermissionLastAccessSummaryTimestamp(null, context, LOCATION) 163 assertThat(result.first).isEqualTo("") 164 assertThat(result.second).isEqualTo(Utils.NOT_IN_LAST_7D) 165 assertThat(result.third).isEqualTo("") 166 } 167 168 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsTodaynull169 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsToday() { 170 val result = Utils.getPermissionLastAccessSummaryTimestamp(System.currentTimeMillis(), 171 context, LOCATION) 172 assertThat(result.first).isNotEmpty() 173 assertThat(result.second).isEqualTo(Utils.LAST_24H_SENSOR_TODAY) 174 assertThat(result.third).isNotEmpty() 175 } 176 177 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsYesterdaynull178 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsYesterday() { 179 val result = Utils.getPermissionLastAccessSummaryTimestamp( 180 System.currentTimeMillis() - 24 * 60 * 60 * 1000, context, LOCATION) 181 assertThat(result.first).isNotEmpty() 182 assertThat(result.second).isEqualTo(Utils.LAST_24H_SENSOR_YESTERDAY) 183 assertThat(result.third).isNotEmpty() 184 } 185 186 @Test getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsLast7Daysnull187 fun getPermissionLastAccessSummaryTimestamp_sensorDataPermission_lastAccessSummaryTimestampIsLast7Days() { 188 val result = Utils.getPermissionLastAccessSummaryTimestamp( 189 System.currentTimeMillis() - 5 * 24 * 60 * 60 * 1000, context, LOCATION) 190 assertThat(result.first).isNotEmpty() 191 assertThat(result.second).isEqualTo(Utils.LAST_7D_SENSOR) 192 assertThat(result.third).isNotEmpty() 193 } 194 195 @Test getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIsLast24Hrsnull196 fun getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIsLast24Hrs() { 197 val result = Utils.getPermissionLastAccessSummaryTimestamp( 198 System.currentTimeMillis(), context, STORAGE) 199 assertThat(result.first).isNotEmpty() 200 assertThat(result.second).isEqualTo(Utils.LAST_24H_CONTENT_PROVIDER) 201 assertThat(result.third).isNotEmpty() 202 } 203 204 @Test getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIs7Daysnull205 fun getPermissionLastAccessSummaryTimestamp_nonSensorDataPermission_lastAccessSummaryTimestampIs7Days() { 206 val result = Utils.getPermissionLastAccessSummaryTimestamp( 207 System.currentTimeMillis() - 5 * 60 * 60 * 24 * 1000, context, STORAGE) 208 assertThat(result.first).isNotEmpty() 209 assertThat(result.second).isEqualTo(Utils.LAST_7D_CONTENT_PROVIDER) 210 assertThat(result.third).isNotEmpty() 211 } 212 213 @Test getOrGenerateSessionId_validSessionIdnull214 fun getOrGenerateSessionId_validSessionId() { 215 val intent = Intent() 216 intent.putExtra(EXTRA_SESSION_ID, VALID_SESSION_ID) 217 val sessionId = Utils.getOrGenerateSessionId(intent) 218 assertThat(sessionId).isEqualTo(VALID_SESSION_ID) 219 } 220 221 @Test getOrGenerateSessionId_invalidSessionIdnull222 fun getOrGenerateSessionId_invalidSessionId() { 223 val intent = Intent() 224 val sessionId = Utils.getOrGenerateSessionId(intent) 225 assertThat(sessionId).isNotEqualTo(INVALID_SESSION_ID) 226 } 227 228 @Test getGroupPermissionInfos_validGroupName_returnsGroupPermissionsnull229 fun getGroupPermissionInfos_validGroupName_returnsGroupPermissions() { 230 val permissionInfos = Utils.getGroupPermissionInfos(CONTACTS, context) 231 assertThat(permissionInfos).isNotNull() 232 val permissions = mutableListOf<String>() 233 for (permissionInfo in permissionInfos!!) { 234 permissions.add(permissionInfo.name) 235 } 236 assertThat(permissions.contains(READ_CONTACTS)).isTrue() 237 } 238 239 @Test getGroupPermissionInfos_inValidGroup_returnsNullnull240 fun getGroupPermissionInfos_inValidGroup_returnsNull() { 241 assertThat(Utils.getGroupPermissionInfos(INVALID_GROUP_NAME, context)).isNull() 242 } 243 244 @Test getGroupPermissionInfos_undefinedGroup_returnsAllSystemPermissionsnull245 fun getGroupPermissionInfos_undefinedGroup_returnsAllSystemPermissions() { 246 val permissionInfos = Utils.getGroupPermissionInfos(UNDEFINED, context) 247 assertThat(permissionInfos).isNotNull() 248 } 249 250 @Test getGroupPermissionInfo_permissionName_returnsSamePermissionnull251 fun getGroupPermissionInfo_permissionName_returnsSamePermission() { 252 val permissionInfos = Utils.getGroupPermissionInfos(READ_CONTACTS, context) 253 assertThat(permissionInfos).isNotNull() 254 assertThat(permissionInfos!!.size).isEqualTo(1) 255 assertThat(permissionInfos[0].name).isEqualTo(READ_CONTACTS) 256 } 257 258 @Test getColorResId_validId_returnsNonZeronull259 fun getColorResId_validId_returnsNonZero() { 260 assertThat(Utils.getColorResId(context, android.R.attr.colorPrimary)) 261 .isNotEqualTo(Resources.ID_NULL) 262 } 263 264 @Test getColorResId_inValidId_returnsZeronull265 fun getColorResId_inValidId_returnsZero() { 266 assertThat(Utils.getColorResId(context, INVALID_ATTR_ID)).isEqualTo(Resources.ID_NULL) 267 } 268 269 companion object { 270 private const val INVALID_ATTR_ID = 1000 271 private const val VALID_SESSION_ID = 10000L 272 private const val INVALID_GROUP_NAME = "invalid group name" 273 } 274 } 275