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