Book Image

Instant Android Systems Development How-to

By : Earlence Fernandes
Book Image

Instant Android Systems Development How-to

By: Earlence Fernandes

Overview of this book

<p>Android is by far the most popular open source mobile operating system. Learning to write high quality code at the platform level and learning how the systems works internally is a vital skill. This book teaches you these skills with clear and concise explanations and code examples.</p> <p>Instant Android Systems Development How-to provides a gentle introduction to the platform internals without sacrificing depth. Source code examples are designed to be meaningful, but at the same time, do not disguise their real purpose, which is to illustrate systems development techniques and common design patterns in android systems programming. Readers will be guided through several examples that give a hands-on experience.</p> <p>Readers begin by downloading the android source code, which is a topic of much discussion on android forums. They are then guided through the android boot process, and later on learn various common android systems development paradigms. More importantly, the book provides advice on when to use certain techniques which is often a mystery for the novice developer. Readers who complete the book will have high confidence in developing good systems code for Android.</p> <p>The book discusses how to setup a development machine and how to obtain the android source code and kernel code. It describes the source code organization and how the system boots up with precise references to various points in the source code. It highlights the common systems design patterns followed and how to create a custom system service. It then covers the all important flashing of phones. This is a topic of much confusion and the book provides direct steps to achieve safe flashing of developer phones. It describes the user application library mechanism and the platform library mechanism. Native code is needed for certain operations and an example service utilizing native code is explained. Modification of core system applications is explained and useful tips are provided on how to speed up the build-test cycle. The book concludes with a case study of two real world android platform extensions which give the user a reference while developing their own extensions.</p> <p>Instant Android Systems Development How-to is a well rounded book on platform internals that provides simple explanations without sacrificing depth and rigor.</p>
Table of Contents (7 chapters)
Instant Android Systems Development How-to
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Free Chapter
1
Instant Android Systems Development How-to

Writing the platform library source code (Must know)


We write simple methods to use the Data Encryption Standard (DES) to encrypt and decrypt a string using an 8-byte password. Our encryption library is named PacktPlatformLibrary.

Getting ready

Since this code is external to the framework and does not need to be tightly integrated with the system, we will place it in a separate directory called /vendor under ANDROID_SRC. Usually, inside this directory, vendor-specific files are added. Create ANDROID_SRC/vendor/PacktVendor. Inside that, include the following one-liner Android.mk file, so that subsequent make files are called during build.

Note

As of Android 4.0 and later, the platform library code can be placed under ANDROID_SRC/device/. However, the reader should note that this is not a fundamental change in the way platform libraries work and the concepts here are easily extended to later versions of the Android source code.

How to do it…

  1. We start out by writing a one-liner make file for the project. This file is saved as Android.mk and is the top-level make file:

    include $(call all-subdir-makefiles)
  2. Under PacktVendor, create a directory named PacktPlatformLibrary. Inside this we will create the platform library and write its code.

  3. Create a directory named java/packt/platformlibrary under PacktPlatformLibrary/. This will hold the source code for the library.

  4. Save the following code as PacktPlatformLibrary.java:

    package packt.platformlibrary;
    
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.spec.InvalidKeySpecException;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    
    import android.util.Log;
    
    public class PacktPlatformLibrary
    {
      private static final String TAG = "packt.PlatformLibrary";
    
             /* key has to be 8 bytes */
        public static byte [] encryptDES(String key, String data)
        {
          byte [] encr = null;
          DESKeySpec keySpec;
        try {
          keySpec = new DESKeySpec(key.getBytes("UTF8"));
          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey skey = keyFactory.generateSecret(keySpec);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            encr = cipher.doFinal(data.getBytes("UTF8"));
        } catch (InvalidKeyException e) {
          Log.e(TAG, Log.getStackTraceString(e));
        } catch (UnsupportedEncodingException e) {
          Log.e(TAG, Log.getStackTraceString(e));
        } catch (NoSuchAlgorithmException e) {
    
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (InvalidKeySpecException e) {
    
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (NoSuchPaddingException e) {
    
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (IllegalBlockSizeException e) {
    
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (BadPaddingException e) {
    
          Log.e(TAG, Log.getStackTraceString(e));
    
        }
        return encr;
    
        }
  5. The preceding method simply DES encrypts a string. You can replace the function with anything you like. The point of the example is to demonstrate a platform library:

     public static String decryptDES(String key, byte [] data)
        {
          DESKeySpec keySpec;
          byte [] unencr = null;
        try {
          keySpec = new DESKeySpec(key.getBytes("UTF8"));
          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey skey = keyFactory.generateSecret(keySpec);
            Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe
            cipher.init(Cipher.DECRYPT_MODE, skey);
            unencr = cipher.doFinal(data);
        
    } catch (InvalidKeyException e) {
          Log.e(TAG, Log.getStackTraceString(e));
        
    } catch (UnsupportedEncodingException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (NoSuchAlgorithmException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (InvalidKeySpecException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (NoSuchPaddingException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (IllegalBlockSizeException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        } catch (BadPaddingException e) {
          Log.e(TAG, Log.getStackTraceString(e));
    
        }
        return new String(unencr);
        }
    
        public static void printHex(byte [] data)
    
        {
          StringBuffer sb = new StringBuffer(); 
    
          for (int i = 0; i < data.length; i++) 
          { 
    
              sb.append(Integer.toString((data[i] & 0xff) + 0x100, 16).substring(1)); 
    
          } 
          Log.i("PacktDESTest", "DES bytes: " + sb.toString()); 
    
        }
    
    }
  6. Similarly, decryptDES performs the opposite function of encryptDES. You can again choose to replace this with a function of your choice. If you choose to do so, keep in mind that later files will have to be adjusted a bit based on the new functions. However, no change is needed in any of the build files:

    1. The Android system requires that an XML file is to be created for every new platform library. Create an XML file at ANDROID_SRC/vendor/PacktVendor/PacktPlatformLibrary/. Save this XML file as PacktPlatformLibrary.xml:

      <permissions>
        <library name="PacktPlatformLibrary" file="/system/framework/PacktPlatformLibrary.jar"/>
      
      </permissions>
    2. Finally, we need a make file to pull all the components together. Create an Android.mk file in the same directory as the preceding file:

      This code is saved as Android.mk
      
      #
      # PacktPlatformLibrary
      
      LOCAL_PATH := $(call my-dir)
      
      # the library
      # ============================================================
      include $(CLEAR_VARS)
      LOCAL_SRC_FILES := $(call all-subdir-java-files)
      LOCAL_MODULE_TAGS := optional
      # This is the target being built.
      LOCAL_MODULE:= PacktPlatformLibrary
      include $(BUILD_JAVA_LIBRARY)
      # the documentation
      # ============================================================
      include $(CLEAR_VARS)
      LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
      LOCAL_MODULE:= PacktPlatformLibrary
      
      LOCAL_DROIDDOC_OPTIONS := PacktPlatformLibrary
      
      LOCAL_MODULE_CLASS := JAVA_LIBRARIES
      LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true
      include $(BUILD_DROIDDOC)
      ########################
      
      include $(CLEAR_VARS)
      LOCAL_MODULE := PacktPlatformLibrary.xml
      LOCAL_MODULE_TAGS := optional
      LOCAL_MODULE_CLASS := ETC
      # This will install the file in /system/etc/permissions
      #
      LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
      LOCAL_SRC_FILES := $(LOCAL_MODULE)
      include $(BUILD_PREBUILT)
      

    The preceding file has three sections. The first compiles the java code for the library and creates a JAR file. The name of this JAR is specified in the LOCAL_MODULE tag. Next, if the project directory contains documentation, that is built. Finally, we need to ensure the XML file is added to /system/etc/permissions/ in the system image. LOCAL_MODULE_CLASS is used to specify this. Now, we need to build the components. On a terminal, inside ANDROID_SRC, issue the following command:

    make PacktPlatformLibrary
    

    The following command will compile the java code, generate a signed JAR, and place it in system/framework/:

    make PacktPlatformLibrary.xml
    

    This will place the XML file at /system/etc/permissions/.

How it works…

The platform library has two main components. One is the library itself, which is written in Java or C, and is packaged into a JAR (with an optional shared object if native code is used). The second component is an XML file that declares the JAR to the system as a platform library. This component is important as it helps the system to identify the location of the platform library when it is needed for loading into an application.

The module class ETC specified in the make file for the XML file is used to place files into the /system/etc directory of the firmware image.