In this recipe, we will create the outline code of our custom system service. This will help us in understanding the basic mechanics and components of system services. To refresh your memory, a system service is a long running task that provides useful functionalities to Android applications. An example is the GPS services that interface with the GPS hardware and provide services such as proximity alerts.
We will add our system server code to ANDROID_SRC/frameworks/base/services/java/com/android
.
Create a directory called packt
at the preceding location. Inside that directory, create a file named PacktCrypto.java
.
PacktCrypto.java
. This is the main system service class file:package com.android.packt; import java.security.MessageDigest; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import android.util.Log; import android.os.packt.IPacktCrypto; /* Our system server provides a hashing service */ public class PacktCrypto extends IPacktCrypto.Stub { private static final String TAG = "PacktCrypto"; //use this for logging private static PacktCrypto mSelf; private PacktCrypto() { //perform one-time initialization here //if needed. } /* This is a singleton pattern. Only one instance of PacktCrypto may exist in the entire system */ public static PacktCrypto getInstance() { if(mSelf == null) mSelf = new PacktCrypto(); return mSelf; }
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
/* The interface method specified in IPacktCrypto.aidl */ 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"); } catch(Exception e) { } if(md5 != null) return md5.digest(dataBytes); else return null; } }
The preceding code block represents the system service. It extends IPacktCrypto.Stub
, which is a stub class that will be generated by the AIDL compiler when it is run on the IPacktCrypto.aidl
file. We use a singleton pattern to instantiate the class to ensure that only one object of PacktCrypto
exists in the system. We need to ensure this, as only one service will be entered into the service directory. The code also illustrates various other best practices. For example, the use of a log tag and the singleton pattern of service instantiation. These are common coding styles for system services.
At this stage, we have created an interface definition for our service, created methods to obtain a reference to the service, and also we have implemented the functionality provided by the service, that is, the hashing function.
cd android_src . build/envsetup.sh lunch select option for generic-eng make -jX where X = number of CPU cores + 2
Traditionally, proxy classes represent the code component that executes on the client side of a remote request. Likewise, stubs execute on the server side. Therefore, our system server extends IPacktCrypto.Stub
, which was generated during the build process from the IPacktCrypto.aidl
file. We also have to implement the getMD5()
interface method as it will provide the required functionality to the client. We choose to utilize the singleton pattern for our service to guarantee that only one object of the service exists in the system. This makes sense, since only one copy of the system service may exist in the service directory.
3.22.181.81