Reimplement the application logic.
New features/improvements:
- timeouts
- better (though still not great) error handling
- hooks for better app developers to make this prettier
- the ability to address EPMs on arbitrary ports (uses EpmController)
- proper threading (via EpmController)
diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml
index 5ebc2f8..6e87eb6 100644
--- a/res/layout/activity_main.xml
+++ b/res/layout/activity_main.xml
@@ -1,25 +1,69 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity" >
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity" >
-<Button
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:context=".MainActivity">
+
+ <TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
- android:text="@string/EPM_ATTACH"
+ android:text="@string/port_input"/>
+
+ <EditText
+ android:id="@+id/portNumber"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:layout_weight="1"
+ android:inputType="number"
+ android:text="@string/port_number_initial"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:context=".MainActivity">
+
+ <Button
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/epm_attach"
+ android:id="@+id/attachButton"
android:onClick="attachEpm" />
-<Button
+ <Button
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
- android:text="@string/EPM_DETACH"
+ android:id="@+id/detachButton"
+ android:text="@string/epm_detach"
android:onClick="detachEpm" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/statusText"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/status_text_initial"/>
+
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 399110e..a3ea92e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4,7 +4,25 @@
<string name="app_name">AraEPM</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
- <string name="EPM_ATTACH">Attach EPM</string>
- <string name="EPM_DETACH">Detach EPM</string>
+ <string name="epm_attach">Attach EPM</string>
+ <string name="epm_detach">Detach EPM</string>
+ <string name="port_input">Port number:</string>
+ <string name="port_number_initial">1</string>
+ <string name="status_text_initial">Ready</string>
+
+ <!-- EPM change status result text strings -->
+ <string name="epm_attached">attached</string>
+ <string name="epm_detached">detached</string>
+ <!-- EPM state change text strings. Argument: port number. -->
+ <string name="epm_attaching">Attaching port %1$d...</string>
+ <string name="epm_detaching">Detaching port %1$d...</string>
+ <!-- EPM state change status update strings.
+
+ Arguments:
+ - 1 (string): state, epm_attached or epm_detached
+ - 2 (int): port number -->
+ <string name="epm_status_ok">Ok: %1$s port %2$d</string>
+ <string name="epm_status_error">ERROR: port %2$d not %1$s</string>
+ <string name="epm_status_timeout">Timed out: port %2$d not %1$s</string>
</resources>
diff --git a/src/com/projectara/araepm/MainActivity.java b/src/com/projectara/araepm/MainActivity.java
index 5067760..2981c9e 100644
--- a/src/com/projectara/araepm/MainActivity.java
+++ b/src/com/projectara/araepm/MainActivity.java
@@ -4,21 +4,57 @@
import android.app.Activity;
import android.view.Menu;
import android.view.View;
-import android.hardware.I2cManager;
-import android.hardware.I2cTransaction;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
import java.io.IOException;
import android.os.Handler;
import android.util.Log;
-public class MainActivity extends Activity {
+public class MainActivity extends Activity
+ implements EpmController.EpmChangeCallback {
private static final String TAG = "araepm";
- private DME dme = null;
+
+ private static String EPM_ATTACHED;
+ private static String EPM_DETACHED;
+
+ private static String EPM_ATTACHING;
+ private static String EPM_DETACHING;
+
+ private static String EPM_STATUS_OK;
+ private static String EPM_STATUS_ERROR;
+ private static String EPM_STATUS_TIMEOUT;
+
+ private TextView statusText;
+ private EditText portNumber;
+ private Handler handler;
+ private Button[] buttons;
+
+ private EpmController epmController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ portNumber = (EditText)findViewById(R.id.portNumber);
+ statusText = (TextView)findViewById(R.id.statusText);
+
+ EPM_ATTACHED = getString(R.string.epm_attached);
+ EPM_DETACHED = getString(R.string.epm_detached);
+
+ EPM_ATTACHING = getString(R.string.epm_attaching);
+ EPM_DETACHING = getString(R.string.epm_detaching);
+
+ EPM_STATUS_OK = getString(R.string.epm_status_ok);
+ EPM_STATUS_ERROR = getString(R.string.epm_status_error);
+ EPM_STATUS_TIMEOUT = getString(R.string.epm_status_timeout);
+
+ buttons = new Button[2];
+ buttons[0] = (Button)findViewById(R.id.attachButton);
+ buttons[1] = (Button)findViewById(R.id.detachButton);
+
+ handler = new Handler();
}
@Override
@@ -32,42 +68,110 @@
protected void onStart(){
Log.d(TAG, "onstart");
super.onStart();
- I2cManager i2c = (I2cManager) getSystemService(I2C_SERVICE);
- dme = new DME(i2c);
+ epmController = new EpmController(this, this);
+ epmController.start();
}
@Override
protected void onStop() {
Log.d(TAG, "onstop");
- super.onStop();
+ super.onStop();
+ epmController.stop();
+ epmController = null;
+ }
+
+ private void disableStateChanges() {
+ for (int i = 0; i < buttons.length; i++) {
+ buttons[i].setClickable(false);
+ }
+ }
+
+ private void enableStateChanges() {
+ for (int i = 0; i < buttons.length; i++) {
+ buttons[i].setClickable(true);
+ }
+ }
+
+ private int getPortNumber() {
+ String s = portNumber.getText().toString();
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException nfe) {
+ // Can't happen; portNumber only allows numeric input
+ Log.wtf(TAG, "non-numeric text " + s + " in portNumber");
+ return -1;
+ }
+ }
+
+ private void doAttachDetach(boolean attach) {
+ int port = getPortNumber();
+ if (port < 0) {
+ return;
+ }
+ Log.d(TAG,
+ (attach ? "Attaching" : "Detaching") + " EPM on port " + port);
+ disableStateChanges();
+ if (attach) {
+ statusText.setText(String.format(EPM_ATTACHING, port));
+ epmController.attachEpm(port);
+ } else {
+ statusText.setText(String.format(EPM_DETACHING, port));
+ epmController.detachEpm(port);
+ }
}
public void attachEpm(View view) {
- int rc;
- Log.d(TAG, "EPM attach button pressed");
- try {
- dme.writeDMEConfig(0,
- true,
- DME.AttributeId.DME_MAILBOX,
- 0,
- 1,
- 0);
- } catch (IOException e) {
- return;
- }
+ doAttachDetach(true);
}
public void detachEpm(View view) {
- int rc;
- Log.d(TAG, "EPM detach button pressed");
- try {
- dme.writeDMEConfig(0, true,
- DME.AttributeId.DME_MAILBOX,
- 0,
- 2,
- 0);
- } catch (IOException e) {
- return;
- }
+ doAttachDetach(false);
+ }
+
+ @Override
+ public void onEpmChangeFinished(EpmController.EpmState attemptedState,
+ EpmController.EpmChangeStatus changeStatus,
+ int changedPort) {
+ final EpmController.EpmState attempted = attemptedState;
+ final EpmController.EpmChangeStatus status = changeStatus;
+ final int port = changedPort;
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ String newStatus;
+ String s;
+
+ enableStateChanges();
+
+ switch (attempted) {
+ case EPM_ATTACH:
+ s = EPM_ATTACHED;
+ break;
+ case EPM_DETACH:
+ s = EPM_DETACHED;
+ break;
+ default:
+ Log.wtf(TAG, "can't happen");
+ return;
+ }
+
+ String statusFormat;
+ switch (status) {
+ case EPM_OK:
+ statusFormat = EPM_STATUS_OK;
+ break;
+ case EPM_ERROR:
+ statusFormat = EPM_STATUS_ERROR;
+ break;
+ case EPM_TIMEOUT:
+ statusFormat = EPM_STATUS_TIMEOUT;
+ break;
+ default:
+ Log.wtf(TAG, "can't happen");
+ return;
+ }
+ statusText.setText(String.format(statusFormat, s, port));
+ }
+ });
}
}