| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package android.appsecurity.cts; |
| |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.fail; |
| import static org.junit.Assume.assumeFalse; |
| |
| import android.platform.test.annotations.AppModeFull; |
| import android.platform.test.annotations.AsbSecurityTest; |
| |
| import com.android.tradefed.log.LogUtil.CLog; |
| import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Tests for ephemeral packages. |
| */ |
| @RunWith(DeviceJUnit4ClassRunner.class) |
| @AppModeFull(reason = "Already handles instant installs when needed") |
| public class EphemeralTest extends BaseAppSecurityTest { |
| |
| // a normally installed application |
| private static final String NORMAL_APK = "CtsEphemeralTestsNormalApp.apk"; |
| private static final String NORMAL_PKG = "com.android.cts.normalapp"; |
| |
| // the first ephemerally installed application |
| private static final String EPHEMERAL_1_APK = "CtsEphemeralTestsEphemeralApp1.apk"; |
| private static final String EPHEMERAL_1_PKG = "com.android.cts.ephemeralapp1"; |
| |
| // the second ephemerally installed application |
| private static final String EPHEMERAL_2_APK = "CtsEphemeralTestsEphemeralApp2.apk"; |
| private static final String EPHEMERAL_2_PKG = "com.android.cts.ephemeralapp2"; |
| |
| // a normally installed application with implicitly exposed components |
| private static final String IMPLICIT_APK = "CtsEphemeralTestsImplicitApp.apk"; |
| private static final String IMPLICIT_PKG = "com.android.cts.implicitapp"; |
| |
| // a normally installed application with no exposed components |
| private static final String UNEXPOSED_APK = "CtsEphemeralTestsUnexposedApp.apk"; |
| private static final String UNEXPOSED_PKG = "com.android.cts.unexposedapp"; |
| |
| // an application that gets upgraded from 'instant' to 'full' |
| private static final String UPGRADED_APK = "CtsInstantUpgradeApp.apk"; |
| private static final String UPGRADED_PKG = "com.android.cts.instantupgradeapp"; |
| |
| private static final String TEST_CLASS = ".ClientTest"; |
| private static final String WEBVIEW_TEST_CLASS = ".WebViewTest"; |
| |
| private static final List<Map<String, String>> EXPECTED_EXPOSED_INTENTS = |
| new ArrayList<>(); |
| static { |
| // Framework intents we expect the system to expose to instant applications |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.CHOOSER", |
| null, null)); |
| // Contact intents we expect the system to expose to instant applications |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.PICK", null, "vnd.android.cursor.dir/contact")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.PICK", null, "vnd.android.cursor.dir/phone_v2")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.PICK", null, "vnd.android.cursor.dir/email_v2")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.PICK", null, "vnd.android.cursor.dir/postal-address_v2")); |
| // Storage intents we expect the system to expose to instant applications |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.OPEN_DOCUMENT", |
| "android.intent.category.OPENABLE", "\\*/\\*")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.OPEN_DOCUMENT", null, "\\*/\\*")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.GET_CONTENT", |
| "android.intent.category.OPENABLE", "\\*/\\*")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.GET_CONTENT", null, "\\*/\\*")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.OPEN_DOCUMENT_TREE", null, null)); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.CREATE_DOCUMENT", |
| "android.intent.category.OPENABLE", "text/plain")); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.intent.action.CREATE_DOCUMENT", null, "text/plain")); |
| /** Camera intents we expect the system to expose to instant applications */ |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.media.action.IMAGE_CAPTURE", null, null)); |
| EXPECTED_EXPOSED_INTENTS.add(makeArgs( |
| "android.media.action.VIDEO_CAPTURE", null, null)); |
| } |
| |
| private String mOldVerifierValue; |
| private Boolean mIsUnsupportedDevice; |
| |
| @Before |
| public void setUp() throws Exception { |
| mIsUnsupportedDevice = isDeviceUnsupported(); |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| |
| Utils.prepareSingleUser(getDevice()); |
| assertNotNull(getAbi()); |
| assertNotNull(getBuild()); |
| |
| uninstallTestPackages(); |
| installTestPackages(); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| uninstallTestPackages(); |
| } |
| |
| @Test |
| public void testNormalQuery() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, "testQuery"); |
| } |
| |
| @Test |
| public void testNormalStartNormal() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, "testStartNormal"); |
| } |
| |
| @Test |
| public void testNormalStartEphemeral() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, |
| "testStartEphemeral"); |
| } |
| |
| @Test |
| public void testEphemeralQuery() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, "testQuery"); |
| } |
| |
| @Test |
| public void testEphemeralStartNormal() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartNormal"); |
| } |
| |
| // each connection to an exposed component needs to run in its own test to |
| // avoid sharing state. once an instant app is exposed to a component, it's |
| // exposed until the device restarts or the instant app is removed. |
| @Test |
| public void testEphemeralStartExposed01() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed01"); |
| } |
| @Test |
| public void testEphemeralStartExposed02() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed02"); |
| } |
| @Test |
| public void testEphemeralStartExposed03() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed03"); |
| } |
| @Test |
| public void testEphemeralStartExposed04() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed04"); |
| } |
| @Test |
| public void testEphemeralStartExposed05() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed05"); |
| } |
| @Test |
| public void testEphemeralStartExposed06() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed06"); |
| } |
| @Test |
| public void testEphemeralStartExposed07() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed07"); |
| } |
| @Test |
| public void testEphemeralStartExposed08() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed08"); |
| } |
| @Test |
| public void testEphemeralStartExposed09() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed09"); |
| } |
| @Test |
| public void testEphemeralStartExposed10() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed10"); |
| } |
| @Test |
| public void testEphemeralStartExposed11() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartExposed11"); |
| } |
| |
| @Test |
| public void testEphemeralStartEphemeral() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartEphemeral"); |
| } |
| |
| @Test |
| public void testEphemeralGetInstaller01() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| installEphemeralApp(EPHEMERAL_1_APK, "com.android.cts.normalapp"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testGetInstaller01"); |
| } |
| @Test |
| public void testEphemeralGetInstaller02() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| installApp(NORMAL_APK, "com.android.cts.normalapp"); |
| installEphemeralApp(EPHEMERAL_1_APK, "com.android.cts.normalapp"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testGetInstaller02"); |
| } |
| @Test |
| public void testEphemeralGetInstaller03() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| installApp(NORMAL_APK, "com.android.cts.normalapp"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testGetInstaller03"); |
| } |
| |
| @Test |
| public void testExposedSystemActivities() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| for (Map<String, String> testArgs : EXPECTED_EXPOSED_INTENTS) { |
| final boolean exposed = isIntentExposed(testArgs); |
| if (exposed) { |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testExposedActivity", testArgs); |
| } else { |
| CLog.w("Skip intent; " + dumpArgs(testArgs)); |
| } |
| } |
| } |
| |
| @Test |
| public void testBuildSerialUnknown() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testBuildSerialUnknown"); |
| } |
| |
| @Test |
| public void testPackageInfo() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testPackageInfo"); |
| } |
| |
| @Test |
| public void testActivityInfo() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testActivityInfo"); |
| } |
| |
| @Test |
| public void testWebViewLoads() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, WEBVIEW_TEST_CLASS, |
| "testWebViewLoads"); |
| } |
| |
| @Test |
| public void testInstallPermissionNotGranted() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testInstallPermissionNotGranted"); |
| } |
| |
| @Test |
| public void testInstallPermissionGranted() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testInstallPermissionGranted"); |
| } |
| |
| @Test |
| @AsbSecurityTest(cveBugId = 140256621) |
| public void testInstallPermissionNotGrantedInPackageInfo() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testInstallPermissionNotGrantedInPackageInfo"); |
| } |
| |
| @Test |
| @AsbSecurityTest(cveBugId = 140256621) |
| public void testInstallPermissionGrantedInPackageInfo() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testInstallPermissionGrantedInPackageInfo"); |
| } |
| |
| /** Test for android.permission.INSTANT_APP_FOREGROUND_SERVICE */ |
| @Test |
| public void testStartForegroundService() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| // Make sure the test package does not have INSTANT_APP_FOREGROUND_SERVICE |
| getDevice().executeShellCommand("cmd package revoke --user cur " + EPHEMERAL_1_PKG |
| + " android.permission.INSTANT_APP_FOREGROUND_SERVICE"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testStartForegroundService"); |
| } |
| |
| /** Test for android.permission.RECORD_AUDIO */ |
| @Test |
| public void testRecordAudioPermission() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testRecordAudioPermission"); |
| } |
| |
| /** Test for android.permission.CAMERA */ |
| @Test |
| public void testCameraPermission() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testCameraPermission"); |
| } |
| |
| /** Test for android.permission.READ_PHONE_NUMBERS */ |
| @Test |
| public void testReadPhoneNumbersPermission() throws Exception { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testReadPhoneNumbersPermission"); |
| } |
| |
| /** Test for android.permission.ACCESS_COARSE_LOCATION */ |
| @Test |
| public void testAccessCoarseLocationPermission() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testAccessCoarseLocationPermission"); |
| } |
| |
| /** Test for android.permission.NETWORK */ |
| @Test |
| public void testInternetPermission() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testInternetPermission"); |
| } |
| |
| /** Test for android.permission.VIBRATE */ |
| @Test |
| public void testVibratePermission() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testVibratePermission"); |
| } |
| |
| /** Test for android.permission.WAKE_LOCK */ |
| @Test |
| public void testWakeLockPermission() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testWakeLockPermission"); |
| } |
| |
| /** Test for search manager */ |
| @Test |
| public void testGetSearchableInfo() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testGetSearchableInfo"); |
| } |
| |
| /** Test for upgrade from instant --> full */ |
| @Test |
| public void testInstantAppUpgrade() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| installEphemeralApp(UPGRADED_APK); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), UPGRADED_PKG, TEST_CLASS, |
| "testInstantApplicationWritePreferences"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), UPGRADED_PKG, TEST_CLASS, |
| "testInstantApplicationWriteFile"); |
| installFullApp(UPGRADED_APK); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), UPGRADED_PKG, TEST_CLASS, |
| "testFullApplicationReadPreferences"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), UPGRADED_PKG, TEST_CLASS, |
| "testFullApplicationReadFile"); |
| } |
| |
| @Test |
| public void testGetChangedPackages() throws Throwable { |
| if (mIsUnsupportedDevice) { |
| return; |
| } |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, |
| "testGetChangedPackages"); |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS, |
| "testGetChangedPackages"); |
| } |
| |
| @Test |
| public void uninstall_userInstalledApp_shouldBeUserInitiated() throws Throwable { |
| assumeFalse("Device does not support instant app", mIsUnsupportedDevice); |
| installEphemeralApp(EPHEMERAL_1_APK, NORMAL_PKG); |
| |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, |
| "uninstall_userInstalledApp_shouldBeUserInitiated"); |
| } |
| |
| @Test |
| public void uninstall_pruneInstantApp_shouldNotBeUserInitiated() |
| throws Throwable { |
| assumeFalse("Device does not support instant app", mIsUnsupportedDevice); |
| |
| Utils.runDeviceTestsAsCurrentUser(getDevice(), NORMAL_PKG, TEST_CLASS, |
| "uninstall_pruneInstantApp_shouldNotBeUserInitiated"); |
| } |
| |
| private static final HashMap<String, String> makeArgs( |
| String action, String category, String mimeType) { |
| if (action == null || action.length() == 0) { |
| fail("action not specified"); |
| } |
| final HashMap<String, String> testArgs = new HashMap<>(); |
| testArgs.put("action", action); |
| if (category != null && category.length() > 0) { |
| testArgs.put("category", category); |
| } |
| if (mimeType != null && mimeType.length() > 0) { |
| testArgs.put("mime_type", mimeType); |
| } |
| return testArgs; |
| } |
| |
| private static final String[] sUnsupportedFeatures = { |
| "feature:android.hardware.type.watch", |
| "android.hardware.type.embedded", |
| }; |
| private boolean isDeviceUnsupported() throws Exception { |
| for (String unsupportedFeature : sUnsupportedFeatures) { |
| if (getDevice().hasFeature(unsupportedFeature)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isIntentExposed(Map<String, String> testArgs) |
| throws Exception { |
| final StringBuffer command = new StringBuffer(); |
| command.append("cmd package query-activities"); |
| command.append(" -a ").append(testArgs.get("action")); |
| if (testArgs.get("category") != null) { |
| command.append(" -c ").append(testArgs.get("category")); |
| } |
| if (testArgs.get("mime_type") != null) { |
| command.append(" -t ").append(testArgs.get("mime_type")); |
| } |
| final String output = getDevice().executeShellCommand(command.toString()).trim(); |
| return !"No activities found".equals(output); |
| } |
| |
| private static final String dumpArgs(Map<String, String> testArgs) { |
| final StringBuffer dump = new StringBuffer(); |
| dump.append("action: ").append(testArgs.get("action")); |
| if (testArgs.get("category") != null) { |
| dump.append(", category: ").append(testArgs.get("category")); |
| } |
| if (testArgs.get("mime_type") != null) { |
| dump.append(", type: ").append(testArgs.get("mime_type")); |
| } |
| return dump.toString(); |
| } |
| |
| private void installApp(String apk) throws Exception { |
| new InstallMultiple(false /* instant */) |
| .addFile(apk) |
| .run(); |
| } |
| |
| private void installApp(String apk, String installer) throws Exception { |
| new InstallMultiple(false /* instant */) |
| .addFile(apk) |
| .addArg("-i " + installer) |
| .run(); |
| } |
| |
| private void installEphemeralApp(String apk) throws Exception { |
| new InstallMultiple(true /* instant */) |
| .addFile(apk) |
| .run(); |
| } |
| |
| private void installEphemeralApp(String apk, String installer) throws Exception { |
| new InstallMultiple(true /* instant */) |
| .addFile(apk) |
| .addArg("-i " + installer) |
| .run(); |
| } |
| |
| private void installFullApp(String apk) throws Exception { |
| new InstallMultiple(false /* instant */) |
| .addFile(apk) |
| .addArg("--full") |
| .run(); |
| } |
| |
| private void installTestPackages() throws Exception { |
| installApp(NORMAL_APK); |
| installApp(UNEXPOSED_APK); |
| installApp(IMPLICIT_APK); |
| |
| installEphemeralApp(EPHEMERAL_1_APK); |
| installEphemeralApp(EPHEMERAL_2_APK); |
| } |
| |
| private void uninstallTestPackages() throws Exception { |
| uninstallPackage(NORMAL_PKG); |
| uninstallPackage(UNEXPOSED_PKG); |
| uninstallPackage(IMPLICIT_PKG); |
| uninstallPackage(EPHEMERAL_1_PKG); |
| uninstallPackage(EPHEMERAL_2_PKG); |
| uninstallPackage(UPGRADED_PKG); |
| } |
| } |