diff --git a/androidgcs/res/layout/system_alarms.xml b/androidgcs/res/layout/system_alarms.xml
index a25c575dd..e67990427 100644
--- a/androidgcs/res/layout/system_alarms.xml
+++ b/androidgcs/res/layout/system_alarms.xml
@@ -4,6 +4,12 @@
android:layout_height="match_parent"
android:layout_gravity="center" >
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java
index 330217c8c..6a9273cc1 100644
--- a/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java
+++ b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerActivity.java
@@ -29,7 +29,7 @@ import android.widget.TextView;
public abstract class ObjectManagerActivity extends Activity {
private final String TAG = "ObjectManagerActivity";
- private static int LOGLEVEL = 0;
+ private static int LOGLEVEL = 1;
// private static boolean WARN = LOGLEVEL > 1;
private static boolean DEBUG = LOGLEVEL > 0;
@@ -162,6 +162,9 @@ public abstract class ObjectManagerActivity extends Activity {
stats.addUpdatedObserver(telemetryObserver);
telemetryStatsConnected = true;
updateStats();
+
+ if (DEBUG) Log.d(TAG, "Notifying listeners about connection. There are " + connectionListeners.countObservers());
+ connectionListeners.connected();
}
/**
@@ -175,6 +178,9 @@ public abstract class ObjectManagerActivity extends Activity {
TextView txRate = (TextView) findViewById(R.id.telemetry_stats_tx_rate);
rxRate.setText("");
txRate.setText("");
+
+ // Providing a null update triggers a disconnect on fragments
+ connectionListeners.disconnected();
}
@Override
@@ -223,6 +229,50 @@ public abstract class ObjectManagerActivity extends Activity {
public void onBind() {
}
+
+
+ /**
+ * Callbacks so ObjectManagerFragments get the onOPConnected and onOPDisconnected signals
+ */
+ class ConnectionObserver extends Observable {
+ public void disconnected() {
+ synchronized(this) {
+ setChanged();
+ notifyObservers();
+ }
+ }
+ public void connected() {
+ synchronized(this) {
+ setChanged();
+ notifyObservers(objMngr);
+ }
+ }
+ };
+ private ConnectionObserver connectionListeners = new ConnectionObserver();
+ public class OnConnectionListener implements Observer {
+
+ // Local reference of the fragment to notify, store in constructor
+ ObjectManagerFragment fragment;
+ OnConnectionListener(ObjectManagerFragment fragment) { this.fragment = fragment; };
+
+ // Whenever the observer is updated either conenct or disconnect based on the data
+ @Override
+ public void update(Observable observable, Object data) {
+ Log.d(TAG, "onConnectionListener called");
+ if (data == null)
+ fragment.onOPDisconnected();
+ else
+ fragment.onOPConnected(objMngr);
+ }
+
+ } ;
+ void addOnConnectionListenerFragment(ObjectManagerFragment frag) {
+ connectionListeners.addObserver(new OnConnectionListener(frag));
+ if (DEBUG) Log.d(TAG, "Connecting " + frag + " there are now " + connectionListeners.countObservers());
+ if (mConnected)
+ frag.onOPConnected(objMngr);
+ }
+
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
diff --git a/androidgcs/src/org/openpilot/androidgcs/ObjectManagerFragment.java b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerFragment.java
new file mode 100644
index 000000000..822e6b8b6
--- /dev/null
+++ b/androidgcs/src/org/openpilot/androidgcs/ObjectManagerFragment.java
@@ -0,0 +1,102 @@
+package org.openpilot.androidgcs;
+
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Observable;
+import java.util.Observer;
+
+import org.openpilot.uavtalk.UAVObject;
+import org.openpilot.uavtalk.UAVObjectManager;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+public class ObjectManagerFragment extends Fragment {
+
+ private static final String TAG = ObjectManagerFragment.class.getSimpleName();
+ private static int LOGLEVEL = 1;
+// private static boolean WARN = LOGLEVEL > 1;
+ private static boolean DEBUG = LOGLEVEL > 0;
+
+ UAVObjectManager objMngr;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (DEBUG) Log.d(TAG, "Created an ObjectManagerFragment");
+ // For an activity this registers against the telemetry service intents. Fragments must be notified by their
+ // parent activity
+ }
+
+ /**
+ * Attach to the parent activity so it can notify us when the connection
+ * changed
+ */
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ if (DEBUG) Log.d(TAG,"onAttach");
+
+ ((ObjectManagerActivity)activity).addOnConnectionListenerFragment(this);
+ }
+
+ // The below methods should all be called by the parent activity at the appropriate times
+ void onOPConnected(UAVObjectManager objMngr) {
+ this.objMngr = objMngr;
+ if (DEBUG) Log.d(TAG,"onOPConnected");
+ }
+
+ void onOPDisconnected() {
+ objMngr = null;
+ if (DEBUG) Log.d(TAG,"onOPDisconnected");
+ }
+
+ public void onBind() {
+
+ }
+
+
+ /**
+ * Called whenever any objects subscribed to via registerObjects
+ */
+ protected void objectUpdated(UAVObject obj) {
+
+ }
+
+ /**
+ * A message handler and a custom Observer to use it which calls
+ * objectUpdated with the right object type
+ */
+ final Handler uavobjHandler = new Handler();
+ private class UpdatedObserver implements Observer {
+ UAVObject obj;
+ UpdatedObserver(UAVObject obj) { this.obj = obj; };
+ public void update(Observable observable, Object data) {
+ uavobjHandler.post(new Runnable() {
+ @Override
+ public void run() { objectUpdated(obj); }
+ });
+ }
+ };
+
+ /**
+ * Register an activity to receive updates from this object
+ *
+ * the objectUpdated() method will be called in the original UI thread
+ */
+ protected void registerObjectUpdates(UAVObject object) {
+ object.addUpdatedObserver(new UpdatedObserver(object));
+ }
+ protected void registerObjectUpdates(List> objects) {
+ ListIterator> li = objects.listIterator();
+ while(li.hasNext()) {
+ ListIterator li2 = li.next().listIterator();
+ while(li2.hasNext())
+ registerObjectUpdates(li2.next());
+ }
+ }
+
+}
diff --git a/androidgcs/src/org/openpilot/androidgcs/SystemAlarmActivity.java b/androidgcs/src/org/openpilot/androidgcs/SystemAlarmActivity.java
index 63c0a6ac4..bb93db465 100644
--- a/androidgcs/src/org/openpilot/androidgcs/SystemAlarmActivity.java
+++ b/androidgcs/src/org/openpilot/androidgcs/SystemAlarmActivity.java
@@ -1,51 +1,14 @@
package org.openpilot.androidgcs;
-import java.util.List;
-
-import org.openpilot.uavtalk.UAVObject;
-import org.openpilot.uavtalk.UAVObjectField;
-
import android.os.Bundle;
-import android.widget.TextView;
+/**
+ * All the work for this activity is performed by it's fragment
+ */
public class SystemAlarmActivity extends ObjectManagerActivity {
- /**
- * Update the UI whenever the attitude is updated
- */
- protected void objectUpdated(UAVObject obj) {
- if (obj.getName().compareTo("SystemAlarms") != 0)
- return;
-
- TextView alarms = (TextView) findViewById(R.id.system_alarms_status);
- UAVObjectField a = obj.getField("Alarm");
- List names = a.getElementNames();
- String contents = new String();
- List options = a.getOptions();
-
- // Rank the alarms by order of severity, skip uninitialized
- for (int j = options.size() - 1; j > 0; j--) {
- for (int i = 0; i < names.size(); i++) {
- if(a.getDouble(i) == j)
- contents += names.get(i) + " : " + a.getValue(i).toString() + "\n";
- }
- }
- alarms.setText(contents);
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.system_alarms);
- }
-
- @Override
- void onOPConnected() {
- super.onOPConnected();
-
- // Connect the update method to AttitudeActual
- UAVObject obj = objMngr.getObject("SystemAlarms");
- if (obj != null)
- registerObjectUpdates(obj);
- objectUpdated(obj);
- }
+ }
}
diff --git a/androidgcs/src/org/openpilot/androidgcs/SystemAlarmsFragment.java b/androidgcs/src/org/openpilot/androidgcs/SystemAlarmsFragment.java
new file mode 100644
index 000000000..2ecda18f8
--- /dev/null
+++ b/androidgcs/src/org/openpilot/androidgcs/SystemAlarmsFragment.java
@@ -0,0 +1,62 @@
+package org.openpilot.androidgcs;
+
+import java.util.List;
+
+import org.openpilot.uavtalk.UAVObject;
+import org.openpilot.uavtalk.UAVObjectField;
+import org.openpilot.uavtalk.UAVObjectManager;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class SystemAlarmsFragment extends ObjectManagerFragment {
+
+ private static final String TAG = SystemAlarmsFragment.class.getSimpleName();
+
+ //@Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.system_alarms_fragment, container, false);
+ }
+
+ public void onOPConnected(UAVObjectManager objMngr) {
+ super.onOPConnected(objMngr);
+ Log.d(TAG,"On connected");
+
+ UAVObject obj = objMngr.getObject("SystemAlarms");
+ if (obj != null)
+ registerObjectUpdates(obj);
+ objectUpdated(obj);
+ }
+
+ /**
+ * Called whenever any objects subscribed to via registerObjects
+ */
+ @Override
+ protected void objectUpdated(UAVObject obj) {
+ Log.d(TAG, "Updated");
+ if (obj.getName().compareTo("SystemAlarms") == 0) {
+ TextView alarms = (TextView) getActivity().findViewById(R.id.system_alarms_fragment_field);
+ UAVObjectField a = obj.getField("Alarm");
+ List names = a.getElementNames();
+ String contents = new String();
+ List options = a.getOptions();
+
+ // Rank the alarms by order of severity, skip uninitialized
+ for (int j = options.size() - 1; j > 0; j--) {
+ for (int i = 0; i < names.size(); i++) {
+ if(a.getDouble(i) == j)
+ contents += names.get(i) + " : " + a.getValue(i).toString() + "\n";
+ }
+ }
+ alarms.setText(contents);
+ }
+ }
+
+
+}