summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ddms/app/src/com/android/ddms/DeviceCommandDialog.java12
-rw-r--r--ddms/app/src/com/android/ddms/UIThread.java18
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/AdbCommandRejectedException.java3
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/CanceledException.java40
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/Device.java107
-rwxr-xr-xddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java41
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/InstallException.java42
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/ShellCommandUnresponsiveException.java3
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/SyncException.java93
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java418
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/TimeoutException.java3
-rw-r--r--ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java45
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java8
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressHelper.java99
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java11
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java172
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java64
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java44
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java11
-rw-r--r--dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java42
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchMessages.java2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/messages.properties2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java50
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/libs/.gitignore1
-rw-r--r--eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java10
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java19
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java1
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java3
-rw-r--r--hierarchyviewer2/.gitignore4
-rw-r--r--screenshot/src/com/android/screenshot/Screenshot.java7
33 files changed, 848 insertions, 545 deletions
diff --git a/ddms/app/src/com/android/ddms/DeviceCommandDialog.java b/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
index 6145733..ce6865d 100644
--- a/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
+++ b/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
@@ -17,9 +17,12 @@
package com.android.ddms;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.Log;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -256,6 +259,15 @@ public class DeviceCommandDialog extends Dialog {
catch (IOException ioe) {
Log.w("ddms", "Remote exec failed: " + ioe.getMessage());
mResult = RESULT_FAILURE;
+ } catch (TimeoutException e) {
+ Log.w("ddms", "Remote exec failed: " + e.getMessage());
+ mResult = RESULT_FAILURE;
+ } catch (AdbCommandRejectedException e) {
+ Log.w("ddms", "Remote exec failed: " + e.getMessage());
+ mResult = RESULT_FAILURE;
+ } catch (ShellCommandUnresponsiveException e) {
+ Log.w("ddms", "Remote exec failed: " + e.getMessage());
+ mResult = RESULT_FAILURE;
}
}
diff --git a/ddms/app/src/com/android/ddms/UIThread.java b/ddms/app/src/com/android/ddms/UIThread.java
index 723442d..9ba1ea0 100644
--- a/ddms/app/src/com/android/ddms/UIThread.java
+++ b/ddms/app/src/com/android/ddms/UIThread.java
@@ -21,13 +21,13 @@ import com.android.ddmlib.Client;
import com.android.ddmlib.ClientData;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
+import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncService;
import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
import com.android.ddmlib.ClientData.IHprofDumpHandler;
import com.android.ddmlib.ClientData.MethodProfilingStatus;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmuilib.AllocationPanel;
import com.android.ddmuilib.DevicePanel;
import com.android.ddmuilib.EmulatorControlPanel;
@@ -328,18 +328,20 @@ public class UIThread implements IUiSelectionListener, IClientChangeListener {
// get the sync service to pull the HPROF file
final SyncService sync = client.getDevice().getSyncService();
if (sync != null) {
- SyncResult result = promptAndPull(sync,
+ promptAndPull(sync,
client.getClientData().getClientDescription() + ".hprof",
remoteFilePath, "Save HPROF file");
- if (result != null && result.getCode() != SyncService.RESULT_OK) {
- displayErrorFromUiThread(
- "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
- device.getSerialNumber(), result.getMessage());
- }
} else {
- displayErrorFromUiThread("Unable to download HPROF file from device '%1$s'.",
+ displayErrorFromUiThread(
+ "Unable to download HPROF file from device '%1$s'.",
device.getSerialNumber());
}
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ displayErrorFromUiThread(
+ "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
+ device.getSerialNumber(), e.getMessage());
+ }
} catch (Exception e) {
displayErrorFromUiThread("Unable to download HPROF file from device '%1$s'.",
device.getSerialNumber());
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/AdbCommandRejectedException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/AdbCommandRejectedException.java
index 673acb5..ae7d014 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/AdbCommandRejectedException.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/AdbCommandRejectedException.java
@@ -16,12 +16,11 @@
package com.android.ddmlib;
-import java.io.IOException;
/**
* Exception thrown when adb refuses a command.
*/
-public class AdbCommandRejectedException extends IOException {
+public class AdbCommandRejectedException extends Exception {
private static final long serialVersionUID = 1L;
private final boolean mIsDeviceOffline;
private final boolean mErrorDuringDeviceSelection;
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/CanceledException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/CanceledException.java
new file mode 100644
index 0000000..84eda03
--- /dev/null
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/CanceledException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ddmlib;
+
+/**
+ * Abstract exception for exception that can be thrown when a user input cancels the action.
+ * <p/>
+ * {@link #wasCanceled()} returns whether the action was canceled because of user input.
+ *
+ */
+public abstract class CanceledException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ CanceledException(String message) {
+ super(message);
+ }
+
+ CanceledException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Returns true if the action was canceled by user input.
+ */
+ public abstract boolean wasCanceled();
+}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
index 7eff98e..bb61e5f 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
@@ -16,7 +16,6 @@
package com.android.ddmlib;
-import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmlib.log.LogReceiver;
import java.io.File;
@@ -408,16 +407,25 @@ final class Device implements IDevice {
}
public String installPackage(String packageFilePath, boolean reinstall)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException {
- String remoteFilePath = syncPackageToDevice(packageFilePath);
- String result = installRemotePackage(remoteFilePath, reinstall);
- removeRemotePackage(remoteFilePath);
- return result;
+ throws InstallException {
+ try {
+ String remoteFilePath = syncPackageToDevice(packageFilePath);
+ String result = installRemotePackage(remoteFilePath, reinstall);
+ removeRemotePackage(remoteFilePath);
+ return result;
+ } catch (IOException e) {
+ throw new InstallException(e);
+ } catch (AdbCommandRejectedException e) {
+ throw new InstallException(e);
+ } catch (TimeoutException e) {
+ throw new InstallException(e);
+ } catch (SyncException e) {
+ throw new InstallException(e);
+ }
}
public String syncPackageToDevice(String localFilePath)
- throws IOException, AdbCommandRejectedException, TimeoutException {
+ throws IOException, AdbCommandRejectedException, TimeoutException, SyncException {
try {
String packageFileName = getFileName(localFilePath);
String remoteFilePath = String.format("/data/local/tmp/%1$s", packageFileName); //$NON-NLS-1$
@@ -430,24 +438,23 @@ final class Device implements IDevice {
String message = String.format("Uploading file onto device '%1$s'",
getSerialNumber());
Log.d(LOG_TAG, message);
- SyncResult result = sync.pushFile(localFilePath, remoteFilePath,
- SyncService.getNullProgressMonitor());
-
- if (result.getCode() != SyncService.RESULT_OK) {
- throw new IOException(String.format("Unable to upload file: %1$s",
- result.getMessage()));
- }
+ sync.pushFile(localFilePath, remoteFilePath, SyncService.getNullProgressMonitor());
} else {
throw new IOException("Unable to open sync connection!");
}
return remoteFilePath;
} catch (TimeoutException e) {
- Log.e(LOG_TAG, "Unable to open sync connection! Timeout.");
+ Log.e(LOG_TAG, "Error during Sync: timeout.");
+ throw e;
+
+ } catch (SyncException e) {
+ Log.e(LOG_TAG, String.format("Error during Sync: %1$s", e.getMessage()));
throw e;
+
} catch (IOException e) {
- Log.e(LOG_TAG, String.format("Unable to open sync connection! reason: %1$s",
- e.getMessage()));
+ Log.e(LOG_TAG, String.format("Error during Sync: %1$s", e.getMessage()));
throw e;
+
}
}
@@ -461,40 +468,52 @@ final class Device implements IDevice {
}
public String installRemotePackage(String remoteFilePath, boolean reinstall)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException {
- InstallReceiver receiver = new InstallReceiver();
- String cmd = String.format(reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"",
- remoteFilePath);
- executeShellCommand(cmd, receiver, INSTALL_TIMEOUT);
- return receiver.getErrorMessage();
+ throws InstallException {
+ try {
+ InstallReceiver receiver = new InstallReceiver();
+ String cmd = String.format(reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"",
+ remoteFilePath);
+ executeShellCommand(cmd, receiver, INSTALL_TIMEOUT);
+ return receiver.getErrorMessage();
+ } catch (TimeoutException e) {
+ throw new InstallException(e);
+ } catch (AdbCommandRejectedException e) {
+ throw new InstallException(e);
+ } catch (ShellCommandUnresponsiveException e) {
+ throw new InstallException(e);
+ } catch (IOException e) {
+ throw new InstallException(e);
+ }
}
- /**
- * {@inheritDoc}
- */
- public void removeRemotePackage(String remoteFilePath)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException {
- // now we delete the app we sync'ed
+ public void removeRemotePackage(String remoteFilePath) throws InstallException {
try {
executeShellCommand("rm " + remoteFilePath, new NullOutputReceiver(), INSTALL_TIMEOUT);
} catch (IOException e) {
- Log.e(LOG_TAG, String.format("Failed to delete temporary package: %1$s",
- e.getMessage()));
- throw e;
+ throw new InstallException(e);
+ } catch (TimeoutException e) {
+ throw new InstallException(e);
+ } catch (AdbCommandRejectedException e) {
+ throw new InstallException(e);
+ } catch (ShellCommandUnresponsiveException e) {
+ throw new InstallException(e);
}
}
- /**
- * {@inheritDoc}
- */
- public String uninstallPackage(String packageName)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException {
- InstallReceiver receiver = new InstallReceiver();
- executeShellCommand("pm uninstall " + packageName, receiver, INSTALL_TIMEOUT);
- return receiver.getErrorMessage();
+ public String uninstallPackage(String packageName) throws InstallException {
+ try {
+ InstallReceiver receiver = new InstallReceiver();
+ executeShellCommand("pm uninstall " + packageName, receiver, INSTALL_TIMEOUT);
+ return receiver.getErrorMessage();
+ } catch (TimeoutException e) {
+ throw new InstallException(e);
+ } catch (AdbCommandRejectedException e) {
+ throw new InstallException(e);
+ } catch (ShellCommandUnresponsiveException e) {
+ throw new InstallException(e);
+ } catch (IOException e) {
+ throw new InstallException(e);
+ }
}
/*
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
index 01814ac..c2e2c16 100755
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
@@ -322,15 +322,10 @@ public interface IDevice {
* @param packageFilePath the absolute file system path to file on local host to install
* @param reinstall set to <code>true</code> if re-install of app should be performed
* @return a {@link String} with an error code, or <code>null</code> if success.
- * @throws TimeoutException in case of timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device didn't respond for long time when
- * performing the action.
- * @throws IOException in case of I/O error on the connection.
+ * @throws InstallException if the installation fails.
*/
public String installPackage(String packageFilePath, boolean reinstall)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException;
+ throws InstallException;
/**
* Pushes a file to device
@@ -340,53 +335,37 @@ public interface IDevice {
* @throws TimeoutException in case of timeout on the connection.
* @throws AdbCommandRejectedException if adb rejects the command
* @throws IOException in case of I/O error on the connection.
+ * @throws SyncException if an error happens during the push of the package on the device.
*/
public String syncPackageToDevice(String localFilePath)
- throws TimeoutException, AdbCommandRejectedException, IOException;
+ throws TimeoutException, AdbCommandRejectedException, IOException, SyncException;
/**
* Installs the application package that was pushed to a temporary location on the device.
*
* @param remoteFilePath absolute file path to package file on device
* @param reinstall set to <code>true</code> if re-install of app should be performed
- * @throws TimeoutException in case of timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device didn't respond for long time when
- * performing the action.
- * @throws IOException if installation failed
+ * @throws InstallException if the installation fails.
*/
public String installRemotePackage(String remoteFilePath, boolean reinstall)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException;
+ throws InstallException;
/**
* Removes a file from device.
*
* @param remoteFilePath path on device of file to remove
- * @throws TimeoutException in case of timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device didn't respond for long time when
- * performing the action.
- * @throws IOException if file removal failed
+ * @throws InstallException if the installation fails.
*/
- public void removeRemotePackage(String remoteFilePath)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException;
+ public void removeRemotePackage(String remoteFilePath) throws InstallException;
/**
* Uninstalls an package from the device.
*
* @param packageName the Android application package name to uninstall
* @return a {@link String} with an error code, or <code>null</code> if success.
- * @throws TimeoutException in case of timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device didn't respond for long time when
- * performing the action.
- * @throws IOException
+ * @throws InstallException if the uninstallation fails.
*/
- public String uninstallPackage(String packageName)
- throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- IOException;
+ public String uninstallPackage(String packageName) throws InstallException;
/**
* Reboot the device.
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/InstallException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/InstallException.java
new file mode 100644
index 0000000..7aa718f
--- /dev/null
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/InstallException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ddmlib;
+
+/**
+ * Thrown if installation or uninstallation of application fails.
+ */
+public class InstallException extends CanceledException {
+ private static final long serialVersionUID = 1L;
+
+ public InstallException(Throwable cause) {
+ super(cause.getMessage(), cause);
+ }
+
+ public InstallException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Returns true if the installation was canceled by user input. This can typically only
+ * happen in the sync phase.
+ */
+ @Override
+ public boolean wasCanceled() {
+ Throwable cause = getCause();
+ return cause instanceof SyncException && ((SyncException)cause).wasCanceled();
+ }
+}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/ShellCommandUnresponsiveException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/ShellCommandUnresponsiveException.java
index 2dc5d3a..09823c4 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/ShellCommandUnresponsiveException.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/ShellCommandUnresponsiveException.java
@@ -16,13 +16,12 @@
package com.android.ddmlib;
-import java.io.IOException;
/**
* Exception thrown when a shell command executed on a device takes too long to send its output.
* <p/>The command may not actually be unresponsive, it just has spent too much time not outputting
* any thing to the console.
*/
-public class ShellCommandUnresponsiveException extends IOException {
+public class ShellCommandUnresponsiveException extends Exception {
private static final long serialVersionUID = 1L;
}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/SyncException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncException.java
new file mode 100644
index 0000000..1e9b692
--- /dev/null
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncException.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ddmlib;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown when a transfer using {@link SyncService} doesn't complete.
+ * <p/>This is different from an {@link IOException} because it's not the underlying connection
+ * that triggered the error, but the adb transfer protocol that didn't work somehow, or that the
+ * targets (local and/or remote) were wrong.
+ */
+public class SyncException extends CanceledException {
+ private static final long serialVersionUID = 1L;
+
+ public enum SyncError {
+ /** canceled transfer */
+ CANCELED("Operation was canceled by the user."),
+ /** Transfer error */
+ TRANSFER_PROTOCOL_ERROR("Adb Transfer Protocol Error."),
+ /** unknown remote object during a pull */
+ NO_REMOTE_OBJECT("Remote object doesn't exist!"),
+ /** Result code when attempting to pull multiple files into a file */
+ TARGET_IS_FILE("Target object is a file."),
+ /** Result code when attempting to pull multiple into a directory that does not exist. */
+ NO_DIR_TARGET("Target directory doesn't exist."),
+ /** wrong encoding on the remote path. */
+ REMOTE_PATH_ENCODING("Remote Path encoding is not supported."),
+ /** remote path that is too long. */
+ REMOTE_PATH_LENGTH("Remote path is too long."),
+ /** error while reading local file. */
+ FILE_READ_ERROR("Reading local file failed!"),
+ /** attempting to push a directory. */
+ LOCAL_IS_DIRECTORY("Local path is a directory."),
+ /** when the target path of a multi file push is a file. */
+ REMOTE_IS_FILE("Remote path is a file."),
+ /** receiving too much data from the remove device at once */
+ BUFFER_OVERRUN("Receiving too much data.");
+
+ private final String mMessage;
+
+ private SyncError(String message) {
+ mMessage = message;
+ }
+
+ public String getMessage() {
+ return mMessage;
+ }
+ }
+
+ private final SyncError mError;
+
+ public SyncException(SyncError error) {
+ super(error.getMessage());
+ mError = error;
+ }
+
+ public SyncException(SyncError error, String message) {
+ super(message);
+ mError = error;
+ }
+
+ public SyncException(SyncError error, Throwable cause) {
+ super(error.getMessage(), cause);
+ mError = error;
+ }
+
+ public SyncError getErrorCode() {
+ return mError;
+ }
+
+ /**
+ * Returns true if the sync was canceled by user input.
+ */
+ @Override
+ public boolean wasCanceled() {
+ return mError == SyncError.CANCELED;
+ }
+}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
index d2b8af3..0303a03 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
@@ -18,6 +18,7 @@ package com.android.ddmlib;
import com.android.ddmlib.AdbHelper.AdbResponse;
import com.android.ddmlib.FileListingService.FileEntry;
+import com.android.ddmlib.SyncException.SyncError;
import com.android.ddmlib.utils.ArrayHelper;
import java.io.File;
@@ -78,69 +79,6 @@ public final class SyncService {
private final static int SYNC_DATA_MAX = 64*1024;
private final static int REMOTE_PATH_MAX_LENGTH = 1024;
- /** Result code for transfer success. */
- public static final int RESULT_OK = 0;
- /** Result code for canceled transfer */
- public static final int RESULT_CANCELED = 1;
- /** Result code for unknown error */
- public static final int RESULT_UNKNOWN_ERROR = 2;
- /** Result code for network connection error */
- public static final int RESULT_CONNECTION_ERROR = 3;
- /** Result code for unknown remote object during a pull */
- public static final int RESULT_NO_REMOTE_OBJECT = 4;
- /** Result code when attempting to pull multiple files into a file */
- public static final int RESULT_TARGET_IS_FILE = 5;
- /** Result code when attempting to pull multiple into a directory that does not exist. */
- public static final int RESULT_NO_DIR_TARGET = 6;
- /** Result code for wrong encoding on the remote path. */
- public static final int RESULT_REMOTE_PATH_ENCODING = 7;
- /** Result code for remote path that is too long. */
- public static final int RESULT_REMOTE_PATH_LENGTH = 8;
- /** Result code for error while writing local file. */
- public static final int RESULT_FILE_WRITE_ERROR = 9;
- /** Result code for error while reading local file. */
- public static final int RESULT_FILE_READ_ERROR = 10;
- /** Result code for attempting to push a file that does not exist. */
- public static final int RESULT_NO_LOCAL_FILE = 11;
- /** Result code for attempting to push a directory. */
- public static final int RESULT_LOCAL_IS_DIRECTORY = 12;
- /** Result code for when the target path of a multi file push is a file. */
- public static final int RESULT_REMOTE_IS_FILE = 13;
- /** Result code for receiving too much data from the remove device at once */
- public static final int RESULT_BUFFER_OVERRUN = 14;
- /** Result code for network connection timeout */
- public static final int RESULT_CONNECTION_TIMEOUT = 15;
-
- /**
- * A file transfer result.
- * <p/>
- * This contains a code, and an optional string
- */
- public static class SyncResult {
- private int mCode;
- private String mMessage;
- SyncResult(int code, String message) {
- mCode = code;
- mMessage = message;
- }
-
- SyncResult(int code, Exception e) {
- this(code, e.getMessage());
- }
-
- SyncResult(int code) {
- this(code, errorCodeToString(code));
- }
-
- public int getCode() {
- return mCode;
- }
-
- public String getMessage() {
- return mMessage;
- }
- }
-
/**
* Classes which implement this interface provide methods that deal
* with displaying transfer progress.
@@ -287,68 +225,30 @@ public final class SyncService {
}
/**
- * Converts an error code into a non-localized string
- * @param code the error code;
- */
- private static String errorCodeToString(int code) {
- switch (code) {
- case RESULT_OK:
- return "Success.";
- case RESULT_CANCELED:
- return "Tranfert canceled by the user.";
- case RESULT_UNKNOWN_ERROR:
- return "Unknown Error.";
- case RESULT_CONNECTION_ERROR:
- return "Adb Connection Error.";
- case RESULT_NO_REMOTE_OBJECT:
- return "Remote object doesn't exist!";
- case RESULT_TARGET_IS_FILE:
- return "Target object is a file.";
- case RESULT_NO_DIR_TARGET:
- return "Target directory doesn't exist.";
- case RESULT_REMOTE_PATH_ENCODING:
- return "Remote Path encoding is not supported.";
- case RESULT_REMOTE_PATH_LENGTH:
- return "Remove path is too long.";
- case RESULT_FILE_WRITE_ERROR:
- return "Writing local file failed!";
- case RESULT_FILE_READ_ERROR:
- return "Reading local file failed!";
- case RESULT_NO_LOCAL_FILE:
- return "Local file doesn't exist.";
- case RESULT_LOCAL_IS_DIRECTORY:
- return "Local path is a directory.";
- case RESULT_REMOTE_IS_FILE:
- return "Remote path is a file.";
- case RESULT_BUFFER_OVERRUN:
- return "Receiving too much data.";
- case RESULT_CONNECTION_TIMEOUT:
- return "timeout";
- }
-
- throw new RuntimeException();
- }
-
- /**
* Pulls file(s) or folder(s).
* @param entries the remote item(s) to pull
* @param localPath The local destination. If the entries count is > 1 or
* if the unique entry is a folder, this should be a folder.
* @param monitor The progress monitor. Cannot be null.
- * @return a {@link SyncResult} object with a code and an optional message.
+ * @throws SyncException
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws TimeoutException
*
* @see FileListingService.FileEntry
* @see #getNullProgressMonitor()
*/
- public SyncResult pull(FileEntry[] entries, String localPath, ISyncProgressMonitor monitor) {
+ public void pull(FileEntry[] entries, String localPath, ISyncProgressMonitor monitor)
+ throws SyncException, FileNotFoundException, IOException, TimeoutException {
// first we check the destination is a directory and exists
File f = new File(localPath);
if (f.exists() == false) {
- return new SyncResult(RESULT_NO_DIR_TARGET);
+ throw new SyncException(SyncError.NO_DIR_TARGET);
}
if (f.isDirectory() == false) {
- return new SyncResult(RESULT_TARGET_IS_FILE);
+ throw new SyncException(SyncError.TARGET_IS_FILE);
}
// get a FileListingService object
@@ -360,11 +260,9 @@ public final class SyncService {
// start the monitor
monitor.start(total);
- SyncResult result = doPull(entries, localPath, fls, monitor);
+ doPull(entries, localPath, fls, monitor);
monitor.stop();
-
- return result;
}
/**
@@ -372,20 +270,23 @@ public final class SyncService {
* @param remote the remote file
* @param localFilename The local destination.
* @param monitor The progress monitor. Cannot be null.
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws SyncException
+ * @throws IOException
+ * @throws FileNotFoundException
+ * @throws TimeoutException
*
* @see FileListingService.FileEntry
* @see #getNullProgressMonitor()
*/
- public SyncResult pullFile(FileEntry remote, String localFilename,
- ISyncProgressMonitor monitor) {
+ public void pullFile(FileEntry remote, String localFilename, ISyncProgressMonitor monitor)
+ throws FileNotFoundException, IOException, SyncException, TimeoutException {
int total = remote.getSizeValue();
monitor.start(total);
- SyncResult result = doPullFile(remote.getFullPath(), localFilename, monitor);
+ doPullFile(remote.getFullPath(), localFilename, monitor);
monitor.stop();
- return result;
}
/**
@@ -396,19 +297,28 @@ public final class SyncService {
* @param remoteFilepath the full path to the remote file
* @param localFilename The local destination.
* @param monitor The progress monitor. Cannot be null.
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws IOException in case of an IO exception.
+ * @throws TimeoutException in case of a timeout reading responses from the device.
+ * @throws SyncException in case of a sync exception.
*
* @see #getNullProgressMonitor()
*/
- public SyncResult pullFile(String remoteFilepath, String localFilename,
- ISyncProgressMonitor monitor) {
+ public void pullFile(String remoteFilepath, String localFilename,
+ ISyncProgressMonitor monitor) throws TimeoutException, IOException, SyncException {
+ Integer mode = readMode(remoteFilepath);
+ if (mode == null) {
+ // attempts to download anyway
+ } else if (mode == 0) {
+ throw new SyncException(SyncError.NO_REMOTE_OBJECT);
+ }
+
monitor.start(0);
//TODO: use the {@link FileListingService} to get the file size.
- SyncResult result = doPullFile(remoteFilepath, localFilename, monitor);
+ doPullFile(remoteFilepath, localFilename, monitor);
monitor.stop();
- return result;
}
/**
@@ -416,11 +326,16 @@ public final class SyncService {
* @param local An array of loca files to push
* @param remote the remote {@link FileEntry} representing a directory.
* @param monitor The progress monitor. Cannot be null.
- * @return a {@link SyncResult} object with a code and an optional message.
+ * @throws SyncException
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws TimeoutException
*/
- public SyncResult push(String[] local, FileEntry remote, ISyncProgressMonitor monitor) {
+ public void push(String[] local, FileEntry remote, ISyncProgressMonitor monitor)
+ throws SyncException, FileNotFoundException, IOException, TimeoutException {
if (remote.isDirectory() == false) {
- return new SyncResult(RESULT_REMOTE_IS_FILE);
+ throw new SyncException(SyncError.REMOTE_IS_FILE);
}
// make a list of File from the list of String
@@ -435,11 +350,9 @@ public final class SyncService {
monitor.start(total);
- SyncResult result = doPush(fileArray, remote.getFullPath(), monitor);
+ doPush(fileArray, remote.getFullPath(), monitor);
monitor.stop();
-
- return result;
}
/**
@@ -447,25 +360,30 @@ public final class SyncService {
* @param local the local filepath.
* @param remote The remote filepath.
* @param monitor The progress monitor. Cannot be null.
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws SyncException
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws TimeoutException
+ *
*/
- public SyncResult pushFile(String local, String remote, ISyncProgressMonitor monitor) {
+ public void pushFile(String local, String remote, ISyncProgressMonitor monitor)
+ throws SyncException, FileNotFoundException, IOException, TimeoutException {
File f = new File(local);
if (f.exists() == false) {
- return new SyncResult(RESULT_NO_LOCAL_FILE);
+ throw new FileNotFoundException();
}
if (f.isDirectory()) {
- return new SyncResult(RESULT_LOCAL_IS_DIRECTORY);
+ throw new SyncException(SyncError.LOCAL_IS_DIRECTORY);
}
monitor.start((int)f.length());
- SyncResult result = doPushFile(local, remote, monitor);
+ doPushFile(local, remote, monitor);
monitor.stop();
-
- return result;
}
/**
@@ -520,16 +438,22 @@ public final class SyncService {
* @param localPath the localpath to a directory
* @param fileListingService a FileListingService object to browse through remote directories.
* @param monitor the progress monitor. Must be started already.
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws SyncException
+ * @throws TimeoutException
*/
- private SyncResult doPull(FileEntry[] entries, String localPath,
+ private void doPull(FileEntry[] entries, String localPath,
FileListingService fileListingService,
- ISyncProgressMonitor monitor) {
+ ISyncProgressMonitor monitor) throws SyncException, FileNotFoundException, IOException,
+ TimeoutException {
for (FileEntry e : entries) {
// check if we're cancelled
if (monitor.isCanceled() == true) {
- return new SyncResult(RESULT_CANCELED);
+ throw new SyncException(SyncError.CANCELED);
}
// get type (we only pull directory and files for now)
@@ -545,22 +469,14 @@ public final class SyncService {
// then recursively call the content. Since we did a ls command
// to get the number of files, we can use the cache
FileEntry[] children = fileListingService.getChildren(e, true, null);
- SyncResult result = doPull(children, dest, fileListingService, monitor);
- if (result.mCode != RESULT_OK) {
- return result;
- }
+ doPull(children, dest, fileListingService, monitor);
monitor.advance(1);
} else if (type == FileListingService.TYPE_FILE) {
monitor.startSubTask(e.getFullPath());
String dest = localPath + File.separator + e.getName();
- SyncResult result = doPullFile(e.getFullPath(), dest, monitor);
- if (result.mCode != RESULT_OK) {
- return result;
- }
+ doPullFile(e.getFullPath(), dest, monitor);
}
}
-
- return new SyncResult(RESULT_OK);
}
/**
@@ -568,10 +484,15 @@ public final class SyncService {
* @param remotePath the remote file (length max is 1024)
* @param localPath the local destination
* @param monitor the monitor. The monitor must be started already.
- * @return a {@link SyncResult} object with a code and an optional message.
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws SyncException
+ * @throws TimeoutException
*/
- private SyncResult doPullFile(String remotePath, String localPath,
- ISyncProgressMonitor monitor) {
+ private void doPullFile(String remotePath, String localPath,
+ ISyncProgressMonitor monitor) throws FileNotFoundException, IOException, SyncException,
+ TimeoutException {
byte[] msg = null;
byte[] pullResult = new byte[8];
@@ -581,7 +502,7 @@ public final class SyncService {
byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
- return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
+ throw new SyncException(SyncError.REMOTE_PATH_LENGTH);
}
// create the full request message
@@ -597,14 +518,11 @@ public final class SyncService {
// check we have the proper data back
if (checkResult(pullResult, ID_DATA) == false &&
checkResult(pullResult, ID_DONE) == false) {
- return new SyncResult(RESULT_CONNECTION_ERROR);
+ throw new SyncException(SyncError.TRANSFER_PROTOCOL_ERROR,
+ readErrorMessage(pullResult, timeOut));
}
} catch (UnsupportedEncodingException e) {
- return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
- } catch (TimeoutException e) {
- return new SyncResult(RESULT_CONNECTION_TIMEOUT, e);
- } catch (IOException e) {
- return new SyncResult(RESULT_CONNECTION_ERROR, e);
+ throw new SyncException(SyncError.REMOTE_PATH_ENCODING, e);
}
// access the destination file
@@ -613,11 +531,7 @@ public final class SyncService {
// create the stream to write in the file. We use a new try/catch block to differentiate
// between file and network io exceptions.
FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(f);
- } catch (FileNotFoundException e) {
- return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
- }
+ fos = new FileOutputStream(f);
// the buffer to read the data
byte[] data = new byte[SYNC_DATA_MAX];
@@ -626,7 +540,7 @@ public final class SyncService {
while (true) {
// check if we're cancelled
if (monitor.isCanceled() == true) {
- return new SyncResult(RESULT_CANCELED);
+ throw new SyncException(SyncError.CANCELED);
}
// if we're done, we stop the loop
@@ -635,43 +549,29 @@ public final class SyncService {
}
if (checkResult(pullResult, ID_DATA) == false) {
// hmm there's an error
- return new SyncResult(RESULT_CONNECTION_ERROR);
+ throw new SyncException(SyncError.TRANSFER_PROTOCOL_ERROR,
+ readErrorMessage(pullResult, timeOut));
}
int length = ArrayHelper.swap32bitFromArray(pullResult, 4);
if (length > SYNC_DATA_MAX) {
// buffer overrun!
// error and exit
- return new SyncResult(RESULT_BUFFER_OVERRUN);
+ throw new SyncException(SyncError.BUFFER_OVERRUN);
}
- try {
- // now read the length we received
- AdbHelper.read(mChannel, data, length, timeOut);
+ // now read the length we received
+ AdbHelper.read(mChannel, data, length, timeOut);
- // get the header for the next packet.
- AdbHelper.read(mChannel, pullResult, -1, timeOut);
- } catch (TimeoutException e) {
- return new SyncResult(RESULT_CONNECTION_TIMEOUT, e);
- } catch (IOException e) {
- return new SyncResult(RESULT_CONNECTION_ERROR, e);
- }
+ // get the header for the next packet.
+ AdbHelper.read(mChannel, pullResult, -1, timeOut);
// write the content in the file
- try {
- fos.write(data, 0, length);
- } catch (IOException e) {
- return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
- }
+ fos.write(data, 0, length);
monitor.advance(length);
}
- try {
- fos.flush();
- } catch (IOException e) {
- return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
- }
- return new SyncResult(RESULT_OK);
+ fos.flush();
}
@@ -680,39 +580,36 @@ public final class SyncService {
* @param fileArray
* @param remotePath
* @param monitor
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws SyncException
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws TimeoutException
*/
- private SyncResult doPush(File[] fileArray, String remotePath, ISyncProgressMonitor monitor) {
+ private void doPush(File[] fileArray, String remotePath, ISyncProgressMonitor monitor)
+ throws SyncException, FileNotFoundException, IOException, TimeoutException {
for (File f : fileArray) {
// check if we're canceled
if (monitor.isCanceled() == true) {
- return new SyncResult(RESULT_CANCELED);
+ throw new SyncException(SyncError.CANCELED);
}
if (f.exists()) {
if (f.isDirectory()) {
// append the name of the directory to the remote path
String dest = remotePath + "/" + f.getName(); // $NON-NLS-1S
monitor.startSubTask(dest);
- SyncResult result = doPush(f.listFiles(), dest, monitor);
-
- if (result.mCode != RESULT_OK) {
- return result;
- }
+ doPush(f.listFiles(), dest, monitor);
monitor.advance(1);
} else if (f.isFile()) {
// append the name of the file to the remote path
String remoteFile = remotePath + "/" + f.getName(); // $NON-NLS-1S
monitor.startSubTask(remoteFile);
- SyncResult result = doPushFile(f.getAbsolutePath(), remoteFile, monitor);
- if (result.mCode != RESULT_OK) {
- return result;
- }
+ doPushFile(f.getAbsolutePath(), remoteFile, monitor);
}
}
}
-
- return new SyncResult(RESULT_OK);
}
/**
@@ -720,10 +617,16 @@ public final class SyncService {
* @param localPath the local file to push
* @param remotePath the remote file (length max is 1024)
* @param monitor the monitor. The monitor must be started already.
- * @return a {@link SyncResult} object with a code and an optional message.
+ *
+ * @throws SyncException
+ * @throws FileNotFoundException if the file exists but is a directory, does not exist but
+ * cannot be created, or cannot be opened for any other reason.
+ * @throws IOException
+ * @throws TimeoutException
*/
- private SyncResult doPushFile(String localPath, String remotePath,
- ISyncProgressMonitor monitor) {
+ private void doPushFile(String localPath, String remotePath,
+ ISyncProgressMonitor monitor) throws SyncException, FileNotFoundException, IOException,
+ TimeoutException {
FileInputStream fis = null;
byte[] msg;
@@ -733,36 +636,23 @@ public final class SyncService {
byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
- return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
+ throw new SyncException(SyncError.REMOTE_PATH_LENGTH);
}
File f = new File(localPath);
- // this shouldn't happen but still...
- if (f.exists() == false) {
- return new SyncResult(RESULT_NO_LOCAL_FILE);
- }
-
// create the stream to read the file
fis = new FileInputStream(f);
// create the header for the action
msg = createSendFileReq(ID_SEND, remotePathContent, 0644);
} catch (UnsupportedEncodingException e) {
- return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
- } catch (FileNotFoundException e) {
- return new SyncResult(RESULT_FILE_READ_ERROR, e);
+ throw new SyncException(SyncError.REMOTE_PATH_ENCODING, e);
}
// and send it. We use a custom try/catch block to make the difference between
// file and network IO exceptions.
- try {
- AdbHelper.write(mChannel, msg, -1, timeOut);
- } catch (TimeoutException e) {
- return new SyncResult(RESULT_CONNECTION_TIMEOUT, e);
- } catch (IOException e) {
- return new SyncResult(RESULT_CONNECTION_ERROR, e);
- }
+ AdbHelper.write(mChannel, msg, -1, timeOut);
// create the buffer used to read.
// we read max SYNC_DATA_MAX, but we need 2 4 bytes at the beginning.
@@ -775,16 +665,11 @@ public final class SyncService {
while (true) {
// check if we're canceled
if (monitor.isCanceled() == true) {
- return new SyncResult(RESULT_CANCELED);
+ throw new SyncException(SyncError.CANCELED);
}
// read up to SYNC_DATA_MAX
- int readCount = 0;
- try {
- readCount = fis.read(mBuffer, 8, SYNC_DATA_MAX);
- } catch (IOException e) {
- return new SyncResult(RESULT_FILE_READ_ERROR, e);
- }
+ int readCount = fis.read(mBuffer, 8, SYNC_DATA_MAX);
if (readCount == -1) {
// we reached the end of the file
@@ -796,65 +681,62 @@ public final class SyncService {
ArrayHelper.swap32bitsToArray(readCount, mBuffer, 4);
// now write it
- try {
- AdbHelper.write(mChannel, mBuffer, readCount+8, timeOut);
- } catch (TimeoutException e) {
- return new SyncResult(RESULT_CONNECTION_TIMEOUT, e);
- } catch (IOException e) {
- return new SyncResult(RESULT_CONNECTION_ERROR, e);
- }
+ AdbHelper.write(mChannel, mBuffer, readCount+8, timeOut);
// and advance the monitor
monitor.advance(readCount);
}
// close the local file
- try {
- fis.close();
- } catch (IOException e) {
- return new SyncResult(RESULT_FILE_READ_ERROR, e);
- }
+ fis.close();
- try {
- // create the DONE message
- long time = System.currentTimeMillis() / 1000;
- msg = createReq(ID_DONE, (int)time);
+ // create the DONE message
+ long time = System.currentTimeMillis() / 1000;
+ msg = createReq(ID_DONE, (int)time);
- // and send it.
- AdbHelper.write(mChannel, msg, -1, timeOut);
+ // and send it.
+ AdbHelper.write(mChannel, msg, -1, timeOut);
- // read the result, in a byte array containing 2 ints
- // (id, size)
- byte[] result = new byte[8];
- AdbHelper.read(mChannel, result, -1 /* full length */, timeOut);
+ // read the result, in a byte array containing 2 ints
+ // (id, size)
+ byte[] result = new byte[8];
+ AdbHelper.read(mChannel, result, -1 /* full length */, timeOut);
+
+ if (checkResult(result, ID_OKAY) == false) {
+ throw new SyncException(SyncError.TRANSFER_PROTOCOL_ERROR,
+ readErrorMessage(result, timeOut));
+ }
+ }
- if (checkResult(result, ID_OKAY) == false) {
- if (checkResult(result, ID_FAIL)) {
- // read some error message...
- int len = ArrayHelper.swap32bitFromArray(result, 4);
+ /**
+ * Reads an error message from the opened {@link #mChannel}.
+ * @param result the current adb result. Must contain both FAIL and the length of the message.
+ * @param timeOut
+ * @return
+ * @throws TimeoutException
+ * @throws IOException
+ */
+ private String readErrorMessage(byte[] result, final int timeOut) throws TimeoutException,
+ IOException {
+ if (checkResult(result, ID_FAIL)) {
+ int len = ArrayHelper.swap32bitFromArray(result, 4);
- AdbHelper.read(mChannel, mBuffer, len, timeOut);
+ if (len > 0) {
+ AdbHelper.read(mChannel, mBuffer, len, timeOut);
- // output the result?
- String message = new String(mBuffer, 0, len);
- Log.e("ddms", "transfer error: " + message);
- return new SyncResult(RESULT_UNKNOWN_ERROR, message);
- }
+ String message = new String(mBuffer, 0, len);
+ Log.e("ddms", "transfer error: " + message);
- return new SyncResult(RESULT_UNKNOWN_ERROR);
+ return message;
}
- } catch (TimeoutException e) {
- return new SyncResult(RESULT_CONNECTION_TIMEOUT, e);
- } catch (IOException e) {
- return new SyncResult(RESULT_CONNECTION_ERROR, e);
}
- return new SyncResult(RESULT_OK);
+ return null;
}
/**
* Returns the mode of the remote file.
* @param path the remote file
- * @return and Integer containing the mode if all went well or null
+ * @return an Integer containing the mode if all went well or null
* otherwise
* @throws IOException
* @throws TimeoutException
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/TimeoutException.java b/ddms/libs/ddmlib/src/com/android/ddmlib/TimeoutException.java
index 25be2f9..78f5db7 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/TimeoutException.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/TimeoutException.java
@@ -16,12 +16,11 @@
package com.android.ddmlib;
-import java.io.IOException;
/**
* Exception thrown when a connection to Adb failed with a timeout.
*
*/
-public class TimeoutException extends IOException {
+public class TimeoutException extends Exception {
private static final long serialVersionUID = 1L;
}
diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
index 9d4e77b..343efdc 100644
--- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
+++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
@@ -16,12 +16,16 @@
package com.android.ddmlib.testrunner;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.Client;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.InstallException;
import com.android.ddmlib.RawImage;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.log.LogReceiver;
import java.io.IOException;
@@ -51,8 +55,12 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
* Test the basic case building of the instrumentation runner command with no arguments.
+ * @throws ShellCommandUnresponsiveException
+ * @throws AdbCommandRejectedException
+ * @throws TimeoutException
*/
- public void testRun() throws IOException {
+ public void testRun() throws IOException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
mRunner.run(new EmptyListener());
assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER),
mMockDevice.getLastShellCommand());
@@ -60,8 +68,12 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
* Test the building of the instrumentation runner command with log set.
+ * @throws ShellCommandUnresponsiveException
+ * @throws AdbCommandRejectedException
+ * @throws TimeoutException
*/
- public void testRunWithLog() throws IOException {
+ public void testRunWithLog() throws IOException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
mRunner.setLogOnly(true);
mRunner.run(new EmptyListener());
assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE,
@@ -70,8 +82,12 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
* Test the building of the instrumentation runner command with method set.
+ * @throws ShellCommandUnresponsiveException
+ * @throws AdbCommandRejectedException
+ * @throws TimeoutException
*/
- public void testRunWithMethod() throws IOException {
+ public void testRunWithMethod() throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
final String className = "FooTest";
final String testName = "fooTest";
mRunner.setMethodName(className, testName);
@@ -82,8 +98,12 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
* Test the building of the instrumentation runner command with test package set.
+ * @throws ShellCommandUnresponsiveException
+ * @throws AdbCommandRejectedException
+ * @throws TimeoutException
*/
- public void testRunWithPackage() throws IOException {
+ public void testRunWithPackage() throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
final String packageName = "foo.test";
mRunner.setTestPackageName(packageName);
mRunner.run(new EmptyListener());
@@ -93,8 +113,12 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
* Test the building of the instrumentation runner command with extra argument added.
+ * @throws ShellCommandUnresponsiveException
+ * @throws AdbCommandRejectedException
+ * @throws TimeoutException
*/
- public void testRunWithAddInstrumentationArg() throws IOException {
+ public void testRunWithAddInstrumentationArg() throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
final String extraArgName = "blah";
final String extraArgValue = "blahValue";
mRunner.addInstrumentationArg(extraArgName, extraArgValue);
@@ -103,7 +127,6 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
extraArgValue, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
}
-
/**
* Assert two strings are equal ignoring whitespace.
*/
@@ -233,21 +256,21 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
}
public String installPackage(String packageFilePath, boolean reinstall)
- throws IOException {
+ throws InstallException {
throw new UnsupportedOperationException();
}
- public String uninstallPackage(String packageName) throws IOException {
+ public String uninstallPackage(String packageName) throws InstallException {
throw new UnsupportedOperationException();
}
- public String installRemotePackage(String remoteFilePath,
- boolean reinstall) throws IOException {
+ public String installRemotePackage(String remoteFilePath, boolean reinstall)
+ throws InstallException {
throw new UnsupportedOperationException();
}
public void removeRemotePackage(String remoteFilePath)
- throws IOException {
+ throws InstallException {
throw new UnsupportedOperationException();
}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
index 99bca99..a0e9cbd 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
@@ -16,9 +16,11 @@
package com.android.ddmuilib;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.RawImage;
+import com.android.ddmlib.TimeoutException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
@@ -265,6 +267,12 @@ public class ScreenShotDialog extends Dialog {
catch (IOException ioe) {
Log.w("ddms", "Unable to get frame buffer: " + ioe.getMessage());
return null;
+ } catch (TimeoutException e) {
+ Log.w("ddms", "Unable to get frame buffer: timeout ");
+ return null;
+ } catch (AdbCommandRejectedException e) {
+ Log.w("ddms", "Unable to get frame buffer: " + e.getMessage());
+ return null;
}
}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressHelper.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressHelper.java
new file mode 100644
index 0000000..23b749e
--- /dev/null
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressHelper.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ddmuilib;
+
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Helper class to run a Sync in a {@link ProgressMonitorDialog}.
+ */
+public class SyncProgressHelper {
+
+ /**
+ * a runnable class run with an {@link ISyncProgressMonitor}.
+ */
+ public interface SyncRunnable {
+ /** Runs the sync action */
+ void run(ISyncProgressMonitor monitor) throws SyncException, IOException, TimeoutException;
+ /** close the {@link SyncService} */
+ void close();
+ }
+
+ /**
+ * Runs a {@link SyncRunnable} in a {@link ProgressMonitorDialog}.
+ * @param runnable The {@link SyncRunnable} to run.
+ * @param progressMessage the message to display in the progress dialog
+ * @param parentShell the parent shell for the progress dialog.
+ *
+ * @throws InvocationTargetException
+ * @throws InterruptedException
+ * @throws SyncException if an error happens during the push of the package on the device.
+ * @throws IOException
+ * @throws TimeoutException
+ */
+ public static void run(final SyncRunnable runnable, final String progressMessage,
+ final Shell parentShell)
+ throws InvocationTargetException, InterruptedException, SyncException, IOException,
+ TimeoutException {
+
+ final Exception[] result = new Exception[1];
+ new ProgressMonitorDialog(parentShell).run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ try {
+ runnable.run(new SyncProgressMonitor(monitor, progressMessage));
+ } catch (Exception e) {
+ result[0] = e;
+ } finally {
+ runnable.close();
+ }
+ }
+ });
+
+ if (result[0] instanceof SyncException) {
+ SyncException se = (SyncException)result[0];
+ if (se.wasCanceled()) {
+ // no need to throw this
+ return;
+ }
+ throw se;
+ }
+
+ // just do some casting so that the method declaration matches what's thrown.
+ if (result[0] instanceof TimeoutException) {
+ throw (TimeoutException)result[0];
+ }
+
+ if (result[0] instanceof IOException) {
+ throw (IOException)result[0];
+ }
+
+ if (result[0] instanceof RuntimeException) {
+ throw (RuntimeException)result[0];
+ }
+ }
+}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
index 8ef237c..6727fcb 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
@@ -16,9 +16,12 @@
package com.android.ddmuilib;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.Client;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.Log;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -157,6 +160,12 @@ public class SysinfoPanel extends TablePanel implements IShellOutputReceiver {
DUMP_COMMAND[mMode], this);
} catch (IOException e) {
Log.e("DDMS", e);
+ } catch (TimeoutException e) {
+ Log.e("DDMS", e);
+ } catch (AdbCommandRejectedException e) {
+ Log.e("DDMS", e);
+ } catch (ShellCommandUnresponsiveException e) {
+ Log.e("DDMS", e);
}
}
@@ -481,7 +490,7 @@ public class SysinfoPanel extends TablePanel implements IShellOutputReceiver {
Pattern valuePattern = Pattern.compile("(\\d+) kB");
long total = 0;
long other = 0;
- mLabel.setText("PSS in kB");
+ mLabel.setText("PSS in kB");
// Scan meminfo
while (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 77a5e57..a44bd1a 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
@@ -16,24 +16,25 @@
package com.android.ddmuilib.explorer;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.FileListingService.FileEntry;
import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmuilib.DdmUiPreferences;
import com.android.ddmuilib.ImageLoader;
import com.android.ddmuilib.Panel;
-import com.android.ddmuilib.SyncProgressMonitor;
+import com.android.ddmuilib.SyncProgressHelper;
import com.android.ddmuilib.TableHelper;
+import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
import com.android.ddmuilib.actions.ICommonAction;
import com.android.ddmuilib.console.DdmConsole;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
@@ -62,7 +63,6 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -407,19 +407,8 @@ public class DeviceExplorer extends Panel {
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;
- }
+ sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor);
+ sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor);
// now that we have the file, we need to launch traceview
String[] command = new String[2];
@@ -464,6 +453,18 @@ public class DeviceExplorer extends Panel {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
return;
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
+ return;
+ }
+ } catch (TimeoutException e) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to pull %1$s: timeout", keyEntry.getName()));
+ } catch (AdbCommandRejectedException e) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
}
}
@@ -602,6 +603,15 @@ public class DeviceExplorer extends Panel {
} catch (IOException e) {
// adb failed somehow, we do nothing. We should be displaying the error from the output
// of the shell command.
+ } catch (TimeoutException e) {
+ // adb failed somehow, we do nothing. We should be displaying the error from the output
+ // of the shell command.
+ } catch (AdbCommandRejectedException e) {
+ // adb failed somehow, we do nothing. We should be displaying the error from the output
+ // of the shell command.
+ } catch (ShellCommandUnresponsiveException e) {
+ // adb failed somehow, we do nothing. We should be displaying the error from the output
+ // of the shell command.
}
}
@@ -672,24 +682,21 @@ public class DeviceExplorer extends Panel {
final FileEntry[] entryArray = entries.toArray(
new FileEntry[entries.size()]);
- // get a progressdialog
- new ProgressMonitorDialog(mParent.getShell()).run(true, true,
- new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
- throws InvocationTargetException,
- InterruptedException {
- // create a monitor wrapper around the jface monitor
- SyncResult result = sync.pull(entryArray, localDirectory,
- new SyncProgressMonitor(monitor,
- "Pulling file(s) from the device"));
-
- if (result.getCode() != SyncService.RESULT_OK) {
- DdmConsole.printErrorToConsole(String.format(
- "Failed to pull selection: %1$s", result.getMessage()));
- }
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException, TimeoutException {
+ sync.pull(entryArray, localDirectory, monitor);
+ }
+
+ public void close() {
sync.close();
}
- });
+ }, "Pulling file(s) from the device", mParent.getShell());
+ }
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to pull selection: %1$s", e.getMessage()));
}
} catch (Exception e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
@@ -706,22 +713,22 @@ public class DeviceExplorer extends Panel {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
- new ProgressMonitorDialog(mParent.getShell()).run(true, true,
- new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
- throws InvocationTargetException,
- InterruptedException {
- SyncResult result = sync.pullFile(remote, local, new SyncProgressMonitor(
- monitor, String.format("Pulling %1$s from the device",
- remote.getName())));
- if (result.getCode() != SyncService.RESULT_OK) {
- DdmConsole.printErrorToConsole(String.format(
- "Failed to pull %1$s: %2$s", remote, result.getMessage()));
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException, TimeoutException {
+ sync.pullFile(remote, local, monitor);
}
- sync.close();
- }
- });
+ public void close() {
+ sync.close();
+ }
+ }, String.format("Pulling %1$s from the device", remote.getName()),
+ mParent.getShell());
+ }
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to pull selection: %1$s", e.getMessage()));
}
} catch (Exception e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
@@ -738,22 +745,21 @@ public class DeviceExplorer extends Panel {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
- new ProgressMonitorDialog(mParent.getShell()).run(true, true,
- new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
- throws InvocationTargetException,
- InterruptedException {
- SyncResult result = sync.push(localFiles, remoteDirectory,
- new SyncProgressMonitor(monitor,
- "Pushing file(s) to the device"));
- if (result.getCode() != SyncService.RESULT_OK) {
- DdmConsole.printErrorToConsole(String.format(
- "Failed to push the items: %1$s", result.getMessage()));
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException, TimeoutException {
+ sync.push(localFiles, remoteDirectory, monitor);
}
- sync.close();
- }
- });
+ public void close() {
+ sync.close();
+ }
+ }, "Pushing file(s) to the device", mParent.getShell());
+ }
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to push selection: %1$s", e.getMessage()));
}
} catch (Exception e) {
DdmConsole.printErrorToConsole("Failed to push the items");
@@ -770,29 +776,27 @@ public class DeviceExplorer extends Panel {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
- new ProgressMonitorDialog(mParent.getShell()).run(true, true,
- new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
- throws InvocationTargetException,
- InterruptedException {
- // get the file name
- String[] segs = local.split(Pattern.quote(File.separator));
- String name = segs[segs.length-1];
- String remoteFile = remoteDirectory + FileListingService.FILE_SEPARATOR
- + name;
-
- SyncResult result = sync.pushFile(local, remoteFile,
- new SyncProgressMonitor(monitor,
- String.format("Pushing %1$s to the device.", name)));
- if (result.getCode() != SyncService.RESULT_OK) {
- DdmConsole.printErrorToConsole(String.format(
- "Failed to push %1$s on %2$s: %3$s",
- name, mCurrentDevice.getSerialNumber(), result.getMessage()));
+ // get the file name
+ String[] segs = local.split(Pattern.quote(File.separator));
+ String name = segs[segs.length-1];
+ final String remoteFile = remoteDirectory + FileListingService.FILE_SEPARATOR
+ + name;
+
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException, TimeoutException {
+ sync.pushFile(local, remoteFile, monitor);
}
- sync.close();
- }
- });
+ public void close() {
+ sync.close();
+ }
+ }, String.format("Pushing %1$s to the device.", name), mParent.getShell());
+ }
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ DdmConsole.printErrorToConsole(String.format(
+ "Failed to push selection: %1$s", e.getMessage()));
}
} catch (Exception e) {
DdmConsole.printErrorToConsole("Failed to push the item(s).");
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java
index 6c086db..7ecf7b9 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java
@@ -16,16 +16,16 @@
package com.android.ddmuilib.handler;
+import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.ClientData.IHprofDumpHandler;
import com.android.ddmlib.ClientData.IMethodProfilingHandler;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.SyncProgressMonitor;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+import com.android.ddmuilib.SyncProgressHelper;
+import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
-import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
@@ -63,21 +63,32 @@ public abstract class BaseFileHandler {
* didn't happen (canceled by the user).
* @throws InvocationTargetException
* @throws InterruptedException
+ * @throws SyncException if an error happens during the push of the package on the device.
+ * @throws IOException
*/
- protected SyncResult promptAndPull(SyncService sync,
- String localFileName, String remoteFilePath, String title)
- throws InvocationTargetException, InterruptedException {
+ protected void promptAndPull(final SyncService sync,
+ String localFileName, final String remoteFilePath, String title)
+ throws InvocationTargetException, InterruptedException, SyncException, TimeoutException,
+ IOException {
FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
fileDialog.setText(title);
fileDialog.setFileName(localFileName);
- String localFilePath = fileDialog.open();
+ final String localFilePath = fileDialog.open();
if (localFilePath != null) {
- return pull(sync, localFilePath, remoteFilePath);
- }
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor) throws SyncException, IOException,
+ TimeoutException {
+ sync.pullFile(remoteFilePath, localFilePath, monitor);
+ }
- return null;
+ public void close() {
+ sync.close();
+ }
+ },
+ String.format("Pulling %1$s from the device", remoteFilePath), mParentShell);
+ }
}
/**
@@ -112,35 +123,6 @@ public abstract class BaseFileHandler {
}
/**
- * Pulls a file off of a device. This displays a {@link ProgressMonitorDialog} and therefore
- * must be run from the UI Thread.
- * @param sync the {@link SyncService} to use to pull the file.
- * @param localFilePath the path of the local file to create
- * @param remoteFilePath the path of the remote file to pull
- * @return the result of the sync as an instance of {@link SyncResult}
- * @throws InvocationTargetException
- * @throws InterruptedException
- */
- protected SyncResult pull(final SyncService sync, final String localFilePath,
- final String remoteFilePath)
- throws InvocationTargetException, InterruptedException {
- final SyncResult[] res = new SyncResult[1];
- new ProgressMonitorDialog(mParentShell).run(true, true, new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor) {
- try {
- res[0] = sync.pullFile(remoteFilePath, localFilePath,
- new SyncProgressMonitor(monitor, String.format(
- "Pulling %1$s from the device", remoteFilePath)));
- } finally {
- sync.close();
- }
- }
- });
-
- return res[0];
- }
-
- /**
* Display an error message.
* <p/>This will call about to {@link Display} to run this in an async {@link Runnable} in the
* UI Thread. This is safe to be called from a non-UI Thread.
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java
index b1d7f2a..f1d0135 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java
@@ -19,10 +19,14 @@ package com.android.ddmuilib.handler;
import com.android.ddmlib.Client;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
+import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.ClientData.IMethodProfilingHandler;
-import com.android.ddmlib.SyncService.SyncResult;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.SyncProgressHelper;
+import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
import com.android.ddmuilib.console.DdmConsole;
import org.eclipse.swt.widgets.Shell;
@@ -82,7 +86,8 @@ public class MethodProfilingHandler extends BaseFileHandler
if (sync != null) {
pullAndOpen(sync, remoteFilePath);
} else {
- displayErrorFromUiThread("Unable to download trace file from device '%1$s'.",
+ displayErrorFromUiThread(
+ "Unable to download trace file from device '%1$s'.",
device.getSerialNumber());
}
} catch (Exception e) {
@@ -109,25 +114,34 @@ public class MethodProfilingHandler extends BaseFileHandler
/**
* pulls and open a file. This is run from the UI thread.
*/
- private void pullAndOpen(SyncService sync, String remoteFilePath)
+ private void pullAndOpen(final SyncService sync, final String remoteFilePath)
throws InvocationTargetException, InterruptedException, IOException {
// get a temp file
File temp = File.createTempFile("android", ".trace"); //$NON-NLS-1$ //$NON-NLS-2$
- String tempPath = temp.getAbsolutePath();
+ final String tempPath = temp.getAbsolutePath();
// pull the file
- SyncResult result = pull(sync, tempPath, remoteFilePath);
- if (result != null) {
- if (result.getCode() == SyncService.RESULT_OK) {
- // open the temp file in traceview
- openInTraceview(tempPath);
- } else {
- displayErrorFromUiThread("Unable to download trace file:\n\n%1$s",
- result.getMessage());
+ try {
+ SyncProgressHelper.run(new SyncRunnable() {
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException, TimeoutException {
+ sync.pullFile(tempPath, remoteFilePath, monitor);
+ }
+
+ public void close() {
+ sync.close();
+ }
+ },
+ String.format("Pulling %1$s from the device", remoteFilePath), mParentShell);
+
+ // open the temp file in traceview
+ openInTraceview(tempPath);
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ displayErrorFromUiThread("Unable to download trace file:\n\n%1$s", e.getMessage());
}
- } else {
- // this really shouldn't happen.
- displayErrorFromUiThread("Unable to download trace file.");
+ } catch (TimeoutException e) {
+ displayErrorFromUiThread("Unable to download trace file:\n\ntimeout");
}
}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
index 710d7eb..180af4c 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
@@ -16,9 +16,12 @@
package com.android.ddmuilib.logcat;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmuilib.DdmUiPreferences;
import com.android.ddmuilib.ITableFocusListener;
@@ -1310,7 +1313,13 @@ public class LogPanel extends SelectionDependentPanel {
try {
mCurrentLoggedDevice.executeShellCommand("ps", psor); //$NON-NLS-1$
} catch (IOException e) {
- // hmm...
+ // Ignore
+ } catch (TimeoutException e) {
+ // Ignore
+ } catch (AdbCommandRejectedException e) {
+ // Ignore
+ } catch (ShellCommandUnresponsiveException e) {
+ // Ignore
}
}
}.start();
diff --git a/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java b/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
index 695573c..0669e33 100644
--- a/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
+++ b/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
@@ -16,9 +16,11 @@
package com.android.dumpeventlog;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.log.LogReceiver;
@@ -120,7 +122,7 @@ public class DumpEventLog {
grabLogFrom(device, args[1]);
} catch (FileNotFoundException e) {
e.printStackTrace();
- } catch (IOException e) {
+ } catch (Exception e) {
e.printStackTrace();
}
return;
@@ -133,7 +135,8 @@ public class DumpEventLog {
}
}
- private static void grabLogFrom(IDevice device, String filePath) throws IOException {
+ private static void grabLogFrom(IDevice device, String filePath) throws IOException,
+ TimeoutException, AdbCommandRejectedException {
LogWriter writer = new LogWriter(filePath);
LogReceiver receiver = new LogReceiver(writer);
writer.setReceiver(receiver);
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 f122e1a..575502a 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
@@ -16,11 +16,15 @@
package com.android.ide.eclipse.adt.internal.launch;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.CanceledException;
import com.android.ddmlib.Client;
import com.android.ddmlib.ClientData;
import com.android.ddmlib.IDevice;
+import com.android.ddmlib.InstallException;
import com.android.ddmlib.Log;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
@@ -892,10 +896,29 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
return installResult;
}
catch (IOException e) {
- String msg = String.format("Failed to upload %1$s on device '%2$s'", fileName,
+ String msg = String.format("Failed to install %1$s on device '%2$s': %3$s", fileName,
+ device.getSerialNumber(), e.getMessage());
+ AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e);
+ } catch (TimeoutException e) {
+ String msg = String.format("Failed to install %1$s on device '%2$s': timeout", fileName,
device.getSerialNumber());
+ AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
+ } catch (AdbCommandRejectedException e) {
+ String msg = String.format(
+ "Failed to install %1$s on device '%2$s': adb rejected install command with: %3$s",
+ fileName, device.getSerialNumber(), e.getMessage());
AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e);
+ } catch (CanceledException e) {
+ if (e.wasCanceled()) {
+ AdtPlugin.printToConsole(launchInfo.getProject(),
+ String.format("Install of %1$s canceled", fileName));
+ } else {
+ String msg = String.format("Failed to install %1$s on device '%2$s': %3$s",
+ fileName, device.getSerialNumber(), e.getMessage());
+ AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e);
+ }
}
+
return false;
}
@@ -987,7 +1010,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
*/
return checkInstallResult(result, device, launchInfo, remotePath,
InstallRetryMode.ALWAYS);
- } catch (IOException e) {
+ } catch (Exception e) {
String msg = String.format(
"Failed to install %1$s on device '%2$s!",
launchInfo.getPackageFile().getName(), device.getSerialNumber());
@@ -1005,10 +1028,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* @param remotePath the temporary path of the package on the device
* @param retryMode indicates what to do in case, a package already exists.
* @return <code>true<code> if success, <code>false</code> otherwise.
- * @throws IOException
+ * @throws InstallException
*/
private boolean checkInstallResult(String result, IDevice device, DelayedLaunchInfo launchInfo,
- String remotePath, InstallRetryMode retryMode) throws IOException {
+ String remotePath, InstallRetryMode retryMode) throws InstallException {
if (result == null) {
AdtPlugin.printToConsole(launchInfo.getProject(), "Success!");
return true;
@@ -1086,13 +1109,14 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* @param device the device on which to install the application.
* @param launchInfo the {@link DelayedLaunchInfo}.
* @return a {@link String} with an error code, or <code>null</code> if success.
- * @throws IOException
+ * @throws InstallException if the installation failed.
*/
@SuppressWarnings("unused")
- private String doUninstall(IDevice device, DelayedLaunchInfo launchInfo) throws IOException {
+ private String doUninstall(IDevice device, DelayedLaunchInfo launchInfo)
+ throws InstallException {
try {
return device.uninstallPackage(launchInfo.getPackageName());
- } catch (IOException e) {
+ } catch (InstallException e) {
String msg = String.format(
"Failed to uninstall %1$s: %2$s", launchInfo.getPackageName(), e.getMessage());
AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
@@ -1108,10 +1132,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* @param device the device on which to install the application.
* @param reinstall
* @return a {@link String} with an error code, or <code>null</code> if success.
- * @throws IOException
+ * @throws InstallException if the uninstallation failed.
*/
private String doInstall(DelayedLaunchInfo launchInfo, final String remotePath,
- final IDevice device, boolean reinstall) throws IOException {
+ final IDevice device, boolean reinstall) throws InstallException {
return device.installRemotePackage(remotePath, reinstall);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchMessages.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchMessages.java
index b2772f7..24111b6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchMessages.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchMessages.java
@@ -45,6 +45,8 @@ public class LaunchMessages extends NLS {
public static String RemoteAdtTestRunner_RunIOException_s;
public static String RemoteAdtTestRunner_RunTimeoutException;
+ public static String RemoteAdtTestRunner_RunAdbCommandRejectedException_s;
+ public static String RemoteAdtTestRunner_RunShellCommandUnresponsiveException;
public static String RemoteAdtTestRunner_RunStoppedMsg;
static {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
index 3484252..64e93b8 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
@@ -16,6 +16,8 @@
package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.testrunner.ITestRunListener;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
@@ -132,6 +134,12 @@ public class RemoteAdtTestRunner extends RemoteTestRunner {
} catch (IOException e) {
reportError(String.format(LaunchMessages.RemoteAdtTestRunner_RunIOException_s,
e.getMessage()));
+ } catch (AdbCommandRejectedException e) {
+ reportError(String.format(
+ LaunchMessages.RemoteAdtTestRunner_RunAdbCommandRejectedException_s,
+ e.getMessage()));
+ } catch (ShellCommandUnresponsiveException e) {
+ reportError(LaunchMessages.RemoteAdtTestRunner_RunTimeoutException);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/messages.properties b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/messages.properties
index 1ac7fb2..2670316 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/messages.properties
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/messages.properties
@@ -38,3 +38,5 @@ RemoteAdtTestRunner_RunFailedMsg_s=Test run failed: %1$s
RemoteAdtTestRunner_RunTimeoutException=Connection with device timed out.
RemoteAdtTestRunner_RunIOException_s=Lost connection with device: %s
RemoteAdtTestRunner_RunStoppedMsg=Test run stopped
+RemoteAdtTestRunner_RunAdbCommandRejectedException_s=Adb rejected command: %s
+RemoteAdtTestRunner_RunShellCommandUnresponsiveException=Device stopped sending output
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
index 48a433a..19d20d8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
@@ -27,7 +27,6 @@ import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonit
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
-import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
@@ -152,7 +151,7 @@ public final class ApkInstallManager {
}
return receiver.foundPackage;
- } catch (IOException e) {
+ } catch (Exception e) {
// failed to query pm? force reinstall.
return false;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
index 079feb7..f7728f5 100644
--- a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
@@ -21,17 +21,21 @@ import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Client;
import com.android.ddmlib.ClientData;
import com.android.ddmlib.IDevice;
+import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
import com.android.ddmlib.ClientData.IHprofDumpHandler;
import com.android.ddmlib.ClientData.MethodProfilingStatus;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.handler.BaseFileHandler;
-import com.android.ddmuilib.handler.MethodProfilingHandler;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
import com.android.ddmuilib.DevicePanel;
import com.android.ddmuilib.ImageLoader;
import com.android.ddmuilib.ScreenShotDialog;
+import com.android.ddmuilib.SyncProgressHelper;
import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
+import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
+import com.android.ddmuilib.handler.BaseFileHandler;
+import com.android.ddmuilib.handler.MethodProfilingHandler;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.ide.eclipse.ddms.DdmsPlugin.IDebugLauncher;
import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
@@ -132,31 +136,43 @@ public class DeviceView extends ViewPart implements IUiSelectionListener, IClien
IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
String value = store.getString(PreferenceInitializer.ATTR_HPROF_ACTION);
- SyncResult result = null;
if (ACTION_OPEN.equals(value)) {
File temp = File.createTempFile("android", DOT_HPROF); //$NON-NLS-1$
- String tempPath = temp.getAbsolutePath();
- result = pull(sync, tempPath, remoteFilePath);
- if (result != null && result.getCode() == SyncService.RESULT_OK) {
- open(tempPath);
- }
+ final String tempPath = temp.getAbsolutePath();
+ SyncProgressHelper.run(new SyncRunnable() {
+
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException,
+ TimeoutException {
+ sync.pullFile(remoteFilePath, tempPath, monitor);
+ }
+
+ public void close() {
+ sync.close();
+ }
+ },
+ String.format("Pulling %1$s from the device", remoteFilePath),
+ mParentShell);
+
+ open(tempPath);
} else {
// default action is ACTION_SAVE
- result = promptAndPull(sync,
+ promptAndPull(sync,
client.getClientData().getClientDescription() + DOT_HPROF,
remoteFilePath, "Save HPROF file");
}
-
- if (result != null && result.getCode() != SyncService.RESULT_OK) {
- displayErrorFromUiThread(
- "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
- device.getSerialNumber(), result.getMessage());
- }
} else {
- displayErrorFromUiThread("Unable to download HPROF file from device '%1$s'.",
+ displayErrorFromUiThread(
+ "Unable to download HPROF file from device '%1$s'.",
device.getSerialNumber());
}
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ displayErrorFromUiThread(
+ "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
+ device.getSerialNumber(), e.getMessage());
+ }
} catch (Exception e) {
displayErrorFromUiThread("Unable to download HPROF file from device '%1$s'.",
device.getSerialNumber());
diff --git a/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/libs/.gitignore b/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/libs/.gitignore
new file mode 100644
index 0000000..f23b948
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/libs/.gitignore
@@ -0,0 +1 @@
+*.jar \ No newline at end of file
diff --git a/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java b/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
index 11444ec..691bf0c 100644
--- a/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
+++ b/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
@@ -16,9 +16,11 @@
package com.android.eventanalyzer;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.log.EventContainer;
@@ -159,7 +161,7 @@ public class EventAnalyzer implements ILogListener {
// analyze the data gathered by the parser methods
analyzeData();
- } catch (IOException e) {
+ } catch (Exception e) {
e.printStackTrace();
}
}
@@ -227,7 +229,8 @@ public class EventAnalyzer implements ILogListener {
}
}
- private void parseLogFromDevice() throws IOException {
+ private void parseLogFromDevice() throws IOException, TimeoutException,
+ AdbCommandRejectedException {
// init the lib
AndroidDebugBridge.init(false /* debugger support */);
@@ -300,7 +303,8 @@ public class EventAnalyzer implements ILogListener {
}
}
- private void grabLogFrom(IDevice device) throws IOException {
+ private void grabLogFrom(IDevice device) throws IOException, TimeoutException,
+ AdbCommandRejectedException {
mParser = new EventLogParser();
if (mParser.init(device) == false) {
printAndExit("Failed to get event-log-tags from " + device.getSerialNumber(),
diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java b/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
index 209577d..2d2cea1 100644
--- a/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
+++ b/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
@@ -21,6 +21,7 @@ import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import java.io.IOException;
@@ -73,6 +74,12 @@ public class DeviceBridge {
}
} catch (IOException e) {
e.printStackTrace();
+ } catch (TimeoutException e) {
+ e.printStackTrace();
+ } catch (AdbCommandRejectedException e) {
+ e.printStackTrace();
+ } catch (ShellCommandUnresponsiveException e) {
+ e.printStackTrace();
}
return result[0];
}
@@ -91,6 +98,12 @@ public class DeviceBridge {
}
} catch (IOException e) {
e.printStackTrace();
+ } catch (TimeoutException e) {
+ e.printStackTrace();
+ } catch (AdbCommandRejectedException e) {
+ e.printStackTrace();
+ } catch (ShellCommandUnresponsiveException e) {
+ e.printStackTrace();
}
return result[0];
}
@@ -105,6 +118,12 @@ public class DeviceBridge {
}
} catch (IOException e) {
e.printStackTrace();
+ } catch (TimeoutException e) {
+ e.printStackTrace();
+ } catch (AdbCommandRejectedException e) {
+ e.printStackTrace();
+ } catch (ShellCommandUnresponsiveException e) {
+ e.printStackTrace();
}
return result[0];
}
diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java b/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
index 0417df6..5c87d33 100644
--- a/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
+++ b/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
@@ -39,6 +39,7 @@ public class Window {
return Integer.toHexString(hashCode);
}
+ @Override
public String toString() {
return title;
}
diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java b/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
index 401fb3e..873b275 100644
--- a/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
+++ b/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
@@ -24,6 +24,7 @@ public class UnifiedContentBorder extends AbstractBorder {
private static final Color BORDER_BOTTOM_COLOR1 = new Color(0x404040);
private static final Color BORDER_BOTTOM_COLOR2 = new Color(0xd8d8d8);
+ @Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
g.setColor(BORDER_TOP_COLOR1);
g.drawLine(x, y, x + width, y);
@@ -33,10 +34,12 @@ public class UnifiedContentBorder extends AbstractBorder {
g.drawLine(x, y + height - 1, x + width, y + height - 1);
}
+ @Override
public Insets getBorderInsets(Component component) {
return new Insets(1, 0, 2, 0);
}
+ @Override
public boolean isBorderOpaque() {
return true;
}
diff --git a/hierarchyviewer2/.gitignore b/hierarchyviewer2/.gitignore
new file mode 100644
index 0000000..89a196a
--- /dev/null
+++ b/hierarchyviewer2/.gitignore
@@ -0,0 +1,4 @@
+app/bin
+libs/hierarchyviewerlib/bin
+libs/hierarchyvieweruilib/bin
+
diff --git a/screenshot/src/com/android/screenshot/Screenshot.java b/screenshot/src/com/android/screenshot/Screenshot.java
index a3fe520..930ea8e 100644
--- a/screenshot/src/com/android/screenshot/Screenshot.java
+++ b/screenshot/src/com/android/screenshot/Screenshot.java
@@ -20,6 +20,7 @@ import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.RawImage;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
@@ -198,8 +199,10 @@ public class Screenshot {
try {
rawImage = device.getScreenshot();
- }
- catch (IOException ioe) {
+ } catch (TimeoutException e) {
+ printAndExit("Unable to get frame buffer: timeout", true /* terminate */);
+ return;
+ } catch (Exception ioe) {
printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
return;
}