• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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
onDestroy()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 
isDevicesMatching(UsbDevice l, UsbDevice r)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 
ReaderThread(UsbDevice device, UsbDeviceConnection conn)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 
requestToQuit()134         private synchronized void requestToQuit() {
135             mShouldQuit = true;
136         }
137 
shouldQuit()138         private synchronized boolean shouldQuit() {
139             return mShouldQuit;
140         }
141 
142         @Override
run()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
onReceive(Context context, Intent intent)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