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

Using the custom method (Should know)


We need to test our newly added method. Therefore, we make use of the PacktLibraryClient application that we created in the Writing the platform library source code recipe.

Getting ready

Open up Client.java from the PacktLibraryClient application, which is located at ANDROID_SRC/packages/apps/PacktLibraryClient/src/com/packtclient/.

How to do it...

  1. The following code represents the client code that makes use of the newly added method and is saved in a file named Client.java:

    package com.packtclient; 
    
    import packt.platformlibrary.PacktPlatformLibrary; 
    import android.app.Activity; 
    import android.app.ActivityManager; 
    import android.os.Bundle; 
    import android.util.Log; 
    
    public class Client extends Activity { 
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
    
            //byte [] encr = PacktPlatformLibrary.encryptDES("password", "Packt"); 
            //PacktPlatformLibrary.printHex(encr); 
            
            invokeNewPacktAMSMethod();       
        } 
        
        void invokeNewPacktAMSMethod() 
        { 
          ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 
          int val = am.packtSensitiveMethod(2); 
          Log.i("CustomAMS", "return: " + val); 
        } 
    }

    I have just commented the earlier code and added a method to execute packtSensitiveMethod.

  2. Now, run a full system make and start the emulator.

    Note

    Sometimes, the emulator may complain that the partition size is too small and it has to be resized. In this case, you can use the memory and partition size switches. (Note that this command will work only if you issue it in the same window in which Android was built. Otherwise, you will have to use the fully qualified paths and specify the full paths to the emulator images—kernel image, system image as well.)

    For example, emulator memory as 512 and partition-size as 1024.

  3. Launch the PacktLibraryClient application. Observe logcat. The output will be similar to the following:

    I/ActivityManager(   63): Start proc com.packtclient for activity com.packtclient/.Client: pid=344 uid=10010 gids={} 
    I/dalvikvm(   63): Jit: resizing JitTable from 512 to 1024 
    I/ARMAssembler(   63): generated scanline__00000177:03515104_00001002_00000000 [ 87 ipp] (110 ins) at [0x4386b6f0:0x4386b8a8] in 1311254 ns 
    D/AndroidRuntime(  344): Shutting down VM 
    W/dalvikvm(  344): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
    E/AndroidRuntime(  344): FATAL EXCEPTION: main 
    E/AndroidRuntime(  344): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.packtclient/com.packtclient.Client}: java.lang.SecurityException: Requires permission packt.PACKT_PERMISSION 
    E/AndroidRuntime(  344):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
    E/AndroidRuntime(  344):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
    E/AndroidRuntime(  344):   at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
    E/AndroidRuntime(  344):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 
    E/AndroidRuntime(  344):   at android.os.Handler.dispatchMessage(Handler.java:99) 
    E/AndroidRuntime(  344):   at android.os.Looper.loop(Looper.java:130) 
    E/AndroidRuntime(  344):   at android.app.ActivityThread.main(ActivityThread.java:3683) 
    E/AndroidRuntime(  344):   at java.lang.reflect.Method.invokeNative(Native Method) 
    E/AndroidRuntime(  344):   at java.lang.reflect.Method.invoke(Method.java:507) 
    E/AndroidRuntime(  344):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    E/AndroidRuntime(  344):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    E/AndroidRuntime(  344):   at dalvik.system.NativeStart.main(Native Method) 
    E/AndroidRuntime(  344): Caused by: java.lang.SecurityException: Requires permission packt.PACKT_PERMISSION 
    E/AndroidRuntime(  344):   at android.os.Parcel.readException(Parcel.java:1322) 
    E/AndroidRuntime(  344):   at android.os.Parcel.readException(Parcel.java:1276) 
    E/AndroidRuntime(  344):   at android.app.ActivityManagerProxy.packtSensitiveMethod(ActivityManagerNative.java:2918) 
    E/AndroidRuntime(  344):   at android.app.ActivityManager.packtSensitiveMethod(ActivityManager.java:1077) 
    E/AndroidRuntime(  344):   at com.packtclient.Client.invokeNewPacktAMSMethod(Client.java:28) 
    E/AndroidRuntime(  344):   at com.packtclient.Client.onCreate(Client.java:22) 
    E/AndroidRuntime(  344):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
    E/AndroidRuntime(  344):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 
    E/AndroidRuntime(  344):   ... 11 more 
    W/ActivityManager(   63):   Force finishing activity com.packtclient/.Client

    What went wrong here? On analyzing the logs, we notice that a security exception was thrown. So, our code works! The sensitive method is protected. But, if PacktLibraryClient is a legitimate application and needs access to packtSensitiveMethod, we need to do two things:

    • Grant it PACKT_PERMISSION.

    • Sign the APK with the platform certificate since the permission is a signature level permission.

      1. To do this, edit the AndroidManifest.xml file of PacktLibraryClient by adding the following tag outside the application tag:

        <uses-permission android:name="packt.PACKT_PERMISSION" />
      2. Next, edit its Android.mk file by adding the following line:

        LOCAL_CERTIFICATE := platform
        
      3. Now we will use a shortcut to quickly build the APK. In a terminal, navigate to the root of your android sources and use the following command:

        mmm packages/apps/PacktLibraryClient
        
      4. This will build the APK, but won't place it into the system image or push it into the emulator. To do this, we will remount the system partition as read/write and then push it manually. If you want to place it into the system image directly and have it rerun the emulator, use the following command:

        mmm packages/apps/PacktLibraryClient snod
        
      5. If you closed the emulator, start it again. Then drop into a shell via adb.

      6. To find out on which block device /system is mounted, use:

        cat /proc/mtd
        

        The output looks like:

        dev:    size   erasesize  name 
        mtd0: 3e100000 00020000 "system" 
        mtd1: 3e100000 00020000 "userdata" 
        mtd2: 04000000 00020000 "cache"

        Hence, /system is mtd0.

      7. To remount as read/write:

        mount -o rw,remount -t yaffs2 /dev/block/mtd0 /system
        chmod 777 /system/app
        
      8. Now exit the adb shell, and push the built APK. The APK will be available at ANDROID_SRC/out/target/product/generic/system/app.

      9. The following command will automatically reinstall the APK onto the emulator. Start the application again and observe the logs.

        adb push PacktLibraryClient.apk /system/app
        I/PACKTinAMS(   68): sensitive method called with parameter: 2 
        I/CustomAMS(  372): return: 4 
        

        We see that everything has worked fine.

How it works...

The application obtains a reference to the Activity Manager service. This reference is in the form of an ActivityManager object. The packtSensitiveMethod shim is executed in the client, which cause an RPC to be sent out to the Activity Manager service, which performs a permission check before executing the main body of the method. When our APK wasn't signed with the platform key and didn't include the correct <uses-permission> tag, this check failed and the application crashed. In the second instance, we made the appropriate changes and the permission check succeeded.