/**
* Funf: Open Sensing Framework
* Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland.
* Acknowledgments: Alan Gardner
* Contact: nadav@media.mit.edu
*
* This file is part of Funf.
*
* Funf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Funf is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Funf. If not, see <http://www.gnu.org/licenses/>.
*/
package edu.mit.media.funf.probe;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.test.ServiceTestCase;
import android.util.Log;
public abstract class ProbeTestCase<T extends Probe> extends ServiceTestCase<T> {
public static final String TAG = "FunfTest";
private final Class<T> probeClass;
private BlockingQueue<Bundle> dataBundles;
private DataReceiver dataReceiver;
private Timer timer;
public ProbeTestCase(Class<T> probeClass) {
super(probeClass);
this.probeClass = probeClass;
}
private void clean() throws InterruptedException {
// Cancel callback
PendingIntent callback = PendingIntent.getBroadcast(getContext(), 0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);
clearData();
// Remove all current state
List<ProbeCommandServiceConnection> connections = new ArrayList<ProbeCommandServiceConnection>();
for (Class<? extends Probe> probeClass : getProbesAffected()) {
ProbeCommandServiceConnection probeConn = new ProbeCommandServiceConnection(getContext(), probeClass) {
@Override
public void runCommand() {
getProbe().reset();
getProbe().stopSelf();
}
};
connections.add(probeConn);
}
for(ProbeCommandServiceConnection conn : connections) {
conn.join();
}
}
protected List<Class<? extends Probe>> getProbesAffected() {
List<Class<? extends Probe>> list = new ArrayList<Class<? extends Probe>>();
list.add(probeClass);
return list;
}
@Override
protected void setUp() throws Exception {
super.setUp();
clean();
timer = new Timer();
dataBundles = new LinkedBlockingQueue<Bundle>();
IntentFilter filter = new IntentFilter();
filter.addAction(Probe.ACTION_DETAILS);
filter.addAction(Probe.ACTION_STATUS);
filter.addAction(Probe.ACTION_DATA);
dataReceiver = new DataReceiver();
getContext().registerReceiver(dataReceiver, filter);
}
@Override
protected void tearDown() throws Exception {
timer.cancel();
getContext().unregisterReceiver(dataReceiver);
clean();
super.tearDown();
}
protected void shouldNotReturnData(int timeoutSeconds) {
Bundle data = null;
try {
data = dataBundles.poll(timeoutSeconds, TimeUnit.SECONDS);
} catch (InterruptedException e) {}
if (data != null) {
fail("Returned data within max wait time.");
}
}
protected void clearData() {
if (dataBundles != null) {
dataBundles.clear();
}
}
protected Bundle getData(int timeoutSeconds) {
Bundle data = null;
try {
data = dataBundles.poll(timeoutSeconds, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail("Was interrupted while waiting for data");
}
if (data == null) {
fail("Did not return data within max wait time.");
}
return data;
}
protected Timer getTimer() {
return timer;
}
protected String getTestRequester() {
return getContext().getPackageName();
}
protected void startProbe(final Bundle... params) {
startProbe(probeClass, params);
}
protected void startProbe(Class<? extends Probe> probeClass, final Bundle... params) {
// TODO: figure out how to reliably get data
// Maybe creating service for saving data to a static variable
Intent i = new Intent(getContext(), probeClass);
i.setAction(Probe.ACTION_REQUEST);
PendingIntent callback = PendingIntent.getBroadcast(getContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
i.putExtra(Probe.CALLBACK_KEY, callback);
i.putExtra(Probe.REQUESTS_KEY, params);
getContext().startService(i);
}
protected void stopProbe() {
Intent i = new Intent(getContext(), probeClass);
i.setAction(Probe.ACTION_STOP);
getContext().startService(i);
}
protected void sendStatusRequest() {
// TODO: implement
}
public class DataReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Recieved: " + intent.getAction());
if (Probe.ACTION_DATA.equals(intent.getAction())
&& probeClass.getName().equals(intent.getStringExtra(Probe.PROBE))) {
Log.i(TAG, "Adding data:" + intent.getExtras());
dataBundles.offer(intent.getExtras());
}
}
}
}