* defined by <code>ILaunchManager</code> - <code>RUN_MODE</code> or
* <code>DEBUG_MODE</code>.
* @param apk the resource to the apk to launch.
+ * @param packageName the Android package name of the app
+ * @param debugPackageName the Android package name to debug
* @param debuggable the debuggable value of the app, or null if not set.
* @param requiredApiVersionNumber the api version required by the app, or
* {@link AndroidManifestParser#INVALID_MIN_SDK} if none.
* @param launch the launch object
*/
public void launch(final IProject project, String mode, IFile apk,
- String packageName, Boolean debuggable, int requiredApiVersionNumber,
+ String packageName, String debugPackageName, Boolean debuggable, int requiredApiVersionNumber,
final IAndroidLaunchAction launchAction, final AndroidLaunchConfiguration config,
final AndroidLaunch launch, IProgressMonitor monitor) {
// create the launch info
final DelayedLaunchInfo launchInfo = new DelayedLaunchInfo(project, packageName,
- launchAction, apk, debuggable, requiredApiVersionNumber, launch, monitor);
+ debugPackageName, launchAction, apk, debuggable, requiredApiVersionNumber, launch,
+ monitor);
// set the debug mode
launchInfo.setDebugMode(mode.equals(ILaunchManager.DEBUG_MODE));
DelayedLaunchInfo delayedLaunchInfo = new DelayedLaunchInfo(
androidProject.getProject(),
manifestParser.getPackage(),
+ manifestParser.getPackage(),
launchInfo.getLaunchAction(),
apk,
manifestParser.getDebuggable(),
for (int i = 0; i < mWaitingForDebuggerApplications.size(); ) {
final DelayedLaunchInfo launchInfo = mWaitingForDebuggerApplications.get(i);
if (client.getDevice() == launchInfo.getDevice() &&
- applicationName.equals(launchInfo.getPackageName())) {
+ applicationName.equals(launchInfo.getDebugPackageName())) {
// this is a match. We remove the launch info from the list
mWaitingForDebuggerApplications.remove(i);
// and connect the debugger.
String msg = String.format(
"Attempting to connect debugger to '%1$s' on port %2$d",
- launchInfo.getPackageName(), client.getDebuggerListenPort());
+ launchInfo.getDebugPackageName(), client.getDebuggerListenPort());
AdtPlugin.printToConsole(launchInfo.getProject(), msg);
new Thread("Debugger Connection") { //$NON-NLS-1$
/** Package name */
private final String mPackageName;
+
+ /** Debug package name */
+ private final String mDebugPackageName;
/** IFile to the package (.apk) file */
private final IFile mPackageFile;
* Basic constructor with activity and package info.
*
* @param project the eclipse project that corresponds to Android app
- * @param packageName package name of Android app
+ * @param packageName package name of Android app
+ * @param debugPackageName the package name of the Andriod app to debug
* @param launchAction action to perform after app install
* @param pack IFile to the package (.apk) file
* @param debuggable debuggable attribute of the app's manifest file.
* @param launch the launch object
* @param monitor progress monitor for launch
*/
- public DelayedLaunchInfo(IProject project, String packageName,
+ public DelayedLaunchInfo(IProject project, String packageName, String debugPackageName,
IAndroidLaunchAction launchAction, IFile pack, Boolean debuggable,
int requiredApiVersionNumber, AndroidLaunch launch, IProgressMonitor monitor) {
mProject = project;
mPackageName = packageName;
+ mDebugPackageName = debugPackageName;
mPackageFile = pack;
mLaunchAction = launchAction;
mLaunch = launch;
}
/**
+ * Returns the Android app process name that the debugger should connect to. Typically this is
+ * the same value as {@link getPackageName}
+ */
+ public String getDebugPackageName() {
+ if (mDebugPackageName == null) {
+ return getPackageName();
+ }
+ return mDebugPackageName;
+ }
+
+ /**
* @return the application package file
*/
public IFile getPackageFile() {
// everything seems fine, we ask the launch controller to handle
// the rest
- controller.launch(project, mode, applicationPackage, manifestParser.getPackage(),
- manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
- launchAction, config, androidLaunch, monitor);
+ controller.launch(project, mode, applicationPackage,manifestParser.getPackage(),
+ manifestParser.getPackage(), manifestParser.getDebuggable(),
+ manifestParser.getApiLevelRequirement(), launchAction, config, androidLaunch,
+ monitor);
}
@Override
try {
mLaunchInfo.setDebugMode(info.isDebugMode());
mLaunchInfo.setDevice(info.getDevice());
- mLaunchInfo.setLaunch(info.getLaunch());
JUnitLaunchDelegate junitDelegate = new JUnitLaunchDelegate(mLaunchInfo);
final String mode = info.isDebugMode() ? ILaunchManager.DEBUG_MODE :
ILaunchManager.RUN_MODE;
import com.android.ide.eclipse.adt.launch.junit.runtime.AndroidJUnitLaunchInfo;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
+import com.android.ide.eclipse.common.project.AndroidManifestParser.Instrumentation;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import org.eclipse.core.resources.IFile;
AndroidLaunchConfiguration config, AndroidLaunchController controller,
IFile applicationPackage, AndroidManifestParser manifestParser) {
- String appPackage = manifestParser.getPackage();
String runner = getRunner(project, configuration, manifestParser);
if (runner == null) {
AdtPlugin.displayError("Android Launch",
androidLaunch.stopLaunch();
return;
}
- AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project, appPackage,
- runner);
+ // get the target app's package
+ String targetAppPackage = getTargetPackage(manifestParser, runner);
+ if (targetAppPackage == null) {
+ AdtPlugin.displayError("Android Launch",
+ String.format("A target package for instrumention test runner %1$s could not be found!",
+ runner));
+ androidLaunch.stopLaunch();
+ return;
+ }
+ String testAppPackage = manifestParser.getPackage();
+ AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project,
+ testAppPackage, runner);
junitLaunchInfo.setTestClass(getTestClass(configuration));
junitLaunchInfo.setTestPackage(getTestPackage(configuration));
junitLaunchInfo.setTestMethod(getTestMethod(configuration));
-
+ junitLaunchInfo.setLaunch(androidLaunch);
IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(junitLaunchInfo);
-
- controller.launch(project, mode, applicationPackage, manifestParser.getPackage(),
+
+ controller.launch(project, mode, applicationPackage, testAppPackage, targetAppPackage,
manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
junitLaunch, config, androidLaunch, monitor);
}
-
+
+ /**
+ * Get the target Android application's package for the given instrumentation runner, or
+ * <code>null</code> if it could not be found.
+ *
+ * @param manifestParser the {@link AndroidManifestParser} for the test project
+ * @param runner the instrumentation runner class name
+ * @return the target package or <code>null</code>
+ */
+ private String getTargetPackage(AndroidManifestParser manifestParser, String runner) {
+ for (Instrumentation instr : manifestParser.getInstrumentations()) {
+ if (instr.getName().equals(runner)) {
+ return instr.getTargetPackage();
+ }
+ }
+ return null;
+ }
+
/**
* Returns the test package stored in the launch configuration, or <code>null</code> if not
* specified.
try {
mInstrValidator = new InstrumentationRunnerValidator(project);
mInstrumentations = (mInstrValidator == null ? null :
- mInstrValidator.getInstrumentations());
+ mInstrValidator.getInstrumentationNames());
if (mInstrumentations != null) {
mInstrumentationCombo.removeAll();
for (String instrumentation : mInstrumentations) {
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
+import com.android.ide.eclipse.common.project.AndroidManifestParser.Instrumentation;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import org.eclipse.core.resources.IProject;
*/
class InstrumentationRunnerValidator {
private final IJavaProject mJavaProject;
- private String[] mInstrumentations = null;
+ private String[] mInstrumentationNames = null;
private boolean mHasRunnerLibrary = false;
static final String INSTRUMENTATION_OK = null;
}
private void init(AndroidManifestParser manifestParser) {
- mInstrumentations = manifestParser.getInstrumentations();
+ Instrumentation[] instrumentations = manifestParser.getInstrumentations();
+ mInstrumentationNames = new String[instrumentations.length];
+ for (int i = 0; i < instrumentations.length; i++) {
+ mInstrumentationNames[i] = instrumentations[i].getName();
+ }
mHasRunnerLibrary = hasTestRunnerLibrary(manifestParser);
}
}
/**
- * Return the set of instrumentations for the Android project.
+ * Return the set of instrumentation names for the Android project.
*
* @return <code>null</code if error occurred parsing instrumentations, otherwise returns array
* of instrumentation class names
*/
- String[] getInstrumentations() {
- return mInstrumentations;
+ String[] getInstrumentationNames() {
+ return mInstrumentationNames;
}
/**
* instrumentation can be found.
*/
String getValidInstrumentationTestRunner() {
- for (String instrumentation : getInstrumentations()) {
+ for (String instrumentation : getInstrumentationNames()) {
if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) {
return instrumentation;
}
* Helper method to determine if specified instrumentation can be used as a test runner
*
* @param instrumentation the instrumentation class name to validate. Assumes this
- * instrumentation is one of {@link #getInstrumentations()}
+ * instrumentation is one of {@link #getInstrumentationNames()}
* @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
*/
String validateInstrumentationRunner(String instrumentation) {
private final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$
private final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$
private final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
+ private final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
private final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
private final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
private final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$
public final static int INVALID_MIN_SDK = -1;
/**
+ * Instrumentation info obtained from manifest
+ */
+ public static class Instrumentation {
+ private final String mName;
+ private final String mTargetPackage;
+
+ public Instrumentation(String name, String targetPackage) {
+ mName = name;
+ mTargetPackage = targetPackage;
+ }
+
+ /**
+ * Returns the fully qualified instrumentation class name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Returns the Android app package that is the target of this instrumentation
+ */
+ public String getTargetPackage() {
+ return mTargetPackage;
+ }
+ }
+
+ /**
* XML error & data handler used when parsing the AndroidManifest.xml file.
* <p/>
* This serves both as an {@link XmlErrorHandler} to report errors and as a data repository
* the attribute was not present. */
private int mApiLevelRequirement = INVALID_MIN_SDK;
/** List of all instrumentations declared by the manifest */
- private final ArrayList<String> mInstrumentations = new ArrayList<String>();
+ private final ArrayList<Instrumentation> mInstrumentations =
+ new ArrayList<Instrumentation>();
/** List of all libraries in use declared by the manifest */
private final ArrayList<String> mLibraries = new ArrayList<String>();
/**
* Returns the list of instrumentations found in the manifest.
- * @return An array of instrumentation names, or empty if no instrumentations were
+ * @return An array of {@link Instrumentation}, or empty if no instrumentations were
* found.
*/
- String[] getInstrumentations() {
- return mInstrumentations.toArray(new String[mInstrumentations.size()]);
+ Instrumentation[] getInstrumentations() {
+ return mInstrumentations.toArray(new Instrumentation[mInstrumentations.size()]);
}
/**
true /* hasNamespace */);
if (instrumentationName != null) {
String instrClassName = combinePackageAndClassName(mPackage, instrumentationName);
- mInstrumentations.add(instrClassName);
+ String targetPackage = getAttributeValue(attributes, ATTRIBUTE_TARGET_PACKAGE,
+ true /* hasNamespace */);
+ mInstrumentations.add(new Instrumentation(instrClassName, targetPackage));
if (mMarkErrors) {
checkClass(instrClassName, AndroidConstants.CLASS_INSTRUMENTATION,
true /* testVisibility */);
private final String[] mProcesses;
private final Boolean mDebuggable;
private final int mApiLevelRequirement;
- private final String[] mInstrumentations;
+ private final Instrumentation[] mInstrumentations;
private final String[] mLibraries;
static {
/**
* Returns the list of instrumentations found in the manifest.
- * @return An array of fully qualified class names, or empty if no instrumentations were found.
+ * @return An array of {@link Instrumentation}, or empty if no instrumentations were found.
*/
- public String[] getInstrumentations() {
+ public Instrumentation[] getInstrumentations() {
return mInstrumentations;
}
*/
private AndroidManifestParser(String javaPackage, String[] activities,
String launcherActivity, String[] processes, Boolean debuggable,
- int apiLevelRequirement, String[] instrumentations, String[] libraries) {
+ int apiLevelRequirement, Instrumentation[] instrumentations, String[] libraries) {
mJavaPackage = javaPackage;
mActivities = activities;
mLauncherActivity = launcherActivity;
private static final String ACTIVITY_NAME = "com.android.testapp.MainActivity"; //$NON-NLS-1$
private static final String LIBRARY_NAME = "android.test.runner"; //$NON-NLS-1$
private static final String INSTRUMENTATION_NAME = "android.test.InstrumentationTestRunner"; //$NON-NLS-1$
-
+ private static final String INSTRUMENTATION_TARGET = "com.android.AndroidProject"; //$NON-NLS-1$
@Override
protected void setUp() throws Exception {
super.setUp();
public void testGetInstrumentationInformation() {
assertEquals(1, mManifestInstrumentation.getInstrumentations().length);
- assertEquals(INSTRUMENTATION_NAME, mManifestTestApp.getInstrumentations()[0]);
+ assertEquals(INSTRUMENTATION_NAME,
+ mManifestInstrumentation.getInstrumentations()[0].getName());
+ assertEquals(INSTRUMENTATION_TARGET,
+ mManifestInstrumentation.getInstrumentations()[0].getTargetPackage());
}
public void testGetPackage() {
public void testGetLauncherActivity() {
assertEquals(ACTIVITY_NAME, mManifestTestApp.getLauncherActivity());
}
-
+
public void testGetUsesLibraries() {
assertEquals(1, mManifestTestApp.getUsesLibraries().length);
assertEquals(LIBRARY_NAME, mManifestTestApp.getUsesLibraries()[0]);
}
-
- public void testGetInstrumentations() {
- assertEquals(1, mManifestTestApp.getInstrumentations().length);
- assertEquals(INSTRUMENTATION_NAME, mManifestTestApp.getInstrumentations()[0]);
- }
-
+
public void testGetPackageName() {
assertEquals(PACKAGE_NAME, mManifestTestApp.getPackage());
}