Skip to content

Commit 6d34e12

Browse files
committed
Merge branch 'release/0.0.2-alpha'
2 parents d8e77f3 + 1657cc5 commit 6d34e12

10 files changed

Lines changed: 250 additions & 7 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
target
2+
tmp

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Note that this version is alpha release.
1010

1111
## How to use
1212

13+
Build the source code (see below) or download a binary from [our SourceForge project page](https://sourceforge.net/projects/procandser/).
14+
1315
Unzip `AndroidSerial-distribution.zip` and copy all files including `AndroidSerial` directory to your `library` folder (e.g. `~/Documents/Processing/library`).
1416

1517
The usage of the library is almost same as [processing.serial.Serial](http://processing.org/reference/libraries/serial/Serial.html) library.
@@ -59,7 +61,14 @@ You can get a working example from the [sparkfun's pulse sensor SEN-11574](https
5961

6062
## How to build
6163

62-
Install [maven](http://maven.apache.org/) and run the command:
64+
You can build the project source code though you can download the built binary from [our SourceForge project page](https://sourceforge.net/projects/procandser/).
65+
66+
Prior to building the project, you need to install the following software:
67+
68+
1. JDK 6 (Any JDK will be available)
69+
1. [Apache Maven](http://maven.apache.org/) (Choose the latest one if possible)
70+
71+
Then run the following command under the root of the project:
6372

6473
mvn clean deploy
6574

@@ -111,15 +120,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
111120
* [Processing Core](http://wiki.processing.org/w/FAQ#Is_Processing_Open_Source.3F_How_.27bout_some_code.3F) ... LGPL, Processing core library
112121
* [Android](http://source.android.com/source/licenses.html) ... ASL 2.0, Android API Library
113122
* [SLFJ Android](http://www.slf4j.org/android/) ... MIT, Logging framework
123+
* [Robolectric](https://github.com/robolectric/robolectric/) ... Android testing library (TEST USE ONLY)
124+
* [Mockito](https://code.google.com/p/mockito/) ... Mock testing library (TEST USE ONLY)
114125

115126
## Known Issues
116127

117-
* The release binary will be moved to [SourceForge](http://sourceforge.net/) though it is currently put under the project root
118128
* Unexpected error occurs when the sketch is compiled and installed into a device
119129
* The current version of [usb-serial-for-android](https://code.google.com/p/usb-serial-for-android/) has several issues regarding data reading. If `java.io.IOException: Expected at least 2 bytes` is observed, please wait a moment or try to re-connect the cable though the trunk version of the driver is already fixed
120130

121131
## Change History
122132

133+
0.0.2-alpha : June 20, 2013
134+
135+
* Fixes an [issue](https://github.com/inventit/processing-android-serial/issues/1) where [Arduino Due](http://arduino.cc/en/Main/arduinoBoardDue) cannot be detected by [usb-serial-for-android](https://code.google.com/p/usb-serial-for-android/) library. Now all Arduino devices are accepted (but not sure they all work properly. [Give us your feedback](https://github.com/inventit/processing-android-serial/issues))
136+
* Adds unit testing libraries, [Robolectric](https://github.com/robolectric/robolectric/) and [Mockito](https://code.google.com/p/mockito/)
137+
* The release binary has been moved to [our SourceForge project page](https://sourceforge.net/projects/procandser/)
138+
123139
0.0.1-alpha : June 10, 2013
124140

125141
* Initial

pom.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,30 @@
7979
<version>20090211</version>
8080
<scope>provided</scope>
8181
</dependency>
82+
<dependency>
83+
<groupId>com.pivotallabs</groupId>
84+
<artifactId>robolectric</artifactId>
85+
<version>1.1</version>
86+
<scope>test</scope>
87+
</dependency>
88+
<dependency>
89+
<groupId>org.mockito</groupId>
90+
<artifactId>mockito-core</artifactId>
91+
<version>1.9.5</version>
92+
<scope>test</scope>
93+
</dependency>
94+
<dependency>
95+
<groupId>org.apache.httpcomponents</groupId>
96+
<artifactId>httpclient</artifactId>
97+
<version>4.2.5</version>
98+
<scope>test</scope>
99+
</dependency>
100+
<dependency>
101+
<groupId>junit</groupId>
102+
<artifactId>junit</artifactId>
103+
<version>4.8.2</version>
104+
<scope>test</scope>
105+
</dependency>
82106
</dependencies>
83107
<build>
84108
<finalName>AndroidSerial</finalName>

src/main/java/com/yourinventit/processing/android/serial/UsbSerialCommunicator.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
import processing.core.PApplet;
1616
import android.content.Context;
1717
import android.hardware.usb.UsbDevice;
18+
import android.hardware.usb.UsbDeviceConnection;
1819
import android.hardware.usb.UsbManager;
1920

21+
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
22+
import com.hoho.android.usbserial.driver.UsbId;
2023
import com.hoho.android.usbserial.driver.UsbSerialDriver;
2124
import com.hoho.android.usbserial.driver.UsbSerialProber;
2225
import com.yourinventit.processing.android.serial.SerialInputOutputManager.Listener;
@@ -27,7 +30,8 @@
2730
* @author dbaba@yourinventit.com
2831
*
2932
*/
30-
class UsbSerialCommunicator extends AbstractAndroidSerialCommunicator implements Listener {
33+
class UsbSerialCommunicator extends AbstractAndroidSerialCommunicator implements
34+
Listener {
3135

3236
/**
3337
* {@link Logger}
@@ -77,8 +81,7 @@ protected UsbSerialDriver findUsbSerialDriver(String deviceName) {
7781
for (final UsbSerialProber prober : UsbSerialProber.values()) {
7882
for (final UsbDevice usbDevice : usbManager.getDeviceList()
7983
.values()) {
80-
final UsbSerialDriver driver = prober.getDevice(usbManager,
81-
usbDevice);
84+
final UsbSerialDriver driver = getDevice(prober, usbDevice);
8285
if (driver != null
8386
&& deviceName
8487
.equals(driver.getDevice().getDeviceName())) {
@@ -224,8 +227,7 @@ public String[] list() {
224227
for (final UsbSerialProber prober : UsbSerialProber.values()) {
225228
for (final UsbDevice usbDevice : usbManager.getDeviceList()
226229
.values()) {
227-
final UsbSerialDriver driver = prober.getDevice(usbManager,
228-
usbDevice);
230+
final UsbSerialDriver driver = getDevice(prober, usbDevice);
229231
if (driver != null) {
230232
names.add(driver.getDevice().getDeviceName());
231233
}
@@ -263,4 +265,39 @@ public void write(int what) {
263265
public void write(String what) {
264266
write(what.getBytes());
265267
}
268+
269+
/**
270+
* Returns a new {@link UsbSerialDriver} instance
271+
*
272+
* @param prober
273+
* @param usbDevice
274+
* @return
275+
*/
276+
protected UsbSerialDriver getDevice(UsbSerialProber prober,
277+
UsbDevice usbDevice) {
278+
UsbSerialDriver driver = prober.getDevice(usbManager, usbDevice);
279+
if (driver == null) {
280+
switch (prober) {
281+
case CDC_ACM_SERIAL:
282+
// Issue #1
283+
// https://github.com/inventit/processing-android-serial/issues/1
284+
// For supporting other Arduino gadgets than what the usb serial
285+
// driver expects shown in the constant UsbId class:
286+
// https://code.google.com/p/usb-serial-for-android/source/browse/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java#39
287+
if (usbDevice.getVendorId() == UsbId.VENDOR_ARDUINO) {
288+
final UsbDeviceConnection connection = usbManager
289+
.openDevice(usbDevice);
290+
if (connection == null) {
291+
return null;
292+
}
293+
driver = new CdcAcmSerialDriver(usbDevice, connection);
294+
}
295+
break;
296+
297+
default:
298+
// do nothing for now
299+
}
300+
}
301+
return driver;
302+
}
266303
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (C) 2013 InventIt Inc.
3+
*/
4+
package com.yourinventit.dmc.api.moat.android;
5+
6+
import java.io.File;
7+
8+
import org.junit.runners.model.InitializationError;
9+
10+
import com.xtremelabs.robolectric.RobolectricConfig;
11+
import com.xtremelabs.robolectric.RobolectricTestRunner;
12+
13+
/**
14+
*
15+
* @author dbaba@yourinventit.com
16+
*
17+
*/
18+
public class MoatRobolectricTestRunner extends RobolectricTestRunner {
19+
20+
private static final File PROJECT_FILE;
21+
22+
static {
23+
System.out.println( System.getenv().get( "ANDROID_HOME" ));
24+
PROJECT_FILE = new File(
25+
"src/test/resources/robolectric/AndroidManifest.xml");
26+
}
27+
28+
/**
29+
* @param testClass
30+
* @throws InitializationError
31+
*/
32+
public MoatRobolectricTestRunner(Class<?> testClass)
33+
throws InitializationError {
34+
super(testClass, new RobolectricConfig(PROJECT_FILE.getParentFile()));
35+
}
36+
37+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) 2013 InventIt Inc.
3+
*/
4+
package com.yourinventit.processing.android.serial;
5+
6+
import static org.junit.Assert.assertNotNull;
7+
import static org.junit.Assert.assertNull;
8+
import static org.mockito.Mockito.mock;
9+
import static org.mockito.Mockito.when;
10+
11+
import org.junit.Before;
12+
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
15+
import processing.core.PApplet;
16+
import android.content.Context;
17+
import android.hardware.usb.UsbDevice;
18+
import android.hardware.usb.UsbDeviceConnection;
19+
import android.hardware.usb.UsbManager;
20+
21+
import com.hoho.android.usbserial.driver.UsbId;
22+
import com.hoho.android.usbserial.driver.UsbSerialDriver;
23+
import com.hoho.android.usbserial.driver.UsbSerialProber;
24+
import com.yourinventit.dmc.api.moat.android.MoatRobolectricTestRunner;
25+
26+
/**
27+
*
28+
* @author dbaba@yourinventit.com
29+
*
30+
*/
31+
@RunWith(MoatRobolectricTestRunner.class)
32+
public class UsbSerialCommunicatorTest {
33+
34+
private UsbSerialCommunicator communicator;
35+
36+
private final PApplet pApplet = mock(PApplet.class);
37+
private final UsbDevice usbDevice = mock(UsbDevice.class);
38+
private final UsbManager usbManager = mock(UsbManager.class);
39+
private final UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
40+
41+
@Before
42+
public void setUp() throws Exception {
43+
when(pApplet.getApplicationContext()).thenReturn(pApplet);
44+
when(pApplet.getSystemService(Context.USB_SERVICE)).thenReturn(
45+
usbManager);
46+
communicator = new UsbSerialCommunicator(pApplet);
47+
}
48+
49+
/**
50+
* Regression Test
51+
*/
52+
@Test
53+
public void test_getDevice_ok1() {
54+
when(usbDevice.getVendorId()).thenReturn(UsbId.VENDOR_ARDUINO);
55+
when(usbDevice.getProductId()).thenReturn(UsbId.ARDUINO_LEONARDO);
56+
when(usbManager.openDevice(usbDevice)).thenReturn(usbDeviceConnection);
57+
final UsbSerialDriver driver = communicator.getDevice(
58+
UsbSerialProber.CDC_ACM_SERIAL, usbDevice);
59+
assertNotNull(driver);
60+
}
61+
62+
/**
63+
* Arduino Due Test
64+
*/
65+
@Test
66+
public void test_getDevice_ok2() {
67+
when(usbDevice.getVendorId()).thenReturn(UsbId.VENDOR_ARDUINO);
68+
// http://www.devtal.de/wiki/Benutzer:Rdiez/ArduinoDue
69+
// 0x003e for Arduino Due
70+
when(usbDevice.getProductId()).thenReturn(0x003e);
71+
when(usbManager.openDevice(usbDevice)).thenReturn(usbDeviceConnection);
72+
final UsbSerialDriver driver = communicator.getDevice(
73+
UsbSerialProber.CDC_ACM_SERIAL, usbDevice);
74+
assertNotNull(driver);
75+
}
76+
77+
/**
78+
* Ensure not working with other vendor ID than Arduino's.
79+
*/
80+
@Test
81+
public void test_getDevice_null() {
82+
when(usbDevice.getVendorId()).thenReturn(UsbId.VENDOR_FTDI);
83+
when(usbManager.openDevice(usbDevice)).thenReturn(usbDeviceConnection);
84+
final UsbSerialDriver driver = communicator.getDevice(
85+
UsbSerialProber.CDC_ACM_SERIAL, usbDevice);
86+
assertNull(driver);
87+
}
88+
}

src/test/java/test/R.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package test;
2+
/* AUTO-GENERATED FILE. DO NOT MODIFY.
3+
*
4+
* This class was automatically generated by the
5+
* aapt tool from the resource data it found. It
6+
* should not be modified by hand.
7+
*/
8+
9+
10+
11+
public final class R {
12+
public static final class attr {
13+
}
14+
}

src/test/resources/.gitkeep

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="test"
4+
android:versionCode="1"
5+
android:versionName="1.0">
6+
<uses-feature android:name="android.hardware.usb.host" />
7+
<uses-sdk android:minSdkVersion="10" />
8+
<application android:label=""
9+
android:icon="@drawable/icon">
10+
<activity android:name="">
11+
<intent-filter>
12+
<action android:name="android.intent.action.MAIN" />
13+
<category android:name="android.intent.category.LAUNCHER" />
14+
</intent-filter>
15+
<intent-filter>
16+
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
17+
</intent-filter>
18+
<meta-data
19+
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
20+
android:resource="@xml/device_filter" />
21+
</activity>
22+
</application>
23+
</manifest>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
</resources>

0 commit comments

Comments
 (0)