\subchapter{Develop a JNI library}{Learn how JNI works and how to integrate it
in Android}

After this lab, you will be able to
\begin{itemize}
  \item Develop bindings from Java to C
  \item Integrate these bindings into the build system
\end{itemize}

\section{Write the bindings}

The code should be pretty close to the one you wrote in the native
application lab, so you will find a skeleton of the folder to
integrate into your product definition in the
\code{$HOME/android-labs/jni} directory. Copy the \code{frameworks}
folder you will find there into your device folder.

You will mostly have to modify function prototypes from your previous
application to make it work with JNI.

As a reminder, JNI requires the function prototype to be like:
\code{JNIEXPORT <jni type> JNICALL Java_<package>_<class>_<function_name>(JNIEnv *env, jobject this)}.
Beware that the function name can't have any underscore in its name
for JNI to function properly.

The package we are going to use is \code{com.fe.android.backend}, and
the class name is \code{USBBackend}. We are going to need the
functions \code{fire}, \code{stop}, \code{initUSB}, \code{freeUSB},
\code{moveDown}, \code{moveUp}, \code{moveLeft} and \code{moveRight}.

\section{Integrate it in the build system}

Now you can integrate it into the build system, by writing an
\code{Android.mk} as usual.

The library should be called \code{liblauncher_jni}.

\section{Testing the bindings}

We should now have a system with the files
\code{/system/lib/liblauncher_jni.so}, containing the JNI bindings and
\code{/system/lib/libusb.so}.

Test what you did so far by using the \code{TestJNI.apk} application
you'll find in the \code{android-labs} directory.

Install it using adb, and run it.

\section{Fix the Problems}

The permission model of Android is heavily based on user
permissions. By default, your USB device won't be accessible to
applications. We didn't see this behaviour because we ran the mlbin
program as root. To test if the program runs properly, test it as a
random user on the system.

To do so, you can use the command \code{su}, and you can test with the
user \code{radio} for example.

When you start your tests, you will find that \code{libusb} cannot
open the usb devices because of restricted permissions. This can be
fixed through \code{ueventd.rc} files. Add a device-specific
\code{ueventd} configuration file to your build to make the files
under \code{/dev/bus/usb/} world accessible.

You should now see a succesful message in the logs after running it.

\section{Going further}

You will find that the binary we developed in the previous lab and
the bindings share a lot of common code. This is not very convenient
to solve bugs impacting this area of the code, since we have to make
the fix at two different places.

If you have some time left at the end of this lab, use it to make this
common code part of a shared library used by both the bindings and the
binary.
