aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRaphael <raphael@google.com>2012-03-16 09:22:48 -0700
committerRaphael <raphael@google.com>2012-03-16 09:29:01 -0700
commit1fcc05b9f5e2509dece74381b37bf7f1b058f95b (patch)
tree92f939edffe9de666150ff49853c30fdc63ac568 /apps
parentb0d1c0b057da074f912c15fd2eebb11cc2175c1e (diff)
downloadsdk-1fcc05b9f5e2509dece74381b37bf7f1b058f95b.tar.gz
sdk-1fcc05b9f5e2509dece74381b37bf7f1b058f95b.tar.bz2
sdk-1fcc05b9f5e2509dece74381b37bf7f1b058f95b.zip
SdkController: async bind result.
In SdkControllerLib: - Add an "onEmulatorBindResult" callback to the emulator listener that indicates the result of the bind operation. This makes it easier to create the EmulatorConnection from within a thread and capture the success/error when it happens. In the apps: - Changed to use the new onEmulatorBindResult. - Changed the app names to make them easier to indentify in the home launcher. - Added the missing onPause in the legacy sensors app to close the emulator connection (otherwise trying to restart it fails because the port is still bound by the paused instance) - In fact really the legacy activities should be in singleInstance mode. Change-Id: Ie194a75f9babebe74c899ea9327b3e4dcfe39f41
Diffstat (limited to 'apps')
-rwxr-xr-xapps/SdkController/SdkControllerApp/.classpath1
-rwxr-xr-xapps/SdkController/SdkControllerApp/.project1
-rwxr-xr-xapps/SdkController/SdkControllerApp/res/values/strings.xml4
-rwxr-xr-xapps/SdkController/SdkControllerApp/src/com/android/tools/sdkcontroller/service/ControllerService.java32
-rwxr-xr-xapps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorConnection.java62
-rw-r--r--apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorListener.java11
-rwxr-xr-xapps/SdkController/SdkControllerMultitouch/.classpath1
-rw-r--r--apps/SdkController/SdkControllerMultitouch/AndroidManifest.xml2
-rw-r--r--apps/SdkController/SdkControllerMultitouch/res/values/strings.xml2
-rw-r--r--apps/SdkController/SdkControllerMultitouch/src/com/android/tools/sdkcontroller/sdkcontrollermultitouch/SdkControllerMultitouchActivity.java37
-rwxr-xr-xapps/SdkController/SdkControllerSensor/.classpath1
-rwxr-xr-xapps/SdkController/SdkControllerSensor/AndroidManifest.xml2
-rwxr-xr-xapps/SdkController/SdkControllerSensor/res/values/strings.xml2
-rwxr-xr-xapps/SdkController/SdkControllerSensor/src/com/android/tools/sdkcontroller/sdkcontrollersensor/SdkControllerSensorActivity.java61
14 files changed, 129 insertions, 90 deletions
diff --git a/apps/SdkController/SdkControllerApp/.classpath b/apps/SdkController/SdkControllerApp/.classpath
index a4f1e4054..57a5df6c3 100755
--- a/apps/SdkController/SdkControllerApp/.classpath
+++ b/apps/SdkController/SdkControllerApp/.classpath
@@ -4,5 +4,6 @@
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkControllerLib"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
diff --git a/apps/SdkController/SdkControllerApp/.project b/apps/SdkController/SdkControllerApp/.project
index a2d5c18b9..a3417c5b0 100755
--- a/apps/SdkController/SdkControllerApp/.project
+++ b/apps/SdkController/SdkControllerApp/.project
@@ -3,6 +3,7 @@
<name>SdkControllerApp</name>
<comment></comment>
<projects>
+ <project>SdkControllerLib</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/apps/SdkController/SdkControllerApp/res/values/strings.xml b/apps/SdkController/SdkControllerApp/res/values/strings.xml
index 642d7b8c2..2596c89c4 100755
--- a/apps/SdkController/SdkControllerApp/res/values/strings.xml
+++ b/apps/SdkController/SdkControllerApp/res/values/strings.xml
@@ -20,7 +20,9 @@
<resources>
<!-- Strings for manifest. -->
- <string name="app_name">Sdk Controller App</string>
+ <!-- App name. TODO change. This is a placeholder to easily differentiate
+ the name in the home launcher compared to the MT/sensor apps. -->
+ <string name="app_name">New Sdk Controller</string>
<string name="service_description">Background service for Sdk Controller App</string>
<!-- Strings for service. -->
diff --git a/apps/SdkController/SdkControllerApp/src/com/android/tools/sdkcontroller/service/ControllerService.java b/apps/SdkController/SdkControllerApp/src/com/android/tools/sdkcontroller/service/ControllerService.java
index 3c2ab2f3b..9f006cbfe 100755
--- a/apps/SdkController/SdkControllerApp/src/com/android/tools/sdkcontroller/service/ControllerService.java
+++ b/apps/SdkController/SdkControllerApp/src/com/android/tools/sdkcontroller/service/ControllerService.java
@@ -16,7 +16,6 @@
package com.android.tools.sdkcontroller.service;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -227,34 +226,39 @@ public class ControllerService extends Service {
return mHandler.onEmulatorBlobQuery(array);
}
- EmuCnxHandler connect() throws InterruptedException {
+ EmuCnxHandler connect() {
assert mCnx == null;
final EmuCnxHandler cnxHandler = this;
// Apps targeting Honeycomb SDK can't do network IO on their main UI
- // thread. So just start the connection from a thread and then join it.
- // Yes there's some irony in there.
+ // thread. So just start the connection from a thread.
Thread t = new Thread(new Runnable() {
@Override
public void run() {
- try {
- mCnx = new EmulatorConnection(mHandler.getPort(),
- EmulatorConnectionType.SYNC_CONNECTION,
- cnxHandler);
- } catch (IOException e) {
- addError("Connection failed: " + e.toString());
- Log.e(TAG, "EmuConnection failed");
- }
+ // This will call onEmulatorBindResult with the result.
+ mCnx = new EmulatorConnection(mHandler.getPort(),
+ EmulatorConnectionType.SYNC_CONNECTION,
+ cnxHandler);
}
}, "EmuCnxH.connect");
t.start();
- t.join();
- mHandler.onStart(mCnx, ControllerService.this /*context*/);
return this;
}
+ @Override
+ public void onEmulatorBindResult(boolean success, Exception e) {
+ if (success) {
+ mHandler.onStart(mCnx, ControllerService.this /*context*/);
+ } else {
+ Log.e(TAG, "EmuCnx failed for " + mHandler.getType(), e);
+ String msg = mHandler.getType().toString() + " failed: " +
+ (e == null ? "n/a" : e.toString());
+ addError(msg);
+ }
+ }
+
void disconnect() {
if (mCnx != null) {
mHandler.onStop();
diff --git a/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorConnection.java b/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorConnection.java
index aa21ca737..f62ef44a9 100755
--- a/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorConnection.java
+++ b/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorConnection.java
@@ -517,23 +517,9 @@ public class EmulatorConnection {
* @param port TCP port where emulator connects.
* @param ctype Defines connection type to use (sync / async). See comments
* to EmulatorConnection class for more info.
- * @throws IOException
+ * @param listener EmulatorConnection event listener. Must not be null.
*/
- public EmulatorConnection(int port, EmulatorConnectionType ctype) throws IOException {
- constructEmulator(port, ctype);
- }
-
- /**
- * Constructs EmulatorConnection instance.
- *
- * @param port TCP port where emulator connects.
- * @param ctype Defines connection type to use (sync / async). See comments
- * to EmulatorConnection class for more info.
- * @param listener EmulatorConnection event listener.
- * @throws IOException
- */
- public EmulatorConnection(int port, EmulatorConnectionType ctype, EmulatorListener listener)
- throws IOException {
+ public EmulatorConnection(int port, EmulatorConnectionType ctype, EmulatorListener listener) {
mListener = listener;
constructEmulator(port, ctype);
}
@@ -552,31 +538,41 @@ public class EmulatorConnection {
* <p/>
* Important: Apps targeting Honeycomb+ SDK are not allowed to do networking on their main
* thread. The caller is responsible to make sure this is NOT called from a main UI thread.
+ * <p/>
+ * On error or success, this calls
+ * {@link EmulatorListener#onEmulatorBindResult(boolean, Exception)} to indicate whether
+ * the socket was properly bound.
+ * The IO loop will start after the method reported a successful bind.
*
* @param port TCP port where emulator connects.
* @param ctype Defines connection type to use (sync / async). See comments
* to EmulatorConnection class for more info.
- * @throws IOException
*/
- private void constructEmulator(final int port, EmulatorConnectionType ctype) throws IOException {
- mConnectionType = ctype;
- // Create I/O looper.
- mSelector = SelectorProvider.provider().openSelector();
-
- // Create non-blocking server socket that would listen for connections,
- // and bind it to the given port on the local host.
- mServerSocket = ServerSocketChannel.open();
- mServerSocket.configureBlocking(false);
- InetAddress local = InetAddress.getLocalHost();
- final InetSocketAddress address = new InetSocketAddress(local, port);
- mServerSocket.socket().bind(address);
-
- // Register 'accept' I/O on the server socket.
- mServerSocket.register(mSelector, SelectionKey.OP_ACCEPT);
+ private void constructEmulator(final int port, EmulatorConnectionType ctype) {
- // TODO we need a call back onBindSuccess(success or exception)
+ try {
+ mConnectionType = ctype;
+ // Create I/O looper.
+ mSelector = SelectorProvider.provider().openSelector();
+
+ // Create non-blocking server socket that would listen for connections,
+ // and bind it to the given port on the local host.
+ mServerSocket = ServerSocketChannel.open();
+ mServerSocket.configureBlocking(false);
+ InetAddress local = InetAddress.getLocalHost();
+ final InetSocketAddress address = new InetSocketAddress(local, port);
+ mServerSocket.socket().bind(address);
+
+ // Register 'accept' I/O on the server socket.
+ mServerSocket.register(mSelector, SelectionKey.OP_ACCEPT);
+ } catch (IOException e) {
+ mListener.onEmulatorBindResult(false, e);
+ return;
+ }
+ mListener.onEmulatorBindResult(true, null);
Logv("EmulatorConnection listener is created for port " + port);
+
// Start I/O looper and dispatcher.
new Thread(new Runnable() {
@Override
diff --git a/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorListener.java b/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorListener.java
index 7a5c1af3b..f707822c2 100644
--- a/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorListener.java
+++ b/apps/SdkController/SdkControllerLib/src/com/android/tools/sdkcontroller/lib/EmulatorListener.java
@@ -22,6 +22,17 @@ package com.android.tools.sdkcontroller.lib;
* setEmulatorListener method of the EmulatorConnection class.
*/
public interface EmulatorListener {
+
+ /**
+ * Called as a side effect of constructing a new {@link EmulatorConnection}
+ * when emulator is bound with its communication socket.
+ *
+ * @param success True if the socket bind was successful.
+ * @param e Any exception thrown whilst trying to bind to the communication socket.
+ * Null if there's no exception (typically when {@code success==true}).
+ */
+ public void onEmulatorBindResult(boolean success, Exception e);
+
/**
* Called when emulator is connected. NOTE: This method is called from the
* I/O loop, so all communication with the emulator will be "on hold" until
diff --git a/apps/SdkController/SdkControllerMultitouch/.classpath b/apps/SdkController/SdkControllerMultitouch/.classpath
index a4f1e4054..57a5df6c3 100755
--- a/apps/SdkController/SdkControllerMultitouch/.classpath
+++ b/apps/SdkController/SdkControllerMultitouch/.classpath
@@ -4,5 +4,6 @@
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkControllerLib"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
diff --git a/apps/SdkController/SdkControllerMultitouch/AndroidManifest.xml b/apps/SdkController/SdkControllerMultitouch/AndroidManifest.xml
index 45f5f8715..a8fb47fdd 100644
--- a/apps/SdkController/SdkControllerMultitouch/AndroidManifest.xml
+++ b/apps/SdkController/SdkControllerMultitouch/AndroidManifest.xml
@@ -33,7 +33,7 @@
android:name=".SdkControllerMultitouchActivity"
android:configChanges="orientation|keyboardHidden|mcc|mnc|locale|touchscreen|keyboard|navigation|screenLayout|fontScale"
android:label="@string/app_name"
- android:screenOrientation="portrait" >
+ android:screenOrientation="portrait" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/apps/SdkController/SdkControllerMultitouch/res/values/strings.xml b/apps/SdkController/SdkControllerMultitouch/res/values/strings.xml
index 3db1f1920..a0a620666 100644
--- a/apps/SdkController/SdkControllerMultitouch/res/values/strings.xml
+++ b/apps/SdkController/SdkControllerMultitouch/res/values/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="app_name">SDK Controller Multitouch</string>
+ <string name="app_name">Multitouch SDK Controller</string>
</resources> \ No newline at end of file
diff --git a/apps/SdkController/SdkControllerMultitouch/src/com/android/tools/sdkcontroller/sdkcontrollermultitouch/SdkControllerMultitouchActivity.java b/apps/SdkController/SdkControllerMultitouch/src/com/android/tools/sdkcontroller/sdkcontrollermultitouch/SdkControllerMultitouchActivity.java
index 1318a68b3..9b6697c74 100644
--- a/apps/SdkController/SdkControllerMultitouch/src/com/android/tools/sdkcontroller/sdkcontrollermultitouch/SdkControllerMultitouchActivity.java
+++ b/apps/SdkController/SdkControllerMultitouch/src/com/android/tools/sdkcontroller/sdkcontrollermultitouch/SdkControllerMultitouchActivity.java
@@ -17,7 +17,6 @@
package com.android.tools.sdkcontroller.sdkcontrollermultitouch;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -29,6 +28,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
+import android.widget.Toast;
import com.android.tools.sdkcontroller.lib.EmulatorConnection;
import com.android.tools.sdkcontroller.lib.EmulatorConnection.EmulatorConnectionType;
@@ -131,15 +131,10 @@ public class SdkControllerMultitouchActivity extends Activity implements Emulato
super.onResume();
// Instantiate emulator connector.
- try {
- mEmulator = new EmulatorConnection(EmulatorConnection.MULTITOUCH_PORT,
- EmulatorConnectionType.SYNC_CONNECTION,
- this);
- } catch (IOException e) {
- Loge("Exception while creating server socket: " + e.getMessage());
- finish();
- }
-
+ // This will call onEmulatorBindResult with the result.
+ mEmulator = new EmulatorConnection(EmulatorConnection.MULTITOUCH_PORT,
+ EmulatorConnectionType.SYNC_CONNECTION,
+ this);
}
@Override
@@ -211,12 +206,22 @@ public class SdkControllerMultitouchActivity extends Activity implements Emulato
}
// Instantiate emulator connector for the next client.
- try {
- mEmulator = new EmulatorConnection(EmulatorConnection.MULTITOUCH_PORT,
- EmulatorConnectionType.SYNC_CONNECTION,
- this);
- } catch (IOException e) {
- Loge("Exception while recreating server socket: " + e.getMessage());
+ // This will call onEmulatorBindResult with the result.
+ mEmulator = new EmulatorConnection(EmulatorConnection.MULTITOUCH_PORT,
+ EmulatorConnectionType.SYNC_CONNECTION,
+ this);
+ }
+
+ /**
+ * Called with the result from {@code new EmulatorConnection}
+ */
+ @Override
+ public void onEmulatorBindResult(boolean success, Exception e) {
+ if (!success) {
+ String msg = "Failed to connect to server socket";
+ if (e != null) msg += ": " + e.toString();
+ Loge(msg);
+ Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
finish();
}
}
diff --git a/apps/SdkController/SdkControllerSensor/.classpath b/apps/SdkController/SdkControllerSensor/.classpath
index a4f1e4054..57a5df6c3 100755
--- a/apps/SdkController/SdkControllerSensor/.classpath
+++ b/apps/SdkController/SdkControllerSensor/.classpath
@@ -4,5 +4,6 @@
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkControllerLib"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
diff --git a/apps/SdkController/SdkControllerSensor/AndroidManifest.xml b/apps/SdkController/SdkControllerSensor/AndroidManifest.xml
index 0255cc90f..62cc09635 100755
--- a/apps/SdkController/SdkControllerSensor/AndroidManifest.xml
+++ b/apps/SdkController/SdkControllerSensor/AndroidManifest.xml
@@ -30,7 +30,7 @@
<activity
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden|mcc|mnc|locale|touchscreen|keyboard|navigation|screenLayout|fontScale"
- android:name=".SdkControllerSensorActivity" >
+ android:name=".SdkControllerSensorActivity" android:launchMode="singleInstance">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
diff --git a/apps/SdkController/SdkControllerSensor/res/values/strings.xml b/apps/SdkController/SdkControllerSensor/res/values/strings.xml
index 29bfa5fff..b082a676d 100755
--- a/apps/SdkController/SdkControllerSensor/res/values/strings.xml
+++ b/apps/SdkController/SdkControllerSensor/res/values/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="app_name">SDK Controller Sensor</string>
+ <string name="app_name">Sensors SDK Controller</string>
</resources>
diff --git a/apps/SdkController/SdkControllerSensor/src/com/android/tools/sdkcontroller/sdkcontrollersensor/SdkControllerSensorActivity.java b/apps/SdkController/SdkControllerSensor/src/com/android/tools/sdkcontroller/sdkcontrollersensor/SdkControllerSensorActivity.java
index d640f2bfb..285ea8e72 100755
--- a/apps/SdkController/SdkControllerSensor/src/com/android/tools/sdkcontroller/sdkcontrollersensor/SdkControllerSensorActivity.java
+++ b/apps/SdkController/SdkControllerSensor/src/com/android/tools/sdkcontroller/sdkcontrollersensor/SdkControllerSensorActivity.java
@@ -18,21 +18,21 @@ package com.android.tools.sdkcontroller.sdkcontrollersensor;
import java.util.ArrayList;
import java.util.List;
-import java.io.IOException;
import android.app.Activity;
+import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import android.hardware.Sensor;
import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
import android.widget.CheckBox;
-import android.widget.TextView;
+import android.widget.CompoundButton;
import android.widget.TableLayout;
import android.widget.TableRow;
-import android.widget.CompoundButton;
-import android.view.LayoutInflater;
-import android.util.Log;
+import android.widget.TextView;
+import android.widget.Toast;
import com.android.tools.sdkcontroller.lib.EmulatorConnection;
import com.android.tools.sdkcontroller.lib.EmulatorConnection.EmulatorConnectionType;
@@ -367,16 +367,23 @@ public class SdkControllerSensorActivity extends Activity implements EmulatorLis
}
// Instantiate emulator connector.
- try {
- // Sensor emulator starts very early during emulator startup. So, as
- // discussed in comments to Emulator class, we must use synchronous
- // type of connection with the emulator.
- mEmulator = new EmulatorConnection(EmulatorConnection.SENSORS_PORT,
- EmulatorConnectionType.SYNC_CONNECTION,
- this);
- } catch (IOException e) {
- Loge("Exception while creating server socket: " + e.getMessage());
- finish();
+ // This will call onEmulatorBindResult with the result.
+ // Sensor emulator starts very early during emulator startup. So, as
+ // discussed in comments to Emulator class, we must use synchronous
+ // type of connection with the emulator.
+ mEmulator = new EmulatorConnection(EmulatorConnection.SENSORS_PORT,
+ EmulatorConnectionType.SYNC_CONNECTION,
+ this);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ if (mEmulator != null) {
+ mEmulator.setEmulatorListener(null);
+ mEmulator.disconnect();
+ mEmulator = null;
}
}
@@ -415,12 +422,22 @@ public class SdkControllerSensorActivity extends Activity implements EmulatorLis
}
// Instantiate emulator connector for the next client.
- try {
- mEmulator = new EmulatorConnection(EmulatorConnection.SENSORS_PORT,
- EmulatorConnectionType.SYNC_CONNECTION,
- this);
- } catch (IOException e) {
- Loge("Exception while creating server socket: " + e.getMessage());
+ // This will call onEmulatorBindResult with the result.
+ mEmulator = new EmulatorConnection(EmulatorConnection.SENSORS_PORT,
+ EmulatorConnectionType.SYNC_CONNECTION,
+ this);
+ }
+
+ /**
+ * Called with the result from {@code new EmulatorConnection}
+ */
+ @Override
+ public void onEmulatorBindResult(boolean success, Exception e) {
+ if (!success) {
+ String msg = "Failed to connect to server socket";
+ if (e != null) msg += ": " + e.toString();
+ Loge(msg);
+ Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
finish();
}
}