1 /* 2 * Copyright (C) 2017 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 com.android.cts.launchertests; 17 18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher; 19 20 import static junit.framework.Assert.assertFalse; 21 import static junit.framework.Assert.assertNotNull; 22 import static junit.framework.Assert.assertTrue; 23 24 import static org.testng.Assert.assertThrows; 25 26 import android.content.BroadcastReceiver; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.os.Bundle; 31 import android.os.UserHandle; 32 import android.os.UserManager; 33 import android.support.test.InstrumentationRegistry; 34 import android.support.test.runner.AndroidJUnit4; 35 import android.support.test.uiautomator.UiDevice; 36 import android.text.TextUtils; 37 38 import com.android.compatibility.common.util.BlockingBroadcastReceiver; 39 40 import org.junit.After; 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 45 import java.util.concurrent.LinkedBlockingQueue; 46 import java.util.concurrent.TimeUnit; 47 48 /** 49 * Test that runs {@link UserManager#trySetQuietModeEnabled(boolean, UserHandle)} API 50 * against valid target user. 51 */ 52 @RunWith(AndroidJUnit4.class) 53 public class QuietModeTest { 54 private static final String PARAM_TARGET_USER = "TARGET_USER"; 55 private static final String PARAM_ORIGINAL_DEFAULT_LAUNCHER = "ORIGINAL_DEFAULT_LAUNCHER"; 56 private static final ComponentName LAUNCHER_ACTIVITY = 57 new ComponentName( 58 "com.android.cts.launchertests.support", 59 "com.android.cts.launchertests.support.LauncherActivity"); 60 61 private static final ComponentName COMMAND_RECEIVER = 62 new ComponentName( 63 "com.android.cts.launchertests.support", 64 "com.android.cts.launchertests.support.QuietModeCommandReceiver"); 65 66 private UserManager mUserManager; 67 private UserHandle mTargetUser; 68 private Context mContext; 69 private String mOriginalLauncher; 70 private UiDevice mUiDevice; 71 72 @Before 73 public void setupUserManager() throws Exception { 74 mContext = InstrumentationRegistry.getTargetContext(); 75 mUserManager = mContext.getSystemService(UserManager.class); 76 } 77 78 @Before 79 public void readParams() { 80 Context context = InstrumentationRegistry.getContext(); 81 Bundle arguments = InstrumentationRegistry.getArguments(); 82 UserManager userManager = context.getSystemService(UserManager.class); 83 final int userSn = Integer.parseInt(arguments.getString(PARAM_TARGET_USER)); 84 mTargetUser = userManager.getUserForSerialNumber(userSn); 85 mOriginalLauncher = arguments.getString(PARAM_ORIGINAL_DEFAULT_LAUNCHER); 86 } 87 88 @Before 89 public void wakeupDeviceAndUnlock() throws Exception { 90 mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 91 mUiDevice.wakeUp(); 92 mUiDevice.pressMenu(); 93 } 94 95 @Before 96 @After 97 public void revertToDefaultLauncher() throws Exception { 98 if (TextUtils.isEmpty(mOriginalLauncher)) { 99 return; 100 } 101 setDefaultLauncher(InstrumentationRegistry.getInstrumentation(), mOriginalLauncher); 102 startActivitySync(mOriginalLauncher); 103 } 104 105 @Test 106 public void testTryEnableQuietMode_defaultForegroundLauncher() throws Exception { 107 setTestAppAsDefaultLauncher(); 108 startLauncherActivityInTestApp(); 109 110 Intent intent = trySetQuietModeEnabled(true); 111 assertNotNull("Failed to receive ACTION_MANAGED_PROFILE_UNAVAILABLE broadcast", intent); 112 assertTrue(mUserManager.isQuietModeEnabled(mTargetUser)); 113 114 intent = trySetQuietModeEnabled(false); 115 assertNotNull("Failed to receive ACTION_MANAGED_PROFILE_AVAILABLE broadcast", intent); 116 assertFalse(mUserManager.isQuietModeEnabled(mTargetUser)); 117 } 118 119 @Test 120 public void testTryEnableQuietMode_notForegroundLauncher() throws InterruptedException { 121 setTestAppAsDefaultLauncher(); 122 123 assertThrows(SecurityException.class, () -> trySetQuietModeEnabled(true)); 124 assertFalse(mUserManager.isQuietModeEnabled(mTargetUser)); 125 } 126 127 @Test 128 public void testTryEnableQuietMode_notDefaultLauncher() throws Exception { 129 startLauncherActivityInTestApp(); 130 131 assertThrows(SecurityException.class, () -> trySetQuietModeEnabled(true)); 132 assertFalse(mUserManager.isQuietModeEnabled(mTargetUser)); 133 } 134 135 private Intent trySetQuietModeEnabled(boolean enabled) throws Exception { 136 final String action = enabled 137 ? Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE 138 : Intent.ACTION_MANAGED_PROFILE_AVAILABLE; 139 140 BlockingBroadcastReceiver receiver = 141 new BlockingBroadcastReceiver(mContext, action); 142 try { 143 receiver.register(); 144 145 boolean notShowingConfirmCredential = askLauncherSupportAppToSetQuietMode(enabled); 146 assertTrue(notShowingConfirmCredential); 147 148 return receiver.awaitForBroadcast(); 149 } finally { 150 receiver.unregisterQuietly(); 151 } 152 } 153 154 /** 155 * Ask launcher support test app to set quiet mode by sending broadcast. 156 * <p> 157 * We cannot simply make this package the launcher and call the API because instrumentation 158 * process would always considered to be in the foreground. The trick here is to send 159 * broadcast to another test app which is launcher itself and call the API through it. 160 * The receiver will then send back the result, and it should be either true, false or 161 * security-exception. 162 * <p> 163 * All the constants defined here should be aligned with 164 * com.android.cts.launchertests.support.QuietModeCommandReceiver. 165 */ 166 private boolean askLauncherSupportAppToSetQuietMode(boolean enabled) throws Exception { 167 Intent intent = new Intent("toggle_quiet_mode"); 168 intent.setComponent(COMMAND_RECEIVER); 169 intent.putExtra("quiet_mode", enabled); 170 intent.putExtra(Intent.EXTRA_USER, mTargetUser); 171 172 // Ask launcher support app to set quiet mode by sending broadcast. 173 LinkedBlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(); 174 mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { 175 @Override 176 public void onReceive(Context context, Intent intent) { 177 blockingQueue.offer(getResultData()); 178 } 179 }, null, 0, "", null); 180 181 // Wait for the result. 182 String result = null; 183 for (int i = 0; i < 10; i++) { 184 // Broadcast won't be delivered when the device is sleeping, so wake up the device 185 // in between each attempt. 186 wakeupDeviceAndUnlock(); 187 result = blockingQueue.poll(10, TimeUnit.SECONDS); 188 if (!TextUtils.isEmpty(result)) { 189 break; 190 } 191 } 192 193 // Parse the result. 194 assertNotNull(result); 195 if ("true".equalsIgnoreCase(result)) { 196 return true; 197 } else if ("false".equalsIgnoreCase(result)) { 198 return false; 199 } else if ("security-exception".equals(result)) { 200 throw new SecurityException(); 201 } 202 throw new IllegalStateException("Unexpected result : " + result); 203 } 204 205 private void startActivitySync(String activity) throws Exception { 206 mUiDevice.executeShellCommand("am start -W -n " + activity); 207 } 208 209 /** 210 * Start the launcher activity in the test app to make it foreground. 211 */ 212 private void startLauncherActivityInTestApp() throws Exception { 213 startActivitySync(LAUNCHER_ACTIVITY.flattenToString()); 214 } 215 216 private void setTestAppAsDefaultLauncher() { 217 setDefaultLauncher( 218 InstrumentationRegistry.getInstrumentation(), 219 LAUNCHER_ACTIVITY.flattenToString()); 220 } 221 } 222 223