From 402efe234b8e2fefa6ea5f135d27c5575ade34d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjetil=20=C3=98rbekk?= Date: Sun, 26 Feb 2012 11:18:26 +0100 Subject: Add StateViewerActivity. StateViewerActivity displays the current state from a ClientInterfaceBridge --- same-android/AndroidManifest.xml | 1 + same-android/res/layout/state_viewer.xml | 19 ++++++++ same-android/res/menu/main_menu.xml | 3 ++ .../main/java/com/orbekk/same/MainActivity.java | 3 ++ .../src/main/java/com/orbekk/same/SameService.java | 35 +++++++++----- .../java/com/orbekk/same/StateViewerActivity.java | 55 ++++++++++++++++++++++ .../orbekk/same/android/ClientInterfaceBridge.java | 42 ++++++++++++++--- 7 files changed, 140 insertions(+), 18 deletions(-) create mode 100644 same-android/res/layout/state_viewer.xml create mode 100644 same-android/src/main/java/com/orbekk/same/StateViewerActivity.java diff --git a/same-android/AndroidManifest.xml b/same-android/AndroidManifest.xml index bc28dd1..ea233e5 100644 --- a/same-android/AndroidManifest.xml +++ b/same-android/AndroidManifest.xml @@ -20,6 +20,7 @@ + diff --git a/same-android/res/layout/state_viewer.xml b/same-android/res/layout/state_viewer.xml new file mode 100644 index 0000000..3f216cc --- /dev/null +++ b/same-android/res/layout/state_viewer.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/same-android/res/menu/main_menu.xml b/same-android/res/menu/main_menu.xml index 49e584a..670ebac 100644 --- a/same-android/res/menu/main_menu.xml +++ b/same-android/res/menu/main_menu.xml @@ -7,5 +7,8 @@ + \ No newline at end of file diff --git a/same-android/src/main/java/com/orbekk/same/MainActivity.java b/same-android/src/main/java/com/orbekk/same/MainActivity.java index ea6e315..a8624ce 100644 --- a/same-android/src/main/java/com/orbekk/same/MainActivity.java +++ b/same-android/src/main/java/com/orbekk/same/MainActivity.java @@ -33,6 +33,9 @@ public class MainActivity extends Activity { case R.id.variable_test: startActivity(new Intent(this, VariableTestActivity.class)); break; + case R.id.state_viewer: + startActivity(new Intent(this, StateViewerActivity.class)); + break; default: logger.error("Unknown menu entry: {}", item); } diff --git a/same-android/src/main/java/com/orbekk/same/SameService.java b/same-android/src/main/java/com/orbekk/same/SameService.java index dad4b50..386b9b8 100644 --- a/same-android/src/main/java/com/orbekk/same/SameService.java +++ b/same-android/src/main/java/com/orbekk/same/SameService.java @@ -2,6 +2,7 @@ package com.orbekk.same; import java.util.ArrayList; import java.util.Properties; +import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +28,7 @@ public class SameService extends Service { public final static int JOIN_NETWORK = 4; public final static int UPDATED_STATE_MESSAGE = 5; public final static int ADD_STATE_RECEIVER = 6; + public final static int REMOVE_STATE_RECEIVER = 7; public final static String AVAILABLE_NETWORKS_UPDATE = "com.orbekk.same.SameService.action.AVAILABLE_NETWORKS_UPDATE"; @@ -41,7 +43,7 @@ public class SameService extends Service { private Logger logger = LoggerFactory.getLogger(getClass()); private SameController sameController = null; private Configuration configuration = null; - private ArrayList stateReceivers = new ArrayList(); + private Vector stateReceivers = new Vector(); private ArrayList networkNames = new ArrayList(); private ArrayList networkUrls = new ArrayList(); @@ -92,6 +94,7 @@ public class SameService extends Service { logger.info("JOIN_NETWORK"); String masterUrl = (String)message.obj; sameController.getClient().joinNetwork(masterUrl); + break; case ADD_STATE_RECEIVER: logger.info("ADD_STATE_RECEIVER: {}", message); Messenger messenger = message.replyTo; @@ -101,6 +104,12 @@ public class SameService extends Service { } else { logger.error("ADD_STATE_RECEIVER: Missing Messenger."); } + break; + case REMOVE_STATE_RECEIVER: + logger.info("REMOVE_STATE_RECEIVER: {}", message); + Messenger droppedMessenger = (Messenger)message.obj; + stateReceivers.remove(droppedMessenger); + break; default: super.handleMessage(message); } @@ -112,19 +121,21 @@ public class SameService extends Service { private StateChangedListener stateListener = new StateChangedListener() { @Override public void stateChanged(Component component) { - ArrayList dropped = new ArrayList(); - for (Messenger messenger : stateReceivers) { - Message message = Message.obtain(null, UPDATED_STATE_MESSAGE); - message.obj = component; - try { - messenger.send(message); - } catch (RemoteException e) { - logger.warn("Failed to send update. Dropping state receiver."); - e.printStackTrace(); - dropped.add(messenger); + synchronized (stateReceivers) { + ArrayList dropped = new ArrayList(); + for (Messenger messenger : stateReceivers) { + Message message = Message.obtain(null, UPDATED_STATE_MESSAGE); + message.obj = component; + try { + messenger.send(message); + } catch (RemoteException e) { + logger.warn("Failed to send update. Dropping state receiver."); + e.printStackTrace(); + dropped.add(messenger); + } } + stateReceivers.removeAll(dropped); } - stateReceivers.removeAll(dropped); } }; diff --git a/same-android/src/main/java/com/orbekk/same/StateViewerActivity.java b/same-android/src/main/java/com/orbekk/same/StateViewerActivity.java new file mode 100644 index 0000000..9dfb61e --- /dev/null +++ b/same-android/src/main/java/com/orbekk/same/StateViewerActivity.java @@ -0,0 +1,55 @@ +package com.orbekk.same; + +import java.util.ArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.orbekk.same.State.Component; +import com.orbekk.same.android.ClientInterfaceBridge; + +public class StateViewerActivity extends Activity { + private Logger logger = LoggerFactory.getLogger(getClass()); + private ClientInterfaceBridge client; + + private StateChangedListener stateListener = new StateChangedListener() { + @Override + public void stateChanged(Component component) { + displayState(); + } + }; + + private void displayState() { + ArrayList contentList = new ArrayList(); + for (State.Component component : client.getState().getComponents()) { + contentList.add(component.toString()); + } + ListView list = (ListView)findViewById(R.id.state_view_list); + list.setAdapter(new ArrayAdapter( + this, R.layout.list_text_item, contentList)); + } + + @Override public void onCreate(Bundle bundle) { + super.onCreate(bundle); + setContentView(R.layout.state_viewer); + } + + @Override public void onResume() { + super.onResume(); + client = new ClientInterfaceBridge(this); + client.addStateListener(stateListener); + client.connect(); + } + + @Override public void onStop() { + super.onStop(); + client.removeStateListener(stateListener); + client.disconnect(); + } +} diff --git a/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java b/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java index 22396f3..f885b5a 100644 --- a/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java +++ b/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java @@ -1,5 +1,7 @@ package com.orbekk.same.android; +import java.util.ArrayList; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,7 +14,6 @@ import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; -import android.widget.Toast; import com.orbekk.same.ClientInterface; import com.orbekk.same.SameService; @@ -21,13 +22,20 @@ import com.orbekk.same.StateChangedListener; import com.orbekk.same.UpdateConflict; public class ClientInterfaceBridge implements ClientInterface { + private State state; + private ArrayList listeners = + new ArrayList(); + class ResponseHandler extends Handler { @Override public void handleMessage(Message message) { + if (serviceMessenger == null) { + logger.warn("Ignoring message to disabled ResponseHandler."); + return; + } switch (message.what) { case SameService.UPDATED_STATE_MESSAGE: State.Component component = (State.Component)message.obj; - Toast.makeText(context, "Updated: " + component, - Toast.LENGTH_SHORT).show(); + updateState(component); default: logger.warn("Received unknown message from service: {}", message); @@ -60,40 +68,62 @@ public class ClientInterfaceBridge implements ClientInterface { } }; + private void updateState(State.Component component) { + state.update(component.getName(), component.getData(), + component.getRevision()); + for (StateChangedListener listener : listeners) { + listener.stateChanged(component); + } + } + public ClientInterfaceBridge(Context context) { this.context = context; } public void connect() { + state = new State(".Temporary"); Intent intent = new Intent(context, SameService.class); context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } + private void disconnectFromService() { + Message message = Message.obtain(null, SameService.REMOVE_STATE_RECEIVER); + message.obj = responseMessenger; + try { + serviceMessenger.send(message); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + public void disconnect() { if (serviceMessenger != null) { + disconnectFromService(); context.unbindService(serviceConnection); + state = null; } } @Override public State getState() { - return null; + return new State(state); } @Override public void set(String name, String data, long revision) throws UpdateConflict { logger.info("set({}, {}, {}", new Object[]{name, data, revision}); + throw new RuntimeException("Not implemented."); } @Override public void addStateListener(StateChangedListener listener) { - logger.info("addStateListener()"); + listeners.add(listener); } @Override public void removeStateListener(StateChangedListener listener) { - logger.info("removeStateListener()"); + listeners.remove(listener); } } -- cgit v1.2.3