1 /* 2 * Copyright (C) 2020 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.permission.persistence 18 19 import android.content.ApexEnvironment 20 import android.content.Context 21 import android.os.Process 22 import android.os.UserHandle 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.platform.app.InstrumentationRegistry 25 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession 26 import com.google.common.truth.Truth.assertThat 27 import java.io.File 28 import org.junit.After 29 import org.junit.Before 30 import org.junit.Test 31 import org.junit.runner.RunWith 32 import org.mockito.ArgumentMatchers.any 33 import org.mockito.ArgumentMatchers.eq 34 import org.mockito.Mock 35 import org.mockito.Mockito.`when` 36 import org.mockito.MockitoAnnotations.initMocks 37 import org.mockito.MockitoSession 38 import org.mockito.quality.Strictness 39 40 @RunWith(AndroidJUnit4::class) 41 class RuntimePermissionsPersistenceTest { 42 private val context = InstrumentationRegistry.getInstrumentation().context 43 44 private lateinit var mockDataDirectory: File 45 46 private lateinit var mockitoSession: MockitoSession 47 @Mock lateinit var apexEnvironment: ApexEnvironment 48 <lambda>null49 private val persistence = RuntimePermissionsPersistenceImpl {} 50 private val permissionState = RuntimePermissionsState.PermissionState("permission", true, 3) 51 private val state = 52 RuntimePermissionsState( 53 1, 54 "fingerprint", 55 mapOf("package" to listOf(permissionState)), 56 mapOf("sharedUser" to listOf(permissionState)) 57 ) 58 private val user = Process.myUserHandle() 59 60 @Before createMockDataDirectorynull61 fun createMockDataDirectory() { 62 mockDataDirectory = context.getDir("mock_data", Context.MODE_PRIVATE) 63 mockDataDirectory.listFiles()!!.forEach { assertThat(it.deleteRecursively()).isTrue() } 64 } 65 66 @Before mockApexEnvironmentnull67 fun mockApexEnvironment() { 68 initMocks(this) 69 mockitoSession = 70 mockitoSession() 71 .mockStatic(ApexEnvironment::class.java) 72 .strictness(Strictness.LENIENT) 73 .startMocking() 74 `when`(ApexEnvironment.getApexEnvironment(eq(APEX_MODULE_NAME))).thenReturn(apexEnvironment) 75 `when`(apexEnvironment.getDeviceProtectedDataDirForUser(any(UserHandle::class.java))).then { 76 File(mockDataDirectory, it.arguments[0].toString()).also { it.mkdirs() } 77 } 78 } 79 80 @After finishMockingApexEnvironmentnull81 fun finishMockingApexEnvironment() { 82 mockitoSession.finishMocking() 83 } 84 85 @Test testWriteReadnull86 fun testWriteRead() { 87 persistence.writeForUser(state, user) 88 val persistedState = persistence.readForUser(user) 89 90 checkPersistedState(persistedState!!) 91 } 92 93 @Test testWriteCorruptReadFromReserveCopynull94 fun testWriteCorruptReadFromReserveCopy() { 95 persistence.writeForUser(state, user) 96 // Corrupt the primary file. 97 RuntimePermissionsPersistenceImpl.getFile(user) 98 .writeText( 99 "<runtime-permissions version=\"10\"><package name=\"com.foo.bar\"><permission" 100 ) 101 val persistedState = persistence.readForUser(user) 102 103 checkPersistedState(persistedState!!) 104 } 105 106 @Test testDeletenull107 fun testDelete() { 108 persistence.writeForUser(state, user) 109 persistence.deleteForUser(user) 110 val persistedState = persistence.readForUser(user) 111 112 assertThat(persistedState).isNull() 113 } 114 checkPersistedStatenull115 private fun checkPersistedState(persistedState: RuntimePermissionsState) { 116 assertThat(persistedState).isEqualTo(state) 117 assertThat(persistedState.version).isEqualTo(state.version) 118 assertThat(persistedState.fingerprint).isEqualTo(state.fingerprint) 119 assertThat(persistedState.packagePermissions).isEqualTo(state.packagePermissions) 120 val persistedPermissionState = persistedState.packagePermissions.values.first().first() 121 assertThat(persistedPermissionState.name).isEqualTo(permissionState.name) 122 assertThat(persistedPermissionState.isGranted).isEqualTo(permissionState.isGranted) 123 assertThat(persistedPermissionState.flags).isEqualTo(permissionState.flags) 124 assertThat(persistedState.sharedUserPermissions).isEqualTo(state.sharedUserPermissions) 125 } 126 127 companion object { 128 private const val APEX_MODULE_NAME = "com.android.permission" 129 } 130 } 131