From 68e0e27f75ed64fc3929fed6b1135d64faef5900 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 20 Mar 2011 21:34:03 -0500 Subject: [PATCH] Added a home page, added an option to select connection type. Made the ListView adapter trigger updates on the data. --- androidgcs/AndroidManifest.xml | 8 ++- androidgcs/Doc/AndroidArchitecture.txt | 39 +++++++++++ androidgcs/res/layout/gcs_home.xml | 7 ++ androidgcs/res/values/arrays.xml | 15 +++++ androidgcs/res/values/strings.xml | 9 ++- androidgcs/res/xml/preferences.xml | 12 ++++ .../org/openpilot/androidgcs/HomePage.java | 23 +++++++ .../androidgcs/OPTelemetryService.java | 39 ++++++----- .../openpilot/androidgcs/ObjectBrowser.java | 65 ++++++++----------- .../androidgcs/ObjectManagerActivity.java | 28 ++++++++ .../org/openpilot/androidgcs/Preferences.java | 12 ++++ 11 files changed, 201 insertions(+), 56 deletions(-) create mode 100644 androidgcs/res/layout/gcs_home.xml create mode 100644 androidgcs/res/values/arrays.xml create mode 100644 androidgcs/res/xml/preferences.xml create mode 100644 androidgcs/src/org/openpilot/androidgcs/HomePage.java create mode 100644 androidgcs/src/org/openpilot/androidgcs/Preferences.java diff --git a/androidgcs/AndroidManifest.xml b/androidgcs/AndroidManifest.xml index 9a3d1dd25..a791d0fbb 100644 --- a/androidgcs/AndroidManifest.xml +++ b/androidgcs/AndroidManifest.xml @@ -10,17 +10,23 @@ - + + + + + + + diff --git a/androidgcs/Doc/AndroidArchitecture.txt b/androidgcs/Doc/AndroidArchitecture.txt index d9cdf2ada..0a17a8dfa 100644 --- a/androidgcs/Doc/AndroidArchitecture.txt +++ b/androidgcs/Doc/AndroidArchitecture.txt @@ -16,6 +16,11 @@ UAVTalk.java - the actual communication layer. Can packetize an object and insert into stream and process the incoming stream and update objects accordingly. +** Threading +Currently object updates run within the thread of the function that called +update. This should be changed so that it adds a message to the Telemetry +thread which will then send on its own time. + ---- MESSAGE PASSING ---- The current implementation/analog to the slots/sockets in QT are Observers which are registered as added to an Observable. This is used extensibly within @@ -28,4 +33,38 @@ Activity) to instantiate a Handler to which messages or runnables are posted. So for external objects they will register a runnable somehow... +--- TELEMETRY SERVICE --- +The telemetry connection will be maintained by a service separate from the the +main activity(s). Although it is a bit unusual, the service will support being +started and stopped, as well as being bound. Binding will be required to get +access to the Object Manager. +In addition, to make it forward looking, the start intent can specify a +connection to open. This will allow the service in future to monitor multiple +connections. + +The service will destroy itself only when all active connections disappear and +all activies are unbound. + +It will also handle any logging desired (I think). + +There will be a primary message handler thread. This thread will separately +launch telemetry threads when required. + +The service should send broadcast intents whenever a connection is estabilished +or dropped. + +I dont think the service should have the options about which UAVs are +supported. + +** Telemetry IBinder +*** Give handle to the ObjectManager for each UAV +*** Call disconnect +*** Query conncetion status + +--- TELEMETRY WIDGET --- +Listens for conncet/disconnect intents + +Also show if service is running? + +Ability to launch service? diff --git a/androidgcs/res/layout/gcs_home.xml b/androidgcs/res/layout/gcs_home.xml new file mode 100644 index 000000000..e6f4ea567 --- /dev/null +++ b/androidgcs/res/layout/gcs_home.xml @@ -0,0 +1,7 @@ + + + + diff --git a/androidgcs/res/values/arrays.xml b/androidgcs/res/values/arrays.xml new file mode 100644 index 000000000..18ee52298 --- /dev/null +++ b/androidgcs/res/values/arrays.xml @@ -0,0 +1,15 @@ + + + + None + Fake + Bluetooth + Network + + + 0 + 1 + 2 + 3 + + \ No newline at end of file diff --git a/androidgcs/res/values/strings.xml b/androidgcs/res/values/strings.xml index 8daa0ec36..e9b66a312 100644 --- a/androidgcs/res/values/strings.xml +++ b/androidgcs/res/values/strings.xml @@ -1,8 +1,13 @@ - OpenPilot GCS + OpenPilot GCS Home + OpenPilot Object Browser Settings Connect Disconnect - OpenPilot Object Browser + Settings + Automatically Connect + Connection Type + Bluetooth + Select the connection method diff --git a/androidgcs/res/xml/preferences.xml b/androidgcs/res/xml/preferences.xml new file mode 100644 index 000000000..d731f59dd --- /dev/null +++ b/androidgcs/res/xml/preferences.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/androidgcs/src/org/openpilot/androidgcs/HomePage.java b/androidgcs/src/org/openpilot/androidgcs/HomePage.java new file mode 100644 index 000000000..478c7cdca --- /dev/null +++ b/androidgcs/src/org/openpilot/androidgcs/HomePage.java @@ -0,0 +1,23 @@ +package org.openpilot.androidgcs; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +public class HomePage extends ObjectManagerActivity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.gcs_home); + Button objectBrowser = (Button) findViewById(R.id.launch_object_browser); + objectBrowser.setOnClickListener(new OnClickListener() { + public void onClick(View arg0) { + startActivity(new Intent(HomePage.this, ObjectBrowser.class)); + } + }); + } + +} diff --git a/androidgcs/src/org/openpilot/androidgcs/OPTelemetryService.java b/androidgcs/src/org/openpilot/androidgcs/OPTelemetryService.java index 7b3030d4f..5af7c7d60 100644 --- a/androidgcs/src/org/openpilot/androidgcs/OPTelemetryService.java +++ b/androidgcs/src/org/openpilot/androidgcs/OPTelemetryService.java @@ -16,6 +16,7 @@ import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Binder; import android.os.Handler; @@ -24,6 +25,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; +import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; @@ -48,8 +50,7 @@ public class OPTelemetryService extends Service { // Message ids static final int MSG_START = 0; - static final int MSG_CONNECT_BT = 1; - static final int MSG_CONNECT_FAKE = 2; + static final int MSG_CONNECT = 1; static final int MSG_DISCONNECT = 3; static final int MSG_TOAST = 100; @@ -70,14 +71,22 @@ public class OPTelemetryService extends Service { Toast.makeText(OPTelemetryService.this, "HERE", Toast.LENGTH_SHORT); System.out.println("HERE"); stopSelf(msg.arg2); - case MSG_CONNECT_BT: + case MSG_CONNECT: terminate = false; - activeTelem = new BTTelemetryThread(); - activeTelem.start(); - break; - case MSG_CONNECT_FAKE: - terminate = false; - activeTelem = new FakeTelemetryThread(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(OPTelemetryService.this); + int connection_type = Integer.decode(prefs.getString("connection_type", "")); + switch(connection_type) { + case 0: // No connection + return; + case 1: + activeTelem = new FakeTelemetryThread(); + break; + case 2: + activeTelem = new BTTelemetryThread(); + break; + case 3: + throw new Error("Unsupported"); + } activeTelem.start(); break; case MSG_DISCONNECT: @@ -146,14 +155,9 @@ public class OPTelemetryService extends Service { public TelemTask getTelemTask(int id) { return (TelemTask) activeTelem; } - public void openFakeConnection() { + public void openConnection() { Message msg = mServiceHandler.obtainMessage(); - msg.arg1 = MSG_CONNECT_FAKE; - mServiceHandler.sendMessage(msg); - } - public void openBTConnection() { - Message msg = mServiceHandler.obtainMessage(); - msg.arg1 = MSG_CONNECT_BT; + msg.arg1 = MSG_CONNECT; mServiceHandler.sendMessage(msg); } public void stopConnection() { @@ -161,6 +165,9 @@ public class OPTelemetryService extends Service { msg.arg1 = MSG_DISCONNECT; mServiceHandler.sendMessage(msg); } + public boolean isConnected() { + return activeTelem != null; + } }; public void toastMessage(String msgText) { diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java b/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java index f68e839c1..f3cc56d47 100644 --- a/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java +++ b/androidgcs/src/org/openpilot/androidgcs/ObjectBrowser.java @@ -6,15 +6,20 @@ import java.util.ListIterator; import java.util.Observable; import java.util.Observer; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.database.DataSetObserver; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.Adapter; import android.widget.ArrayAdapter; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; @@ -27,36 +32,13 @@ import android.widget.Toast; import org.openpilot.uavtalk.UAVDataObject; import org.openpilot.uavtalk.UAVObject; -public class ObjectBrowser extends ObjectManagerActivity { - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { - case R.id.menu_connect: - binder.openBTConnection(); - return true; - case R.id.menu_disconnect: - binder.stopConnection(); - updateText.run(); - return true; - case R.id.menu_settings: - return true; - default: - return super.onOptionsItemSelected(item); - } - - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.options_menu, menu); - return true; - } +public class ObjectBrowser extends ObjectManagerActivity implements OnSharedPreferenceChangeListener { private final String TAG = "ObjectBrower"; boolean connected; - + SharedPreferences prefs; + ArrayAdapter adapter; + final Handler uavobjHandler = new Handler(); final Runnable updateText = new Runnable() { public void run() { @@ -70,6 +52,8 @@ public class ObjectBrowser extends ObjectManagerActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); + prefs = PreferenceManager.getDefaultSharedPreferences(this); + prefs.registerOnSharedPreferenceChangeListener(this); } @Override @@ -77,6 +61,17 @@ public class ObjectBrowser extends ObjectManagerActivity { Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT); Log.d(TAG, "onOPConnected()"); + List> allobjects = objMngr.getDataObjects(); + List linearized = new ArrayList(); + ListIterator> li = allobjects.listIterator(); + while(li.hasNext()) { + linearized.addAll(li.next()); + } + + adapter = new ArrayAdapter(this,R.layout.object_view, linearized); + ListView objects = (ListView) findViewById(R.id.object_list); + objects.setAdapter(adapter); + UAVObject obj = objMngr.getObject("SystemStats"); if(obj != null) obj.addUpdatedObserver(new Observer() { @@ -88,16 +83,12 @@ public class ObjectBrowser extends ObjectManagerActivity { } public void update() { - List> allobjects = objMngr.getDataObjects(); - List linearized = new ArrayList(); - ListIterator> li = allobjects.listIterator(); - while(li.hasNext()) { - linearized.addAll(li.next()); - } - - ArrayAdapter adapter = new ArrayAdapter(this,R.layout.object_view, linearized); - ListView objects = (ListView) findViewById(R.id.object_list); - objects.setAdapter(adapter); + adapter.notifyDataSetChanged(); + } + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + // TODO Auto-generated method stub + } } diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java index 12a072de7..d91946b92 100644 --- a/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java +++ b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java @@ -14,6 +14,9 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; public abstract class ObjectManagerActivity extends Activity { @@ -72,6 +75,31 @@ public abstract class ObjectManagerActivity extends Activity { } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch(item.getItemId()) { + case R.id.menu_connect: + binder.openConnection(); + return true; + case R.id.menu_disconnect: + binder.stopConnection(); + return true; + case R.id.menu_settings: + startActivity(new Intent(this, Preferences.class)); + return true; + default: + return super.onOptionsItemSelected(item); + } + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + @Override public void onStart() { super.onStart(); diff --git a/androidgcs/src/org/openpilot/androidgcs/Preferences.java b/androidgcs/src/org/openpilot/androidgcs/Preferences.java new file mode 100644 index 000000000..913de0f73 --- /dev/null +++ b/androidgcs/src/org/openpilot/androidgcs/Preferences.java @@ -0,0 +1,12 @@ +package org.openpilot.androidgcs; + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +public class Preferences extends PreferenceActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences); + } +}