29
Extending Android with New Devices Shree Kumar InnoMinds Software Nitheesh K L PES Institute of Technology Android outside the mobile context

Extending Android with New Devices

Embed Size (px)

DESCRIPTION

Shows how a device maker can extend Android to support new devices, while preserving Android compatibility. We demonstrate a joystick & an industrial barcode scanner.

Citation preview

Page 1: 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

Page 2: Extending Android with New Devices

Speaker Intro

Shree Kumar InnoMinds Software

Nitheesh K L PES Institute of Technology

Page 3: Extending Android with New Devices

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

Page 4: Extending Android with New Devices

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

Page 5: Extending Android with New Devices

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

Page 6: Extending Android with New Devices

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

Page 7: Extending Android with New Devices

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

Page 8: Extending Android with New Devices

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

Page 9: Extending Android with New Devices

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);

Page 10: Extending Android with New Devices

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

Page 11: Extending Android with New Devices

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

...

Page 12: Extending Android with New Devices

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

Page 13: Extending Android with New Devices

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” />

Page 14: Extending Android with New Devices

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

}

}

Page 15: Extending Android with New Devices

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

Page 16: Extending Android with New Devices

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){

}

}

}

Page 17: Extending Android with New Devices

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);

}

});

}

};

Page 18: Extending Android with New Devices

Joystick : Step 6 (contd) User App (Java) Service Wrapper (optional)

Privileged Service (Java)

ueventd

JNI Interface

Device Node

Kernel Device

Page 19: Extending Android with New Devices

Joystick : Overall User App (Java) Service Wrapper (optional)

Privileged Service (Java)

ueventd

JNI Interface

Device Node

Kernel Device

Page 20: Extending Android with New Devices

Example 2 • Barcode Scanner

– Opticon MDI 2300 • 2D scanner

– Available as a module for development

Extending Android with New Devices | DroidCon India 2011

Page 21: Extending Android with New Devices

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

Page 22: Extending Android with New Devices

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

Page 23: Extending Android with New Devices

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

Page 24: Extending Android with New Devices

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

Page 25: Extending Android with New Devices

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

Page 26: Extending Android with New Devices

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

Page 27: Extending Android with New Devices

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

Page 28: Extending Android with New Devices

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

Page 29: Extending Android with New Devices

Questions ?

Shree [email protected]

Nitheesh [email protected]