altosdroid: begin adding IPC to main thread
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosDroid.java
index 8abc8a7b9848c3f3977864dd9594e46e84ece617..c1b9c654cd59c163a53736277ba884a981324749 100644 (file)
@@ -21,9 +21,15 @@ import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
 import android.text.method.ScrollingMovementMethod;
 import android.util.Log;
 //import android.view.KeyEvent;
@@ -48,18 +54,15 @@ public class AltosDroid extends Activity {
        private static final String TAG = "AltosDroid";
        private static final boolean D = true;
 
-    // Message types sent from the BluetoothChatService Handler
-    public static final int MESSAGE_STATE_CHANGE = 1;
-    public static final int MESSAGE_READ = 2;
-    public static final int MESSAGE_WRITE = 3;
-    public static final int MESSAGE_DEVICE_NAME = 4;
-    public static final int MESSAGE_TOAST = 5;
-
-    // Key names received from the BluetoothChatService Handler
-    public static final String DEVICE_NAME = "device_name";
-    public static final String TOAST = "toast";
-
+       // Message types sent from the TelemetryService Handler
+       public static final int MSG_STATE_CHANGE    = 1;
+       public static final int MSG_DEVNAME         = 2;
+       public static final int MSG_INCOMING_TELEM  = 3;
+       public static final int MSG_TOAST           = 4;
 
+       // Key names received from the TelemetryService Handler
+       public static final String KEY_DEVNAME = "key_devname";
+       public static final String KEY_TOAST   = "key_toast";
 
        // Intent request codes
        private static final int REQUEST_CONNECT_DEVICE = 1;
@@ -70,11 +73,81 @@ public class AltosDroid extends Activity {
        private TextView mSerialView;
        //private EditText mOutEditText;
        //private Button mSendButton;
+
+       private boolean mIsBound;
+       Messenger mService = null;
+       final Messenger mMessenger = new Messenger(new IncomingHandler());
+
        // Name of the connected device
        private String mConnectedDeviceName = null;
        // Local Bluetooth adapter
        private BluetoothAdapter mBluetoothAdapter = null;
 
+
+       // The Handler that gets information back from the Telemetry Service
+       class IncomingHandler extends Handler {
+               @Override
+               public void handleMessage(Message msg) {
+                       switch (msg.what) {
+                       case MSG_STATE_CHANGE:
+                               if(D) Log.i(TAG, "MSG_STATE_CHANGE: " + msg.arg1);
+                               switch (msg.arg1) {
+                               case TelemetryService.STATE_CONNECTED:
+                                       mTitle.setText(R.string.title_connected_to);
+                                       mTitle.append(mConnectedDeviceName);
+                                       mSerialView.setText("");
+                                       break;
+                               case TelemetryService.STATE_CONNECTING:
+                                       mTitle.setText(R.string.title_connecting);
+                                       break;
+                               case TelemetryService.STATE_READY:
+                               case TelemetryService.STATE_NONE:
+                                       mTitle.setText(R.string.title_not_connected);
+                                       break;
+                               }
+                               break;
+                       case MSG_INCOMING_TELEM:
+                               byte[] buf = (byte[]) msg.obj;
+                               // construct a string from the buffer
+                               String telem = new String(buf);
+                               mSerialView.append(telem);
+                               break;
+                       case MSG_DEVNAME:
+                               // save the connected device's name
+                               mConnectedDeviceName = msg.getData().getString(KEY_DEVNAME);
+                               Toast.makeText(getApplicationContext(), "Connected to "
+                                                       + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
+                               break;
+                       case MSG_TOAST:
+                               Toast.makeText(
+                                               getApplicationContext(),
+                                               msg.getData().getString(KEY_TOAST),
+                                               Toast.LENGTH_SHORT).show();
+                               break;
+                       }
+               }
+       };
+
+
+       private ServiceConnection mConnection = new ServiceConnection() {
+               public void onServiceConnected(ComponentName className, IBinder service) {
+                       mService = new Messenger(service);
+                       try {
+                               Message msg = Message.obtain(null, TelemetryService.MSG_REGISTER_CLIENT);
+                               msg.replyTo = mMessenger;
+                               mService.send(msg);
+                       } catch (RemoteException e) {
+                               // In this case the service has crashed before we could even do anything with it
+                       }
+               }
+
+               public void onServiceDisconnected(ComponentName className) {
+                       // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
+                       mService = null;
+               }
+       };
+
+
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
@@ -105,6 +178,10 @@ public class AltosDroid extends Activity {
                        return;
                }
 
+               // Start Telemetry Service
+               startService(new Intent(AltosDroid.this, TelemetryService.class));
+
+               doBindService();
        }
 
        @Override
@@ -152,6 +229,9 @@ public class AltosDroid extends Activity {
        @Override
        public void onDestroy() {
                super.onDestroy();
+
+               doUnbindService();
+
                if(D) Log.e(TAG, "--- ON DESTROY ---");
        }
 
@@ -254,6 +334,14 @@ public class AltosDroid extends Activity {
                // Get the BLuetoothDevice object
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
+               try {
+                       //Message msg = Message.obtain(null, TelemetryService.MSG_CONNECT_TELEBT);
+                       //msg.obj = device;
+                       //mService.send(msg);
+                       mService.send(Message.obtain(null, TelemetryService.MSG_CONNECT_TELEBT, device));
+               } catch (RemoteException e) {
+                       e.printStackTrace();
+               }
        }
 
 
@@ -277,4 +365,28 @@ public class AltosDroid extends Activity {
                return false;
        }
 
+
+       void doBindService() {
+               bindService(new Intent(this, TelemetryService.class), mConnection, Context.BIND_AUTO_CREATE);
+               mIsBound = true;
+       }
+
+       void doUnbindService() {
+               if (mIsBound) {
+                       // If we have received the service, and hence registered with it, then now is the time to unregister.
+                       if (mService != null) {
+                               try {
+                                       Message msg = Message.obtain(null, TelemetryService.MSG_UNREGISTER_CLIENT);
+                                       msg.replyTo = mMessenger;
+                                       mService.send(msg);
+                               } catch (RemoteException e) {
+                                       // There is nothing special we need to do if the service has crashed.
+                               }
+                       }
+                       // Detach our existing connection.
+                       unbindService(mConnection);
+                       mIsBound = false;
+               }
+       }
+
 }