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 org.junit.After
28 import org.junit.Before
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.mockito.ArgumentMatchers.any
32 import org.mockito.ArgumentMatchers.eq
33 import org.mockito.Mock
34 import org.mockito.Mockito.`when`
35 import org.mockito.MockitoAnnotations.initMocks
36 import org.mockito.MockitoSession
37 import org.mockito.quality.Strictness
38 import java.io.File
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
48     lateinit var apexEnvironment: ApexEnvironment
49 
50     private val persistence = RuntimePermissionsPersistence.createInstance()
51     private val permissionState = RuntimePermissionsState.PermissionState("permission", true, 3)
52     private val state = RuntimePermissionsState(
53         1, "fingerprint", mapOf("package" to listOf(permissionState)),
54         mapOf("sharedUser" to listOf(permissionState))
55     )
56     private val user = Process.myUserHandle()
57 
58     @Before
59     fun createMockDataDirectory() {
60         mockDataDirectory = context.getDir("mock_data", Context.MODE_PRIVATE)
61         mockDataDirectory.listFiles()!!.forEach { assertThat(it.deleteRecursively()).isTrue() }
62     }
63 
64     @Before
65     fun mockApexEnvironment() {
66         initMocks(this)
67         mockitoSession = mockitoSession()
68             .mockStatic(ApexEnvironment::class.java)
69             .strictness(Strictness.LENIENT)
70             .startMocking()
71         `when`(ApexEnvironment.getApexEnvironment(eq(APEX_MODULE_NAME))).thenReturn(apexEnvironment)
72         `when`(apexEnvironment.getDeviceProtectedDataDirForUser(any(UserHandle::class.java))).then {
73             File(mockDataDirectory, it.arguments[0].toString()).also { it.mkdirs() }
74         }
75     }
76 
77     @After
78     fun finishMockingApexEnvironment() {
79         mockitoSession.finishMocking()
80     }
81 
82     @Test
83     fun testReadWrite() {
84         persistence.writeForUser(state, user)
85         val persistedState = persistence.readForUser(user)
86 
87         assertThat(persistedState).isEqualTo(state)
88         assertThat(persistedState!!.version).isEqualTo(state.version)
89         assertThat(persistedState.fingerprint).isEqualTo(state.fingerprint)
90         assertThat(persistedState.packagePermissions).isEqualTo(state.packagePermissions)
91         val persistedPermissionState = persistedState.packagePermissions.values.first().first()
92         assertThat(persistedPermissionState.name).isEqualTo(permissionState.name)
93         assertThat(persistedPermissionState.isGranted).isEqualTo(permissionState.isGranted)
94         assertThat(persistedPermissionState.flags).isEqualTo(permissionState.flags)
95         assertThat(persistedState.sharedUserPermissions).isEqualTo(state.sharedUserPermissions)
96     }
97 
98     @Test
99     fun testDelete() {
100         persistence.writeForUser(state, user)
101         persistence.deleteForUser(user)
102         val persistedState = persistence.readForUser(user)
103 
104         assertThat(persistedState).isNull()
105     }
106 
107     companion object {
108         private const val APEX_MODULE_NAME = "com.android.permission"
109     }
110 }
111