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 package android.platform.test.rule
17 
18 import android.app.role.RoleManager
19 import android.os.Build
20 import android.platform.helpers.notesrole.NotesRoleUtil
21 import android.provider.Settings
22 import org.junit.runner.Description
23 
24 /**
25  * This rule allows end-to-end tests to manage requirements pertaining to [RoleManager.ROLE_NOTES].
26  *
27  * @param requiredAndroidVersion enforce required Android version, default is Android U
28  * @param requiredNotesRoleHolderPackage the package name for the [RoleManager.ROLE_NOTES] holder
29  *   that should be used in the tests. The rule will take care of setting and restoring the role
30  *   holder for each test. Test will be skipped if the provided package is not installed. The rule
31  *   will also ensure to kill this app before and after the test to ensure clean state.
32  */
33 class NotesRoleManagerRule
34 @JvmOverloads
35 constructor(
36     private val requiredAndroidVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
37     private val requiredNotesRoleHolderPackage: String,
38     private val isStylusEverUsed: Boolean = true,
39 ) : TestWatcher() {
40 
41     /**
42      * A [NotesRoleUtil] helper instance. Should be used in E2E tests for changing and asserting the
43      * current [RoleManager.ROLE_NOTES].
44      */
45     val utils = NotesRoleUtil(context)
46     private val contentResolver = context.contentResolver
47 
48     private var prevNotesRoleHolder: String? = null
49     private var previousStylusEverUsed: Int = 1
50 
startingnull51     override fun starting(description: Description?) {
52         super.starting(description)
53 
54         // Check if the device configuration can run the test. Assumption is used instead of
55         // assertion because not all devices have the Notes role or the required app installed.
56         // So this rule takes care of skipping the test on incompatible devices. This is a
57         // workaround to run the test on select few devices.
58         utils.checkAndroidRolePackageAssumptions(
59             requiredAndroidVersion,
60             requiredNotesRoleHolderPackage
61         )
62 
63         prevNotesRoleHolder = utils.getRoleHolderPackageName()
64         utils.setRoleHolder(requiredNotesRoleHolderPackage)
65 
66         // Kill the supplied Notes role holder app to avoid issues during verification in test.
67         utils.forceStopPackage(requiredNotesRoleHolderPackage)
68 
69         previousStylusEverUsed =
70             Settings.Global.getInt(contentResolver, Settings.Global.STYLUS_EVER_USED, /* def= */ 0)
71         setStylusEverUsed(if (isStylusEverUsed) 1 else 0)
72     }
73 
finishednull74     override fun finished(description: Description?) {
75         super.finished(description)
76 
77         utils.forceStopPackage(requiredNotesRoleHolderPackage)
78 
79         prevNotesRoleHolder?.let { utils.setRoleHolder(it) }
80 
81         setStylusEverUsed(previousStylusEverUsed)
82     }
83 
setStylusEverUsednull84     private fun setStylusEverUsed(stylusEverUsed: Int) {
85         Settings.Global.putInt(contentResolver, Settings.Global.STYLUS_EVER_USED, stylusEverUsed)
86     }
87 }
88