-Formatting source files prior to additional changes.
Change-Id: I9d653eb70163dba83d21f0dc74f6459c3bb391b2
diff --git a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java b/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
index 4b65c99..3680f61 100644
--- a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
@@ -1,422 +1,455 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.googlecode.android_scripting.facade;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.googlecode.android_scripting.Log;
-import com.googlecode.android_scripting.event.Event;
-import com.googlecode.android_scripting.future.FutureResult;
-import com.googlecode.android_scripting.jsonrpc.JsonBuilder;
-import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
-import com.googlecode.android_scripting.rpc.Rpc;
-import com.googlecode.android_scripting.rpc.RpcDefault;
-import com.googlecode.android_scripting.rpc.RpcDeprecated;
-import com.googlecode.android_scripting.rpc.RpcName;
-import com.googlecode.android_scripting.rpc.RpcOptional;
-import com.googlecode.android_scripting.rpc.RpcParameter;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-
-import org.json.JSONException;
-
-/**
- * Manage the event queue. <br>
- * <br>
- * <b>Usage Notes:</b><br>
- * EventFacade APIs interact with the Event Queue (a data buffer containing up to 1024 event
- * entries).<br>
- * Events are automatically entered into the Event Queue following API calls such as startSensing()
- * and startLocating().<br>
- * The Event Facade provides control over how events are entered into (and removed from) the Event
- * Queue.<br>
- * The Event Queue provides a useful means of recording background events (such as sensor data) when
- * the phone is busy with foreground activities.
- *
- * @author Felix Arends (felix.arends@gmail.com)
- *
- */
-public class EventFacade extends RpcReceiver {
- /**
- * The maximum length of the event queue. Old events will be discarded when this limit is
- * exceeded.
- */
- private static final int MAX_QUEUE_SIZE = 1024;
- private final Queue<Event> mEventQueue = new ConcurrentLinkedQueue<Event>();
- private final CopyOnWriteArrayList<EventObserver> mGlobalEventObservers =
- new CopyOnWriteArrayList<EventObserver>();
- private final Multimap<String, EventObserver> mNamedEventObservers = Multimaps
- .synchronizedListMultimap(ArrayListMultimap.<String, EventObserver> create());
- private EventServer mEventServer = null;
- private final HashMap<String, BroadcastListener> mBroadcastListeners =
- new HashMap<String, BroadcastListener>();
- private final Context mContext;
- private boolean bEventServerRunning;
-
- public EventFacade(FacadeManager manager) {
- super(manager);
- mContext = manager.getService().getApplicationContext();
- Log.v("Creating new EventFacade Instance()");
- bEventServerRunning = false;
- }
-
- /**
- * Example (python): droid.eventClearBuffer()
- */
- @Rpc(description = "Clears all events from the event buffer.")
- public void eventClearBuffer() {
- mEventQueue.clear();
- }
-
- /**
- * Registers a listener for a new broadcast signal
- */
- @Rpc(description = "Registers a listener for a new broadcast signal")
- public boolean eventRegisterForBroadcast(
- @RpcParameter(name = "category") String category,
- @RpcParameter(name = "enqueue", description = "Should this events be added to the event queue or only dispatched") @RpcDefault(value = "true") Boolean enqueue) {
- if (mBroadcastListeners.containsKey(category)) {
- return false;
- }
-
- BroadcastListener b = new BroadcastListener(this, enqueue.booleanValue());
- IntentFilter c = new IntentFilter(category);
- mContext.registerReceiver(b, c);
- mBroadcastListeners.put(category, b);
-
- return true;
- }
-
- @Rpc(description = "Stop listening for a broadcast signal")
- public void eventUnregisterForBroadcast(@RpcParameter(name = "category") String category) {
- if (!mBroadcastListeners.containsKey(category)) {
- return;
- }
-
- mContext.unregisterReceiver(mBroadcastListeners.get(category));
- mBroadcastListeners.remove(category);
- }
-
- @Rpc(description = "Lists all the broadcast signals we are listening for")
- public Set<String> eventGetBrodcastCategories() {
- return mBroadcastListeners.keySet();
- }
-
- /**
- * Actual data returned in the map will depend on the type of event.
- *
- * <pre>
- * Example (python):
- * import android, time
- * droid = android.Android()
- * droid.startSensing()
- * time.sleep(1)
- * droid.eventClearBuffer()
- * time.sleep(1)
- * e = eventPoll(1).result
- * event_entry_number = 0
- * x = e[event_entry_ number]['data']['xforce']
- * </pre>
- *
- * e has the format:<br>
- * [{u'data': {u'accuracy': 0, u'pitch': -0.48766891956329345, u'xmag': -5.6875, u'azimuth':
- * 0.3312483489513397, u'zforce': 8.3492730000000002, u'yforce': 4.5628165999999997, u'time':
- * 1297072704.813, u'ymag': -11.125, u'zmag': -42.375, u'roll': -0.059393649548292161, u'xforce':
- * 0.42223078000000003}, u'name': u'sensors', u'time': 1297072704813000L}]<br>
- * x has the string value of the x force data (0.42223078000000003) at the time of the event
- * entry. </pre>
- */
-
- @Rpc(description = "Returns and removes the oldest n events (i.e. location or sensor update, etc.) from the event buffer.", returns = "A List of Maps of event properties.")
- public List<Event> eventPoll(
- @RpcParameter(name = "number_of_events") @RpcDefault("1") Integer number_of_events) {
- List<Event> events = Lists.newArrayList();
- for (int i = 0; i < number_of_events; i++) {
- Event event = mEventQueue.poll();
- if (event == null) {
- break;
- }
- events.add(event);
- }
- return events;
- }
-
- @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
- returns = "Map of event properties.")
- public Event eventWaitFor(
- @RpcParameter(name = "eventName") final String eventName,
- @RpcParameter(name = "removeEvent") final Boolean removeEvent,
- @RpcParameter(name = "timeout", description = "the maximum time to wait (in ms)") @RpcOptional Integer timeout)
- throws InterruptedException {
- Event result = null;
- final FutureResult<Event> futureEvent;
- synchronized (mEventQueue) { // First check to make sure it isn't already there
- for (Event event : mEventQueue) {
- if (event.getName().equals(eventName)) {
- result = event;
- if(removeEvent)
- mEventQueue.remove(event);
- return result;
- }
- }
- futureEvent = new FutureResult<Event>();
- addNamedEventObserver(eventName, new EventObserver() {
- @Override
- public void onEventReceived(Event event) {
- if (event.getName().equals(eventName)) {
- synchronized (futureEvent) {
- if (!futureEvent.isDone()) {
- futureEvent.set(event);
- //TODO(navtej) Remove log.
- Log.v(String.format("Removeing observer (%s) got event (%s)",this, event));
- removeEventObserver(this);
- }
- if(removeEvent)
- mEventQueue.remove(event);
- }
- }
- }
- });
- }
- if (futureEvent != null) {
- if (timeout != null) {
- result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
- } else {
- result = futureEvent.get();
- }
- }
- return result;
- }
-
- @Rpc(description = "Blocks until an event occurs. The returned event is removed from the buffer.", returns = "Map of event properties.")
- public Event eventWait(
- @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout)
- throws InterruptedException {
- Event result = null;
- final FutureResult<Event> futureEvent = new FutureResult<Event>();
- EventObserver observer;
- synchronized (mEventQueue) { // Anything in queue?
- if (mEventQueue.size() > 0) {
- return mEventQueue.poll(); // return it.
- }
- observer = new EventObserver() {
- @Override
- public void onEventReceived(Event event) { // set up observer for any events.
- synchronized (futureEvent) {
- if (!futureEvent.isDone()) {
- futureEvent.set(event);
- //TODO(navtej) Remove log.
- Log.v(String.format("onEventReceived for event (%s)", event));
- }
- mEventQueue.remove(event);
- }
- }
- };
- addGlobalEventObserver(observer);
- }
- if (timeout != null) {
- result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
- if(result == null){
- result = new Event( "eventTimeout", null);
- }
- } else {
- result = futureEvent.get();
- }
- //TODO(navtej) Remove log.
- Log.v(String.format("Removeing observer (%s) got event (%s)", observer, result ));
- if (observer != null) {
- removeEventObserver(observer); // Make quite sure this goes away.
- }
- return result;
- }
-
- /**
- * <pre>
- * Example:
- * import android
- * from datetime import datetime
- * droid = android.Android()
- * t = datetime.now()
- * droid.eventPost('Some Event', t)
- * </pre>
- */
- @Rpc(description = "Post an event to the event queue.")
- public void eventPost(
- @RpcParameter(name = "name", description = "Name of event") String name,
- @RpcParameter(name = "data", description = "Data contained in event.") String data,
- @RpcParameter(name = "enqueue", description = "Set to False if you don't want your events to be added to the event queue, just dispatched.") @RpcOptional @RpcDefault("false") Boolean enqueue) {
- postEvent(name, data, enqueue.booleanValue());
- }
-
- /**
- * Post an event and queue it
- */
- public void postEvent(String name, Object data) {
- postEvent(name, data, true);
- }
-
- /**
- * Posts an event with to the event queue.
- */
- public void postEvent(String name, Object data, boolean enqueue) {
- Event event = new Event(name, data);
- if (enqueue != false) {
- synchronized (mEventQueue) {
- while (mEventQueue.size() >= MAX_QUEUE_SIZE) {
- mEventQueue.remove();
- }
- mEventQueue.add(event);
- }
- Log.v(String.format("postEvent(%s)", name));
- }
- synchronized (mNamedEventObservers) {
- for (EventObserver observer : mNamedEventObservers.get(name)) {
- observer.onEventReceived(event);
- }
- }
- synchronized (mGlobalEventObservers) {
- //TODO(navtej) Remove log.
- Log.v(String.format("mGlobalEventObservers size (%s)", mGlobalEventObservers.size()));
- for (EventObserver observer : mGlobalEventObservers) {
- observer.onEventReceived(event);
- }
- }
- }
-
- @RpcDeprecated(value = "eventPost", release = "r4")
- @Rpc(description = "Post an event to the event queue.")
- @RpcName(name = "postEvent")
- public void rpcPostEvent(@RpcParameter(name = "name") String name,
- @RpcParameter(name = "data") String data) {
- postEvent(name, data);
- }
-
- @RpcDeprecated(value = "eventPoll", release = "r4")
- @Rpc(description = "Returns and removes the oldest event (i.e. location or sensor update, etc.) from the event buffer.", returns = "Map of event properties.")
- public Event receiveEvent() {
- return mEventQueue.poll();
- }
-
- @RpcDeprecated(value = "eventWaitFor", release = "r4")
- @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
- returns = "Map of event properties.")
- public Event waitForEvent(
- @RpcParameter(name = "eventName") final String eventName,
- @RpcOptional final Boolean removeEvent,
- @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout)
- throws InterruptedException {
- return eventWaitFor(eventName, removeEvent, timeout);
- }
-
- @Rpc(description = "Opens up a socket where you can read for events posted")
- public int startEventDispatcher(
- @RpcParameter(name = "port", description = "Port to use") @RpcDefault("0") @RpcOptional() Integer port) {
- if (mEventServer == null) {
- if (port == null) {
- port = 0;
- }
- mEventServer = new EventServer(port);
- addGlobalEventObserver(mEventServer);
- bEventServerRunning = true;
- }
- return mEventServer.getAddress().getPort();
- }
-
- @Rpc(description = "Stops the event server, you can't read in the port anymore")
- public void stopEventDispatcher() throws RuntimeException {
- if (bEventServerRunning == true) {
- if (mEventServer == null) {
- throw new RuntimeException("Not running");
- }
- bEventServerRunning = false;
- mEventServer.shutdown();
- Log.v(String.format("stopEventDispatcher (%s)", mEventServer ));
- removeEventObserver(mEventServer);
- mEventServer = null;
- }
- return;
- }
-
- @Override
- public void shutdown() {
-
- try {
- stopEventDispatcher();
- } catch (Exception e) {
- Log.e("Exception tearing down event dispatcher", e);
- }
- mGlobalEventObservers.clear();
- mEventQueue.clear();
- }
-
- public void addNamedEventObserver(String eventName, EventObserver observer) {
- mNamedEventObservers.put(eventName, observer);
- }
-
- public void addGlobalEventObserver(EventObserver observer) {
- mGlobalEventObservers.add(observer);
- }
-
- public void removeEventObserver(EventObserver observer) {
- mNamedEventObservers.removeAll(observer);
- mGlobalEventObservers.remove(observer);
- }
-
- public interface EventObserver {
- public void onEventReceived(Event event);
- }
-
- public class BroadcastListener extends android.content.BroadcastReceiver {
- private EventFacade mParent;
- private boolean mEnQueue;
-
- public BroadcastListener(EventFacade parent, boolean enqueue) {
- mParent = parent;
- mEnQueue = enqueue;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Bundle data;
- if (intent.getExtras() != null) {
- data = (Bundle) intent.getExtras().clone();
- } else {
- data = new Bundle();
- }
- data.putString("action", intent.getAction());
- try {
- mParent.eventPost("sl4a", JsonBuilder.build(data).toString(), mEnQueue);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- }
-}
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.googlecode.android_scripting.facade;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.googlecode.android_scripting.Log;
+import com.googlecode.android_scripting.event.Event;
+import com.googlecode.android_scripting.future.FutureResult;
+import com.googlecode.android_scripting.jsonrpc.JsonBuilder;
+import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
+import com.googlecode.android_scripting.rpc.Rpc;
+import com.googlecode.android_scripting.rpc.RpcDefault;
+import com.googlecode.android_scripting.rpc.RpcDeprecated;
+import com.googlecode.android_scripting.rpc.RpcName;
+import com.googlecode.android_scripting.rpc.RpcOptional;
+import com.googlecode.android_scripting.rpc.RpcParameter;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+
+import org.json.JSONException;
+
+/**
+ * Manage the event queue. <br>
+ * <br>
+ * <b>Usage Notes:</b><br>
+ * EventFacade APIs interact with the Event Queue (a data buffer containing up to 1024 event
+ * entries).<br>
+ * Events are automatically entered into the Event Queue following API calls such as startSensing()
+ * and startLocating().<br>
+ * The Event Facade provides control over how events are entered into (and removed from) the Event
+ * Queue.<br>
+ * The Event Queue provides a useful means of recording background events (such as sensor data) when
+ * the phone is busy with foreground activities.
+ *
+ * @author Felix Arends (felix.arends@gmail.com)
+ */
+public class EventFacade extends RpcReceiver {
+ /**
+ * The maximum length of the event queue. Old events will be discarded when this limit is
+ * exceeded.
+ */
+ private static final int MAX_QUEUE_SIZE = 1024;
+ private final Queue<Event> mEventQueue = new ConcurrentLinkedQueue<Event>();
+ private final CopyOnWriteArrayList<EventObserver> mGlobalEventObservers =
+ new CopyOnWriteArrayList<EventObserver>();
+ private final Multimap<String, EventObserver> mNamedEventObservers = Multimaps
+ .synchronizedListMultimap(ArrayListMultimap.<String, EventObserver> create());
+ private EventServer mEventServer = null;
+ private final HashMap<String, BroadcastListener> mBroadcastListeners =
+ new HashMap<String, BroadcastListener>();
+ private final Context mContext;
+ private boolean bEventServerRunning;
+
+ public EventFacade(FacadeManager manager) {
+ super(manager);
+ mContext = manager.getService().getApplicationContext();
+ Log.v("Creating new EventFacade Instance()");
+ bEventServerRunning = false;
+ }
+
+ /**
+ * Example (python): droid.eventClearBuffer()
+ */
+ @Rpc(description = "Clears all events from the event buffer.")
+ public void eventClearBuffer() {
+ mEventQueue.clear();
+ }
+
+ /**
+ * Registers a listener for a new broadcast signal
+ */
+ @Rpc(description = "Registers a listener for a new broadcast signal")
+ public boolean eventRegisterForBroadcast(
+ @RpcParameter(name = "category")
+ String category,
+ @RpcParameter(name = "enqueue",
+ description = "Should this events be added to the event queue or only dispatched")
+ @RpcDefault(value = "true")
+ Boolean enqueue) {
+ if (mBroadcastListeners.containsKey(category)) {
+ return false;
+ }
+
+ BroadcastListener b = new BroadcastListener(this, enqueue.booleanValue());
+ IntentFilter c = new IntentFilter(category);
+ mContext.registerReceiver(b, c);
+ mBroadcastListeners.put(category, b);
+
+ return true;
+ }
+
+ @Rpc(description = "Stop listening for a broadcast signal")
+ public void eventUnregisterForBroadcast(
+ @RpcParameter(name = "category")
+ String category) {
+ if (!mBroadcastListeners.containsKey(category)) {
+ return;
+ }
+
+ mContext.unregisterReceiver(mBroadcastListeners.get(category));
+ mBroadcastListeners.remove(category);
+ }
+
+ @Rpc(description = "Lists all the broadcast signals we are listening for")
+ public Set<String> eventGetBrodcastCategories() {
+ return mBroadcastListeners.keySet();
+ }
+
+ /**
+ * Actual data returned in the map will depend on the type of event.
+ *
+ * <pre>
+ * Example (python):
+ * import android, time
+ * droid = android.Android()
+ * droid.startSensing()
+ * time.sleep(1)
+ * droid.eventClearBuffer()
+ * time.sleep(1)
+ * e = eventPoll(1).result
+ * event_entry_number = 0
+ * x = e[event_entry_ number]['data']['xforce']
+ * </pre>
+ *
+ * e has the format:<br>
+ * [{u'data': {u'accuracy': 0, u'pitch': -0.48766891956329345, u'xmag': -5.6875, u'azimuth':
+ * 0.3312483489513397, u'zforce': 8.3492730000000002, u'yforce': 4.5628165999999997, u'time':
+ * 1297072704.813, u'ymag': -11.125, u'zmag': -42.375, u'roll': -0.059393649548292161,
+ * u'xforce': 0.42223078000000003}, u'name': u'sensors', u'time': 1297072704813000L}]<br>
+ * x has the string value of the x force data (0.42223078000000003) at the time of the event
+ * entry. </pre>
+ */
+
+ @Rpc(description = "Returns and removes the oldest n events (i.e. location or sensor update, etc.) from the event buffer.",
+ returns = "A List of Maps of event properties.")
+ public List<Event> eventPoll(
+ @RpcParameter(name = "number_of_events")
+ @RpcDefault("1")
+ Integer number_of_events) {
+ List<Event> events = Lists.newArrayList();
+ for (int i = 0; i < number_of_events; i++) {
+ Event event = mEventQueue.poll();
+ if (event == null) {
+ break;
+ }
+ events.add(event);
+ }
+ return events;
+ }
+
+ @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
+ returns = "Map of event properties.")
+ public Event eventWaitFor(
+ @RpcParameter(name = "eventName")
+ final String eventName,
+ @RpcParameter(name = "removeEvent")
+ final Boolean removeEvent,
+ @RpcParameter(name = "timeout", description = "the maximum time to wait (in ms)")
+ @RpcOptional
+ Integer timeout)
+ throws InterruptedException {
+ Event result = null;
+ final FutureResult<Event> futureEvent;
+ synchronized (mEventQueue) { // First check to make sure it isn't already there
+ for (Event event : mEventQueue) {
+ if (event.getName().equals(eventName)) {
+ result = event;
+ if (removeEvent)
+ mEventQueue.remove(event);
+ return result;
+ }
+ }
+ futureEvent = new FutureResult<Event>();
+ addNamedEventObserver(eventName, new EventObserver() {
+ @Override
+ public void onEventReceived(Event event) {
+ if (event.getName().equals(eventName)) {
+ synchronized (futureEvent) {
+ if (!futureEvent.isDone()) {
+ futureEvent.set(event);
+ // TODO(navtej) Remove log.
+ Log.v(String.format("Removeing observer (%s) got event (%s)", this,
+ event));
+ removeEventObserver(this);
+ }
+ if (removeEvent)
+ mEventQueue.remove(event);
+ }
+ }
+ }
+ });
+ }
+ if (futureEvent != null) {
+ if (timeout != null) {
+ result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
+ } else {
+ result = futureEvent.get();
+ }
+ }
+ return result;
+ }
+
+ @Rpc(description = "Blocks until an event occurs. The returned event is removed from the buffer.",
+ returns = "Map of event properties.")
+ public Event eventWait(
+ @RpcParameter(name = "timeout", description = "the maximum time to wait")
+ @RpcOptional
+ Integer timeout)
+ throws InterruptedException {
+ Event result = null;
+ final FutureResult<Event> futureEvent = new FutureResult<Event>();
+ EventObserver observer;
+ synchronized (mEventQueue) { // Anything in queue?
+ if (mEventQueue.size() > 0) {
+ return mEventQueue.poll(); // return it.
+ }
+ observer = new EventObserver() {
+ @Override
+ public void onEventReceived(Event event) { // set up observer for any events.
+ synchronized (futureEvent) {
+ if (!futureEvent.isDone()) {
+ futureEvent.set(event);
+ // TODO(navtej) Remove log.
+ Log.v(String.format("onEventReceived for event (%s)", event));
+ }
+ mEventQueue.remove(event);
+ }
+ }
+ };
+ addGlobalEventObserver(observer);
+ }
+ if (timeout != null) {
+ result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
+ if (result == null) {
+ result = new Event("eventTimeout", null);
+ }
+ } else {
+ result = futureEvent.get();
+ }
+ // TODO(navtej) Remove log.
+ Log.v(String.format("Removeing observer (%s) got event (%s)", observer, result));
+ if (observer != null) {
+ removeEventObserver(observer); // Make quite sure this goes away.
+ }
+ return result;
+ }
+
+ /**
+ * <pre>
+ * Example:
+ * import android
+ * from datetime import datetime
+ * droid = android.Android()
+ * t = datetime.now()
+ * droid.eventPost('Some Event', t)
+ * </pre>
+ */
+ @Rpc(description = "Post an event to the event queue.")
+ public void eventPost(
+ @RpcParameter(name = "name", description = "Name of event")
+ String name,
+ @RpcParameter(name = "data", description = "Data contained in event.")
+ String data,
+ @RpcParameter(name = "enqueue",
+ description = "Set to False if you don't want your events to be added to the event queue, just dispatched.")
+ @RpcOptional
+ @RpcDefault("false")
+ Boolean enqueue) {
+ postEvent(name, data, enqueue.booleanValue());
+ }
+
+ /**
+ * Post an event and queue it
+ */
+ public void postEvent(String name, Object data) {
+ postEvent(name, data, true);
+ }
+
+ /**
+ * Posts an event with to the event queue.
+ */
+ public void postEvent(String name, Object data, boolean enqueue) {
+ Event event = new Event(name, data);
+ if (enqueue != false) {
+ synchronized (mEventQueue) {
+ while (mEventQueue.size() >= MAX_QUEUE_SIZE) {
+ mEventQueue.remove();
+ }
+ mEventQueue.add(event);
+ }
+ Log.v(String.format("postEvent(%s)", name));
+ }
+ synchronized (mNamedEventObservers) {
+ for (EventObserver observer : mNamedEventObservers.get(name)) {
+ observer.onEventReceived(event);
+ }
+ }
+ synchronized (mGlobalEventObservers) {
+ // TODO(navtej) Remove log.
+ Log.v(String.format("mGlobalEventObservers size (%s)", mGlobalEventObservers.size()));
+ for (EventObserver observer : mGlobalEventObservers) {
+ observer.onEventReceived(event);
+ }
+ }
+ }
+
+ @RpcDeprecated(value = "eventPost", release = "r4")
+ @Rpc(description = "Post an event to the event queue.")
+ @RpcName(name = "postEvent")
+ public void rpcPostEvent(
+ @RpcParameter(name = "name")
+ String name,
+ @RpcParameter(name = "data")
+ String data) {
+ postEvent(name, data);
+ }
+
+ @RpcDeprecated(value = "eventPoll", release = "r4")
+ @Rpc(description = "Returns and removes the oldest event (i.e. location or sensor update, etc.) from the event buffer.",
+ returns = "Map of event properties.")
+ public Event receiveEvent() {
+ return mEventQueue.poll();
+ }
+
+ @RpcDeprecated(value = "eventWaitFor", release = "r4")
+ @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
+ returns = "Map of event properties.")
+ public Event waitForEvent(
+ @RpcParameter(name = "eventName")
+ final String eventName,
+ @RpcOptional
+ final Boolean removeEvent,
+ @RpcParameter(name = "timeout", description = "the maximum time to wait")
+ @RpcOptional
+ Integer timeout)
+ throws InterruptedException {
+ return eventWaitFor(eventName, removeEvent, timeout);
+ }
+
+ @Rpc(description = "Opens up a socket where you can read for events posted")
+ public int startEventDispatcher(
+ @RpcParameter(name = "port", description = "Port to use")
+ @RpcDefault("0")
+ @RpcOptional()
+ Integer port) {
+ if (mEventServer == null) {
+ if (port == null) {
+ port = 0;
+ }
+ mEventServer = new EventServer(port);
+ addGlobalEventObserver(mEventServer);
+ bEventServerRunning = true;
+ }
+ return mEventServer.getAddress().getPort();
+ }
+
+ @Rpc(description = "Stops the event server, you can't read in the port anymore")
+ public void stopEventDispatcher() throws RuntimeException {
+ if (bEventServerRunning == true) {
+ if (mEventServer == null) {
+ throw new RuntimeException("Not running");
+ }
+ bEventServerRunning = false;
+ mEventServer.shutdown();
+ Log.v(String.format("stopEventDispatcher (%s)", mEventServer));
+ removeEventObserver(mEventServer);
+ mEventServer = null;
+ }
+ return;
+ }
+
+ @Override
+ public void shutdown() {
+
+ try {
+ stopEventDispatcher();
+ } catch (Exception e) {
+ Log.e("Exception tearing down event dispatcher", e);
+ }
+ mGlobalEventObservers.clear();
+ mEventQueue.clear();
+ }
+
+ public void addNamedEventObserver(String eventName, EventObserver observer) {
+ mNamedEventObservers.put(eventName, observer);
+ }
+
+ public void addGlobalEventObserver(EventObserver observer) {
+ mGlobalEventObservers.add(observer);
+ }
+
+ public void removeEventObserver(EventObserver observer) {
+ mNamedEventObservers.removeAll(observer);
+ mGlobalEventObservers.remove(observer);
+ }
+
+ public interface EventObserver {
+ public void onEventReceived(Event event);
+ }
+
+ public class BroadcastListener extends android.content.BroadcastReceiver {
+ private EventFacade mParent;
+ private boolean mEnQueue;
+
+ public BroadcastListener(EventFacade parent, boolean enqueue) {
+ mParent = parent;
+ mEnQueue = enqueue;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Bundle data;
+ if (intent.getExtras() != null) {
+ data = (Bundle) intent.getExtras().clone();
+ } else {
+ data = new Bundle();
+ }
+ data.putString("action", intent.getAction());
+ try {
+ mParent.eventPost("sl4a", JsonBuilder.build(data).toString(), mEnQueue);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+}
diff --git a/Utils/src/com/googlecode/android_scripting/future/FutureResult.java b/Utils/src/com/googlecode/android_scripting/future/FutureResult.java
index 78a63b0..bdf9cb8 100644
--- a/Utils/src/com/googlecode/android_scripting/future/FutureResult.java
+++ b/Utils/src/com/googlecode/android_scripting/future/FutureResult.java
@@ -27,39 +27,39 @@
*/
public class FutureResult<T> implements Future<T> {
- private final CountDownLatch mLatch = new CountDownLatch(1);
- private volatile T mResult = null;
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private volatile T mResult = null;
- public void set(T result) {
- mResult = result;
- mLatch.countDown();
- }
+ public void set(T result) {
+ mResult = result;
+ mLatch.countDown();
+ }
- @Override
- public boolean cancel(boolean mayInterruptIfRunning) {
- return false;
- }
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
- @Override
- public T get() throws InterruptedException {
- mLatch.await();
- return mResult;
- }
+ @Override
+ public T get() throws InterruptedException {
+ mLatch.await();
+ return mResult;
+ }
- @Override
- public T get(long timeout, TimeUnit unit) throws InterruptedException {
- mLatch.await(timeout, unit);
- return mResult;
- }
+ @Override
+ public T get(long timeout, TimeUnit unit) throws InterruptedException {
+ mLatch.await(timeout, unit);
+ return mResult;
+ }
- @Override
- public boolean isCancelled() {
- return false;
- }
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
- @Override
- public boolean isDone() {
- return mResult != null;
- }
+ @Override
+ public boolean isDone() {
+ return mResult != null;
+ }
}