Package com.polysfactory.glassremote.model

Source Code of com.polysfactory.glassremote.model.GlassConnection$GlassReaderThread

package com.polysfactory.glassremote.model;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

import com.google.glass.companion.CompanionMessagingUtil;
import com.google.glass.companion.GlassProtocol;
import com.google.glass.companion.Proto.Envelope;
import com.google.glass.companion.Proto.GlassInfoRequest;
import com.polysfactory.glassremote.App;

/**
* Handling connection with Google Glass companion service
*
* @author poly
*
*/
public class GlassConnection {

    private static final String SECURE_UUID = "F15CC914E4BC45CE9930CB7695385850";
    private DiscoveryAgent mDiscoveryAgent;
    private String mConnectionURL;
    private StreamConnection mStreamConnection;
    private OutputStream mOutStream;
    private InputStream mInStream;
    private List<GlassConnectionListener> mListeners = new ArrayList<GlassConnection.GlassConnectionListener>();
    private GlassReaderThread mGlassReaderThread;
    private final Client mClient;
    private final ExecutorService mWriteThread = Executors.newSingleThreadExecutor();
    private final Object STREAM_WRITE_LOCK = new Object();

    public GlassConnection() {
        LocalDevice localDevice;
        try {
            localDevice = LocalDevice.getLocalDevice();
            mDiscoveryAgent = localDevice.getDiscoveryAgent();
        } catch (BluetoothStateException e) {
            e.printStackTrace();
        }
        mClient = new Client();
    }

    public List<Device> getBondedDevices() {
        RemoteDevice[] devices = mDiscoveryAgent.retrieveDevices(DiscoveryAgent.PREKNOWN);
        List<Device> list = new ArrayList<Device>();
        for (RemoteDevice remoteDevice : devices) {
            list.add(new Device(remoteDevice));
        }
        return list;
    }

    public void scan() {
        try {
            mDiscoveryAgent.startInquiry(DiscoveryAgent.GIAC, mClient);
        } catch (BluetoothStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void cancelScan() {
        mDiscoveryAgent.cancelInquiry(mClient);
    }

    public void connect(Device device) {
        UUID[] uuidSet = new UUID[1];
        uuidSet[0] = new UUID(SECURE_UUID, false);
        try {
            mDiscoveryAgent.searchServices(null, uuidSet, device.getRemoteDevice(), mClient);
        } catch (BluetoothStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void close() {
        if (mGlassReaderThread != null) {
            mGlassReaderThread.interrupt();
            try {
                mGlassReaderThread.join(10000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
        if (mStreamConnection != null) {
            try {
                mStreamConnection.close();
                mStreamConnection = null;
                mOutStream = null;
                mInStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void registerListener(GlassConnectionListener glassConnectionListener) {
        if (glassConnectionListener == null) {
            return;
        }
        synchronized (mListeners) {
            final int size = mListeners.size();
            for (int i = 0; i < size; i++) {
                GlassConnectionListener listener = mListeners.get(i);
                if (listener == glassConnectionListener) {
                    return;
                }
            }
            this.mListeners.add(glassConnectionListener);
        }
    }

    public void unregisterListener(GlassConnectionListener glassConnectionListener) {
        if (glassConnectionListener == null) {
            return;
        }
        synchronized (mListeners) {
            final int size = mListeners.size();
            for (int i = 0; i < size; i++) {
                GlassConnectionListener listener = mListeners.get(i);
                if (listener == glassConnectionListener) {
                    mListeners.remove(i);
                    break;
                }
            }
        }
    }

    private class Client implements DiscoveryListener {

        @Override
        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
            // TODO Auto-generated method stub

            // TODO filter glass?
            if (App.DEBUG) {
                System.out.println("deviceDiscovered");
            }
            synchronized (mListeners) {
                for (GlassConnectionListener listener : mListeners) {
                    listener.onDeviceDiscovered(new Device(btDevice));
                }
            }
        }

        @Override
        public void inquiryCompleted(int discType) {
            if (App.DEBUG) {
                System.out.println("inquiryCompleted");
            }
            synchronized (mListeners) {
                for (GlassConnectionListener listener : mListeners) {
                    listener.onDeviceScanCompleted();
                }
            }
        }

        @Override
        public void serviceSearchCompleted(int transID, int respCode) {
            if (App.DEBUG) {
                System.out.println("serviceSearchCompleted:" + respCode);
            }
            if (respCode == DiscoveryListener.SERVICE_SEARCH_NO_RECORDS) {
                synchronized (mListeners) {
                    for (GlassConnectionListener listener : mListeners) {
                        listener.onServiceNotFound();
                    }
                }
            } else if (respCode == DiscoveryListener.SERVICE_SEARCH_ERROR) {
                synchronized (mListeners) {
                    for (GlassConnectionListener listener : mListeners) {
                        listener.onServiceSearchError();
                    }
                }
            }
        }

        @Override
        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
            mConnectionURL = null;
            if (servRecord == null || servRecord.length <= 0) {
                System.err.println("invalid service discovered");
                return;
            }

            ServiceRecord service = servRecord[0];
            mConnectionURL = service.getConnectionURL(ServiceRecord.AUTHENTICATE_NOENCRYPT, false);
            if (App.DEBUG) {
                System.out.println(mConnectionURL);
            }

            try {
                mStreamConnection = (StreamConnection) Connector.open(mConnectionURL);
                mOutStream = mStreamConnection.openOutputStream();
                mInStream = mStreamConnection.openInputStream();
                mGlassReaderThread = new GlassReaderThread();
                mGlassReaderThread.start();

                // handshaking
                Envelope envelope = CompanionMessagingUtil.newEnvelope();
                envelope.timezoneC2G = TimeZone.getDefault().getID();
                write(envelope);

                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // handshaking
                Envelope envelope2 = CompanionMessagingUtil.newEnvelope();
                GlassInfoRequest glassInfoRequest = new GlassInfoRequest();
                glassInfoRequest.requestBatteryLevel = true;
                glassInfoRequest.requestStorageInfo = true;
                glassInfoRequest.requestDeviceName = true;
                glassInfoRequest.requestSoftwareVersion = true;
                envelope2.glassInfoRequestC2G = glassInfoRequest;
                write(envelope2);

                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (mListeners) {
                    for (GlassConnectionListener listener : mListeners) {
                        listener.onConnectionOpened();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void write(Envelope envelope) {
        synchronized (STREAM_WRITE_LOCK) {
            try {
                if (App.DEBUG) {
                    System.out.println("write:" + envelope);
                }
                if (mOutStream != null) {
                    GlassProtocol.writeMessage(envelope, mOutStream);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void writeAsync(final Envelope envelope) {
        mWriteThread.execute(new Runnable() {
            @Override
            public void run() {
                write(envelope);
            }
        });
    }

    public void writeAsync(final List<Envelope> envelopes) {
        mWriteThread.execute(new Runnable() {
            @Override
            public void run() {
                for (Envelope envelope : envelopes) {
                    write(envelope);
                }
            }
        });
    }

    public interface GlassConnectionListener {
        public abstract void onDeviceDiscovered(Device device);

        public abstract void onDeviceScanCompleted();

        public abstract void onServiceSearchError();

        public abstract void onReceivedEnvelope(Envelope envelope);

        public abstract void onServiceNotFound();

        public abstract void onConnectionOpened();
    }

    private class GlassReaderThread extends Thread {
        public void run() {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        Envelope envelope = (Envelope) GlassProtocol.readMessage(new Envelope(), mInStream);
                        if (App.DEBUG) {
                            if (envelope.screenshot == null) {
                                System.out.println("read:" + envelope);
                            }
                        }
                        if (envelope != null) {
                            synchronized (mListeners) {
                                for (GlassConnectionListener listener : mListeners) {
                                    listener.onReceivedEnvelope(envelope);
                                }
                            }
                        }
                    } catch (InterruptedIOException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
                if (App.DEBUG) {
                    System.out.println("Reader thread finished.");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
    };

}
TOP

Related Classes of com.polysfactory.glassremote.model.GlassConnection$GlassReaderThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.