Merge commit 'goog/cupcake'

This commit is contained in:
The Android Open Source Project
2009-03-27 18:48:30 -07:00
14 changed files with 286 additions and 47 deletions

View File

@@ -45,16 +45,16 @@ Require-Bundle: com.android.ide.eclipse.ddms,
org.eclipse.ltk.core.refactoring,
org.eclipse.ltk.ui.refactoring
Eclipse-LazyStart: true
Export-Package: com.android.ide.eclipse.adt,
Export-Package: com.android.ide.eclipse.adt;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.build;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.launch;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.project.internal;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.sdk;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.wizards.newproject;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common,
com.android.ide.eclipse.common.project,
com.android.ide.eclipse.common.resources,
com.android.ide.eclipse.common;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common.resources;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.layout;x-friends:="com.android.ide.eclipse.tests",

View File

@@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.ApkInstallManager;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.sdk.Sdk;
@@ -551,6 +552,9 @@ public class ApkBuilder extends BaseBuilder {
// and store it
saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
// reset the installation manager to force new installs of this project
ApkInstallManager.getInstance().resetInstallationFor(project);
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
"Build Success!");
}

View File

@@ -32,6 +32,7 @@ import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration.TargetMode;
import com.android.ide.eclipse.adt.launch.DelayedLaunchInfo.InstallRetryMode;
import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
import com.android.ide.eclipse.adt.project.ApkInstallManager;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
@@ -762,13 +763,46 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
/**
* Syncs the application on the device/emulator.
* If needed, syncs the application and all its dependencies on the device/emulator.
*
* @param launchInfo The Launch information object.
* @param device the device on which to sync the application
* @return true if the install succeeded.
*/
private boolean syncApp(DelayedLaunchInfo launchInfo, IDevice device) {
boolean alreadyInstalled = ApkInstallManager.getInstance().isApplicationInstalled(
launchInfo.getProject(), device);
if (alreadyInstalled) {
AdtPlugin.printToConsole(launchInfo.getProject(),
"Application already deployed. No need to reinstall.");
} else {
if (doSyncApp(launchInfo, device) == false) {
return false;
}
}
// The app is now installed, now try the dependent projects
for (DelayedLaunchInfo dependentLaunchInfo : getDependenciesLaunchInfo(launchInfo)) {
String msg = String.format("Project dependency found, installing: %s",
dependentLaunchInfo.getProject().getName());
AdtPlugin.printToConsole(launchInfo.getProject(), msg);
if (syncApp(dependentLaunchInfo, device) == false) {
return false;
}
}
return true;
}
/**
* Syncs the application on the device/emulator.
*
* @param launchInfo The Launch information object.
* @param device the device on which to sync the application
* @return true if the install succeeded.
*/
private boolean doSyncApp(DelayedLaunchInfo launchInfo, IDevice device) {
SyncService sync = device.getSyncService();
if (sync != null) {
IPath path = launchInfo.getPackageFile().getLocation();
@@ -812,12 +846,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
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);
// if the installation succeeded, we register it.
if (installResult) {
ApkInstallManager.getInstance().registerInstallation(
launchInfo.getProject(), device);
}
return installResult;

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.project;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
import org.eclipse.core.resources.IProject;
import java.util.ArrayList;
/**
* Registers which apk was installed on which device.
* <p/>
* The goal of this class is to remember the installation of APKs on devices, and provide
* information about whether a new APK should be installed on a device prior to running the
* application from a launch configuration.
* <p/>
* The manager uses {@link IProject} and {@link IDevice} to identify the target device and the
* (project generating the) APK. This ensures that disconnected and reconnected devices will
* always receive new APKs (since the APK could be uninstalled manually).
* <p/>
* Manually uninstalling an APK from a connected device will still be a problem, but this should
* be a limited use case.
* <p/>
* This is a singleton. To get the instance, use {@link #getInstance()}
*/
public class ApkInstallManager implements IDeviceChangeListener, IDebugBridgeChangeListener,
IProjectListener {
private final static ApkInstallManager sThis = new ApkInstallManager();
/**
* Internal struct to associate a project and a device.
*/
private static class ApkInstall {
public ApkInstall(IProject project, IDevice device) {
this.project = project;
this.device = device;
}
IProject project;
IDevice device;
}
private final ArrayList<ApkInstall> mInstallList = new ArrayList<ApkInstall>();
public static ApkInstallManager getInstance() {
return sThis;
}
/**
* Registers an installation of <var>project</var> onto <var>device</var>
* @param project The project that was installed.
* @param device The device that received the installation.
*/
public void registerInstallation(IProject project, IDevice device) {
synchronized (mInstallList) {
mInstallList.add(new ApkInstall(project, device));
}
}
/**
* Returns whether a <var>project</var> was installed on the <var>device</var>.
* @param project the project that may have been installed.
* @param device the device that may have received the installation.
* @return
*/
public boolean isApplicationInstalled(IProject project, IDevice device) {
synchronized (mInstallList) {
for (ApkInstall install : mInstallList) {
if (project == install.project && device == install.device) {
return true;
}
}
}
return false;
}
/**
* Resets registered installations for a specific {@link IProject}.
* <p/>This ensures that {@link #isApplicationInstalled(IProject, IDevice)} will always return
* <code>null</code> for this specified project, for any device.
* @param project the project for which to reset all installations.
*/
public void resetInstallationFor(IProject project) {
synchronized (mInstallList) {
for (int i = 0 ; i < mInstallList.size() ;) {
ApkInstall install = mInstallList.get(i);
if (install.project == project) {
mInstallList.remove(i);
} else {
i++;
}
}
}
}
private ApkInstallManager() {
AndroidDebugBridge.addDeviceChangeListener(this);
AndroidDebugBridge.addDebugBridgeChangeListener(this);
ResourceMonitor.getMonitor().addProjectListener(this);
}
/*
* Responds to a bridge change by clearing the full installation list.
* (non-Javadoc)
* @see com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener#bridgeChanged(com.android.ddmlib.AndroidDebugBridge)
*/
public void bridgeChanged(AndroidDebugBridge bridge) {
// the bridge changed, there is no way to know which IDevice will be which.
// We reset everything
synchronized (mInstallList) {
mInstallList.clear();
}
}
/*
* Responds to a device being disconnected by removing all installations related to this device.
* (non-Javadoc)
* @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceDisconnected(com.android.ddmlib.Device)
*/
public void deviceDisconnected(Device device) {
synchronized (mInstallList) {
for (int i = 0 ; i < mInstallList.size() ;) {
ApkInstall install = mInstallList.get(i);
if (install.device == device) {
mInstallList.remove(i);
} else {
i++;
}
}
}
}
/*
* Responds to a close project by resetting all its installation.
* (non-Javadoc)
* @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectClosed(org.eclipse.core.resources.IProject)
*/
public void projectClosed(IProject project) {
resetInstallationFor(project);
}
/*
* Responds to a close project by resetting all its installation.
* (non-Javadoc)
* @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectDeleted(org.eclipse.core.resources.IProject)
*/
public void projectDeleted(IProject project) {
resetInstallationFor(project);
}
/*
* Does nothing
* (non-Javadoc)
* @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceChanged(com.android.ddmlib.Device, int)
*/
public void deviceChanged(Device device, int changeMask) {
// nothing to do.
}
/*
* Does nothing
* (non-Javadoc)
* @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceConnected(com.android.ddmlib.Device)
*/
public void deviceConnected(Device device) {
// nothing to do.
}
/*
* Does nothing
* (non-Javadoc)
* @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectOpened(org.eclipse.core.resources.IProject)
*/
public void projectOpened(IProject project) {
// nothing to do.
}
/*
* Does nothing
* (non-Javadoc)
* @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectOpenedWithWorkspace(org.eclipse.core.resources.IProject)
*/
public void projectOpenedWithWorkspace(IProject project) {
// nothing to do.
}
}

View File

@@ -16,7 +16,7 @@
package com.android.ide.eclipse.adt.wizards.actions;
import com.android.ide.eclipse.editors.wizards.NewXmlFileWizard;
import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard;
import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IWorkbenchWizard;

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.project;
package com.android.ide.eclipse.adt.wizards.actions;
import com.android.ide.eclipse.editors.wizards.NewXmlFileWizard;
import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;

View File

@@ -15,7 +15,7 @@
*/
package com.android.ide.eclipse.editors.wizards;
package com.android.ide.eclipse.adt.wizards.newxmlfile;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
@@ -31,6 +31,7 @@ import com.android.ide.eclipse.editors.resources.configurations.FolderConfigurat
import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.editors.wizards.ConfigurationSelector;
import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.ConfigurationState;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;

View File

@@ -16,11 +16,11 @@
package com.android.ide.eclipse.editors.wizards;
package com.android.ide.eclipse.adt.wizards.newxmlfile;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.wizards.NewXmlFileCreationPage.TypeInfo;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;

View File

@@ -90,7 +90,7 @@ public class AndroidConstants {
/** Name of the android sources directory */
public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$
/** Resource java class filename, i.e. "R.java" */
public final static String FN_RESOURCE_CLASS = "R.java"; //$NON-NLS-1$
/** Resource class file filename, i.e. "R.class" */
@@ -128,7 +128,8 @@ public class AndroidConstants {
public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS;
/** Leaf of the javaDoc folder. Does not start with a separator. */
public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/reference"; //$NON-NLS-1$
public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/" +
SdkConstants.FD_DOCS_REFERENCE; //$NON-NLS-1$
/** Path of the samples directory relative to the sdk folder.
* This is an OS path, ending with a separator.