Extending Android with New Devices
-
Upload
shree-kumar -
Category
Technology
-
view
7.295 -
download
4
description
Transcript of Extending Android with New Devices
Extending Android with New Devices
Shree Kumar InnoMinds Software
Nitheesh K L PES Institute of Technology
Android outside the mobile context
Speaker Intro
Shree Kumar InnoMinds Software
Nitheesh K L PES Institute of Technology
Background • Android expected to proliferate
– Not just on smart-phones & tablets • Android built with MID devices in mind
– Newer use cases => other devices – Changing the API is not permitted
• New devices, Additional APIs !
Extending Android with New Devices | DroidCon India 2011
Overview • Device support in Linux • Layered approach for Android • Two examples
– Joystick – Industrial Barcode Scanner
• Device Maker’s Perspective – Standardized interfaces may not happen due to
schedules – Market compatibility provided
Extending Android with New Devices | DroidCon India 2011
Linux Device Support
User App Device API
Privileged Daemon
udev Device Node
Kernel
Device SUBSYSTEMS="usb",ATTRS(idVendor)=="0bb4",MODE="0666",OWNER="shree" SUBSYSTEMS="usb",ATTRS(idVendor)=="8086",MODE="0666",OWNER="shree"
Linux devs : Remember adding these lines to /etc/udev/rules.d/51-android.rules?
setuid() setgid()
Extending Android with New Devices | DroidCon India 2011
Our Android Approach
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel
Device
Platform Library Preserves Android
Compatibility
chown USER:GROUP /dev/XYZ chmod 0ppp /dev/XYZ
mknod /dev/XYZ
sharedUserId=android.uid.system
Extending Android with New Devices | DroidCon India 2011
uses-permission=USE_DEVICE uses-library=sample_device
Example 1 • Supporting a USB Joystick • Why this device ?
– Simplicity – Map concepts to details
• You need – Android device with USB host/OTG
Extending Android with New Devices | DroidCon India 2011
Joystick : Step 1 • Kernel drivers
– Defaults to HID raw driver present – Boot & Check
• Device node – /dev/input/eventX
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Device
Kernel
$ cat /proc/bus/input/devices | grep ^[NH] | grep –A 1 Gamepad \ > | grep event N: Logitech Precision Gamepad H: Handlers=event15
Joystick : Step 2
• Interface to the device node
– Read /dev/input/eventX • Get single key code per event
– ev.code : scan code – ev.value : key down/up
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
fd = open(“/dev/input/event15”, O_RDONLY);
struct input_event ev;
rd = read (fd, &ev, sizeof(struct input_event);
Joystick : Step 2 (contd) • Wrap native code using JNI
• Android.mk – generate lib
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
static const JNINativeMethod gMethods[] = {
{“open”, “()Z”, (void *)Java_Joystick_open},
{“getKey”, “()I”, (void *)Java_Joystick_getKey},
{“close”, “()V”, (void *)Java_Joystick_close},
};
Jint JNI_OnLoad(JavaVM* vm, void* reserved) {
//register your methods
...
}
LOCAL_MODULE := libsample_joystick
Joystick : Step 3 • Permission for device node
– <Android-src>/system/core/init/devices.c
– Ueventd.rc
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Static struct perms_devperms[] = {
...
{“/dev/input”, 0666, AID_SYSTEM, AID_INPUT, 1},
...
}
$ls –l /dev/input
crw-rw---- system input 13, 79 2011-11-18 14:05 event15
crw-rw---- system input 13, 79 2011-11-18 14:05 event11
crw-rw---- system input 13, 79 2011-11-18 14:05 event4
...
Joystick : Step 4 • Service Wrapper around JNI
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
|
+---com
| \---sample
| +---hardware
| | \---joystick
| | JoystickAPI.aidl
| | JoystickCallback.aidl
| | Joystick.java
| | Joystick.class
| |
| \---service
| JoystickService.java
|
+---jni
| Android.mk
| Joystick.h
| Joystick.cpp
| Jsfunctions.h
| Jsfunctions.cpp
Joystick : Step 4 (contd) • Signed APK provides privileged access
• Define permission in AndroidManifest.xml
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
# we ask for restricted permissions for our service,
# so the apk has to be signed
LOCAL_CERTIFICATE := platform
<permission android:name = “com.sample.USE_JOYSTICK” />
Joystick : Step 4 (contd)
• IPC service exposes API to applications – …/ JoystickAPI.aidl
– … / JoystickService.java
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
interface JoystickAPI {
boolean setCallback(in JoystickCallback cb);
boolean clearCallback();
}
Private JoystickAPI.Stub api = new JoystickAPI.Stub(){
public boolean setCallback(JoystickCallback cb){
// enable setting callback
}
public boolean clearCallback(){
// enable clearing callback
}
}
Joystick : Step 5
• Platform Library • Declare your library to the framework
– /system/etc/permissions – com.sample.hardware.joystick.xml
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.sample.hardware.joystick"
file="/system/framework/com.sample.hardware.joystick.jar"/>
</permissions>
adb push \
out/target/product/generic_x86/system/framework/com.sample.hardware.joystick.jar \
/system/framework
• Output product is raw .jar file, NOT a .apk
Joystick : Step 6 • Application interacts with device
– Binds to Service – Uses API provided by Service
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Intent intent = new Intent(“com.sample.android.service.JoystickService”);
bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
ServiceConnection sc = new ServiceConnection(){
private void onServiceConnected(ComponentName n, Ibinder service){
api = Ijoystick.stub.asInterface(service);
try{
api.setCallback(jsCallback);
}catch (RemoteException e){
}
}
}
Joystick : Step 6 (contd) • Run on UI Thread
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
JoystickCallback jsCallback = new JoystickCallback.Stub() {
private void onKeyPress(int arg0) throws RemoteException {
final int key = arg0;
runOnUiThread(new Runnable(){
public void run(){
updateUI(key);
}
});
}
};
Joystick : Step 6 (contd) User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Joystick : Overall User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Example 2 • Barcode Scanner
– Opticon MDI 2300 • 2D scanner
– Available as a module for development
Extending Android with New Devices | DroidCon India 2011
Example 2 • Why use a dedicated device ?
– Supports tons of symbologies – Purpose made
• Fast • Long cables, Laser illumination
– Would you drop your smart-phone ?
ZXing symbology support
Opticon symbology support, “Menubook” excerpt
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 1 • Setup the device
– We’ll use USB VCP (Virtual COM Port) mode – Scan barcodes! Barcodes vary by device.
USB VCP configuration for MDI 2300 | Screenshot from opticonfigure.opticon.com
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Excerpts from Sec 2-5 of Xenon 1900 User Guide
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 2 • Change the kernel
– Specific steps depend on Android/kernel version – Include support for CDC ACM devices
• Ensure support for protocol=“None” in cdc-acm.c
• Boot with the new kernel & check
/* control interfaces without any protocol set */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE) },
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 3 • Interface to the driver
– Read /dev/ttyACM0 – Get single barcode per line
• Test… at every step • Wrap native code using JNI
– Can an app use the wrapper ?
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
# ls –l /dev/input* crw-r----- 1 system input 13, 64 2011-11-02 14:51 event0 crw-r----- 1 system input 13, 64 2011-11-02 14:51 event1
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 4 • ueventd : fix /dev/ttyACM0 access
– owner “system” (android.uid.system)
– Another method: owner “com.sample.uid.acm” • Passes Android Compatibility !
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
mSettings.addSharedUserLP("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM); … mSettings.addSharedUserLP("com.sample.uid.acm", 1018, ApplicationInfo.FLAG_SYSTEM);
frameworks/base/services/java/com/android/server/PackageManagerService.java
/dev/ttyACM0 0660 system root
Add this line to : system/core/rootdir/ueventd.rc
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 5 • Service Wrapper around JNI
– AIDL based IPC service exposes API to applications
– Signed APK provides privileged access
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
interface IBarcodeScanner { boolean setCallback(in BarcodeScannerCallback callback); boolean scanBarcode(int timeout); boolean clearCallback(); }; Interface BarcodeScannerCallback { void handlerBarcode(boolean timedout, String barcode); }
android:sharedUsedId=“android.uid.system”
Extending Android with New Devices | DroidCon India 2011
Barcode Scanner : Step 6 • Application interacts with device
– Binds to Service – Uses API provided by Service
• Could be beautified… – Unbinds when done!
User App (Java) Service Wrapper (optional)
Privileged Service (Java)
ueventd
JNI Interface
Device Node
Kernel Device
Extending Android with New Devices | DroidCon India 2011
Summary • HOWTO-support-devices-on-android.txt
– Important steps – Examples
• Kept simple on purpose – Skipped
• Power Management • Deeper system integration
– You may want to rethink the interfaces !
Extending Android with New Devices | DroidCon India 2011