blob: 3cafd1c0d41edd058bbba484dc2179d20bbb6d57 [file] [log] [blame]
Svet Ganov29881a52018-02-20 23:18:52 -08001/*
2 * Copyright (C) 2018 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
17package android.server.wm;
18
Svet Ganov29881a52018-02-20 23:18:52 -080019import static android.app.AppOpsManager.MODE_ALLOWED;
Svet Ganov29881a52018-02-20 23:18:52 -080020import static android.app.AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW;
Brett Chabot2ca72e92019-02-15 11:21:51 -080021
22import static androidx.test.InstrumentationRegistry.getInstrumentation;
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090023
Svet Ganov29881a52018-02-20 23:18:52 -080024import static org.junit.Assert.assertFalse;
25import static org.junit.Assert.assertTrue;
26import static org.mockito.ArgumentMatchers.anyBoolean;
27import static org.mockito.ArgumentMatchers.anyInt;
28import static org.mockito.ArgumentMatchers.anyString;
29import static org.mockito.ArgumentMatchers.eq;
30import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.reset;
32import static org.mockito.Mockito.timeout;
33import static org.mockito.Mockito.verify;
34
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090035import android.app.AppOpsManager;
36import android.os.Process;
37import android.platform.test.annotations.Presubmit;
Brett Chabot2ca72e92019-02-15 11:21:51 -080038
Brett Chabot2ca72e92019-02-15 11:21:51 -080039import androidx.test.rule.ActivityTestRule;
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090040
41import com.android.compatibility.common.util.AppOpsUtils;
42
43import org.junit.AfterClass;
44import org.junit.BeforeClass;
45import org.junit.Rule;
46import org.junit.Test;
47
48import java.io.IOException;
49import java.util.concurrent.TimeUnit;
50
Svet Ganov29881a52018-02-20 23:18:52 -080051/**
52 * Test whether system alert window properly interacts with app ops.
53 *
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090054 * Build/Install/Run:
55 * atest CtsWindowManagerDeviceTestCases:AlertWindowsAppOpsTests
Svet Ganov29881a52018-02-20 23:18:52 -080056 */
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090057@Presubmit
Svet Ganov29881a52018-02-20 23:18:52 -080058public class AlertWindowsAppOpsTests {
59 private static final long APP_OP_CHANGE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(2);
60
Bernardo Rufino9ab0d982020-10-15 18:36:34 +000061 private static int sPreviousSawAppOp;
62
Svet Ganov29881a52018-02-20 23:18:52 -080063 @Rule
64 public final ActivityTestRule<AlertWindowsAppOpsTestsActivity> mActivityRule =
65 new ActivityTestRule<>(AlertWindowsAppOpsTestsActivity.class);
66
67 @BeforeClass
68 public static void grantSystemAlertWindowAccess() throws IOException {
Bernardo Rufino9ab0d982020-10-15 18:36:34 +000069 String packageName = getInstrumentation().getContext().getPackageName();
70 sPreviousSawAppOp = AppOpsUtils.getOpMode(packageName, OPSTR_SYSTEM_ALERT_WINDOW);
71 AppOpsUtils.setOpMode(packageName, OPSTR_SYSTEM_ALERT_WINDOW, MODE_ALLOWED);
Svet Ganov29881a52018-02-20 23:18:52 -080072 }
73
74 @AfterClass
75 public static void revokeSystemAlertWindowAccess() throws IOException {
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090076 AppOpsUtils.setOpMode(getInstrumentation().getContext().getPackageName(),
Bernardo Rufino9ab0d982020-10-15 18:36:34 +000077 OPSTR_SYSTEM_ALERT_WINDOW, sPreviousSawAppOp);
Svet Ganov29881a52018-02-20 23:18:52 -080078 }
79
80 @Test
81 public void testSystemAlertWindowAppOpsInitiallyAllowed() {
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090082 final String packageName = getInstrumentation().getContext().getPackageName();
Svet Ganov29881a52018-02-20 23:18:52 -080083 final int uid = Process.myUid();
84
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +090085 final AppOpsManager appOpsManager = getInstrumentation().getContext()
86 .getSystemService(AppOpsManager.class);
Svet Ganov29881a52018-02-20 23:18:52 -080087 final AppOpsManager.OnOpActiveChangedListener listener = mock(
88 AppOpsManager.OnOpActiveChangedListener.class);
89
90 // Launch our activity.
91 final AlertWindowsAppOpsTestsActivity activity = mActivityRule.getActivity();
92
93 // Start watching for app op
Jeff Sharkey055639b2019-08-20 16:50:37 -060094 appOpsManager.startWatchingActive(new String[] { OPSTR_SYSTEM_ALERT_WINDOW },
95 getInstrumentation().getContext().getMainExecutor(), listener);
Svet Ganov29881a52018-02-20 23:18:52 -080096
97 // Assert the app op is not started
Jeff Sharkey055639b2019-08-20 16:50:37 -060098 assertFalse(appOpsManager.isOpActive(OPSTR_SYSTEM_ALERT_WINDOW, uid, packageName));
Svet Ganov29881a52018-02-20 23:18:52 -080099
100
101 // Show a system alert window.
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +0900102 getInstrumentation().runOnMainSync(activity::showSystemAlertWindow);
Svet Ganov29881a52018-02-20 23:18:52 -0800103
104 // The app op should start
105 verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS)
Jeff Sharkey055639b2019-08-20 16:50:37 -0600106 .only()).onOpActiveChanged(eq(OPSTR_SYSTEM_ALERT_WINDOW),
Svet Ganov29881a52018-02-20 23:18:52 -0800107 eq(uid), eq(packageName), eq(true));
108
109 // The app op should be reported as started
Jeff Sharkey055639b2019-08-20 16:50:37 -0600110 assertTrue(appOpsManager.isOpActive(OPSTR_SYSTEM_ALERT_WINDOW,
Svet Ganov29881a52018-02-20 23:18:52 -0800111 uid, packageName));
112
113
114 // Start with a clean slate
115 reset(listener);
116
117 // Hide a system alert window.
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +0900118 getInstrumentation().runOnMainSync(activity::hideSystemAlertWindow);
Svet Ganov29881a52018-02-20 23:18:52 -0800119
120 // The app op should finish
121 verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS)
Jeff Sharkey055639b2019-08-20 16:50:37 -0600122 .only()).onOpActiveChanged(eq(OPSTR_SYSTEM_ALERT_WINDOW),
Svet Ganov29881a52018-02-20 23:18:52 -0800123 eq(uid), eq(packageName), eq(false));
124
125 // The app op should be reported as finished
Jeff Sharkey055639b2019-08-20 16:50:37 -0600126 assertFalse(appOpsManager.isOpActive(OPSTR_SYSTEM_ALERT_WINDOW, uid, packageName));
Svet Ganov29881a52018-02-20 23:18:52 -0800127
128
129 // Start with a clean slate
130 reset(listener);
131
132 // Stop watching for app op
133 appOpsManager.stopWatchingActive(listener);
134
135 // Show a system alert window
Tadashi G. Takaokaf280a9b2019-02-01 15:28:04 +0900136 getInstrumentation().runOnMainSync(activity::showSystemAlertWindow);
Svet Ganov29881a52018-02-20 23:18:52 -0800137
138 // No other callbacks expected
139 verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS).times(0))
Jeff Sharkey055639b2019-08-20 16:50:37 -0600140 .onOpActiveChanged(eq(OPSTR_SYSTEM_ALERT_WINDOW),
Svet Ganov29881a52018-02-20 23:18:52 -0800141 anyInt(), anyString(), anyBoolean());
142
143 // The app op should be reported as started
Jeff Sharkey055639b2019-08-20 16:50:37 -0600144 assertTrue(appOpsManager.isOpActive(OPSTR_SYSTEM_ALERT_WINDOW, uid, packageName));
Svet Ganov29881a52018-02-20 23:18:52 -0800145 }
Wale Ogunwale5871c5b2019-02-21 15:56:14 -0800146}