Home | History | Annotate | Download | only in launchertests
      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