diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java index 0957171c6..c587b4e40 100644 --- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java +++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java @@ -37,7 +37,7 @@ import java.util.regex.Pattern; *
{@link #init(boolean)} must be called before anything is done. */ 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. * 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. + * This also stops the current adb host server. * * 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. * 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 withadb that does not guarantee that the {@link Device} list has been
* built before the call to {@link #getDevices()}.
- * The recommended way to get the list of {@link Device} objects is to create a
+ * 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 {
*
* 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/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
index 0e7f0bbd0..37b33cf05 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
+++ b/tools/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/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
index 5dbce9292..a54af8adb 100755
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
+++ b/tools/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 null if the SyncService couldn't be created.
+ * @return null 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/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
index 44df00017..c1d1d3b93 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
+++ b/tools/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/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
index ba0f55517..34f575fa1 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
+++ b/tools/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;
- }
+ 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;
+ }
- 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;
- }
+ 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;
+ // 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);
+ 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);
+ // 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;
+ // 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