1 /* 2 * Copyright (C) 2012 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.app.tests; 17 18 import com.android.tradefed.build.IAppBuildInfo; 19 import com.android.tradefed.build.IBuildInfo; 20 import com.android.tradefed.build.VersionedFile; 21 import com.android.tradefed.device.DeviceNotAvailableException; 22 import com.android.tradefed.device.ITestDevice; 23 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 24 import com.android.tradefed.result.ITestInvocationListener; 25 import com.android.tradefed.result.InputStreamSource; 26 import com.android.tradefed.result.LogDataType; 27 import com.android.tradefed.result.TestDescription; 28 import com.android.tradefed.testtype.IBuildReceiver; 29 import com.android.tradefed.testtype.IDeviceTest; 30 import com.android.tradefed.testtype.IRemoteTest; 31 import com.android.tradefed.testtype.InstrumentationTest; 32 import com.android.tradefed.util.AaptParser; 33 import com.android.tradefed.util.FileUtil; 34 35 import org.junit.Assert; 36 37 import java.io.File; 38 import java.util.HashMap; 39 40 /** 41 * A harness that installs and launches an app on device and verifies it doesn't crash. 42 * 43 * <p>Requires a {@link IAppBuildInfo} and 'aapt' being present in path. Assume the AppLaunch test 44 * app is already present on device. 45 */ 46 public class AppLaunchTest implements IDeviceTest, IRemoteTest, IBuildReceiver { 47 48 private static final String RUN_NAME = "AppLaunch"; 49 private ITestDevice mDevice; 50 private IBuildInfo mBuild; 51 52 /** {@inheritDoc} */ 53 @Override setDevice(ITestDevice device)54 public void setDevice(ITestDevice device) { 55 mDevice = device; 56 } 57 58 /** {@inheritDoc} */ 59 @Override getDevice()60 public ITestDevice getDevice() { 61 return mDevice; 62 } 63 64 /** {@inheritDoc} */ 65 @Override setBuild(IBuildInfo buildInfo)66 public void setBuild(IBuildInfo buildInfo) { 67 mBuild = buildInfo; 68 } 69 70 /** 71 * Installs all apks listed in {@link IAppBuildInfo}, then attempts to run the package in the 72 * first apk. Note that this does <emph>not</emph> attempt to uninstall the apks, and requires 73 * external cleanup. 74 * 75 * <p>{@inheritDoc} 76 */ 77 @Override run(ITestInvocationListener listener)78 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 79 long startTime = System.currentTimeMillis(); 80 listener.testRunStarted(RUN_NAME, 2); 81 try { 82 Assert.assertTrue(mBuild instanceof IAppBuildInfo); 83 IAppBuildInfo appBuild = (IAppBuildInfo) mBuild; 84 Assert.assertFalse(appBuild.getAppPackageFiles().isEmpty()); 85 86 // We assume that the first apk is the one to be executed, and any others are to be 87 // installed and uninstalled. 88 File appApkFile = appBuild.getAppPackageFiles().get(0).getFile(); 89 AaptParser p = AaptParser.parse(appApkFile); 90 Assert.assertNotNull(p); 91 String packageName = p.getPackageName(); 92 Assert.assertNotNull( 93 String.format( 94 "Failed to parse package name from %s", appApkFile.getAbsolutePath()), 95 packageName); 96 97 for (final VersionedFile apkVersionedFile : appBuild.getAppPackageFiles()) { 98 final File apkFile = apkVersionedFile.getFile(); 99 performInstallTest(apkFile, listener); 100 } 101 102 performLaunchTest(packageName, listener); 103 } catch (AssertionError e) { 104 listener.testRunFailed(e.toString()); 105 } finally { 106 listener.testRunEnded( 107 System.currentTimeMillis() - startTime, new HashMap<String, Metric>()); 108 } 109 } 110 performInstallTest(File apkFile, ITestInvocationListener listener)111 private void performInstallTest(File apkFile, ITestInvocationListener listener) 112 throws DeviceNotAvailableException { 113 TestDescription installTest = 114 new TestDescription( 115 "com.android.app.tests.InstallTest", 116 FileUtil.getBaseName(apkFile.getName())); 117 listener.testStarted(installTest); 118 String result = getDevice().installPackage(apkFile, true); 119 if (result != null) { 120 listener.testFailed(installTest, result); 121 } 122 listener.testEnded(installTest, new HashMap<String, Metric>()); 123 } 124 performLaunchTest(String packageName, ITestInvocationListener listener)125 private void performLaunchTest(String packageName, ITestInvocationListener listener) 126 throws DeviceNotAvailableException { 127 InstrumentationTest i = new InstrumentationTest(); 128 i.setRunName(RUN_NAME); 129 i.setPackageName("com.android.applaunchtest"); 130 i.setRunnerName("com.android.applaunchtest.AppLaunchRunner"); 131 i.setDevice(getDevice()); 132 i.addInstrumentationArg("packageName", packageName); 133 i.run(listener); 134 try (InputStreamSource s = getDevice().getScreenshot()) { 135 listener.testLog("screenshot", LogDataType.PNG, s); 136 } 137 } 138 } 139