To test our native library, we need to write some Java code that will call the native function. I will re-use code from an earlier example, where we created and tested the PacktCrypto
system service.
We need to call the native code from the Java-based PacktCrypto
service. Hence, in this recipe, we will modify the PacktCrypto
system service so that it can call a native method.
Open up the PacktCrypto.java
file that is located in the services/java/com/android/packt
directory and change it by adding the following lines towards the end of the file.
To test the
sort
method, I simply call thesort()
method inside our existinggetMD5
method. I am doing this so that you can quickly test whether the native code works as expected without making too many changes. If you recall, we have already written a test harness forgetMD5
insideSystemServer.java
. The first step is to modify thePacktCrypto.java
file by adding the following lines towards the end of the file.This is a fragment of the
PacktCrypto.java
file that tests our native function:void sort(int [] data) { int [] sorted = quickSort(data); for(int i = 0; i < data.length; i++) Log.i(TAG, "s: " + sorted[i]); } native int [] quickSort(int [] data);
By adding the following lines to the
getMD5
method towards the end, we will be able to quickly test our native code. The new version ofgetMD5()
is as follows:public byte [] getMD5(String data) { byte [] dataBytes = null; MessageDigest md5 = null; try { dataBytes = data.getBytes("UTF-8"); md5 = MessageDigest.getInstance("MD5"); Log.i(TAG, "MD5 digestion invoked"); } catch(java.io.UnsupportedEncodingException uee) { Log.e(TAG, "Unsupported Encoding UTF8"); } catch(java.security.NoSuchAlgorithmException nsae) { Log.e(TAG, "No Algorithm MD5"); } //quick hack to test our native method int toSort [] = { 5, -1, 0, 30, 4, 0, 1, 3, 15, 3 }; sort(toSort); if(md5 != null) return md5.digest(dataBytes); else return null; }
Notice the call to
sort()
.Now, we can build our code. In a terminal, as usual, issue the
make
command. Once the build is complete, run the emulator and observe the logs:I/SystemServer( 67): PacktCrypto service I/PacktCrypto( 67): MD5 digestion invoked I/PacktCrypto( 67): s: -1 I/PacktCrypto( 67): s: 0 I/PacktCrypto( 67): s: 0 I/PacktCrypto( 67): s: 1 I/PacktCrypto( 67): s: 3 I/PacktCrypto( 67): s: 3 I/PacktCrypto( 67): s: 4 I/PacktCrypto( 67): s: 5 I/PacktCrypto( 67): s: 15 I/PacktCrypto( 67): s: 30 I/PacktTest( 67): MD5 sum: 422164113c2fc595dd0ab44a18925ac5
The Java code contains a native method definition. The framework loads the native code and during the onload
event, our native implementation is loaded and registered. When getMD5()
is called, our native code is executed and the output is visible on the logger.
In the next recipe, we will learn how some of the most important core Android services are organized and how to make changes to these services. We will also learn how to secure our changes with custom permissions added to the framework.
The Internet infrastructure on Android requires discussion as its design is non-conventional as compared to other services such as the Location Manager service.