Android Open Source - LibGeppa Connection Thread






From Project

Back to project page LibGeppa.

License

The source code is released under:

Apache License

If you think the Android project LibGeppa listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package net.cattaka.libgeppa.thread;
//from   w  ww .  j  a v  a  2 s .co m
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.Semaphore;

import net.cattaka.libgeppa.Constants;
import net.cattaka.libgeppa.IRawSocket;
import net.cattaka.libgeppa.data.ConnectionCode;
import net.cattaka.libgeppa.data.ConnectionState;
import net.cattaka.libgeppa.data.IPacket;
import net.cattaka.libgeppa.data.IPacketFactory;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class ConnectionThread<T extends IPacket> {
    private static final int EVENT_RECEIVE = 1;

    private static final int EVENT_SEND = 2;

    private static final int EVENT_SOCKET_CONNECTING = 3;

    private static final int EVENT_SOCKET_CONNECTED = 4;

    private static final int EVENT_SOCKET_CLOSED = 5;

    public interface IRawSocketPrepareTask {
        public IRawSocket prepareRawSocket();
    }

    private Handler.Callback mOuterCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == EVENT_RECEIVE) {
                if (mConnectionThreadListener != null) {
                    @SuppressWarnings("unchecked")
                    T packet = (T)msg.obj;
                    mConnectionThreadListener.onReceive(packet);
                }
                return true;
            } else if (msg.what == EVENT_SOCKET_CONNECTING) {
                mInnerHandler = (Handler)msg.obj;

                mLastConnectionState = ConnectionState.CONNECTING;
                mConnectionThreadListener.onConnectionStateChanged(ConnectionState.CONNECTING,
                        ConnectionCode.UNKNOWN);
                return true;
            } else if (msg.what == EVENT_SOCKET_CONNECTED) {
                mLastConnectionState = ConnectionState.CONNECTED;
                mConnectionThreadListener.onConnectionStateChanged(ConnectionState.CONNECTED,
                        ConnectionCode.UNKNOWN);
                return true;
            } else if (msg.what == EVENT_SOCKET_CLOSED) {
                mLastConnectionState = ConnectionState.CLOSED;
                ConnectionCode code = (ConnectionCode)msg.obj;
                mConnectionThreadListener.onConnectionStateChanged(ConnectionState.CLOSED, code);
                return true;
            }
            return false;
        }
    };

    /**
     * This is used by {@link #mInnerHandler}.
     */
    private class InnerCallback implements Handler.Callback {
        private OutputStream mOutputStream;

        private ReceiveThread<T> mReceiveThread;

        public InnerCallback() {
            super();
        }

        public void setOutputStream(OutputStream outputStream) {
            mOutputStream = outputStream;
        }

        public void setReceiveThread(ReceiveThread<T> receiveThread) {
            mReceiveThread = receiveThread;
        }

        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == EVENT_RECEIVE) {
                mOuterHandler.obtainMessage(EVENT_RECEIVE, msg.obj).sendToTarget();
                return true;
            } else if (msg.what == EVENT_SEND) {
                @SuppressWarnings("unchecked")
                T packet = (T)msg.obj;
                if (packet != null) {
                    try {
                        mPacketFactory.writePacket(mOutputStream, packet);
                        mOutputStream.flush();
                    } catch (IOException e) {
                        mInnerHandler.obtainMessage(EVENT_SOCKET_CLOSED).sendToTarget();
                    }
                }
                return true;
            } else if (msg.what == EVENT_SOCKET_CLOSED) {
                if (mReceiveThread != null) {
                    try {
                        mReceiveThread.stopThread();
                    } catch (InterruptedException e) {
                        Log.w(Constants.TAG, e.getMessage(), e);
                    }
                    mReceiveThread = null;
                }
                Looper.myLooper().quit();
                return true;
            }
            return false;
        }
    }

    private Thread mThread;

    private IRawSocketPrepareTask mPrepareTask;

    private Handler mOuterHandler;

    private Handler mInnerHandler;

    private IPacketFactory<T> mPacketFactory;

    private IConnectionThreadListener<T> mConnectionThreadListener;

    private ConnectionState mLastConnectionState = ConnectionState.INITIAL;

    private IRawSocket mRawSocket;

    public ConnectionThread(IRawSocketPrepareTask prepareTask, IPacketFactory<T> packetFactory,
            IConnectionThreadListener<T> connectionThreadListener) {
        this(prepareTask, packetFactory, connectionThreadListener, false);
    }

    public ConnectionThread(IRawSocketPrepareTask prepareTask, IPacketFactory<T> packetFactory,
            IConnectionThreadListener<T> connectionThreadListener, boolean useMainLooperForListener) {
        super();
        mPrepareTask = prepareTask;
        mPacketFactory = packetFactory;
        mConnectionThreadListener = connectionThreadListener;

        if (useMainLooperForListener) {
            mOuterHandler = new Handler(Looper.getMainLooper(), mOuterCallback);
        } else {
            mOuterHandler = new Handler(mOuterCallback);
        }

        mRawSocket = mPrepareTask.prepareRawSocket();
    }

    public void startThread() throws InterruptedException {
        final Semaphore semaphore = new Semaphore(1);
        semaphore.acquire();
        mThread = new Thread("ConnectionThread:CONNECTING") {
            @Override
            public void run() {
                super.run();
                Looper.prepare();
                InnerCallback innerCallback = new InnerCallback();
                Handler handler = new Handler(innerCallback);
                mOuterHandler.obtainMessage(EVENT_SOCKET_CONNECTING, handler).sendToTarget();

                semaphore.release();
                if (mRawSocket != null && mRawSocket.setup()) {
                    try {
                        this.setName("ConnectionThread:" + mRawSocket.getLabel());
                        InputStream inputStream = mRawSocket.getInputStream();
                        OutputStream outputStream = mRawSocket.getOutputStream();
                        innerCallback.setOutputStream(outputStream);

                        { // Creating receiveThread
                            ReceiveThread<T> receiveThread = new ReceiveThread<T>(EVENT_RECEIVE,
                                    EVENT_SOCKET_CLOSED, handler, inputStream, mPacketFactory);
                            innerCallback.setReceiveThread(receiveThread);
                            receiveThread.startThread(mRawSocket.getLabel());
                        }
                        mOuterHandler.obtainMessage(EVENT_SOCKET_CONNECTED).sendToTarget();

                        Looper.loop();
                    } finally {
                        try {
                            mRawSocket.close();
                        } catch (IOException e) {
                            Log.w(Constants.TAG, e.getMessage());
                        }
                        mOuterHandler.obtainMessage(EVENT_SOCKET_CLOSED,
                                ConnectionCode.DISCONNECTED).sendToTarget();
                    }
                } else {
                    mOuterHandler.obtainMessage(EVENT_SOCKET_CLOSED, ConnectionCode.NO_DEVICE)
                            .sendToTarget();
                }
            }
        };
        mThread.start();
        semaphore.acquire();
        semaphore.release();
    }

    public void stopThread() throws InterruptedException {
        if (mRawSocket != null && !mRawSocket.isConnected()) {
            try {
                mRawSocket.close();
            } catch (IOException e) {
                // Impossible
                Log.w(Constants.TAG, e.getMessage(), e);
            }
        }
        // note : mInnerHandler is exactly not null because it uses semaphore.
        mInnerHandler.obtainMessage(EVENT_SOCKET_CLOSED).sendToTarget();
        mThread.join();
    }

    public boolean sendPacket(T packet) {
        // note : mInnerHandler is exactly not null because it uses semaphore.
        if (mLastConnectionState == ConnectionState.CONNECTED) {
            mInnerHandler.obtainMessage(EVENT_SEND, packet).sendToTarget();
            return true;
        } else {
            return false;
        }
    }

    public ConnectionState getLastConnectionState() {
        return mLastConnectionState;
    }

}




Java Source Code List

net.cattaka.libgeppa.ActiveGeppaService.java
net.cattaka.libgeppa.AdkPassiveGeppaService.java
net.cattaka.libgeppa.BluetoothPassiveGeppaService.java
net.cattaka.libgeppa.Constants.java
net.cattaka.libgeppa.GeppaService.java
net.cattaka.libgeppa.IRawSocket.java
net.cattaka.libgeppa.PassiveGeppaService.java
net.cattaka.libgeppa.adapter.AbsConnectionAdapter.java
net.cattaka.libgeppa.adapter.DummyDeviceAdapter.java
net.cattaka.libgeppa.adapter.IDeviceAdapterListener.java
net.cattaka.libgeppa.adapter.IDeviceAdapter.java
net.cattaka.libgeppa.adapter.IDeviceCommandAdapter.java
net.cattaka.libgeppa.adapter.LocalDeviceAdapter.java
net.cattaka.libgeppa.adapter.RemoteDeviceAdapter.java
net.cattaka.libgeppa.binder.ActiveGeppaServiceFuncs.java
net.cattaka.libgeppa.binder.PassiveGeppaServiceFuncs.java
net.cattaka.libgeppa.binder.async.ActiveGeppaServiceFuncsAsync.java
net.cattaka.libgeppa.binder.async.AsyncInterfaceException.java
net.cattaka.libgeppa.binder.async.PassiveGeppaServiceFuncsAsync.java
net.cattaka.libgeppa.bluetooth.BluetoothAdapterFactory.java
net.cattaka.libgeppa.bluetooth.BluetoothAdapterWrapper.java
net.cattaka.libgeppa.bluetooth.BluetoothDeviceWrapper.java
net.cattaka.libgeppa.bluetooth.BluetoothSocketWrapper.java
net.cattaka.libgeppa.bluetooth.IBluetoothAdapter.java
net.cattaka.libgeppa.bluetooth.IBluetoothDevice.java
net.cattaka.libgeppa.bluetooth.IBluetoothSocket.java
net.cattaka.libgeppa.data.BaudRate.java
net.cattaka.libgeppa.data.ConnectionCode.java
net.cattaka.libgeppa.data.ConnectionState.java
net.cattaka.libgeppa.data.DeviceEventCode.java
net.cattaka.libgeppa.data.DeviceInfo.java
net.cattaka.libgeppa.data.DeviceState.java
net.cattaka.libgeppa.data.IPacketFactory.java
net.cattaka.libgeppa.data.IPacket.java
net.cattaka.libgeppa.data.PacketWrapper.java
net.cattaka.libgeppa.data.SocketState.java
net.cattaka.libgeppa.exception.NotImplementedException.java
net.cattaka.libgeppa.net.DummySocketPrepareTask.java
net.cattaka.libgeppa.net.DummySocket.java
net.cattaka.libgeppa.net.PhysicaloidSocketPrepareTask.java
net.cattaka.libgeppa.net.PhysicaloidSocket.java
net.cattaka.libgeppa.net.RemoteSocketPrepareTask.java
net.cattaka.libgeppa.net.RemoteSocket.java
net.cattaka.libgeppa.net.UsbClass.java
net.cattaka.libgeppa.passive.AdkPassiveReceiver.java
net.cattaka.libgeppa.passive.BluetoothPassiveReceiver.java
net.cattaka.libgeppa.passive.IPassiveReceiverListener.java
net.cattaka.libgeppa.passive.IPassiveReceiver.java
net.cattaka.libgeppa.socket.AdkRawSocket.java
net.cattaka.libgeppa.socket.BtRawSocket.java
net.cattaka.libgeppa.thread.ClientThread.java
net.cattaka.libgeppa.thread.ConnectionThread.java
net.cattaka.libgeppa.thread.IConnectionThreadListener.java
net.cattaka.libgeppa.thread.ReceiveThread.java
net.cattaka.libgeppa.thread.ServerThread.java
net.cattaka.libgeppa.util.AidlUtil.java
net.cattaka.libgeppa.util.DeviceUtil.java