org.chromium.latency.walt.Connection.java Source code

Java tutorial

Introduction

Here is the source code for org.chromium.latency.walt.Connection.java

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.chromium.latency.walt;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.support.v4.content.LocalBroadcastManager;

import java.util.HashMap;
import java.util.Locale;

public abstract class Connection {
    private static final String USB_PERMISSION_RESPONSE_INTENT = "usb-permission-response";
    private static final String CONNECT_INTENT = "org.chromium.latency.walt.CONNECT";

    protected SimpleLogger mLogger;
    protected Context mContext;
    private LocalBroadcastManager mBroadcastManager;
    private BroadcastReceiver mCurrentConnectReceiver;

    private UsbManager mUsbManager;
    protected UsbDevice mUsbDevice = null;
    protected UsbDeviceConnection mUsbConnection;

    public Connection(Context context) {
        mContext = context;
        mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        mLogger = SimpleLogger.getInstance(context);
        mBroadcastManager = LocalBroadcastManager.getInstance(context);
    }

    public abstract void onConnect();

    public abstract void onDisconnect();

    public abstract int getVid();

    public abstract int getPid();

    private String getConnectIntent() {
        return CONNECT_INTENT + getVid() + ":" + getPid();
    }

    private String getUsbPermissionResponseIntent() {
        return USB_PERMISSION_RESPONSE_INTENT + getVid() + ":" + getPid();
    }

    public boolean isConnected() {
        return mUsbConnection != null;
    }

    public void registerConnectCallback(final Runnable r) {
        if (mCurrentConnectReceiver != null) {
            mBroadcastManager.unregisterReceiver(mCurrentConnectReceiver);
            mCurrentConnectReceiver = null;
        }

        if (isConnected()) {
            r.run();
            return;
        }

        mCurrentConnectReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mBroadcastManager.unregisterReceiver(this);
                r.run();
            }
        };
        mBroadcastManager.registerReceiver(mCurrentConnectReceiver, new IntentFilter(getConnectIntent()));
    }

    public void connect() {
        UsbDevice usbDevice = findUsbDevice();
        connect(usbDevice);
    }

    public void connect(UsbDevice usbDevice) {
        if (usbDevice == null) {
            mLogger.log("Device not found.");
            return;
        }

        if (usbDevice.getProductId() != getPid() || usbDevice.getVendorId() != getVid()) {
            mLogger.log("Not a valid device");
            return;
        }

        mUsbDevice = usbDevice;

        // Request permission
        // This displays a dialog asking user for permission to use the device.
        // No dialog is displayed if the permission was already given before or the app started as a
        // result of intent filter when the device was plugged in.

        PendingIntent permissionIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent(getUsbPermissionResponseIntent()), 0);
        mContext.registerReceiver(respondToUsbPermission, new IntentFilter(getUsbPermissionResponseIntent()));
        mLogger.log("Requesting permission for USB device.");
        mUsbManager.requestPermission(mUsbDevice, permissionIntent);
    }

    public void disconnect() {
        onDisconnect();

        mUsbConnection.close();
        mUsbConnection = null;
        mUsbDevice = null;

        mContext.unregisterReceiver(disconnectReceiver);
    }

    private BroadcastReceiver disconnectReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (isConnected() && mUsbDevice.equals(usbDevice)) {
                mLogger.log("WALT was detached");
                disconnect();
            }
        }
    };

    private BroadcastReceiver respondToUsbPermission = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            if (mUsbDevice == null) {
                mLogger.log("USB device was not properly opened");
                return;
            }

            if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                    && mUsbDevice.equals(intent.getParcelableExtra(UsbManager.EXTRA_DEVICE))) {
                mUsbConnection = mUsbManager.openDevice(mUsbDevice);

                mContext.registerReceiver(disconnectReceiver,
                        new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));

                onConnect();

                mBroadcastManager.sendBroadcast(new Intent(getConnectIntent()));
            } else {
                mLogger.log("Could not get permission to open the USB device");
            }
            mContext.unregisterReceiver(respondToUsbPermission);
        }
    };

    public UsbDevice findUsbDevice() {

        mLogger.log(String.format("Looking for TeensyUSB VID=0x%x PID=0x%x", getVid(), getPid()));

        HashMap<String, UsbDevice> deviceHash = mUsbManager.getDeviceList();
        if (deviceHash.size() == 0) {
            mLogger.log("No connected USB devices found");
            return null;
        }

        mLogger.log("Found " + deviceHash.size() + " connected USB devices:");

        UsbDevice usbDevice = null;

        for (String key : deviceHash.keySet()) {

            UsbDevice dev = deviceHash.get(key);

            String msg = String.format(Locale.US, "USB Device: %s, VID:PID - %x:%x, %d interfaces", key,
                    dev.getVendorId(), dev.getProductId(), dev.getInterfaceCount());

            if (dev.getVendorId() == getVid() && dev.getProductId() == getPid()) {
                usbDevice = dev;
                msg += " <- using this one.";
            }

            mLogger.log(msg);
        }
        return usbDevice;
    }
}