Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.android.android_acm_serial;
00018
00019 import com.google.common.base.Preconditions;
00020 import com.google.common.collect.Lists;
00021 import com.google.common.collect.Maps;
00022
00023 import android.app.PendingIntent;
00024 import android.content.BroadcastReceiver;
00025 import android.content.Context;
00026 import android.content.Intent;
00027 import android.content.IntentFilter;
00028 import android.hardware.usb.UsbDevice;
00029 import android.hardware.usb.UsbDeviceConnection;
00030 import android.hardware.usb.UsbInterface;
00031 import android.hardware.usb.UsbManager;
00032 import android.os.Bundle;
00033 import org.apache.commons.logging.Log;
00034 import org.apache.commons.logging.LogFactory;
00035 import org.ros.android.RosActivity;
00036 import org.ros.exception.RosRuntimeException;
00037
00038 import java.util.Collection;
00039 import java.util.Map;
00040
00044 public abstract class AcmDeviceActivity extends RosActivity implements AcmDevicePermissionCallback {
00045
00046 private static final boolean DEBUG = true;
00047 private static final Log log = LogFactory.getLog(AcmDeviceActivity.class);
00048
00049 static final String ACTION_USB_PERMISSION = "org.ros.android.USB_PERMISSION";
00050
00051 private final Map<String, AcmDevice> acmDevices;
00052
00053 private UsbManager usbManager;
00054 private PendingIntent usbPermissionIntent;
00055 private BroadcastReceiver usbDevicePermissionReceiver;
00056 private BroadcastReceiver usbDeviceDetachedReceiver;
00057
00058 protected AcmDeviceActivity(String notificationTicker, String notificationTitle) {
00059 super(notificationTicker, notificationTitle);
00060 log.info("<New> - Enter - v0.1");
00061 acmDevices = Maps.newConcurrentMap();
00062 usbDevicePermissionReceiver =
00063 new UsbDevicePermissionReceiver(new UsbDevicePermissionCallback() {
00064 @Override
00065 public void onPermissionGranted(UsbDevice usbDevice) {
00066 log.info("New ACM device. Permission Granted");
00067 newAcmDevice(usbDevice);
00068 }
00069
00070 @Override
00071 public void onPermissionDenied() {
00072 log.info("New ACM device. Permission Denied");
00073 AcmDeviceActivity.this.onPermissionDenied();
00074 }
00075 });
00076 usbDeviceDetachedReceiver = new UsbDeviceDetachedReceiver(acmDevices);
00077 log.info("<New> - Exit");
00078 }
00079
00083 private void newAcmDevice(UsbDevice usbDevice) {
00084 try {
00085 Preconditions.checkNotNull(usbDevice);
00086 String deviceName = usbDevice.getDeviceName();
00087 Preconditions.checkState(!acmDevices.containsKey(deviceName), "Already connected to device: "
00088 + deviceName);
00089 Preconditions.checkState(usbManager.hasPermission(usbDevice), "Permission denied: "
00090 + deviceName);
00091
00092 UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(usbDevice);
00093 Preconditions.checkNotNull(usbDeviceConnection, "Failed to open device: " + deviceName);
00094 if (DEBUG) {
00095 log.info("Adding new ACM device: " + deviceName);
00096 }
00097 AcmDevice acmDevice = new AcmDevice(usbDeviceConnection, usbDevice);
00098 acmDevices.put(deviceName, acmDevice);
00099 AcmDeviceActivity.this.onPermissionGranted(acmDevice);
00100 } catch(IllegalStateException e) {
00101 log.info("A precondition failed: " + e);
00102 } catch(IllegalArgumentException e) {
00103 log.info("Failed to create ACM device: " + e);
00104 }
00105 }
00106
00107 @Override
00108 protected void onCreate(Bundle savedInstanceState) {
00109 super.onCreate(savedInstanceState);
00110 usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
00111 usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
00112 registerReceiver(usbDevicePermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));
00113 registerReceiver(usbDeviceDetachedReceiver, new IntentFilter(
00114 UsbManager.ACTION_USB_DEVICE_DETACHED));
00115 onUsbDeviceAttached(getIntent());
00116 }
00117
00118 @Override
00119 protected void onNewIntent(Intent intent) {
00120 super.onNewIntent(intent);
00121 onUsbDeviceAttached(intent);
00122 }
00123
00124 private void onUsbDeviceAttached(Intent intent) {
00125 if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
00126 UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
00127 String deviceName = usbDevice.getDeviceName();
00128 if (!acmDevices.containsKey(deviceName)) {
00129 newAcmDevice(usbDevice);
00130 } else if (DEBUG) {
00131 log.info("Ignoring already connected device: " + deviceName);
00132 }
00133 }
00134 }
00135
00136 protected Collection<UsbDevice> getUsbDevices(int vendorId, int productId) {
00137 Collection<UsbDevice> allDevices = usbManager.getDeviceList().values();
00138 Collection<UsbDevice> matchingDevices = Lists.newArrayList();
00139 for (UsbDevice device : allDevices) {
00140 if (device.getVendorId() == vendorId && device.getProductId() == productId) {
00141 matchingDevices.add(device);
00142 }
00143 }
00144 return matchingDevices;
00145 }
00146
00155 protected void requestPermission(UsbDevice usbDevice) {
00156 usbManager.requestPermission(usbDevice, usbPermissionIntent);
00157 }
00158
00159 private void closeAcmDevices() {
00160 synchronized (acmDevices) {
00161 for (AcmDevice device : acmDevices.values()) {
00162 try {
00163 device.close();
00164 } catch (RosRuntimeException e) {
00165
00166 }
00167 }
00168 }
00169 }
00170
00171 @Override
00172 protected void onDestroy() {
00173 if (usbDeviceDetachedReceiver != null) {
00174 unregisterReceiver(usbDeviceDetachedReceiver);
00175 }
00176 if (usbDevicePermissionReceiver != null) {
00177 unregisterReceiver(usbDevicePermissionReceiver);
00178 }
00179 closeAcmDevices();
00180 super.onDestroy();
00181 }
00182 }