diff options
6 files changed, 181 insertions, 175 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java index 0957171..c587b4e 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java @@ -37,7 +37,7 @@ import java.util.regex.Pattern; * <p/><b>{@link #init(boolean)} must be called before anything is done.</b> */ public final class AndroidDebugBridge { - + /* * Minimum and maximum version of adb supported. This correspond to * ADB_SERVER_VERSION found in //device/tools/adb/adb.h @@ -48,7 +48,7 @@ public final class AndroidDebugBridge { private final static Pattern sAdbVersion = Pattern.compile( "^.*(\\d+)\\.(\\d+)\\.(\\d+)$"); //$NON-NLS-1$ - + private final static String ADB = "adb"; //$NON-NLS-1$ private final static String DDMS = "ddms"; //$NON-NLS-1$ @@ -212,7 +212,7 @@ public final class AndroidDebugBridge { monitorThread.quit(); } } - + /** * Returns whether the ddmlib is setup to support monitoring and interacting with * {@link Client}s running on the {@link Device}s. @@ -220,7 +220,7 @@ public final class AndroidDebugBridge { static boolean getClientSupport() { return sClientSupport; } - + /** * Creates a {@link AndroidDebugBridge} that is not linked to any particular executable. * <p/>This bridge will expect adb to be running. It will not be able to start/stop/restart @@ -325,6 +325,7 @@ public final class AndroidDebugBridge { /** * Disconnects the current debug bridge, and destroy the object. + * <p/>This also stops the current adb host server. * <p/> * A new object will have to be created with {@link #createBridge(String, boolean)}. */ @@ -454,21 +455,21 @@ public final class AndroidDebugBridge { return new Device[0]; } - + /** * Returns whether the bridge has acquired the initial list from adb after being created. * <p/>Calling {@link #getDevices()} right after {@link #createBridge(String, boolean)} will * generally result in an empty list. This is due to the internal asynchronous communication * mechanism with <code>adb</code> that does not guarantee that the {@link Device} list has been * built before the call to {@link #getDevices()}. - * <p/>The recommended way to get the list of {@link Device} objects is to create a + * <p/>The recommended way to get the list of {@link Device} objects is to create a * {@link IDeviceChangeListener} object. */ public boolean hasInitialDeviceList() { if (mDeviceMonitor != null) { return mDeviceMonitor.hasInitialDeviceList(); } - + return false; } @@ -515,7 +516,7 @@ public final class AndroidDebugBridge { } return -1; } - + /** * Creates a new bridge. * @param osLocation the location of the command line tool @@ -529,7 +530,7 @@ public final class AndroidDebugBridge { checkAdbVersion(); } - + /** * Creates a new bridge not linked to any particular adb executable. */ @@ -591,7 +592,7 @@ public final class AndroidDebugBridge { Log.logAndDisplay(LogLevel.ERROR, ADB, "Failed to parse the output of 'adb version'"); //$NON-NLS-1$ } - + } catch (IOException e) { Log.logAndDisplay(LogLevel.ERROR, ADB, "Failed to get the adb version: " + e.getMessage()); //$NON-NLS-1$ @@ -609,7 +610,7 @@ public final class AndroidDebugBridge { * <p/> * Returns true when a version number has been found so that we can stop scanning, * whether the version number is in the acceptable range or not. - * + * * @param line The line to scan. * @return True if a version number was found (whether it is acceptable or not). */ @@ -666,7 +667,7 @@ public final class AndroidDebugBridge { } /** - * Kills the debug bridge. + * Kills the debug bridge, and the adb host server. * @return true if success */ boolean stop() { @@ -740,7 +741,7 @@ public final class AndroidDebugBridge { listenersCopy = sDeviceListeners.toArray( new IDeviceChangeListener[sDeviceListeners.size()]); } - + // Notify the listeners for (IDeviceChangeListener listener : listenersCopy) { // we attempt to catch any exception so that a bad listener doesn't kill our @@ -776,7 +777,7 @@ public final class AndroidDebugBridge { listenersCopy = sDeviceListeners.toArray( new IDeviceChangeListener[sDeviceListeners.size()]); } - + // Notify the listeners for (IDeviceChangeListener listener : listenersCopy) { // we attempt to catch any exception so that a bad listener doesn't kill our @@ -812,7 +813,7 @@ public final class AndroidDebugBridge { listenersCopy = sDeviceListeners.toArray( new IDeviceChangeListener[sDeviceListeners.size()]); } - + // Notify the listeners for (IDeviceChangeListener listener : listenersCopy) { // we attempt to catch any exception so that a bad listener doesn't kill our @@ -848,7 +849,7 @@ public final class AndroidDebugBridge { synchronized (sLock) { listenersCopy = sClientListeners.toArray( new IClientChangeListener[sClientListeners.size()]); - + } // Notify the listeners @@ -962,7 +963,7 @@ public final class AndroidDebugBridge { * @param errorOutput The array to store the stderr output. cannot be null. * @param stdOutput The array to store the stdout output. cannot be null. * @param displayStdOut If true this will display stdout as well - * @param waitforReaders if true, this will wait for the reader threads. + * @param waitforReaders if true, this will wait for the reader threads. * @return the process return code. * @throws InterruptedException */ diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java index 0e7f0bb..37b33cf 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java @@ -208,7 +208,7 @@ public final class Device implements IDevice { * (non-Javadoc) * @see com.android.ddmlib.IDevice#getSyncService() */ - public SyncService getSyncService() { + public SyncService getSyncService() throws IOException { SyncService syncService = new SyncService(AndroidDebugBridge.sSocketAddr, this); if (syncService.openSync()) { return syncService; diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java index 5dbce92..a54af8a 100755 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java @@ -118,9 +118,11 @@ public interface IDevice { /** * Returns a {@link SyncService} object to push / pull files to and from the device. - * @return <code>null</code> if the SyncService couldn't be created. + * @return <code>null</code> if the SyncService couldn't be created. This can happen if abd + * refuse to open the connection because the {@link IDevice} is invalid (or got disconnected). + * @throws IOException if the connection with adb failed. */ - public SyncService getSyncService(); + public SyncService getSyncService() throws IOException; /** * Returns a {@link FileListingService} for this device. diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java index 44df000..c1d1d3b 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java @@ -209,9 +209,11 @@ public final class SyncService { /** * Opens the sync connection. This must be called before any calls to push[File] / pull[File]. - * @return true if the connection opened, false otherwise. + * @return true if the connection opened, false if adb refuse the connection. This can happen + * if the {@link Device} is invalid. + * @throws IOException If the connection to adb failed. */ - boolean openSync() { + boolean openSync() throws IOException { try { mChannel = SocketChannel.open(mAddress); mChannel.configureBlocking(false); @@ -236,13 +238,15 @@ public final class SyncService { if (mChannel != null) { try { mChannel.close(); - } catch (IOException e1) { - // we do nothing, since we'll return false just below + } catch (IOException e2) { + // we want to throw the original exception, so we ignore this one. } mChannel = null; - return false; } + + throw e; } + return true; } diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java index ba0f555..34f575f 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java @@ -374,13 +374,13 @@ public class DeviceExplorer extends Panel { } }.start(); - + return mTree; } - + @Override protected void postCreation() { - + } /** @@ -418,61 +418,67 @@ public class DeviceExplorer extends Panel { } // download the files - SyncService sync = mCurrentDevice.getSyncService(); - if (sync != null) { - ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor(); - SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor); - if (result.getCode() != SyncService.RESULT_OK) { - DdmConsole.printErrorToConsole(String.format( - "Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage())); - return; - } - - result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor); - if (result.getCode() != SyncService.RESULT_OK) { - DdmConsole.printErrorToConsole(String.format( - "Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage())); - return; - } - - // now that we have the file, we need to launch traceview - String[] command = new String[2]; - command[0] = DdmUiPreferences.getTraceview(); - command[1] = path + File.separator + baseName; + try { + SyncService sync = mCurrentDevice.getSyncService(); + if (sync != null) { + ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor(); + SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor); + if (result.getCode() != SyncService.RESULT_OK) { + DdmConsole.printErrorToConsole(String.format( + "Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage())); + return; + } - try { - final Process p = Runtime.getRuntime().exec(command); + result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor); + if (result.getCode() != SyncService.RESULT_OK) { + DdmConsole.printErrorToConsole(String.format( + "Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage())); + return; + } - // create a thread for the output - new Thread("Traceview output") { - @Override - public void run() { - // create a buffer to read the stderr output - InputStreamReader is = new InputStreamReader(p.getErrorStream()); - BufferedReader resultReader = new BufferedReader(is); - - // read the lines as they come. if null is returned, it's - // because the process finished - try { - while (true) { - String line = resultReader.readLine(); - if (line != null) { - DdmConsole.printErrorToConsole("Traceview: " + line); - } else { - break; + // now that we have the file, we need to launch traceview + String[] command = new String[2]; + command[0] = DdmUiPreferences.getTraceview(); + command[1] = path + File.separator + baseName; + + try { + final Process p = Runtime.getRuntime().exec(command); + + // create a thread for the output + new Thread("Traceview output") { + @Override + public void run() { + // create a buffer to read the stderr output + InputStreamReader is = new InputStreamReader(p.getErrorStream()); + BufferedReader resultReader = new BufferedReader(is); + + // read the lines as they come. if null is returned, it's + // because the process finished + try { + while (true) { + String line = resultReader.readLine(); + if (line != null) { + DdmConsole.printErrorToConsole("Traceview: " + line); + } else { + break; + } } - } - // get the return code from the process - p.waitFor(); - } catch (IOException e) { - } catch (InterruptedException e) { + // get the return code from the process + p.waitFor(); + } catch (IOException e) { + } catch (InterruptedException e) { + } } - } - }.start(); + }.start(); - } catch (IOException e) { + } catch (IOException e) { + } } + } catch (IOException e) { + DdmConsole.printErrorToConsole(String.format( + "Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage())); + return; } } @@ -667,21 +673,21 @@ public class DeviceExplorer extends Panel { * @param localDirector the local directory in which to save the files. */ private void pullSelection(TreeItem[] items, final String localDirectory) { - final SyncService sync = mCurrentDevice.getSyncService(); - if (sync != null) { - // make a list of the FileEntry. - ArrayList<FileEntry> entries = new ArrayList<FileEntry>(); - for (TreeItem item : items) { - Object data = item.getData(); - if (data instanceof FileEntry) { - entries.add((FileEntry)data); + try { + final SyncService sync = mCurrentDevice.getSyncService(); + if (sync != null) { + // make a list of the FileEntry. + ArrayList<FileEntry> entries = new ArrayList<FileEntry>(); + for (TreeItem item : items) { + Object data = item.getData(); + if (data instanceof FileEntry) { + entries.add((FileEntry)data); + } } - } - final FileEntry[] entryArray = entries.toArray( - new FileEntry[entries.size()]); + final FileEntry[] entryArray = entries.toArray( + new FileEntry[entries.size()]); - // get a progressdialog - try { + // get a progressdialog new ProgressMonitorDialog(mParent.getShell()).run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) @@ -699,13 +705,10 @@ public class DeviceExplorer extends Panel { sync.close(); } }); - } catch (InvocationTargetException e) { - DdmConsole.printErrorToConsole( "Failed to pull selection"); - DdmConsole.printErrorToConsole(e.getMessage()); - } catch (InterruptedException e) { - DdmConsole.printErrorToConsole("Failed to pull selection"); - DdmConsole.printErrorToConsole(e.getMessage()); } + } catch (Exception e) { + DdmConsole.printErrorToConsole( "Failed to pull selection"); + DdmConsole.printErrorToConsole(e.getMessage()); } } @@ -715,9 +718,9 @@ public class DeviceExplorer extends Panel { * @param local the destination filepath */ private void pullFile(final FileEntry remote, final String local) { - final SyncService sync = mCurrentDevice.getSyncService(); - if (sync != null) { - try { + try { + final SyncService sync = mCurrentDevice.getSyncService(); + if (sync != null) { new ProgressMonitorDialog(mParent.getShell()).run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) @@ -734,13 +737,10 @@ public class DeviceExplorer extends Panel { sync.close(); } }); - } catch (InvocationTargetException e) { - DdmConsole.printErrorToConsole( "Failed to pull selection"); - DdmConsole.printErrorToConsole(e.getMessage()); - } catch (InterruptedException e) { - DdmConsole.printErrorToConsole("Failed to pull selection"); - DdmConsole.printErrorToConsole(e.getMessage()); } + } catch (Exception e) { + DdmConsole.printErrorToConsole( "Failed to pull selection"); + DdmConsole.printErrorToConsole(e.getMessage()); } } @@ -750,9 +750,9 @@ public class DeviceExplorer extends Panel { * @param remoteDirectory */ private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory) { - final SyncService sync = mCurrentDevice.getSyncService(); - if (sync != null) { - try { + try { + final SyncService sync = mCurrentDevice.getSyncService(); + if (sync != null) { new ProgressMonitorDialog(mParent.getShell()).run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) @@ -769,14 +769,10 @@ public class DeviceExplorer extends Panel { sync.close(); } }); - } catch (InvocationTargetException e) { - DdmConsole.printErrorToConsole("Failed to push the items"); - DdmConsole.printErrorToConsole(e.getMessage()); - } catch (InterruptedException e) { - DdmConsole.printErrorToConsole("Failed to push the items"); - DdmConsole.printErrorToConsole(e.getMessage()); } - return; + } catch (Exception e) { + DdmConsole.printErrorToConsole("Failed to push the items"); + DdmConsole.printErrorToConsole(e.getMessage()); } } @@ -786,9 +782,9 @@ public class DeviceExplorer extends Panel { * @param remoteDirectory the remote destination directory on the device */ private void pushFile(final String local, final String remoteDirectory) { - final SyncService sync = mCurrentDevice.getSyncService(); - if (sync != null) { - try { + try { + final SyncService sync = mCurrentDevice.getSyncService(); + if (sync != null) { new ProgressMonitorDialog(mParent.getShell()).run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) @@ -812,14 +808,10 @@ public class DeviceExplorer extends Panel { sync.close(); } }); - } catch (InvocationTargetException e) { - DdmConsole.printErrorToConsole("Failed to push the item(s)."); - DdmConsole.printErrorToConsole(e.getMessage()); - } catch (InterruptedException e) { - DdmConsole.printErrorToConsole("Failed to push the item(s)."); - DdmConsole.printErrorToConsole(e.getMessage()); } - return; + } catch (Exception e) { + DdmConsole.printErrorToConsole("Failed to push the item(s)."); + DdmConsole.printErrorToConsole(e.getMessage()); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java index e1d7f18..f178597 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java @@ -848,63 +848,70 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * @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(); - String message = String.format("Uploading %1$s onto device '%2$s'", - path.lastSegment(), device.getSerialNumber()); - AdtPlugin.printToConsole(launchInfo.getProject(), message); - - String osLocalPath = path.toOSString(); - String apkName = launchInfo.getPackageFile().getName(); - String remotePath = "/data/local/tmp/" + apkName; //$NON-NLS-1$ - - SyncResult result = sync.pushFile(osLocalPath, remotePath, - SyncService.getNullProgressMonitor()); - - if (result.getCode() != SyncService.RESULT_OK) { - String msg = String.format("Failed to upload %1$s on '%2$s': %3$s", - apkName, device.getSerialNumber(), result.getMessage()); - AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg); - return false; - } + try { + SyncService sync = device.getSyncService(); + if (sync != null) { + IPath path = launchInfo.getPackageFile().getLocation(); + String message = String.format("Uploading %1$s onto device '%2$s'", + path.lastSegment(), device.getSerialNumber()); + AdtPlugin.printToConsole(launchInfo.getProject(), message); + + String osLocalPath = path.toOSString(); + String apkName = launchInfo.getPackageFile().getName(); + String remotePath = "/data/local/tmp/" + apkName; //$NON-NLS-1$ + + SyncResult result = sync.pushFile(osLocalPath, remotePath, + SyncService.getNullProgressMonitor()); + + if (result.getCode() != SyncService.RESULT_OK) { + String msg = String.format("Failed to upload %1$s on '%2$s': %3$s", + apkName, device.getSerialNumber(), result.getMessage()); + AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg); + return false; + } - // Now that the package is uploaded, we can install it properly. - // This will check that there isn't another apk declaring the same package, or - // that another install used a different key. - boolean installResult = installPackage(launchInfo, remotePath, device); + // Now that the package is uploaded, we can install it properly. + // This will check that there isn't another apk declaring the same package, or + // that another install used a different key. + boolean installResult = installPackage(launchInfo, remotePath, device); - // now we delete the app we sync'ed - try { - device.executeShellCommand("rm " + remotePath, new MultiLineReceiver() { //$NON-NLS-1$ - @Override - public void processNewLines(String[] lines) { - // pass - } - public boolean isCancelled() { - return false; - } - }); - } catch (IOException e) { - AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format( - "Failed to delete temporary package: %1$s", e.getMessage())); - return false; - } + // now we delete the app we sync'ed + try { + device.executeShellCommand("rm " + remotePath, new MultiLineReceiver() { //$NON-NLS-1$ + @Override + public void processNewLines(String[] lines) { + // pass + } + public boolean isCancelled() { + return false; + } + }); + } catch (IOException e) { + AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format( + "Failed to delete temporary package: %1$s", e.getMessage())); + return false; + } - // if the installation succeeded, we register it. - if (installResult) { - ApkInstallManager.getInstance().registerInstallation( - launchInfo.getProject(), device); - } + // if the installation succeeded, we register it. + if (installResult) { + ApkInstallManager.getInstance().registerInstallation( + launchInfo.getProject(), device); + } - return installResult; + return installResult; + } else { + String msg = String.format( + "Failed to upload %1$s on device '%2$s': Unable to open sync connection!", + launchInfo.getPackageFile().getName(), device.getSerialNumber()); + AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg); + } + } catch (IOException e) { + String msg = String.format( + "Failed to upload %1$s on device '%2$s': Unable to open sync connection!", + launchInfo.getPackageFile().getName(), device.getSerialNumber()); + AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e.getMessage()); } - String msg = String.format( - "Failed to upload %1$s on device '%2$s': Unable to open sync connection!", - launchInfo.getPackageFile().getName(), device.getSerialNumber()); - AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg); - return false; } |