import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.Sdk;
+import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.avd.AvdManager;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMConnector;
import org.eclipse.jdt.launching.JavaRuntime;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
return false;
}
+ // The app is now installed, now try the dependent projects
+ for (DelayedLaunchInfo dependentLaunchInfo : getDependenciesLaunchInfo(launchInfo)) {
+ String msg = String.format("Project dependency found, syncing: %s",
+ dependentLaunchInfo.getProject().getName());
+ AdtPlugin.printToConsole(launchInfo.getProject(), msg);
+ syncApp(dependentLaunchInfo, device);
+ }
+
return installResult;
}
}
/**
+ * For the current launchInfo, create additional DelayedLaunchInfo that should be used to
+ * sync APKs that we are dependent on to the device.
+ *
+ * @param launchInfo the original launch info that we want to find the
+ * @return a list of DelayedLaunchInfo (may be empty if no dependencies were found or error)
+ */
+ public List<DelayedLaunchInfo> getDependenciesLaunchInfo(DelayedLaunchInfo launchInfo) {
+ List<DelayedLaunchInfo> dependencies = new ArrayList<DelayedLaunchInfo>();
+
+ // Convert to equivalent JavaProject
+ IJavaProject javaProject;
+ try {
+ //assuming this is an Android (and Java) project since it is attached to the launchInfo.
+ javaProject = BaseProjectHelper.getJavaProject(launchInfo.getProject());
+ } catch (CoreException e) {
+ // return empty dependencies
+ AdtPlugin.printErrorToConsole(launchInfo.getProject(), e);
+ return dependencies;
+ }
+
+ // Get all projects that this depends on
+ List<IJavaProject> androidProjectList;
+ try {
+ androidProjectList = ProjectHelper.getAndroidProjectDependencies(javaProject);
+ } catch (JavaModelException e) {
+ // return empty dependencies
+ AdtPlugin.printErrorToConsole(launchInfo.getProject(), e);
+ return dependencies;
+ }
+
+ // for each project, parse manifest and create launch information
+ for (IJavaProject androidProject : androidProjectList) {
+ // Parse the Manifest to get various required information
+ // copied from LaunchConfigDelegate
+ AndroidManifestParser manifestParser;
+ try {
+ manifestParser = AndroidManifestParser.parse(
+ androidProject, null /* errorListener */,
+ true /* gatherData */, false /* markErrors */);
+ } catch (CoreException e) {
+ AdtPlugin.printErrorToConsole(
+ launchInfo.getProject(),
+ String.format("Error parsing manifest of %s",
+ androidProject.getElementName()));
+ continue;
+ }
+
+ // Get the APK location (can return null)
+ IFile apk = ProjectHelper.getApplicationPackage(androidProject.getProject());
+ if (apk == null) {
+ // getApplicationPackage will have logged an error message
+ continue;
+ }
+
+ // Create new launchInfo as an hybrid between parent and dependency information
+ DelayedLaunchInfo delayedLaunchInfo = new DelayedLaunchInfo(
+ androidProject.getProject(),
+ manifestParser.getPackage(),
+ launchInfo.getLaunchAction(),
+ apk,
+ manifestParser.getDebuggable(),
+ manifestParser.getApiLevelRequirement(),
+ launchInfo.getLaunch(),
+ launchInfo.getMonitor());
+
+ // Add to the list
+ dependencies.add(delayedLaunchInfo);
+ }
+
+ return dependencies;
+ }
+
+
+
+ /**
* Installs the application package that was pushed to a temporary location on the device.
* @param launchInfo The launch information
* @param remotePath The remote path of the package.
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
AdtPlugin.printToConsole(project, "Android Launch!");
// check if the project is using the proper sdk.
- // if that throws an exception, we simply let it propage to the caller.
+ // if that throws an exception, we simply let it propagate to the caller.
if (checkAndroidProject(project) == false) {
AdtPlugin.printErrorToConsole(project, "Project is not an Android Project. Aborting!");
androidLaunch.stopLaunch();
AndroidLaunchController controller = AndroidLaunchController.getInstance();
// get the application package
- IFile applicationPackage = getApplicationPackage(project);
+ IFile applicationPackage = ProjectHelper.getApplicationPackage(project);
if (applicationPackage == null) {
androidLaunch.stopLaunch();
return;
/**
- * Returns the android package file as an IFile object for the specified
- * project.
- * @param project The project
- * @return The android package as an IFile object or null if not found.
- */
- private IFile getApplicationPackage(IProject project) {
- // get the output folder
- IFolder outputLocation = BaseProjectHelper.getOutputFolder(project);
-
- if (outputLocation == null) {
- AdtPlugin.printErrorToConsole(project,
- "Failed to get the output location of the project. Check build path properties"
- );
- return null;
- }
-
-
- // get the package path
- String packageName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
- IResource r = outputLocation.findMember(packageName);
-
- // check the package is present
- if (r instanceof IFile && r.exists()) {
- return (IFile)r;
- }
-
- String msg = String.format("Could not find %1$s!", packageName);
- AdtPlugin.printErrorToConsole(project, msg);
-
- return null;
- }
-
- /**
* Returns the name of the activity.
*/
private String getActivityName(ILaunchConfiguration configuration) {
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
+import com.android.ide.eclipse.common.project.BaseProjectHelper;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import java.util.ArrayList;
+import java.util.List;
/**
* Utility class to manipulate Project parameters/properties.
return project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
}
+
+ /**
+ * Find the list of projects on which this JavaProject is dependent on at the compilation level.
+ *
+ * @param javaProject Java project that we are looking for the dependencies.
+ * @return A list of Java projects for which javaProject depend on.
+ * @throws JavaModelException
+ */
+ public static List<IJavaProject> getAndroidProjectDependencies(IJavaProject javaProject)
+ throws JavaModelException {
+ String[] requiredProjectNames = javaProject.getRequiredProjectNames();
+
+ // Go from java project name to JavaProject name
+ IJavaModel javaModel = javaProject.getJavaModel();
+
+ // loop through all dependent projects and keep only those that are Android projects
+ List<IJavaProject> projectList = new ArrayList<IJavaProject>(requiredProjectNames.length);
+ for (String javaProjectName : requiredProjectNames) {
+ IJavaProject androidJavaProject = javaModel.getJavaProject(javaProjectName);
+
+ //Verify that the project has also the Android Nature
+ try {
+ if (!androidJavaProject.getProject().hasNature(AndroidConstants.NATURE)) {
+ continue;
+ }
+ } catch (CoreException e) {
+ continue;
+ }
+
+ projectList.add(androidJavaProject);
+ }
+
+ return projectList;
+ }
+
+ /**
+ * Returns the android package file as an IFile object for the specified
+ * project.
+ * @param project The project
+ * @return The android package as an IFile object or null if not found.
+ */
+ public static IFile getApplicationPackage(IProject project) {
+ // get the output folder
+ IFolder outputLocation = BaseProjectHelper.getOutputFolder(project);
+
+ if (outputLocation == null) {
+ AdtPlugin.printErrorToConsole(project,
+ "Failed to get the output location of the project. Check build path properties"
+ );
+ return null;
+ }
+
+
+ // get the package path
+ String packageName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
+ IResource r = outputLocation.findMember(packageName);
+
+ // check the package is present
+ if (r instanceof IFile && r.exists()) {
+ return (IFile)r;
+ }
+
+ String msg = String.format("Could not find %1$s!", packageName);
+ AdtPlugin.printErrorToConsole(project, msg);
+
+ return null;
+ }
}