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 * <p/> 43 * Requires a {@link IAppBuildInfo} and 'aapt' being present in path. Assume the AppLaunch 44 * test 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 /** 53 * {@inheritDoc} 54 */ 55 @Override 56 public void setDevice(ITestDevice device) { 57 mDevice = device; 58 } 59 60 /** 61 * {@inheritDoc} 62 */ 63 @Override 64 public ITestDevice getDevice() { 65 return mDevice; 66 } 67 68 /** 69 * {@inheritDoc} 70 */ 71 @Override 72 public void setBuild(IBuildInfo buildInfo) { 73 mBuild = buildInfo; 74 } 75 76 /** 77 * Installs all apks listed in {@link IAppBuildInfo}, then attempts to run the package in the 78 * first apk. Note that this does <emph>not</emph> attempt to uninstall the apks, and requires 79 * external cleanup. 80 * <p /> 81 * {@inheritDoc} 82 */ 83 @Override 84 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 85 long startTime = System.currentTimeMillis(); 86 listener.testRunStarted(RUN_NAME, 2); 87 try { 88 Assert.assertTrue(mBuild instanceof IAppBuildInfo); 89 IAppBuildInfo appBuild = (IAppBuildInfo)mBuild; 90 Assert.assertFalse(appBuild.getAppPackageFiles().isEmpty()); 91 92 // We assume that the first apk is the one to be executed, and any others are to be 93 // installed and uninstalled. 94 File appApkFile = appBuild.getAppPackageFiles().get(0).getFile(); 95 AaptParser p = AaptParser.parse(appApkFile); 96 Assert.assertNotNull(p); 97 String packageName = p.getPackageName(); 98 Assert.assertNotNull(String.format("Failed to parse package name from %s", 99 appApkFile.getAbsolutePath()), packageName); 100 101 for (final VersionedFile apkVersionedFile : appBuild.getAppPackageFiles()) { 102 final File apkFile = apkVersionedFile.getFile(); 103 performInstallTest(apkFile, listener); 104 } 105 106 performLaunchTest(packageName, listener); 107 } catch (AssertionError e) { 108 listener.testRunFailed(e.toString()); 109 } finally { 110 listener.testRunEnded( 111 System.currentTimeMillis() - startTime, new HashMap<String, Metric>()); 112 } 113 114 } 115 116 private void performInstallTest(File apkFile, ITestInvocationListener listener) 117 throws DeviceNotAvailableException { 118 TestDescription installTest = 119 new TestDescription( 120 "com.android.app.tests.InstallTest", 121 FileUtil.getBaseName(apkFile.getName())); 122 listener.testStarted(installTest); 123 String result = getDevice().installPackage(apkFile, true); 124 if (result != null) { 125 listener.testFailed(installTest, result); 126 } 127 listener.testEnded(installTest, new HashMap<String, Metric>()); 128 } 129 130 private void performLaunchTest(String packageName, ITestInvocationListener listener) 131 throws DeviceNotAvailableException { 132 InstrumentationTest i = new InstrumentationTest(); 133 i.setRunName(RUN_NAME); 134 i.setPackageName("com.android.applaunchtest"); 135 i.setRunnerName("com.android.applaunchtest.AppLaunchRunner"); 136 i.setDevice(getDevice()); 137 i.addInstrumentationArg("packageName", packageName); 138 i.run(listener); 139 try (InputStreamSource s = getDevice().getScreenshot()) { 140 listener.testLog("screenshot", LogDataType.PNG, s); 141 } 142 } 143 } 144