• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2022 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 android.trust.test.lib
18 
19 import android.content.Context
20 import android.util.Log
21 import android.view.KeyEvent
22 import android.view.WindowManagerGlobal
23 import androidx.test.core.app.ApplicationProvider.getApplicationContext
24 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
25 import androidx.test.uiautomator.UiDevice
26 import com.android.internal.widget.LockPatternUtils
27 import com.android.internal.widget.LockscreenCredential
28 import com.google.common.truth.Truth.assertWithMessage
29 import org.junit.rules.TestRule
30 import org.junit.runner.Description
31 import org.junit.runners.model.Statement
32 
33 /**
34  * Sets a screen lock on the device for the duration of the test.
35  */
36 class ScreenLockRule : TestRule {
37     private val context: Context = getApplicationContext()
38     private val uiDevice = UiDevice.getInstance(getInstrumentation())
39     private val windowManager = WindowManagerGlobal.getWindowManagerService()
40     private val lockPatternUtils = LockPatternUtils(context)
41     private var instantLockSavedValue = false
42 
43     override fun apply(base: Statement, description: Description) = object : Statement() {
44         override fun evaluate() {
45             verifyNoScreenLockAlreadySet()
46             dismissKeyguard()
47             setScreenLock()
48             setLockOnPowerButton()
49 
50             try {
51                 base.evaluate()
52             } finally {
53                 removeScreenLock()
54                 revertLockOnPowerButton()
55                 dismissKeyguard()
56             }
57         }
58     }
59 
60     private fun verifyNoScreenLockAlreadySet() {
61         assertWithMessage("Screen Lock must not already be set on device")
62                 .that(lockPatternUtils.isSecure(context.userId))
63                 .isFalse()
64     }
65 
66     fun dismissKeyguard() {
67         wait("keyguard dismissed") { count ->
68             if (!uiDevice.isScreenOn) {
69                 Log.i(TAG, "Waking device, +500ms")
70                 uiDevice.wakeUp()
71             }
72 
73             // Bouncer may be shown due to a race; back dismisses it
74             if (count >= 10) {
75                 Log.i(TAG, "Pressing back to dismiss Bouncer")
76                 uiDevice.pressKeyCode(KeyEvent.KEYCODE_BACK)
77             }
78 
79             windowManager.dismissKeyguard(null, null)
80 
81             !windowManager.isKeyguardLocked
82         }
83     }
84 
85     private fun setScreenLock() {
86         lockPatternUtils.setLockCredential(
87                 LockscreenCredential.createPin(PIN),
88                 LockscreenCredential.createNone(),
89                 context.userId
90         )
91         wait("screen lock set") { lockPatternUtils.isSecure(context.userId) }
92         Log.i(TAG, "Device PIN set to $PIN")
93     }
94 
95     private fun setLockOnPowerButton() {
96         instantLockSavedValue = lockPatternUtils.getPowerButtonInstantlyLocks(context.userId)
97         lockPatternUtils.setPowerButtonInstantlyLocks(true, context.userId)
98     }
99 
100     private fun removeScreenLock() {
101         var lockCredentialUnset = lockPatternUtils.setLockCredential(
102                 LockscreenCredential.createNone(),
103                 LockscreenCredential.createPin(PIN),
104                 context.userId)
105         Log.i(TAG, "Removing screen lock")
106         assertWithMessage("Lock screen credential should be unset")
107                 .that(lockCredentialUnset)
108                 .isTrue()
109 
110         lockPatternUtils.setLockScreenDisabled(true, context.userId)
111         wait("screen lock un-set") {
112             lockPatternUtils.isLockScreenDisabled(context.userId)
113         }
114         wait("screen lock insecure") { !lockPatternUtils.isSecure(context.userId) }
115     }
116 
117     private fun revertLockOnPowerButton() {
118         lockPatternUtils.setPowerButtonInstantlyLocks(instantLockSavedValue, context.userId)
119     }
120 
121     companion object {
122         private const val TAG = "ScreenLockRule"
123         private const val PIN = "0000"
124     }
125 }
126