package org.schmivits.airball.dataproxy.data; import java.io.IOException; import java.io.OutputStream; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import android.bluetooth.BluetoothSocket; import android.content.Context; public class DataServant extends ConcurrentProcess { private static final long WRITE_PAUSE = 20L; private static final long WRITE_TIMEOUT = 1000L; private final BlockingQueue<String> mData = new LinkedBlockingQueue<String>(); private final BluetoothSocket mTargetSocket; private final DataSourceStream mSource; private static final int HACK_COUNT = 4; int iHack = 0; private final DataSourceStream.Listener mListener = new DataSourceStream.Listener() { @Override public void data(String s) { iHack++; if (iHack == HACK_COUNT) { iHack = 0; try { mData.put(s); } catch (InterruptedException e) { } } } }; public DataServant(Context context, ProcessNode parent, String title, BluetoothSocket socket, DataSourceStream source) { super(context, parent, title); setStatus("Created DataServant"); mTargetSocket = socket; mSource = source; source.addListener(mListener); } @Override public void doRun() { try { OutputStream os = mTargetSocket.getOutputStream(); long timeoutStart = 0L; setStatus("DataServant entering servant loop"); while (isRunning()) { if (mData.size() > 0) { String s = null; synchronized (mData) { if (mData.size() > 0) { s = mData.take(); } } if (s != null) { setStatus(s); os.write(s.getBytes()); os.write('\n'); os.flush(); timeoutStart = 0L; } } else { if (timeoutStart == 0L) { timeoutStart = System.currentTimeMillis(); } else if (System.currentTimeMillis() - timeoutStart > WRITE_TIMEOUT) { setStatus("DataServant timeout"); signal(); return; } Thread.sleep(WRITE_PAUSE); } } } catch (InterruptedException e) { setStatus("DataServant interrupted"); signal(); return; } catch (IOException e) { setStatus("DataServant IOException " + e); signal(); return; } } @Override public void signal() { mSource.removeListener(mListener); try { mTargetSocket.close(); } catch (IOException e) { } super.signal(); } }