Home | History | Annotate | Download | only in aoaphosttest
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.hardware.usb.aoaphosttest;
     17 
     18 import android.app.Activity;
     19 import android.content.BroadcastReceiver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.hardware.usb.UsbAccessory;
     24 import android.hardware.usb.UsbConstants;
     25 import android.hardware.usb.UsbDevice;
     26 import android.hardware.usb.UsbDeviceConnection;
     27 import android.hardware.usb.UsbEndpoint;
     28 import android.hardware.usb.UsbInterface;
     29 import android.hardware.usb.UsbManager;
     30 import android.os.Bundle;
     31 import android.os.Handler;
     32 import android.os.HandlerThread;
     33 import android.os.Process;
     34 import android.text.TextUtils;
     35 import android.util.Log;
     36 
     37 import libcore.io.IoUtils;
     38 
     39 public class UsbAoapHostTestActivity extends Activity {
     40 
     41     private static final String TAG = UsbAoapHostTestActivity.class.getSimpleName();
     42 
     43     private UsbManager mUsbManager;
     44     private UsbStateReceiver mReceiver;
     45     private UsbDevice mUsbDevice;
     46     private UsbDeviceConnection mUsbConnection;
     47     private ReaderThread mReaderThread;
     48 
     49     @Override
     50     protected void onCreate(Bundle savedInstanceState) {
     51         super.onCreate(savedInstanceState);
     52 
     53         setContentView(R.layout.host);
     54 
     55         mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
     56         IntentFilter filter = new IntentFilter();
     57         filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
     58         mReceiver = new UsbStateReceiver();
     59         registerReceiver(mReceiver, filter);
     60 
     61         Intent intent = getIntent();
     62         if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
     63             mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
     64             mUsbConnection = mUsbManager.openDevice(mUsbDevice);
     65             mReaderThread = new ReaderThread(mUsbDevice, mUsbConnection);
     66             mReaderThread.start();
     67         } else {
     68             finish();
     69         }
     70     }
     71 
     72     @Override
     73     protected void onDestroy() {
     74         super.onDestroy();
     75         unregisterReceiver(mReceiver);
     76         if (mUsbConnection != null) {
     77             mUsbConnection.close();
     78         }
     79         if (mReaderThread != null) {
     80             mReaderThread.requestToQuit();
     81             try {
     82                 mReaderThread.join(1000);
     83             } catch (InterruptedException e) {
     84             }
     85             if (mReaderThread.isAlive()) { // reader thread stuck
     86                 throw new RuntimeException("ReaderThread still alive");
     87             }
     88         }
     89     }
     90 
     91     private static boolean isDevicesMatching(UsbDevice l, UsbDevice r) {
     92         if (l.getVendorId() == r.getVendorId() && l.getProductId() == r.getProductId() &&
     93                 TextUtils.equals(l.getSerialNumber(), r.getSerialNumber())) {
     94             return true;
     95         }
     96         return false;
     97     }
     98 
     99     private class ReaderThread extends Thread {
    100         private boolean mShouldQuit = false;
    101         private final UsbDevice mDevice;
    102         private final UsbDeviceConnection mUsbConnection;
    103         private final UsbEndpoint mBulkIn;
    104         private final UsbEndpoint mBulkOut;
    105         private final byte[] mBuffer = new byte[16384];
    106 
    107         private ReaderThread(UsbDevice device, UsbDeviceConnection conn) {
    108             super("AOAP");
    109             mDevice = device;
    110             mUsbConnection = conn;
    111             UsbInterface iface = mDevice.getInterface(0);
    112             // Setup bulk endpoints.
    113             UsbEndpoint bulkIn = null;
    114             UsbEndpoint bulkOut = null;
    115             for (int i = 0; i < iface.getEndpointCount(); i++) {
    116                 UsbEndpoint ep = iface.getEndpoint(i);
    117                 if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
    118                     if (bulkIn == null) {
    119                         bulkIn = ep;
    120                     }
    121                 } else {
    122                     if (bulkOut == null) {
    123                         bulkOut = ep;
    124                     }
    125                 }
    126             }
    127             if (bulkIn == null || bulkOut == null) {
    128                 throw new IllegalStateException("Unable to find bulk endpoints");
    129             }
    130             mBulkIn = bulkIn;
    131             mBulkOut = bulkOut;
    132         }
    133 
    134         private synchronized void requestToQuit() {
    135             mShouldQuit = true;
    136         }
    137 
    138         private synchronized boolean shouldQuit() {
    139             return mShouldQuit;
    140         }
    141 
    142         @Override
    143         public void run() {
    144             while (!shouldQuit()) {
    145                 int read = mUsbConnection.bulkTransfer(mBulkIn, mBuffer, mBuffer.length,
    146                         Integer.MAX_VALUE);
    147                 if (read < 0) {
    148                     throw new RuntimeException("bulkTransfer failed, read = " + read);
    149                 }
    150             }
    151         }
    152     }
    153 
    154     private class UsbStateReceiver extends BroadcastReceiver {
    155         @Override
    156         public void onReceive(Context context, Intent intent) {
    157             if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
    158                 UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    159                 if (isDevicesMatching(mUsbDevice, device)) {
    160                     finish();
    161                 }
    162             }
    163         }
    164     }
    165 }
    166