Permalink
Browse files

Process data from the external sensor

  • Loading branch information...
1 parent 3ff950a commit ed436a68f38ed9267b8949bc59d439714ab1eba2 @obrok obrok committed Mar 16, 2012
@@ -0,0 +1,4 @@
+package pl.llp.aircasting.event;
+
+public class ExternalSensorEvent extends AirCastingEvent {
+}
@@ -19,6 +19,7 @@
*/
package pl.llp.aircasting.guice;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.location.Geocoder;
import android.telephony.TelephonyManager;
@@ -58,6 +59,8 @@ protected void configure() {
bind(EventBus.class).in(Scopes.SINGLETON);
bindConstant().annotatedWith(SharedPreferencesName.class).to("pl.llp.aircasting_preferences");
+
+ bind(BluetoothAdapter.class).toProvider(BluetoothAdapterProvider.class);
bind(TelephonyManager.class).toProvider(new SystemServiceProvider<TelephonyManager>(Context.TELEPHONY_SERVICE));
}
@@ -0,0 +1,11 @@
+package pl.llp.aircasting.guice;
+
+import android.bluetooth.BluetoothAdapter;
+import com.google.inject.Provider;
+
+public class BluetoothAdapterProvider implements Provider<BluetoothAdapter> {
+ @Override
+ public BluetoothAdapter get() {
+ return BluetoothAdapter.getDefaultAdapter();
+ }
+}
@@ -275,4 +275,8 @@ public boolean isShowRoute() {
public void setSensorAddress(String address) {
writeString(SENSOR_ADDRESS, address);
}
+
+ public String getSensorAddress() {
+ return preferences.getString(SENSOR_ADDRESS, null);
+ }
}
@@ -30,6 +30,7 @@
import pl.llp.aircasting.sensor.builtin.SoundVolumeListener;
import pl.llp.aircasting.helper.*;
import pl.llp.aircasting.repository.SessionRepository;
+import pl.llp.aircasting.sensor.external.ExternalSensor;
import java.util.Date;
import java.util.HashSet;
@@ -49,14 +50,18 @@
@Singleton
public class SessionManager implements SoundVolumeListener {
@Inject SimpleAudioReader audioReader;
+ @Inject ExternalSensor externalSensor;
+
@Inject SessionRepository sessionRepository;
+
@Inject SettingsHelper settingsHelper;
- @Inject Application applicationContext;
@Inject LocationHelper locationHelper;
@Inject MetadataHelper metadataHelper;
- @Inject TelephonyManager telephonyManager;
@Inject NotificationHelper notificationHelper;
+ @Inject Application applicationContext;
+ @Inject TelephonyManager telephonyManager;
+
Session session = new Session();
private double dbLast = SoundHelper.TOTALLY_QUIET;
@@ -125,8 +130,11 @@ private void notifyNote(Note note) {
public void startSensors() {
if (!recording) {
locationHelper.start();
+
audioReader.start(this);
+ externalSensor.start();
+
recording = true;
}
}
@@ -151,6 +159,8 @@ public void stopSensors() {
audioReader.stop();
+ externalSensor.stop();
+
recording = false;
}
}
@@ -244,8 +254,8 @@ public int getNoteCount() {
}
public void restartSensors() {
- stopSensors();
- startSensors();
+ externalSensor.stop();
+ externalSensor.start();
}
public interface Listener {
@@ -0,0 +1,106 @@
+package pl.llp.aircasting.sensor.external;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.util.Log;
+import com.google.common.eventbus.EventBus;
+import com.google.common.io.CharStreams;
+import com.google.common.io.InputSupplier;
+import com.google.common.io.LineProcessor;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import pl.llp.aircasting.event.ExternalSensorEvent;
+import pl.llp.aircasting.helper.SettingsHelper;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.UUID;
+
+import static com.google.common.io.Closeables.closeQuietly;
+
+@Singleton
+public class ExternalSensor {
+ private static final String TAG = ExternalSensor.class.getSimpleName();
+ public static final UUID SPP_SERIAL = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
+
+ @Inject EventBus eventBus;
+ @Inject SettingsHelper settingsHelper;
+ @Nullable @Inject BluetoothAdapter bluetoothAdapter;
+ @Inject ExternalSensorParser parser;
+
+ private BluetoothDevice device;
+ private Thread readerThread;
+ private ReaderWorker readerWorker;
+
+ public synchronized void start() {
+ if (bluetoothAdapter != null && readerWorker == null) {
+ String address = settingsHelper.getSensorAddress();
+ device = bluetoothAdapter.getRemoteDevice(address);
+
+ readerWorker = new ReaderWorker();
+ readerThread = new Thread(readerWorker);
+ readerThread.start();
+ }
+ }
+
+ public synchronized void stop() {
+ if(readerWorker != null){
+ readerWorker.stop();
+ readerWorker = null;
+ }
+ }
+
+ public void read(String line) {
+ ExternalSensorEvent event = parser.parse(line);
+ eventBus.post(event);
+ }
+
+ private class ReaderWorker implements Runnable {
+ private boolean stopped = false;
+
+ @Override
+ public void run() {
+ BluetoothSocket socket = null;
+ InputStreamReader reader = null;
+
+ try {
+ socket = device.createRfcommSocketToServiceRecord(SPP_SERIAL);
+ reader = new InputStreamReader(socket.getInputStream());
+ final InputStreamReader finalReader = reader;
+
+ CharStreams.readLines(
+ new InputSupplier<Reader>() {
+ @Override
+ public Reader getInput() throws IOException {
+ return finalReader;
+ }
+ },
+ new LineProcessor<Void>() {
+ @Override
+ public boolean processLine(String line) throws IOException {
+ read(line);
+ return stopped;
+ }
+
+ @Override
+ public Void getResult() {
+ return null;
+ }
+ }
+ );
+ } catch (IOException e) {
+ Log.e(TAG, "Bluetooth communication failure", e);
+ } finally {
+ closeQuietly(reader);
+ closeQuietly(socket);
+ }
+ }
+
+ public void stop() {
+ stopped = true;
+ }
+ }
+}
@@ -0,0 +1,9 @@
+package pl.llp.aircasting.sensor.external;
+
+import pl.llp.aircasting.event.ExternalSensorEvent;
+
+public class ExternalSensorParser {
+ public ExternalSensorEvent parse(String string) {
+ return null;
+ }
+}
@@ -1,22 +1,22 @@
/**
- AirCasting - Share your Air!
- Copyright (C) 2011-2012 HabitatMap, Inc.
+ AirCasting - Share your Air!
+ Copyright (C) 2011-2012 HabitatMap, Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program 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 General Public License for more details.
+ This program 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 General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
- You can contact the authors by email at <info@habitatmap.org>
-*/
+ You can contact the authors by email at <info@habitatmap.org>
+ */
package pl.llp.aircasting.model;
import android.location.Location;
@@ -34,6 +34,7 @@
import pl.llp.aircasting.helper.MetadataHelper;
import pl.llp.aircasting.helper.SettingsHelper;
import pl.llp.aircasting.repository.SessionRepository;
+import pl.llp.aircasting.sensor.external.ExternalSensor;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
@@ -58,6 +59,7 @@ private void mockSensors() {
sessionManager.locationHelper = mock(LocationHelper.class);
sessionManager.audioReader = mock(SimpleAudioReader.class);
sessionManager.metadataHelper = mock(MetadataHelper.class);
+ sessionManager.externalSensor = mock(ExternalSensor.class);
when(sessionManager.locationHelper.getLastLocation()).thenReturn(location);
}
@@ -328,4 +330,12 @@ public void shouldMarkNotesToBeDeletedForSavedSessions() {
verify(sessionManager.session).deleteNote(note);
verify(sessionManager.sessionRepository).deleteNote(sessionManager.session, note);
}
+
+ @Test
+ public void shouldRestartExternalSensor() {
+ sessionManager.restartSensors();
+
+ verify(sessionManager.externalSensor).stop();
+ verify(sessionManager.externalSensor).start();
+ }
}
@@ -0,0 +1,43 @@
+package pl.llp.aircasting.sensor.external;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import com.google.common.eventbus.EventBus;
+import com.google.inject.Inject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import pl.llp.aircasting.InjectedTestRunner;
+import pl.llp.aircasting.event.ExternalSensorEvent;
+import pl.llp.aircasting.helper.SettingsHelper;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(InjectedTestRunner.class)
+public class ExternalSensorTest {
+ @Inject ExternalSensor sensor;
+
+ @Before
+ public void setup() throws IOException {
+ sensor.parser = mock(ExternalSensorParser.class);
+
+ sensor.eventBus = mock(EventBus.class);
+ }
+
+ @Test
+ public void shouldReadInputAndGenerateEvents() throws IOException {
+ ExternalSensorEvent event1 = mock(ExternalSensorEvent.class);
+ when(sensor.parser.parse("Reading 1")).thenReturn(event1);
+
+ sensor.read("Reading 1");
+
+ verify(sensor.eventBus).post(event1);
+ }
+}

0 comments on commit ed436a6

Please sign in to comment.