You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
745 lines
26 KiB
745 lines
26 KiB
package org.mavlink.qgroundcontrol; |
|
|
|
/* Copyright 2013 Google Inc. |
|
* |
|
* This library is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU Lesser General Public |
|
* License as published by the Free Software Foundation; either |
|
* version 2.1 of the License, or (at your option) any later version. |
|
* |
|
* This library is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
* Lesser General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU Lesser General Public |
|
* License along with this library; if not, write to the Free Software |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
|
* USA. |
|
* |
|
* Project home page: http://code.google.com/p/usb-serial-for-android/ |
|
*/ |
|
/////////////////////////////////////////////////////////////////////////////////////////// |
|
// Written by: Mike Goza April 2014 |
|
// |
|
// These routines interface with the Android USB Host devices for serial port communication. |
|
// The code uses the usb-serial-for-android software library. The QGCActivity class is the |
|
// interface to the C++ routines through jni calls. Do not change the functions without also |
|
// changing the corresponding calls in the C++ routines or you will break the interface. |
|
// |
|
//////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
import java.util.ArrayList; |
|
import java.util.HashMap; |
|
import java.util.List; |
|
import java.util.ArrayList; |
|
import java.util.concurrent.ExecutorService; |
|
import java.util.concurrent.Executors; |
|
import java.util.Timer; |
|
import java.util.TimerTask; |
|
import java.io.IOException; |
|
|
|
import android.app.Activity; |
|
import android.app.PendingIntent; |
|
import android.content.BroadcastReceiver; |
|
import android.content.Context; |
|
import android.content.Intent; |
|
import android.content.IntentFilter; |
|
import android.hardware.usb.UsbAccessory; |
|
import android.hardware.usb.UsbDevice; |
|
import android.hardware.usb.UsbDeviceConnection; |
|
import android.hardware.usb.UsbManager; |
|
import android.widget.Toast; |
|
import android.util.Log; |
|
import android.os.PowerManager; |
|
import android.os.Bundle; |
|
import android.app.PendingIntent; |
|
import android.view.WindowManager; |
|
import android.os.Bundle; |
|
import android.bluetooth.BluetoothDevice; |
|
|
|
import com.hoho.android.usbserial.driver.*; |
|
import org.qtproject.qt5.android.bindings.QtActivity; |
|
import org.qtproject.qt5.android.bindings.QtApplication; |
|
|
|
public class QGCActivity extends QtActivity |
|
{ |
|
public static int BAD_DEVICE_ID = 0; |
|
private static QGCActivity _instance = null; |
|
private static UsbManager _usbManager = null; |
|
private static List<UsbSerialDriver> _drivers; |
|
private static HashMap<Integer, UsbIoManager> m_ioManager; |
|
private static HashMap<Integer, Integer> _userDataHashByDeviceId; |
|
private static final String TAG = "QGC_QGCActivity"; |
|
private static PowerManager.WakeLock _wakeLock; |
|
private static final String ACTION_USB_PERMISSION = "org.mavlink.qgroundcontrol.action.USB_PERMISSION"; |
|
private static PendingIntent _usbPermissionIntent = null; |
|
private TaiSync taiSync = null; |
|
private Timer probeAccessoriesTimer = null; |
|
|
|
public static Context m_context; |
|
|
|
private final static ExecutorService m_Executor = Executors.newSingleThreadExecutor(); |
|
|
|
private final static UsbIoManager.Listener m_Listener = |
|
new UsbIoManager.Listener() |
|
{ |
|
@Override |
|
public void onRunError(Exception eA, int userData) |
|
{ |
|
Log.e(TAG, "onRunError Exception"); |
|
nativeDeviceException(userData, eA.getMessage()); |
|
} |
|
|
|
@Override |
|
public void onNewData(final byte[] dataA, int userData) |
|
{ |
|
nativeDeviceNewData(userData, dataA); |
|
} |
|
}; |
|
|
|
private final BroadcastReceiver mOpenAccessoryReceiver = |
|
new BroadcastReceiver() |
|
{ |
|
@Override |
|
public void onReceive(Context context, Intent intent) { |
|
String action = intent.getAction(); |
|
if (ACTION_USB_PERMISSION.equals(action)) { |
|
UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); |
|
if (accessory != null && intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { |
|
openAccessory(accessory); |
|
} |
|
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { |
|
UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); |
|
if (accessory != null) { |
|
closeAccessory(accessory); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
private static UsbSerialDriver _findDriverByDeviceId(int deviceId) { |
|
for (UsbSerialDriver driver: _drivers) { |
|
if (driver.getDevice().getDeviceId() == deviceId) { |
|
return driver; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
private static UsbSerialDriver _findDriverByDeviceName(String deviceName) { |
|
for (UsbSerialDriver driver: _drivers) { |
|
if (driver.getDevice().getDeviceName().equals(deviceName)) { |
|
return driver; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
private final static BroadcastReceiver _usbReceiver = new BroadcastReceiver() { |
|
public void onReceive(Context context, Intent intent) { |
|
String action = intent.getAction(); |
|
Log.i(TAG, "BroadcastReceiver USB action " + action); |
|
|
|
if (ACTION_USB_PERMISSION.equals(action)) { |
|
synchronized (_instance) { |
|
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); |
|
if (device != null) { |
|
UsbSerialDriver driver = _findDriverByDeviceId(device.getDeviceId()); |
|
|
|
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { |
|
qgcLogDebug("Permission granted to " + device.getDeviceName()); |
|
driver.setPermissionStatus(UsbSerialDriver.permissionStatusSuccess); |
|
} else { |
|
qgcLogDebug("Permission denied for " + device.getDeviceName()); |
|
driver.setPermissionStatus(UsbSerialDriver.permissionStatusDenied); |
|
} |
|
} |
|
} |
|
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { |
|
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); |
|
if (device != null) { |
|
if (_userDataHashByDeviceId.containsKey(device.getDeviceId())) { |
|
nativeDeviceHasDisconnected(_userDataHashByDeviceId.get(device.getDeviceId())); |
|
} |
|
} |
|
} |
|
|
|
try { |
|
nativeUpdateAvailableJoysticks(); |
|
} catch(Exception e) { |
|
Log.e(TAG, "Exception nativeUpdateAvailableJoysticks()"); |
|
} |
|
} |
|
}; |
|
|
|
// Native C++ functions which connect back to QSerialPort code |
|
private static native void nativeDeviceHasDisconnected(int userData); |
|
private static native void nativeDeviceException(int userData, String messageA); |
|
private static native void nativeDeviceNewData(int userData, byte[] dataA); |
|
private static native void nativeUpdateAvailableJoysticks(); |
|
|
|
// Native C++ functions called to log output |
|
public static native void qgcLogDebug(String message); |
|
public static native void qgcLogWarning(String message); |
|
|
|
// QGCActivity singleton |
|
public QGCActivity() |
|
{ |
|
_instance = this; |
|
_drivers = new ArrayList<UsbSerialDriver>(); |
|
_userDataHashByDeviceId = new HashMap<Integer, Integer>(); |
|
m_ioManager = new HashMap<Integer, UsbIoManager>(); |
|
} |
|
|
|
@Override |
|
public void onCreate(Bundle savedInstanceState) |
|
{ |
|
super.onCreate(savedInstanceState); |
|
PowerManager pm = (PowerManager)_instance.getSystemService(Context.POWER_SERVICE); |
|
_wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "QGroundControl"); |
|
if(_wakeLock != null) { |
|
_wakeLock.acquire(); |
|
} else { |
|
Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK not acquired!!!"); |
|
} |
|
_instance.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
|
|
|
_usbManager = (UsbManager)_instance.getSystemService(Context.USB_SERVICE); |
|
|
|
// Register for USB Detach and USB Permission intent |
|
IntentFilter filter = new IntentFilter(); |
|
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); |
|
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); |
|
filter.addAction(ACTION_USB_PERMISSION); |
|
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); |
|
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); |
|
_instance.registerReceiver(_instance._usbReceiver, filter); |
|
|
|
// Create intent for usb permission request |
|
_usbPermissionIntent = PendingIntent.getBroadcast(_instance, 0, new Intent(ACTION_USB_PERMISSION), 0); |
|
|
|
try { |
|
taiSync = new TaiSync(); |
|
|
|
IntentFilter accessoryFilter = new IntentFilter(ACTION_USB_PERMISSION); |
|
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); |
|
registerReceiver(mOpenAccessoryReceiver, accessoryFilter); |
|
|
|
probeAccessoriesTimer = new Timer(); |
|
probeAccessoriesTimer.schedule(new TimerTask() { |
|
@Override |
|
public void run() |
|
{ |
|
probeAccessories(); |
|
} |
|
}, 0, 3000); |
|
} catch(Exception e) { |
|
Log.e(TAG, "Exception: " + e); |
|
} |
|
} |
|
|
|
@Override |
|
public void onResume() { |
|
super.onResume(); |
|
|
|
// Plug in of USB ACCESSORY triggers only onResume event. |
|
// Then we scan if there is actually anything new |
|
probeAccessories(); |
|
} |
|
|
|
@Override |
|
protected void onDestroy() |
|
{ |
|
if (probeAccessoriesTimer != null) { |
|
probeAccessoriesTimer.cancel(); |
|
} |
|
unregisterReceiver(mOpenAccessoryReceiver); |
|
try { |
|
if(_wakeLock != null) { |
|
_wakeLock.release(); |
|
} |
|
} catch(Exception e) { |
|
Log.e(TAG, "Exception onDestroy()"); |
|
} |
|
super.onDestroy(); |
|
} |
|
|
|
public void onInit(int status) { |
|
} |
|
|
|
/// Incrementally updates the list of drivers connected to the device |
|
private static void updateCurrentDrivers() |
|
{ |
|
List<UsbSerialDriver> currentDrivers = UsbSerialProber.findAllDevices(_usbManager); |
|
|
|
// Remove stale drivers |
|
for (int i=_drivers.size()-1; i>=0; i--) { |
|
boolean found = false; |
|
for (UsbSerialDriver currentDriver: currentDrivers) { |
|
if (_drivers.get(i).getDevice().getDeviceId() == currentDriver.getDevice().getDeviceId()) { |
|
found = true; |
|
break; |
|
} |
|
} |
|
|
|
if (!found) { |
|
qgcLogDebug("Remove stale driver " + _drivers.get(i).getDevice().getDeviceName()); |
|
_drivers.remove(i); |
|
} |
|
} |
|
|
|
// Add new drivers |
|
for (int i=0; i<currentDrivers.size(); i++) { |
|
boolean found = false; |
|
for (int j=0; j<_drivers.size(); j++) { |
|
if (currentDrivers.get(i).getDevice().getDeviceId() == _drivers.get(j).getDevice().getDeviceId()) { |
|
found = true; |
|
break; |
|
} |
|
} |
|
|
|
if (!found) { |
|
UsbSerialDriver newDriver = currentDrivers.get(i); |
|
UsbDevice device = newDriver.getDevice(); |
|
String deviceName = device.getDeviceName(); |
|
|
|
_drivers.add(newDriver); |
|
qgcLogDebug("Adding new driver " + deviceName); |
|
|
|
// Request permission if needed |
|
if (_usbManager.hasPermission(device)) { |
|
qgcLogDebug("Already have permission to use device " + deviceName); |
|
newDriver.setPermissionStatus(UsbSerialDriver.permissionStatusSuccess); |
|
} else { |
|
qgcLogDebug("Requesting permission to use device " + deviceName); |
|
newDriver.setPermissionStatus(UsbSerialDriver.permissionStatusRequested); |
|
_usbManager.requestPermission(device, _usbPermissionIntent); |
|
} |
|
} |
|
} |
|
} |
|
|
|
/// Returns array of device info for each unopened device. |
|
/// @return Device info format DeviceName:Company:ProductId:VendorId |
|
public static String[] availableDevicesInfo() |
|
{ |
|
updateCurrentDrivers(); |
|
|
|
if (_drivers.size() <= 0) { |
|
return null; |
|
} |
|
|
|
List<String> deviceInfoList = new ArrayList<String>(); |
|
|
|
for (int i=0; i<_drivers.size(); i++) { |
|
String deviceInfo; |
|
UsbSerialDriver driver = _drivers.get(i); |
|
|
|
if (driver.permissionStatus() != UsbSerialDriver.permissionStatusSuccess) { |
|
continue; |
|
} |
|
|
|
UsbDevice device = driver.getDevice(); |
|
|
|
deviceInfo = device.getDeviceName() + ":"; |
|
|
|
if (driver instanceof FtdiSerialDriver) { |
|
deviceInfo = deviceInfo + "FTDI:"; |
|
} else if (driver instanceof CdcAcmSerialDriver) { |
|
deviceInfo = deviceInfo + "Cdc Acm:"; |
|
} else if (driver instanceof Cp2102SerialDriver) { |
|
deviceInfo = deviceInfo + "Cp2102:"; |
|
} else if (driver instanceof ProlificSerialDriver) { |
|
deviceInfo = deviceInfo + "Prolific:"; |
|
} else { |
|
deviceInfo = deviceInfo + "Unknown:"; |
|
} |
|
|
|
deviceInfo = deviceInfo + Integer.toString(device.getProductId()) + ":"; |
|
deviceInfo = deviceInfo + Integer.toString(device.getVendorId()) + ":"; |
|
|
|
deviceInfoList.add(deviceInfo); |
|
} |
|
|
|
String[] rgDeviceInfo = new String[deviceInfoList.size()]; |
|
for (int i=0; i<deviceInfoList.size(); i++) { |
|
rgDeviceInfo[i] = deviceInfoList.get(i); |
|
} |
|
|
|
return rgDeviceInfo; |
|
} |
|
|
|
/// Open the specified device |
|
/// @param userData Data to associate with device and pass back through to native calls. |
|
/// @return Device id |
|
public static int open(Context parentContext, String deviceName, int userData) |
|
{ |
|
int deviceId = BAD_DEVICE_ID; |
|
|
|
m_context = parentContext; |
|
|
|
UsbSerialDriver driver = _findDriverByDeviceName(deviceName); |
|
if (driver == null) { |
|
qgcLogWarning("Attempt to open unknown device " + deviceName); |
|
return BAD_DEVICE_ID; |
|
} |
|
|
|
if (driver.permissionStatus() != UsbSerialDriver.permissionStatusSuccess) { |
|
qgcLogWarning("Attempt to open device with incorrect permission status " + deviceName + " " + driver.permissionStatus()); |
|
return BAD_DEVICE_ID; |
|
} |
|
|
|
UsbDevice device = driver.getDevice(); |
|
deviceId = device.getDeviceId(); |
|
|
|
try { |
|
driver.setConnection(_usbManager.openDevice(device)); |
|
driver.open(); |
|
driver.setPermissionStatus(UsbSerialDriver.permissionStatusOpen); |
|
|
|
_userDataHashByDeviceId.put(deviceId, userData); |
|
|
|
UsbIoManager ioManager = new UsbIoManager(driver, m_Listener, userData); |
|
m_ioManager.put(deviceId, ioManager); |
|
m_Executor.submit(ioManager); |
|
|
|
qgcLogDebug("Port open successful"); |
|
} catch(IOException exA) { |
|
driver.setPermissionStatus(UsbSerialDriver.permissionStatusRequestRequired); |
|
_userDataHashByDeviceId.remove(deviceId); |
|
|
|
if(m_ioManager.get(deviceId) != null) { |
|
m_ioManager.get(deviceId).stop(); |
|
m_ioManager.remove(deviceId); |
|
} |
|
qgcLogWarning("Port open exception: " + exA.getMessage()); |
|
return BAD_DEVICE_ID; |
|
} |
|
|
|
return deviceId; |
|
} |
|
|
|
public static void startIoManager(int idA) |
|
{ |
|
if (m_ioManager.get(idA) != null) |
|
return; |
|
|
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return; |
|
|
|
UsbIoManager managerL = new UsbIoManager(driverL, m_Listener, _userDataHashByDeviceId.get(idA)); |
|
m_ioManager.put(idA, managerL); |
|
m_Executor.submit(managerL); |
|
} |
|
|
|
public static void stopIoManager(int idA) |
|
{ |
|
if(m_ioManager.get(idA) == null) |
|
return; |
|
|
|
m_ioManager.get(idA).stop(); |
|
m_ioManager.remove(idA); |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Sets the parameters on an open port. |
|
// |
|
// Args: idA - ID number from the open command |
|
// baudRateA - Decimal value of the baud rate. I.E. 9600, 57600, 115200, etc. |
|
// dataBitsA - number of data bits. Valid numbers are 5, 6, 7, 8 |
|
// stopBitsA - number of stop bits. Valid numbers are 1, 2 |
|
// parityA - No Parity=0, Odd Parity=1, Even Parity=2 |
|
// |
|
// Returns: T/F Success/Failure |
|
// |
|
//////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
public static boolean setParameters(int idA, int baudRateA, int dataBitsA, int stopBitsA, int parityA) |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return false; |
|
|
|
try |
|
{ |
|
driverL.setParameters(baudRateA, dataBitsA, stopBitsA, parityA); |
|
return true; |
|
} |
|
catch(IOException eA) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Close the device. |
|
// |
|
// Args: idA - ID number from the open command |
|
// |
|
// Returns: T/F Success/Failure |
|
// |
|
//////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
public static boolean close(int idA) |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return false; |
|
|
|
try |
|
{ |
|
stopIoManager(idA); |
|
_userDataHashByDeviceId.remove(idA); |
|
driverL.setPermissionStatus(UsbSerialDriver.permissionStatusRequestRequired); |
|
driverL.close(); |
|
|
|
return true; |
|
} |
|
catch(IOException eA) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Write data to the device. |
|
// |
|
// Args: idA - ID number from the open command |
|
// sourceA - byte array of data to write |
|
// timeoutMsecA - amount of time in milliseconds to wait for the write to occur |
|
// |
|
// Returns: number of bytes written |
|
// |
|
///////////////////////////////////////////////////////////////////////////////////////////////////// |
|
public static int write(int idA, byte[] sourceA, int timeoutMSecA) |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return 0; |
|
|
|
try |
|
{ |
|
return driverL.write(sourceA, timeoutMSecA); |
|
} |
|
catch(IOException eA) |
|
{ |
|
return 0; |
|
} |
|
/* |
|
UsbIoManager managerL = m_ioManager.get(idA); |
|
|
|
if(managerL != null) |
|
{ |
|
managerL.writeAsync(sourceA); |
|
return sourceA.length; |
|
} |
|
else |
|
return 0; |
|
*/ |
|
} |
|
|
|
public static boolean isDeviceNameValid(String nameA) |
|
{ |
|
for (UsbSerialDriver driver: _drivers) { |
|
if (driver.getDevice().getDeviceName() == nameA) |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
public static boolean isDeviceNameOpen(String nameA) |
|
{ |
|
for (UsbSerialDriver driverL: _drivers) { |
|
if (nameA.equals(driverL.getDevice().getDeviceName()) && driverL.permissionStatus() == UsbSerialDriver.permissionStatusOpen) { |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Set the Data Terminal Ready flag on the device |
|
// |
|
// Args: idA - ID number from the open command |
|
// onA - on=T, off=F |
|
// |
|
// Returns: T/F Success/Failure |
|
// |
|
//////////////////////////////////////////////////////////////////////////////////////////////////// |
|
public static boolean setDataTerminalReady(int idA, boolean onA) |
|
{ |
|
try |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return false; |
|
|
|
driverL.setDTR(onA); |
|
return true; |
|
} |
|
catch(IOException eA) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Set the Request to Send flag |
|
// |
|
// Args: idA - ID number from the open command |
|
// onA - on=T, off=F |
|
// |
|
// Returns: T/F Success/Failure |
|
// |
|
//////////////////////////////////////////////////////////////////////////////////////////// |
|
public static boolean setRequestToSend(int idA, boolean onA) |
|
{ |
|
try |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return false; |
|
|
|
driverL.setRTS(onA); |
|
return true; |
|
} |
|
catch(IOException eA) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Purge the hardware buffers based on the input and output flags |
|
// |
|
// Args: idA - ID number from the open command |
|
// inputA - input buffer purge. purge=T |
|
// outputA - output buffer purge. purge=T |
|
// |
|
// Returns: T/F Success/Failure |
|
// |
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
public static boolean purgeBuffers(int idA, boolean inputA, boolean outputA) |
|
{ |
|
try |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return false; |
|
|
|
return driverL.purgeHwBuffers(inputA, outputA); |
|
} |
|
catch(IOException eA) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Get the native device handle (file descriptor) |
|
// |
|
// Args: idA - ID number from the open command |
|
// |
|
// Returns: device handle |
|
// |
|
/////////////////////////////////////////////////////////////////////////////////////////// |
|
public static int getDeviceHandle(int idA) |
|
{ |
|
UsbSerialDriver driverL = _findDriverByDeviceId(idA); |
|
|
|
if (driverL == null) |
|
return -1; |
|
|
|
UsbDeviceConnection connectL = driverL.getDeviceConnection(); |
|
if (connectL == null) |
|
return -1; |
|
else |
|
return connectL.getFileDescriptor(); |
|
} |
|
|
|
UsbAccessory openUsbAccessory = null; |
|
Object openAccessoryLock = new Object(); |
|
|
|
private void openAccessory(UsbAccessory usbAccessory) |
|
{ |
|
Log.i(TAG, "openAccessory: " + usbAccessory.getSerial()); |
|
try { |
|
synchronized(openAccessoryLock) { |
|
if ((openUsbAccessory != null && !taiSync.isRunning()) || openUsbAccessory == null) { |
|
openUsbAccessory = usbAccessory; |
|
taiSync.open(_usbManager.openAccessory(usbAccessory)); |
|
} |
|
} |
|
} catch (IOException e) { |
|
Log.e(TAG, "openAccessory exception: " + e); |
|
taiSync.close(); |
|
closeAccessory(openUsbAccessory); |
|
} |
|
} |
|
|
|
private void closeAccessory(UsbAccessory usbAccessory) |
|
{ |
|
Log.i(TAG, "closeAccessory"); |
|
|
|
synchronized(openAccessoryLock) { |
|
if (openUsbAccessory != null && usbAccessory == openUsbAccessory && taiSync.isRunning()) { |
|
taiSync.close(); |
|
openUsbAccessory = null; |
|
} |
|
} |
|
} |
|
|
|
Object probeAccessoriesLock = new Object(); |
|
|
|
private void probeAccessories() |
|
{ |
|
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); |
|
new Thread(new Runnable() { |
|
public void run() { |
|
synchronized(openAccessoryLock) { |
|
// Log.i(TAG, "probeAccessories"); |
|
UsbAccessory[] accessories = _usbManager.getAccessoryList(); |
|
if (accessories != null) { |
|
for (UsbAccessory usbAccessory : accessories) { |
|
if (usbAccessory == null) { |
|
continue; |
|
} |
|
if (_usbManager.hasPermission(usbAccessory)) { |
|
openAccessory(usbAccessory); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
}).start(); |
|
} |
|
} |
|
|
|
|