1 /* 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 17 package android.harmfulappwarning.cts; 18 19 import com.android.tradefed.device.DeviceNotAvailableException; 20 import com.android.tradefed.device.ITestDevice; 21 import com.android.tradefed.device.PackageInfo; 22 import com.android.tradefed.result.InputStreamSource; 23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 24 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 25 26 import org.junit.Assert; 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 31 import java.util.Scanner; 32 33 import static org.junit.Assert.assertEquals; 34 import static org.junit.Assert.assertNull; 35 import static org.junit.Assert.assertTrue; 36 import static org.junit.Assume.assumeFalse; 37 38 /** 39 * Host-side tests for the harmful app launch warning 40 * 41 * <p>These tests have a few different components. This is the host-side part of the test, which is 42 * responsible for setting up the environment and passing off execution to the device-side part 43 * of the test. 44 * 45 * <p>The {@link HarmfulAppWarningDeviceTest} class is the device side of these tests. It attempts to launch 46 * the sample warned application, and verifies the correct behavior of the harmful app warning that 47 * is shown by the platform. 48 * 49 * <p>The third component is the sample app, which is just a placeholder app with a basic activity 50 * that only serves as a target for the harmful app warning. 51 * 52 * <p>Run with: atest CtsHarmfulAppWarningHostTestCases 53 */ 54 @RunWith(DeviceJUnit4ClassRunner.class) 55 public class HarmfulAppWarningTest extends BaseHostJUnit4Test { 56 57 private static final String FEATURE_WEARABLE = "android.hardware.type.watch"; 58 59 private static final String TEST_APP_PACKAGE_NAME = "android.harmfulappwarning.sampleapp"; 60 private static final String TEST_APP_ACTIVITY_CLASS_NAME = "SampleDeviceActivity"; 61 private static final String TEST_APP_LAUNCHED_STRING = "Sample activity started."; 62 63 private static final String WARNING_MESSAGE = "This is a warning message."; 64 private static final String SET_HARMFUL_APP_WARNING_COMMAND = String.format( 65 "cmd package set-harmful-app-warning %s \"" + WARNING_MESSAGE + "\"", 66 TEST_APP_PACKAGE_NAME); 67 68 private static final String CLEAR_HARMFUL_APP_WARNING_COMMAND = String.format( 69 "cmd package set-harmful-app-warning %s", TEST_APP_PACKAGE_NAME); 70 71 private static final String GET_HARMFUL_APP_WARNING_COMMAND = String.format( 72 "cmd package get-harmful-app-warning %s", TEST_APP_PACKAGE_NAME); 73 74 private ITestDevice mDevice; 75 76 @Before 77 public void setUp() throws Exception { 78 installPackage("CtsHarmfulAppWarningSampleApp.apk"); 79 mDevice = getDevice(); 80 mDevice.clearLogcat(); 81 82 // Skip the tests for wearable devices. This feature is not used on wearable 83 // devices, for now (no wearable UI, etc.) 84 assumeFalse(hasFeature(FEATURE_WEARABLE)); 85 } 86 87 private void runDeviceTest(String testName) throws DeviceNotAvailableException { 88 runDeviceTests("android.harmfulappwarning.testapp", 89 "android.harmfulappwarning.testapp.HarmfulAppWarningDeviceTest", 90 testName); 91 } 92 93 private void verifyHarmfulAppWarningSet() throws DeviceNotAvailableException { 94 String warning = getDevice().executeShellCommand(GET_HARMFUL_APP_WARNING_COMMAND); 95 assertEquals(WARNING_MESSAGE, warning.trim()); 96 } 97 98 private void verifyHarmfulAppWarningUnset() throws DeviceNotAvailableException { 99 String warning = getDevice().executeShellCommand(GET_HARMFUL_APP_WARNING_COMMAND); 100 if (warning != null) { 101 warning = warning.trim(); 102 } 103 assertTrue(warning == null || warning.length() == 0); 104 } 105 106 private void verifySampleAppUninstalled() throws DeviceNotAvailableException { 107 PackageInfo info = getDevice().getAppPackageInfo(TEST_APP_PACKAGE_NAME); 108 Assert.assertNull("Harmful application was not uninstalled", info); 109 } 110 111 private void verifySampleAppInstalled() throws DeviceNotAvailableException { 112 PackageInfo info = getDevice().getAppPackageInfo(TEST_APP_PACKAGE_NAME); 113 Assert.assertNotNull("Harmful application was uninstalled", info); 114 } 115 116 /** 117 * A basic smoke test to ensure that we're able to detect the launch of the activity when there 118 * is no warning. 119 */ 120 @Test 121 public void testNormalLaunch() throws Exception { 122 runDeviceTest("testNormalLaunch"); 123 } 124 125 /** 126 * Tests that when the user clicks "launch anyway" on the harmful app warning dialog, the 127 * warning is cleared and the activity is launched. 128 */ 129 @Test 130 public void testLaunchAnyway() throws DeviceNotAvailableException { 131 mDevice.executeShellCommand(SET_HARMFUL_APP_WARNING_COMMAND); 132 runDeviceTest("testLaunchAnyway"); 133 134 verifyHarmfulAppWarningUnset(); 135 } 136 137 /** 138 * Tests that when the user clicks "uninstall" on the harmful app warning dialog, the 139 * application is uninstalled. 140 */ 141 @Test 142 public void testUninstall() throws DeviceNotAvailableException { 143 mDevice.executeShellCommand(SET_HARMFUL_APP_WARNING_COMMAND); 144 runDeviceTest("testUninstall"); 145 verifySampleAppUninstalled(); 146 } 147 148 /** 149 * Tests that no action is taken when the user dismisses the harmful app warning 150 */ 151 @Test 152 public void testDismissDialog() throws DeviceNotAvailableException { 153 mDevice.executeShellCommand(SET_HARMFUL_APP_WARNING_COMMAND); 154 runDeviceTest("testDismissDialog"); 155 verifyHarmfulAppWarningSet(); 156 verifySampleAppInstalled(); 157 } 158 159 protected boolean hasFeature(String featureName) throws DeviceNotAvailableException { 160 return getDevice().executeShellCommand("pm list features").contains(featureName); 161 } 162 } 163