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( 45 name = "skip-injector", 46 description = 47 "Set to true if we should skip automatically " 48 + "adding all package names of installed packages. Default is false.") 49 private boolean mSkipInjecting = false; 50 51 private IConfiguration mConfig; 52 53 /** {@inheritDoc} */ 54 @Override setConfiguration(IConfiguration configuration)55 public void setConfiguration(IConfiguration configuration) { 56 mConfig = configuration; 57 } 58 59 /** {@inheritDoc} */ 60 @Override setUp(ITestDevice device, IBuildInfo buildInfo)61 public void setUp(ITestDevice device, IBuildInfo buildInfo) 62 throws TargetSetupError, BuildError, DeviceNotAvailableException { 63 if (mSkipInjecting) { 64 return; 65 } 66 Assert.assertNotNull(mConfig); 67 Assert.assertTrue( 68 "provided build is not a IAppBuildInfo", buildInfo instanceof IAppBuildInfo); 69 IAppBuildInfo appBuild = (IAppBuildInfo) buildInfo; 70 for (VersionedFile apkFile : appBuild.getAppPackageFiles()) { 71 AaptParser aapt = AaptParser.parse(apkFile.getFile()); 72 if (aapt == null) { 73 // throw a build error because typically aapt parse errors are issues with the apk 74 throw new BuildError( 75 String.format( 76 "aapt parse of %s failed", apkFile.getFile().getAbsolutePath()), 77 device.getDeviceDescriptor()); 78 } 79 String pkgName = aapt.getPackageName(); 80 if (pkgName == null) { 81 // this should never happen 82 throw new TargetSetupError( 83 String.format( 84 "Failed to parse package name from %s", 85 apkFile.getFile().getAbsolutePath()), 86 device.getDeviceDescriptor()); 87 } 88 try { 89 mConfig.injectOptionValue("package", pkgName); 90 } catch (ConfigurationException e) { 91 throw new TargetSetupError( 92 "Failed to inject --package option.", e, device.getDeviceDescriptor()); 93 } 94 } 95 } 96 } 97