package ioio.lib.util; import ioio.lib.api.IOIO; import ioio.lib.api.IOIOFactory; import ioio.lib.api.exception.ConnectionLostException; import ioio.lib.api.exception.IncompatibilityException; import ioio.lib.spi.IOIOConnectionFactory; import ioio.lib.spi.Log; import ioio.lib.util.IOIOConnectionManager.IOIOConnectionThreadProvider; import ioio.lib.util.IOIOConnectionManager.Thread; public abstract class IOIOBaseApplicationHelper implements IOIOConnectionThreadProvider { private static final String TAG = "IOIOBaseApplicationHelper"; protected final IOIOLooperProvider looperProvider_; public IOIOBaseApplicationHelper(IOIOLooperProvider provider) { looperProvider_ = provider; } /** * A thread, dedicated for communication with a single physical IOIO device. */ protected static class IOIOThread extends IOIOConnectionManager.Thread { protected IOIO ioio_; private boolean abort_ = false; private boolean connected_ = false; private final IOIOLooper looper_; private final IOIOConnectionFactory connectionFactory_; IOIOThread(IOIOLooper looper, IOIOConnectionFactory factory) { looper_ = looper; connectionFactory_ = factory; } /* * (non-Javadoc) * * @see ioio.lib.util.IOIOConnectionThread#run() */ @Override public final void run() { super.run(); while (!abort_) { try { synchronized (this) { if (abort_) { break; } ioio_ = IOIOFactory.create(connectionFactory_ .createConnection()); } } catch (Exception e) { Log.e(TAG, "Failed to create IOIO, aborting IOIOThread!"); return; } // if we got here, we have a ioio_! try { ioio_.waitForConnect(); connected_ = true; looper_.setup(ioio_); while (!abort_ && ioio_.getState() == IOIO.State.CONNECTED) { looper_.loop(); } } catch (ConnectionLostException e) { } catch (InterruptedException e) { ioio_.disconnect(); } catch (IncompatibilityException e) { Log.e(TAG, "Incompatible IOIO firmware", e); looper_.incompatible(ioio_); // nothing to do - just wait until physical // disconnection } catch (Exception e) { Log.e(TAG, "Unexpected exception caught", e); ioio_.disconnect(); break; } finally { try { ioio_.waitForDisconnect(); } catch (InterruptedException e1) { } synchronized (this) { ioio_ = null; } if (connected_) { looper_.disconnected(); connected_ = false; } } } Log.d(TAG, "IOIOThread is exiting"); } /* * (non-Javadoc) * * @see ioio.lib.util.IOIOConnectionThread#abort() */ @Override public synchronized final void abort() { abort_ = true; if (ioio_ != null) { ioio_.disconnect(); } if (connected_) { interrupt(); } } } @Override public Thread createThreadFromFactory(IOIOConnectionFactory factory) { IOIOLooper looper = looperProvider_.createIOIOLooper(factory.getType(), factory.getExtra()); if (looper == null) { return null; } return new IOIOThread(looper, factory); } }