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.monkey; 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.config.ConfigurationException; 22 import com.android.tradefed.config.IConfiguration; 23 import com.android.tradefed.config.IConfigurationReceiver; 24 import com.android.tradefed.config.Option; 25 import com.android.tradefed.device.DeviceNotAvailableException; 26 import com.android.tradefed.device.ITestDevice; 27 import com.android.tradefed.targetprep.BaseTargetPreparer; 28 import com.android.tradefed.targetprep.BuildError; 29 import com.android.tradefed.targetprep.ITargetPreparer; 30 import com.android.tradefed.targetprep.TargetSetupError; 31 import com.android.tradefed.util.AaptParser; 32 33 import org.junit.Assert; 34 35 /** 36 * A {@link ITargetPreparer} for {@link IAppBuildInfo}, that dynamically determines the app package 37 * name given its apk file. This saves the user from having to manually specify the --package arg 38 * when running monkey. 39 * 40 * <p>Requires that aapt is on current path. 41 */ 42 public class AppPkgInjector extends BaseTargetPreparer implements IConfigurationReceiver { 43 44 @Option(name = "skip-injector", description = "Set to true if we should skip automatically " + 45 "adding all package names of installed packages. Default is false.") 46 private boolean mSkipInjecting = false; 47 48 private IConfiguration mConfig; 49 50 /** 51 * {@inheritDoc} 52 */ 53 @Override 54 public void setConfiguration(IConfiguration configuration) { 55 mConfig = configuration; 56 57 } 58 59 /** 60 * {@inheritDoc} 61 */ 62 @Override 63 public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, 64 BuildError, DeviceNotAvailableException { 65 if (mSkipInjecting) { 66 return; 67 } 68 Assert.assertNotNull(mConfig); 69 Assert.assertTrue("provided build is not a IAppBuildInfo", 70 buildInfo instanceof IAppBuildInfo); 71 IAppBuildInfo appBuild = (IAppBuildInfo)buildInfo; 72 for (VersionedFile apkFile : appBuild.getAppPackageFiles()) { 73 AaptParser aapt = AaptParser.parse(apkFile.getFile()); 74 if (aapt == null) { 75 // throw a build error because typically aapt parse errors are issues with the apk 76 throw new BuildError(String.format("aapt parse of %s failed", 77 apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor()); 78 } 79 String pkgName = aapt.getPackageName(); 80 if (pkgName == null) { 81 // this should never happen 82 throw new TargetSetupError(String.format("Failed to parse package name from %s", 83 apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor()); 84 } 85 try { 86 mConfig.injectOptionValue("package", pkgName); 87 } catch (ConfigurationException e) { 88 throw new TargetSetupError("Failed to inject --package option.", e, 89 device.getDeviceDescriptor()); 90 } 91 } 92 } 93 } 94