SlideShare une entreprise Scribd logo
1  sur  102
Télécharger pour lire hors ligne
Low Level View of
 Android System Architecture



Jim Huang ( 黃敬群 ) <jserv@0xlab.org>
Developer, 0xlab
       Nov 17, 2012 / 横浜 Android プラットフォーム部第 26 回勉強会
Rights to copy
                                                               © Copyright 2012 0xlab
                                                                      http://0xlab.org/
                                                                      contact@0xlab.org
Attribution – ShareAlike 3.0
                                        Corrections, suggestions, contributions and translations
You are free                                                                        are welcome!
   to copy, distribute, display, and perform the work
   to make derivative works                                           Latest update: Dec 3, 2012
   to make commercial use of the work
Under the following conditions
      Attribution. You must give the original author credit.
      Share Alike. If you alter, transform, or build upon this work, you may distribute the
      resulting work only under a license identical to this one.
   For any reuse or distribution, you must make clear to others the license terms of this work.
   Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.
License text: http://creativecommons.org/licenses/by-sa/3.0/legalcode
Low Level Android ?!
It means...
the hidden part!
Binder IPC: The heart of Android




NOTE: This presentation only covers Android 4.0
NOTE: This presentation only covers Android 4.0
Android Tasks

                  Process A               Process B



        Task          Activity                Activity



                                              Content
                      Activity
                                              Provider


                                             .apk package
                      Service



                     .apk package


Our focus is the interaction among Android Activities.
Our focus is the interaction among Android Activities.
• Different component types
   – Activity
                                             Component View
   – Service
   – Content Provider
   – Broadcast Receiver




Let's recall the behavior of Android Framework.
Let's recall the behavior of Android Framework.
Application Components System

Please check 4 major component types in the object hierarchy.
Please check 4 major component types in the object hierarchy.
Context is tricky because it is indeed the abstraction of Android View
Context is tricky because it is indeed the abstraction of Android View
and Activity/Service.
and Activity/Service.
The interaction is not boring as it implies
The interaction is      boring as it implies
once if you find the right objects.
once if you find the right objects.
IPC = Inter-Process Communication




                           Activity
             Activity                   Window       Alarm
             Manager                    Manager     Manager




        Kernel




Let's get back to Binder IPC. What is the essential working model?
Let's get back to Binder IPC. What is the essential working model?
Why IPC?

• Each process has its own address space
• Provides data isolation
• Prevents harmful direct interaction between two
  different processes
   – Sometimes, communication between processes is
     required for modularization
IPC Mechanisms

• In GNU/Linux
   – Signal
   – Pipe
   – Socket
   – Semaphore
   – Message queue
   – Shared memory
• In Android
   – Binder: lightweight RPC (Remote Procedure
     Communication) mechanism


                                                 12
Binder History
• Developed under the name OpenBinder by Palm Inc.
  under the leadership of Dianne Hackborn
• Android Binder: customized and reduced
  re-implementation of OpenBinder, providing bindings
  to functions/data from one execution env to another
Background Problems

      • Applications and Services may run in separated
        processes but must communicate and share data
      • IPC can introduce significant processing overhead and
        security holes




D-Bus does suffer from such issues if socket backend is used.
D-Bus does suffer from such issues if socket backend is used.
Binder: Android's Solution

• Driver to facilitate inter-process communication
• High performance through shared memory
• Per-process thread pool for processing requests
• Reference counting, and mapping of object references
  across processes
• Synchronous calls between processes

“In the Android platform, the binder is used for
nearly everything that happens across processes
in the core platform. " – Dianne Hackborn
https://lkml.org/lkml/2009/6/25/3
IPC Abstraction

                    More abstract   • Intent
  Intent
                                       – The highest level abstraction
       AIDL                         • Inter process method invocation
                                       – AIDL: Android Interface
                                         Definition Language
           Binder
                                    • binder: kernel driver
                                    • ashmem: shared memory




Level of abstraction: Binder → AIDL → Intent
Level of abstraction: Binder → AIDL → Intent
Method invocation




                                                          caller




                                                          callee


                                                    In the same process


Think of how the typical function call works:
Think of how the typical function call works:
caller (call somebody) + callee (somebody called)
caller (call somebody) + callee (somebody called)
Inter-process method invocation


                                    caller
                                               interface



           caller

                       interface
                                        How?
          callee

                                               interface


                                    callee
How to make remote function call?
How to make remote function call?
Inter-process method invocation


                                                 caller
                                                                 interface


                                                 Proxy
           caller

                        interface             Binder in kernel

                                              Binder Thread
           callee
                                                   Stub
                                                                 interface


                                                 callee
Introduce Proxy-Stub pair along with Binder
Introduce Proxy-Stub pair along with Binder
IPC Interaction in Android
                                         (Application View)

                                           3 parts:
                                         • BnXXX: native
2   call interface   1   getService      • BpXXX: proxy
                                         • Client
                                           Invoke BpXXX




    Framework
Binder in Action

Process A            Process B
Process A
Process A                         Process B
                                          B




       1   getService



                        2   call interface
Binder Internals
Binder Terminology

• Binder
• Binder Object
   – an instance of a class that implements the Binder interface.
   – One Binder object can implement multiple Binders

• Binder Protocol
• IBinder Interface
   – is a well-defined set of methods, properties and events that
     a Binder can implement.

• Binder Token
   – A numeric value that uniquely identifies a Binder
Binder protocol is important. You don't have to take care
Binder protocol is important. You don't have to take care
about the existence of target object.
about the existence of target object.
Facilities

      •   Simple inter process messaging system
      •   Managing
      •   Identifying
      •   Calls
      •   Notification
      •   Binder as a security access token




Binder simplifies the traditional RPC by abstracting its behavior.
Binder simplifies the traditional RPC by abstracting its behavior.
• Binder framework provides more than a simple
  interprocess messaging system.
• Methods on remote objects can be called as if they
  where local object methods.
• Binder IPC facilities:
• Direct:                  • Indirect:
   – Managing                 – Binder as token
   – Identifying              – Find fd of shared
   – Calls                      memory
   – Notification
Communication protocol




If one process sends data to another process, it is called transaction.
The data is called transaction data.
Service Manager (SM)
• Special Binder node with known Binder address
• Client does not know the address of remote Binder
   – only Binder interface knows its own address
• Binder submits a name and its Binder token to SM
   – Client retrieves Binder address with service name from
     SM
Get Service list from SM
$ adb shell service list
Found 71 services:
0 stub_isms: [com.android.internal.telephony.ISms]
1 stub_phone: [com.android.internal.telephony.ITelephony]
2 stub_iphonesubinfo:
               [com.android.internal.telephony.IPhoneSubInfo]
..
5 stub_telephony.registry:
           [com.android.internal.telephony.ITelephonyRegistry]
...
7 stub_activity: [android.app.IActivityManager]
...
9 phone: [com.android.internal.telephony.ITelephony]
…
56 activity: [android.app.IActivityManager]
...
64 SurfaceFlinger: [android.ui.ISurfaceComposer]
...
Call remote method in ActivityManager
$ adb shell service list
...
56 activity: [android.app.IActivityManager]
...
$ adb shell service call activity 1598968902
Result: Parcel(
  0x00000000: 0000001c 006e0061 00720064 0069006f '....a.n.d.r.o.i.'
  0x00000010: 002e0064 00700061 002e0070 00410049 'd...a.p.p...I.A.'
  0x00000020: 00740063 00760069 00740069 004d0079 'c.t.i.v.i.t.y.M.'
  0x00000030: 006e0061 00670061 00720065 00000000 'a.n.a.g.e.r.....')




      public abstract interface IBinder {
          ...
          field public static final int INTERFACE_TRANSACTION
              = 1598968902; // 0x5f4e5446
          …
      }                          Source: frameworks/base/api/current.txt
Interact with Android Service
$ adb shell service call phone 1 s16 "123"
Result: Parcel(00000000 '....')


interface ITelephony {
    /* Dial a number. This doesn't place the call. It displays
     * the Dialer screen. */                                     Source: frameworks/base/
    void dial(String number); telephony/java/com/android/internal/telephony/ITelephony.aidl
service call SERVICE CODE [i32 INT | s16 STR] …

Options:

   i32: Write the integer INT into the send parcel.

   s16: Write the UTF-16 string STR into the send parcel.



$ adb shell service list        Phone Application appears in foreground.
Found 71 services:              parameter “1” → dial()
                                s16 "123" → String("123")
...
9 phone: [com.android.internal.telephony.ITelephony]
“I can call you after getService() from SystemManager."
“I can call you after getService() from SystemManager."
Even if you don't know the phone number (= memory address) of
Even if you don't know the phone number (= memory address) of
that girl, you can still make phone call because SM exists.
that girl, you can still make phone call because SM exists.
Binder and Android Framework
Implementation Layers of Binder



            Implemented in Java




              Implemented in C++




            Implemented in C
API Layer
• AIDL (Android Interface Definition
  Language)
   – Ease the implementation of Android
     remote services
   – Defines an interface with method of
     remote services
   – AIDL parser generates Java class
      • Proxy class for Client
      • Stub class for Service
• Java API Wrapper
     Introduce facilities to the binder
   – Wraps the middleware layer
AIDL

• Data Types
  – Java Primitives
  – Containers
      • String, List, Map, CharSequence
      • List<>
      • Multidimensional Array
  – Parcelable
  – Interface Reference
• Direction: in, out, inout
• oneway
   – android.os.IBinder.FLAG_ONEWAY
                                          38
AIDL Compiler
• Full-fledged Java(-only) Support
• Stub and Proxy Generator
  // Interface
  interface IRemoteService {
      void ping();
  }



               IRemoteService mService =           Client
                   IRemoteService.Stub.asInterface(service);



 public class RemoteService extends Service {
     public IBinder onBind(Intent intent) { return mBinder; }
     private final IRemoteService.Stub mBinder =
         new IRemoteService.Stub() {
             public void ping() { // Nothing }
     };
 }                                                 Server
                                                        39
General Architecture


                        IDL
                        Compiler


                              in args
                              operation()
 Client           OBJ
                                                 Object
                  REF     out args,
                          return



                                             IDL
                                            skeleton
            IDL            Binder
          stubs         INTERFACE                  Object Adapter


Binder
Parcels and Marshalling

• Simple inter process messaging system
• In an object oriented view, the transaction data is
  called parcel.
• The procedure of building a parcel is called
  marshalling an object.
• The procedure of rebuilding a object from a parcel is
  called unmarshalling an object.
Parcel

• Marshalling – The transferring of data across process
  boundaries
   – Represented in native binary encoding
• Mostly handled by AIDL-generated code
• Extensible – Parcelable




                                                   43
android.os.Parcel



                  Delivering arguments of method




     ”flatten”                                               ”unflatten”


                        Transmit object as FAX

Source: Inter-process communication of Android, Tetsuyuki Kobayashi
Source: Inter-process communication of Android, Tetsuyuki Kobayashi
public class TaskInfo implements android.os.Parcelable {
    public long mPss, mTotalMemory, mElapsedTime;
    public int mPid, mUid;
    public String mPackageName;           class TypeInfo as example
    TaskInfo() { ... }
    public void writeToParcel(Parcel out, int flags) { … }
    public static final Parcelable.Creator<TaskInfo>CREATOR =
        new Parcelable.Creator<TaskInfo>() { … }
    public TaskInfo createFromParcel(Parcel in) {
        return TaskInfo(in); }
    private TaskInfo(Parcel in) { … }
Application                                     Remote Service




                 Binder is the media to transmit




”flatten”                                                   ”unflatten”


                   Transmit object as FAX
Parcel Definition
• Container for a message (data and object references) that
  can be sent through an IBinder.
                                • A Parcel can contain both
                                  flattened data that will be
                                  unflattened on the other side of
                                  the IPC (using the various
                                  methods here for writing specific
                                  types, or the general Parcelable
                                  interface), and references to live
                                  IBinder objects that will result in
                                  the other side receiving a proxy
                                  IBinder connected with the
                                  original IBinder in the Parcel.
Representation of Parcel

• Parcel is not for general-purpose serialization
   – This class (and the corresponding Parcelable API
     for placing arbitrary objects into a Parcel) is
     designed as a high-performance IPC transport.
   – Not appropriate to place any Parcel data into
     persistent storage
• Functions for writing/reading primitive data types:
   – writeByte(byte) / readByte()
   – writeDouble(double) / readDouble()
   – writeFloat(float) / readFloat()
   – writeInt(int) / readInt()
   – writeLong(long) / readLong()
   – writeString(String) / readString()
Parcelable

• The Parcelable protocol provides an extremely
  efficient (but low-level) protocol for objects to write and
  read themselves from Parcels.
• Use the direct methods to write/read
   – writeParcelable(Parcelable, int)
     readParcelable(ClassLoader)
   – writeParcelableArray(T[],int)
     readParcelableArray(ClassLoader)

• These methods write both the class type and its data
  to the Parcel, allowing that class to be reconstructed
  from the appropriate class loader when later reading.
Parcelable

• Implement the Parcelable interface.
   – implement writeToParcel() and readFromParcel().
   – Note: the order in which you write properties must be the
     same as the order in which you read them.
• Add a static final property to the class with the name
  CREATOR .
   – The property needs to implement the
     android.os.Parcelable.Creator<T> interface.
• Provide a constructor for the Parcelable that knows how to
  create the object from the Parcel.
• Define a Parcelable class in an .aidl file that matches the .java
  file containing the complex type .
   – AIDL compiler will look for this file when compiling your
      AIDL files.
Bundles

• A special type-safe container, called Bundle, is
  available for key/value maps of heterogeneous values.
• This has many optimizations for improved
  performance when reading and writing data, and its
  type-safe API avoids difficult to debug type errors
  when finally marshalling the data contents into a
  Parcel.




                                                  51
RPC Implementation in Binder

Process A                                  Process B
[call remote method]                       [real method]
                                   Marshalling
                  Unmarshalling    reply
                  reply



    Marshalling                           Unmarshaling
    request                               request

                   Binder Driver
• Parcel
• Parcelable
• Bundle




"May II pack you back to my home by Parcel?"
"May pack you back to my home by Parcel?"
Middleware Layer



• Implements the user space facilities of
  the Binder framework in C++
• Implements structures and methods to
  spawn and manage new threads
• Marshalling and unmarshalling of
  specific data
• Provides interaction with the Binder
  kernel driver
• frameworks/base/include/binder/IServiceManager.h
     sp<IServiceManager> defaultServiceManager()
• frameworks/base/include/binder/IInterface.h
     template BpInterface
Kernel Driver Layer
 • Binder Driver supports the file
   operations open, mmap, release, poll
   and the system call ioctl
 • ioctl arguments
    – Binder driver command code
    – Data buffer


• Command codes
  – BINDER_WRITE_READ
  – BINDER_SET_MAX_THREADS
  – BINDER_SET_CONTEXT_MGR
  – BINDER_THREAD_EXIT
  – BINDER_VERSION
                                   56
Binder Driver

• Multi-thread aware
  – Have internal status per thead
  – Compare to UNIX socket: sockets have internal
    status per file descriptor (FD)
Binder Driver




• A pool of threads is associated to each service application to
  process incoming IPC
• Binder performs mapping of object between two processes.
• Binder uses an object reference as an address in a process’s
  memory space.
• Synchronous call, reference counting
Binder is different from UNIX socket

                  socket             binder
internal status   associated to FD   associated to PID
                                     (FD can be shared among
                                     threads in the same
                                     process)


read & write      stream I/O         done at once by
operation                            ioctl

network           Yes                No
transparency                         expected local only
$ adb cat /sys/devices/virtual/misc/binder/uevent
MAJOR=10                                            Binder
MINOR=47
DEVNAME=binder
from SM to Binder Driver

Client               Service Manager
                     service list         1
                                                       Server
      IXXX
                         Name:Handle                   onTransact(…)
  2                      Name:Handle                       thread pool
      Handle=0           Name:Handle

transact(…)


                 3            4                    5             User Space

                                                                Kernel Space

                      Binder Driver: /dev/binder

                                              memory mapping
Transaction
                                BR → BinderDriverReturnProtocol
                                BC → BinderDriverCommandProtocol



                      binder_write_read
         write_size                                 write buffer
    write_consumed
       write_buffer
        read_size
    read_consumed                                   read buffer
       read_buffer




if (ioctl(fd, BINDER_WRITE_READ, &bwt ) >= 0)
     err = NO_ERROR;
else
     err = -errno;
Transaction of Binder
                                           Process A and B have different memory space.
                                           They can not see each other.
             Kernel                             Process B
                                             Process A
                       Binder


                                 Copy memory by copy_from _user
                                 Then, wake up process B

             Kernel                               Process B
                       Binder


                                             Process A
                                 Copy memory by copy_to_user



Internally, Android uses Binder for graphics data transaction across processes.
                               It is fairly efficient.
Process A
              Process                             Process B
                                                  Process




                                Transaction




                                                           Kernel Space

                     Binder Driver: /dev/binder

Binder driver manipulates memory mapping for userspace transaction.
Binder driver manipulates memory mapping for userspace transaction.
Limitation of Binder IPC

• Binders are used to to communicate over process
  boundaries since different processes don't share a
  common VM context
   – no more direct access to each others Objects
     (memory).
• Binders are not ideal for transferring large data
  streams (like audio/video) since every object has to be
  converted to (and back from) a Parcel.




                                                    65
Binder Performance

• Good
  – Compact method index
  – Native binary marshalling
  – Support of ashmem shortcut
  – No GUID
• Bad
   – Dalvik Parcel overhead
   – ioctl() path is not optimal
   – Interface name overhead
   – Global lock

                                           66
Binder Security

• Binder’s Security Features
   – Securely Determined Client Identity
     • Binder.getCallingUid(), Binder.getCallingPid()
     • Similar to Unix Domain Socket
       getsockopt(..., SO_PEERCRED, ...)
  – Interface Reference Security
     • Client cannot guess Interface Reference
• Service Manager
   – Directory Service for System Services
• Server should check client permission
  Context.checkPermission(permission, pid, uid)


                                                        67
Binder is not ideally perfect, but it makes busy world work.
Binder is not ideally perfect, but it makes busy world work.
Binder sample program

• Build binder benchmark program
  cd system/extras/tests/binder/benchmarks
  mm
  adb push 
   ../../../../out/target/product/crespo/data/nativebenchmark/binderAddInts   
    /data/local/
• Execute
  adb shell
  su
  /data/local/binderAddInts -d 5 -n 5 &
  ps
  ...
  root      17133 16754 4568          860     ffffffff 400e6284 S
  /data/local/binderAddInts
  root      17135 17133 2520          616     00000000 400e5cb0 R
  /data/local/binderAddInts
Binder sample program

• Execute
  /data/local/binderAddInts -d 5 -n 5 &
  ps
  ...
  root      17133 16754 4568   860   ffffffff 400e6284 S
  /data/local/binderAddInts
  root      17135 17133 2520   616   00000000 400e5cb0 R
  /data/local/binderAddInts
  cat /sys/kernel/debug/binder/transaction_log
  transaction_log:3439847: call from 17133:17133 to 72:0 node
  1 handle 0 size 124:4
  transaction_log:3439850: reply from 72:72 to 17133:17133 node
  0 handle 0 size 4:0
  transaction_log:3439855: call from 17135:17135 to 17133:0
  node 3439848 handle 1 size 8:0
  ...
Binder sysfs entries

• adb shell ls /sys/kernel/debug/binder
  failed_transaction_log
  proc
  state
  stats
  transaction_log
  transactions
Activities and Services are communicating with each other by Binder!
Activities and Services are communicating with each other by Binder!
Remote Procedure Call
BINDER_WRITE_READ
• Target Method
   – handle : Remote Interface        Binder Transaction
   – ptr & cookie : Local Interface
  – code : Method ID
• Parcel - Input/Output Parameters
   – data.ptr.buffer
   – data_size
• Object Reference Management
  – data.ptr.offsets
  – offsets_size
• Security
  – sender_pid
  – sender_euid
• No Transaction GUID
  – Transparent Recursion
Object Reference Management
Service Registration and Discovery
• System service is executed by IServiceManager::addService() calls.
   – Parameter: handle to Binder Driver
• Look up the name of specific service in Binder Driver Map
   – IServiceManager::getService() returns the handle of the found
     registered services
• android.os.IBinder.INTERFACE_TRANSACTION: the actual name
Let's take a break!
Let's take a break!
Binder use case: Android Graphics
Real
                                                                               Case




Binder IPC is used for communicating between Graphics client and server.
Taken from http://www.cnblogs.com/xl19862005/archive/2011/11/17/2215363.html
Surface

  Source: frameworks/base/core/java/android/view/Surface.java
• /* Handle on to a raw buffer that is being
  managed by the screen compositor */
  public class Surface implements Parcelable {
     public Surface() {
        mCanvas = new CompatibleCanvas();
      }
      private class CompatibleCanvas
                extends Canvas { /* ... */ }
  }

 Surface instances can be written to and restored from a Parcel.
 Surface instances can be written to and restored from a Parcel.
Delivering arguments of method



”flatten”                                    ”unflatten”


                     transmit
from SurfaceFlinger to Framebuffer
from EGL to SurfaceFlinger




hgl = hardware
hgl = hardware      agl = android software
                    agl = android software
 OpenGL|ES
 OpenGL|ES          OpenGL|ES renderer
                     OpenGL|ES renderer
   Properties
                                   Android SurfaceFlinger
        Can combine 2D/3D surfaces and surfaces from multiple applications
        Surfaces passed as buffers via Binder IPC calls
        Can use OpenGL ES and 2D hardware accelerator for its compositions
             Double-buffering using page-flip
Everything is
 Everything is
around Binder
around Binder
Camera + SurfaceFlinger + Binder
Binder use case: Android Power
          Management
Base: Linux Kernel



Android does rely on Linux Kernel for core system
services
●   Memory/Process Management
●   Device Driver Model
●   sysfs, kobject/uevent, netlink
Android Kernel extensions
●   Binder                      Key Idea: Android attempts to provide
                                Key Idea: Android attempts to provide
                                    an abstraction layer between
                                     an abstraction layer between
●   android_power              hardware and the related software stack.
                               hardware and the related software stack.

     –   /sys/android_power/, /sys/power/
Android's PM Concepts
     Android PM is built on top of standard Linux Power Management.
     It can support more aggressive PM, but looks fairly simple now.
     Components make requests to keep the power on through “Wake
     Locks”.
      ●   PM does support several types of “Wake Locks”.




If there are no active wake locks, CPU will
be turned off.
If there is are partial wake locks, screen
and keyboard will be turned off.
PM State Machine
Touchscreen or keyboard user activity
Touchscreen or keyboard user activity
  event or full wake locks acquired.
  event or full wake locks acquired.




        All partial wake locks
        All partial wake locks
               released
                released

                     Partial wake locks acquired
                     Partial wake locks acquired
Design and Implementation




IBinder as interface
 IBinder as interface
  to PowerManager
   to PowerManager
Sample WakeLocks usage: AudioFlinger
•   File frameworks/base/services/audioflinger/AudioFlinger.cpp
    void AudioFlinger::ThreadBase::acquireWakeLock_l() {
        if (mPowerManager == 0) {
             sp<IBinder> binder =
                 defaultServiceManager()->checkService(String16("power"));
             if (binder == 0) {
                 LOGW("Thread %s can't connect to the PM service", mName);
             } else {
                 mPowerManager = interface_cast<IPowerManager>(binder);
                 binder->linkToDeath(mDeathRecipient);
             }
        }
        if (mPowerManager != 0) {
             sp<IBinder> binder = new BBinder();
             status_t status =
                 mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
                                                     binder, String16(mName));
             if (status == NO_ERROR) { mWakeLockToken = binder; }
             LOGV("acquireWakeLock_l() %s status %d", mName, status);
        }
    }
android_os_Power
                               frameworks/base/core/jni/android_os_Power.cpp
                               frameworks/base/core/jni/android_os_Power.cpp
...
...
static JNINativeMethod method_table[] = {
static JNINativeMethod method_table[] = {
    { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
    { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
    { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
    { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
    { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
    { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
    { "setLightBrightness", "(II)I", (void*)setLightBrightness },
    { "setLightBrightness", "(II)I", (void*)setLightBrightness },
    { "setScreenState", "(Z)I", (void*)setScreenState },
    { "setScreenState", "(Z)I", (void*)setScreenState },
    { "shutdown", "()V", (void*)android_os_Power_shutdown },
    { "shutdown", "()V", (void*)android_os_Power_shutdown },
    { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
    { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
};
};
int register_android_os_Power(JNIEnv *env)
 int register_android_os_Power(JNIEnv *env)
{{
     return AndroidRuntime::registerNativeMethods(
     return AndroidRuntime::registerNativeMethods(
         env, "android/os/Power",
         env, "android/os/Power",
         method_table, NELEM(method_table));
         method_table, NELEM(method_table));
}}



                               static void
                               static void
                               acquireWakeLock(JNIEnv *env, jobject clazz,
                               acquireWakeLock(JNIEnv *env, jobject clazz,
                                               jint lock, jstring idObj)
                                                jint lock, jstring idObj)
                               {
                               {
                                   if (idObj == NULL) {
                                   if (idObj == NULL) {
                                       throw_NullPointerException(env, "id is null");
                                       throw_NullPointerException(env, "id is null");
                                       return ;
                                       return ;
                                   }
                                   }
                                   const char *id = env->GetStringUTFChars(idObj, NULL);
                                   const char *id = env->GetStringUTFChars(idObj, NULL);
                                   acquire_wake_lock(lock, id);
                                   acquire_wake_lock(lock, id);
                                   env->ReleaseStringUTFChars(idObj, id);
                                   env->ReleaseStringUTFChars(idObj, id);
                               }
                               }
Power
                                                          hardware/libhardware_legacy/power/power.c
                                                          hardware/libhardware_legacy/power/power.c
                                                          ...
                                                          ...
                                                          int
                                                          int
                                                          acquire_wake_lock(int lock, const char* id)
                                                          acquire_wake_lock(int lock, const char* id)
                                                          {
                                                          {
                                                              initialize_fds();
                                                              initialize_fds();
const char * const OLD_PATHS[] = {
const char * const OLD_PATHS[] = {                            if (g_error) return g_error;
                                                              if (g_error) return g_error;
    "/sys/android_power/acquire_partial_wake_lock",
    "/sys/android_power/acquire_partial_wake_lock",
    "/sys/android_power/release_wake_lock",
    "/sys/android_power/release_wake_lock",                   int fd;
                                                              int fd;
    "/sys/android_power/request_state"
    "/sys/android_power/request_state"                        if (lock == PARTIAL_WAKE_LOCK) {
                                                              if (lock == PARTIAL_WAKE_LOCK) {
};
};                                                                fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
                                                                  fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
                                                              }
                                                              }
const char * const NEW_PATHS[] = {
const char * const NEW_PATHS[] = {                            else {
                                                              else {
    "/sys/power/wake_lock",
    "/sys/power/wake_lock",                                       return EINVAL;
                                                                  return EINVAL;
    "/sys/power/wake_unlock",
    "/sys/power/wake_unlock",                                 }
                                                              }
    "/sys/power/state"
    "/sys/power/state"                                        return write(fd, id, strlen(id));
                                                              return write(fd, id, strlen(id));
};
};                                                        }
                                                          }
        (Kernel interface changes in Android Cupcake)
        (Kernel interface changes in Android Cupcake)




                                                        static inline void
                                                        static inline void
                                                        initialize_fds(void)
                                                        initialize_fds(void)
                                                        {
                                                        {
                                                            if (g_initialized == 0) {
                                                            if (g_initialized == 0) {
                                                                if(open_file_descriptors(NEW_PATHS) < 0) {
                                                                if(open_file_descriptors(NEW_PATHS) < 0) {
                                                                    open_file_descriptors(OLD_PATHS);
                                                                    open_file_descriptors(OLD_PATHS);
                                                                    on_state = "wake";
                                                                    on_state = "wake";
                                                                    off_state = "standby";
                                                                    off_state = "standby";
                                                                }
                                                                }
                                                                g_initialized = 1;
                                                                g_initialized = 1;
                                                            }
                                                            }
                                                        }
                                                        }
Android PM Kernel APIs
   Source code                                   static long has_wake_lock_locked(int type)
                                                 static long has_wake_lock_locked(int type)
                                                 {
                                                 {
                                                      struct wake_lock *lock, *n;
                                                      struct wake_lock *lock, *n;
                                                      long max_timeout = 0;
                                                      long max_timeout = 0;
    ●   kernel/power/userwake.c                       BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
                                                      BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
                                                      list_for_each_entry_safe(lock, n,
                                                      list_for_each_entry_safe(lock, n,
    ●   /kernel/power/wakelock.c                                &active_wake_locks[type], link) {
                                                                 &active_wake_locks[type], link) {
                                                           if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
                                                           if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
                                                                long timeout = lock->expires - jiffies;
                                                                long timeout = lock->expires - jiffies;
                                                                if (timeout <= 0)
                                                                if (timeout <= 0)
                                                                     expire_wake_lock(lock);
                                                                      expire_wake_lock(lock);
                                                                else if (timeout > max_timeout)
                                                                else if (timeout > max_timeout)
static int power_suspend_late(
static int power_suspend_late(                                       max_timeout = timeout;
     struct platform_device *pdev,                                    max_timeout = timeout;
      struct platform_device *pdev,                        } else
                                                           } else
     pm_message_t state)
      pm_message_t state)                                       return -1;
{                                                               return -1;
{                                                     }
                                                      }
     int ret =
     int ret =                                        return max_timeout;
           has_wake_lock(WAKE_LOCK_SUSPEND) ?         return max_timeout;
           has_wake_lock(WAKE_LOCK_SUSPEND) ?    }
                                                 }
           -EAGAIN : 0;
           -EAGAIN : 0;
     return ret;
     return ret;                                 long has_wake_lock(int type)
}                                                long has_wake_lock(int type)
}                                                {
                                                 {
                                                      long ret;
                                                      long ret;
static struct platform_driver power_driver = {
static struct platform_driver power_driver = {        unsigned long irqflags;
     .driver.name = "power",                          unsigned long irqflags;
     .driver.name = "power",                          spin_lock_irqsave(&list_lock, irqflags);
                                                      spin_lock_irqsave(&list_lock, irqflags);
     .suspend_late = power_suspend_late,
     .suspend_late = power_suspend_late,              ret = has_wake_lock_locked(type);
};                                                    ret = has_wake_lock_locked(type);
};                                                    spin_unlock_irqrestore(&list_lock, irqflags);
                                                      spin_unlock_irqrestore(&list_lock, irqflags);
static struct platform_device power_device = {
static struct platform_device power_device = {        return ret;
     .name = "power",                                 return ret;
     .name = "power",                            }
                                                 }
};
};
Android PM Kernel APIs
kernel/power/wakelock.c



                          static int __init wakelocks_init(void)
                          static int __init wakelocks_init(void)
                          {
                          {
                               int ret;
                               int ret;
                               int i;
                               int i;
                              for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++)
                              for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++)
                                   INIT_LIST_HEAD(&active_wake_locks[i]);
                                   INIT_LIST_HEAD(&active_wake_locks[i]);


                              wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
                              wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
                              wake_lock(&main_wake_lock);
                              wake_lock(&main_wake_lock);
                              wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
                              wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
                              ret = platform_device_register(&power_device);
                              ret = platform_device_register(&power_device);
                              if (ret) {
                              if (ret) {
                                   pr_err("wakelocks_init: platform_device_register failedn");
                                   pr_err("wakelocks_init: platform_device_register failedn");
                                   goto err_platform_device_register;
                                   goto err_platform_device_register;
                              }
                              }
                              ret = platform_driver_register(&power_driver);
                              ret = platform_driver_register(&power_driver);
                              if (ret) {
                              if (ret) {
                                   pr_err("wakelocks_init: platform_driver_register failedn");
                                   pr_err("wakelocks_init: platform_driver_register failedn");
                                   goto err_platform_driver_register;
                                   goto err_platform_driver_register;
                              }
                              }
                              suspend_work_queue = create_singlethread_workqueue("suspend");
                              suspend_work_queue = create_singlethread_workqueue("suspend");
                              if (suspend_work_queue == NULL) {
                              if (suspend_work_queue == NULL) {
                                   ret = -ENOMEM;
                                   ret = -ENOMEM;
                                   goto err_suspend_work_queue;
                                   goto err_suspend_work_queue;
                              }
                              }
Review

•   Low-level parts
•   Process, Thread, system call
•   Memory operations
•   Binder IPC
•   interactions with frameworks
Reference

• Inter-process communication of Android, Tetsuyuki
  Kobayashi
• 淺談 Android 系統進程間通信( IPC )機制 Binder 中
  的 Server 和 Client 獲得 Service Manager 接口之路
  http://blog.goggb.com/?post=1580
• Service 與 Android 系統設計,宋寶華
• Android Binder – Android Interprocess
  Communication, Thorsten Schreiber
http://0xlab.org

Contenu connexe

Tendances

Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Opersys inc.
 

Tendances (20)

Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
 
Android Internals
Android InternalsAndroid Internals
Android Internals
 
Understanding the Android System Server
Understanding the Android System ServerUnderstanding the Android System Server
Understanding the Android System Server
 
Android Booting Sequence
Android Booting SequenceAndroid Booting Sequence
Android Booting Sequence
 
Android crash debugging
Android crash debuggingAndroid crash debugging
Android crash debugging
 
Embedded Android : System Development - Part IV (Android System Services)
Embedded Android : System Development - Part IV (Android System Services)Embedded Android : System Development - Part IV (Android System Services)
Embedded Android : System Development - Part IV (Android System Services)
 
Inter-process communication of Android
Inter-process communication of AndroidInter-process communication of Android
Inter-process communication of Android
 
Android Things : Building Embedded Devices
Android Things : Building Embedded DevicesAndroid Things : Building Embedded Devices
Android Things : Building Embedded Devices
 
Android for Embedded Linux Developers
Android for Embedded Linux DevelopersAndroid for Embedded Linux Developers
Android for Embedded Linux Developers
 
Android graphic system (SurfaceFlinger) : Design Pattern's perspective
Android graphic system (SurfaceFlinger) : Design Pattern's perspectiveAndroid graphic system (SurfaceFlinger) : Design Pattern's perspective
Android graphic system (SurfaceFlinger) : Design Pattern's perspective
 
Design and Concepts of Android Graphics
Design and Concepts of Android GraphicsDesign and Concepts of Android Graphics
Design and Concepts of Android Graphics
 
Embedded Android : System Development - Part II (Linux device drivers)
Embedded Android : System Development - Part II (Linux device drivers)Embedded Android : System Development - Part II (Linux device drivers)
Embedded Android : System Development - Part II (Linux device drivers)
 
Embedded Android : System Development - Part III
Embedded Android : System Development - Part IIIEmbedded Android : System Development - Part III
Embedded Android : System Development - Part III
 
Embedded Android : System Development - Part I
Embedded Android : System Development - Part IEmbedded Android : System Development - Part I
Embedded Android : System Development - Part I
 
Android device driver structure introduction
Android device driver structure introductionAndroid device driver structure introduction
Android device driver structure introduction
 
Android ipm 20110409
Android ipm 20110409Android ipm 20110409
Android ipm 20110409
 
Learning AOSP - Android Linux Device Driver
Learning AOSP - Android Linux Device DriverLearning AOSP - Android Linux Device Driver
Learning AOSP - Android Linux Device Driver
 
Project meeting: Android Graphics Architecture Overview
Project meeting: Android Graphics Architecture OverviewProject meeting: Android Graphics Architecture Overview
Project meeting: Android Graphics Architecture Overview
 
Embedded Android : System Development - Part II (HAL)
Embedded Android : System Development - Part II (HAL)Embedded Android : System Development - Part II (HAL)
Embedded Android : System Development - Part II (HAL)
 
Introduction to Android Window System
Introduction to Android Window SystemIntroduction to Android Window System
Introduction to Android Window System
 

En vedette

OWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
OWF12/PAUG Conf Days Android system development, maxime ripard, free electronsOWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
OWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
Paris Open Source Summit
 

En vedette (20)

Brief Tour about Android Security
Brief Tour about Android SecurityBrief Tour about Android Security
Brief Tour about Android Security
 
Understanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual MachineUnderstanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual Machine
 
Making Linux do Hard Real-time
Making Linux do Hard Real-timeMaking Linux do Hard Real-time
Making Linux do Hard Real-time
 
OWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
OWF12/PAUG Conf Days Android system development, maxime ripard, free electronsOWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
OWF12/PAUG Conf Days Android system development, maxime ripard, free electrons
 
Shorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation SystemsShorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation Systems
 
Lecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and ImplementationLecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and Implementation
 
Hints for L4 Microkernel
Hints for L4 MicrokernelHints for L4 Microkernel
Hints for L4 Microkernel
 
Implement Runtime Environments for HSA using LLVM
Implement Runtime Environments for HSA using LLVMImplement Runtime Environments for HSA using LLVM
Implement Runtime Environments for HSA using LLVM
 
olibc: Another C Library optimized for Embedded Linux
olibc: Another C Library optimized for Embedded Linuxolibc: Another C Library optimized for Embedded Linux
olibc: Another C Library optimized for Embedded Linux
 
L4 Microkernel :: Design Overview
L4 Microkernel :: Design OverviewL4 Microkernel :: Design Overview
L4 Microkernel :: Design Overview
 
Construct an Efficient and Secure Microkernel for IoT
Construct an Efficient and Secure Microkernel for IoTConstruct an Efficient and Secure Microkernel for IoT
Construct an Efficient and Secure Microkernel for IoT
 
Embedded Virtualization applied in Mobile Devices
Embedded Virtualization applied in Mobile DevicesEmbedded Virtualization applied in Mobile Devices
Embedded Virtualization applied in Mobile Devices
 
Develop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM BoardsDevelop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM Boards
 
F9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded SystemsF9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
 
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
Microkernel Evolution
Microkernel EvolutionMicrokernel Evolution
Microkernel Evolution
 
Priority Inversion on Mars
Priority Inversion on MarsPriority Inversion on Mars
Priority Inversion on Mars
 
Plan 9: Not (Only) A Better UNIX
Plan 9: Not (Only) A Better UNIXPlan 9: Not (Only) A Better UNIX
Plan 9: Not (Only) A Better UNIX
 
Hardware Accelerated 2D Rendering for Android
Hardware Accelerated 2D Rendering for AndroidHardware Accelerated 2D Rendering for Android
Hardware Accelerated 2D Rendering for Android
 

Similaire à Low Level View of Android System Architecture

Android application development
Android application developmentAndroid application development
Android application development
Linh Vi Tường
 
The missing piece : when Docker networking and services finally unleashes so...
 The missing piece : when Docker networking and services finally unleashes so... The missing piece : when Docker networking and services finally unleashes so...
The missing piece : when Docker networking and services finally unleashes so...
Adrien Blind
 
Distributed objects & components of corba
Distributed objects & components of corbaDistributed objects & components of corba
Distributed objects & components of corba
Mayuresh Wadekar
 

Similaire à Low Level View of Android System Architecture (20)

Applied Computer Science Concepts in Android
Applied Computer Science Concepts in AndroidApplied Computer Science Concepts in Android
Applied Computer Science Concepts in Android
 
Improve Android System Component Performance
Improve Android System Component PerformanceImprove Android System Component Performance
Improve Android System Component Performance
 
Android media framework overview
Android media framework overviewAndroid media framework overview
Android media framework overview
 
Android application development
Android application developmentAndroid application development
Android application development
 
Microservices
MicroservicesMicroservices
Microservices
 
BlackHat EU 2012 - Zhenhua Liu - Breeding Sandworms: How To Fuzz Your Way Out...
BlackHat EU 2012 - Zhenhua Liu - Breeding Sandworms: How To Fuzz Your Way Out...BlackHat EU 2012 - Zhenhua Liu - Breeding Sandworms: How To Fuzz Your Way Out...
BlackHat EU 2012 - Zhenhua Liu - Breeding Sandworms: How To Fuzz Your Way Out...
 
internet
internetinternet
internet
 
DockerCon - The missing piece : when Docker networking unleashes software arc...
DockerCon - The missing piece : when Docker networking unleashes software arc...DockerCon - The missing piece : when Docker networking unleashes software arc...
DockerCon - The missing piece : when Docker networking unleashes software arc...
 
The missing piece : when Docker networking and services finally unleashes so...
 The missing piece : when Docker networking and services finally unleashes so... The missing piece : when Docker networking and services finally unleashes so...
The missing piece : when Docker networking and services finally unleashes so...
 
Thick Application Penetration Testing: Crash Course
Thick Application Penetration Testing: Crash CourseThick Application Penetration Testing: Crash Course
Thick Application Penetration Testing: Crash Course
 
DockerCon EU 2015: The Missing Piece: when Docker networking unleashing soft ...
DockerCon EU 2015: The Missing Piece: when Docker networking unleashing soft ...DockerCon EU 2015: The Missing Piece: when Docker networking unleashing soft ...
DockerCon EU 2015: The Missing Piece: when Docker networking unleashing soft ...
 
Code Reuse Made Easy: Uncovering the Hidden Gems of Corporate and Open Source...
Code Reuse Made Easy: Uncovering the Hidden Gems of Corporate and Open Source...Code Reuse Made Easy: Uncovering the Hidden Gems of Corporate and Open Source...
Code Reuse Made Easy: Uncovering the Hidden Gems of Corporate and Open Source...
 
Micro-services meetup
Micro-services meetupMicro-services meetup
Micro-services meetup
 
Introductio to Docker Containers
Introductio to Docker ContainersIntroductio to Docker Containers
Introductio to Docker Containers
 
Android Developer Meetup
Android Developer MeetupAndroid Developer Meetup
Android Developer Meetup
 
IPC07 Talk - Beautiful Code with AOP and DI
IPC07 Talk - Beautiful Code with AOP and DIIPC07 Talk - Beautiful Code with AOP and DI
IPC07 Talk - Beautiful Code with AOP and DI
 
I'll See You On the Write Side of the Web
I'll See You On the Write Side of the WebI'll See You On the Write Side of the Web
I'll See You On the Write Side of the Web
 
Profiling Multicore Systems to Maximize Core Utilization
Profiling Multicore Systems to Maximize Core Utilization Profiling Multicore Systems to Maximize Core Utilization
Profiling Multicore Systems to Maximize Core Utilization
 
Deep Dive into WinRT
Deep Dive into WinRTDeep Dive into WinRT
Deep Dive into WinRT
 
Distributed objects & components of corba
Distributed objects & components of corbaDistributed objects & components of corba
Distributed objects & components of corba
 

Plus de National Cheng Kung University

Plus de National Cheng Kung University (17)

PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtime
 
2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
 
How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU ToolchainHow A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
 
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
 
從線上售票看作業系統設計議題
從線上售票看作業系統設計議題從線上售票看作業系統設計議題
從線上售票看作業系統設計議題
 
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
 
Xvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisorXvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisor
 
Making Linux do Hard Real-time
Making Linux do Hard Real-timeMaking Linux do Hard Real-time
Making Linux do Hard Real-time
 
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
 
Open Source from Legend, Business, to Ecosystem
Open Source from Legend, Business, to EcosystemOpen Source from Legend, Business, to Ecosystem
Open Source from Legend, Business, to Ecosystem
 
Summer Project: Microkernel (2013)
Summer Project: Microkernel (2013)Summer Project: Microkernel (2013)
Summer Project: Microkernel (2013)
 
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
 
Faults inside System Software
Faults inside System SoftwareFaults inside System Software
Faults inside System Software
 
Develop Your Own Operating System
Develop Your Own Operating SystemDevelop Your Own Operating System
Develop Your Own Operating System
 

Dernier

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Dernier (20)

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 

Low Level View of Android System Architecture

  • 1. Low Level View of Android System Architecture Jim Huang ( 黃敬群 ) <jserv@0xlab.org> Developer, 0xlab Nov 17, 2012 / 横浜 Android プラットフォーム部第 26 回勉強会
  • 2. Rights to copy © Copyright 2012 0xlab http://0xlab.org/ contact@0xlab.org Attribution – ShareAlike 3.0 Corrections, suggestions, contributions and translations You are free are welcome! to copy, distribute, display, and perform the work to make derivative works Latest update: Dec 3, 2012 to make commercial use of the work Under the following conditions Attribution. You must give the original author credit. Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. For any reuse or distribution, you must make clear to others the license terms of this work. Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. License text: http://creativecommons.org/licenses/by-sa/3.0/legalcode
  • 5. Binder IPC: The heart of Android NOTE: This presentation only covers Android 4.0 NOTE: This presentation only covers Android 4.0
  • 6. Android Tasks Process A Process B Task Activity Activity Content Activity Provider .apk package Service .apk package Our focus is the interaction among Android Activities. Our focus is the interaction among Android Activities.
  • 7. • Different component types – Activity Component View – Service – Content Provider – Broadcast Receiver Let's recall the behavior of Android Framework. Let's recall the behavior of Android Framework.
  • 8. Application Components System Please check 4 major component types in the object hierarchy. Please check 4 major component types in the object hierarchy. Context is tricky because it is indeed the abstraction of Android View Context is tricky because it is indeed the abstraction of Android View and Activity/Service. and Activity/Service.
  • 9. The interaction is not boring as it implies The interaction is boring as it implies once if you find the right objects. once if you find the right objects.
  • 10. IPC = Inter-Process Communication Activity Activity Window Alarm Manager Manager Manager Kernel Let's get back to Binder IPC. What is the essential working model? Let's get back to Binder IPC. What is the essential working model?
  • 11. Why IPC? • Each process has its own address space • Provides data isolation • Prevents harmful direct interaction between two different processes – Sometimes, communication between processes is required for modularization
  • 12. IPC Mechanisms • In GNU/Linux – Signal – Pipe – Socket – Semaphore – Message queue – Shared memory • In Android – Binder: lightweight RPC (Remote Procedure Communication) mechanism 12
  • 13. Binder History • Developed under the name OpenBinder by Palm Inc. under the leadership of Dianne Hackborn • Android Binder: customized and reduced re-implementation of OpenBinder, providing bindings to functions/data from one execution env to another
  • 14. Background Problems • Applications and Services may run in separated processes but must communicate and share data • IPC can introduce significant processing overhead and security holes D-Bus does suffer from such issues if socket backend is used. D-Bus does suffer from such issues if socket backend is used.
  • 15. Binder: Android's Solution • Driver to facilitate inter-process communication • High performance through shared memory • Per-process thread pool for processing requests • Reference counting, and mapping of object references across processes • Synchronous calls between processes “In the Android platform, the binder is used for nearly everything that happens across processes in the core platform. " – Dianne Hackborn https://lkml.org/lkml/2009/6/25/3
  • 16. IPC Abstraction More abstract • Intent Intent – The highest level abstraction AIDL • Inter process method invocation – AIDL: Android Interface Definition Language Binder • binder: kernel driver • ashmem: shared memory Level of abstraction: Binder → AIDL → Intent Level of abstraction: Binder → AIDL → Intent
  • 17. Method invocation caller callee In the same process Think of how the typical function call works: Think of how the typical function call works: caller (call somebody) + callee (somebody called) caller (call somebody) + callee (somebody called)
  • 18. Inter-process method invocation caller interface caller interface How? callee interface callee How to make remote function call? How to make remote function call?
  • 19. Inter-process method invocation caller interface Proxy caller interface Binder in kernel Binder Thread callee Stub interface callee Introduce Proxy-Stub pair along with Binder Introduce Proxy-Stub pair along with Binder
  • 20. IPC Interaction in Android (Application View) 3 parts: • BnXXX: native 2 call interface 1 getService • BpXXX: proxy • Client Invoke BpXXX Framework
  • 22. Process A Process A Process B B 1 getService 2 call interface
  • 24. Binder Terminology • Binder • Binder Object – an instance of a class that implements the Binder interface. – One Binder object can implement multiple Binders • Binder Protocol • IBinder Interface – is a well-defined set of methods, properties and events that a Binder can implement. • Binder Token – A numeric value that uniquely identifies a Binder
  • 25. Binder protocol is important. You don't have to take care Binder protocol is important. You don't have to take care about the existence of target object. about the existence of target object.
  • 26. Facilities • Simple inter process messaging system • Managing • Identifying • Calls • Notification • Binder as a security access token Binder simplifies the traditional RPC by abstracting its behavior. Binder simplifies the traditional RPC by abstracting its behavior.
  • 27. • Binder framework provides more than a simple interprocess messaging system. • Methods on remote objects can be called as if they where local object methods.
  • 28. • Binder IPC facilities: • Direct: • Indirect: – Managing – Binder as token – Identifying – Find fd of shared – Calls memory – Notification
  • 29. Communication protocol If one process sends data to another process, it is called transaction. The data is called transaction data.
  • 30. Service Manager (SM) • Special Binder node with known Binder address • Client does not know the address of remote Binder – only Binder interface knows its own address • Binder submits a name and its Binder token to SM – Client retrieves Binder address with service name from SM
  • 31. Get Service list from SM $ adb shell service list Found 71 services: 0 stub_isms: [com.android.internal.telephony.ISms] 1 stub_phone: [com.android.internal.telephony.ITelephony] 2 stub_iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo] .. 5 stub_telephony.registry: [com.android.internal.telephony.ITelephonyRegistry] ... 7 stub_activity: [android.app.IActivityManager] ... 9 phone: [com.android.internal.telephony.ITelephony] … 56 activity: [android.app.IActivityManager] ... 64 SurfaceFlinger: [android.ui.ISurfaceComposer] ...
  • 32. Call remote method in ActivityManager $ adb shell service list ... 56 activity: [android.app.IActivityManager] ... $ adb shell service call activity 1598968902 Result: Parcel( 0x00000000: 0000001c 006e0061 00720064 0069006f '....a.n.d.r.o.i.' 0x00000010: 002e0064 00700061 002e0070 00410049 'd...a.p.p...I.A.' 0x00000020: 00740063 00760069 00740069 004d0079 'c.t.i.v.i.t.y.M.' 0x00000030: 006e0061 00670061 00720065 00000000 'a.n.a.g.e.r.....') public abstract interface IBinder { ... field public static final int INTERFACE_TRANSACTION = 1598968902; // 0x5f4e5446 … } Source: frameworks/base/api/current.txt
  • 33. Interact with Android Service $ adb shell service call phone 1 s16 "123" Result: Parcel(00000000 '....') interface ITelephony { /* Dial a number. This doesn't place the call. It displays * the Dialer screen. */ Source: frameworks/base/ void dial(String number); telephony/java/com/android/internal/telephony/ITelephony.aidl service call SERVICE CODE [i32 INT | s16 STR] … Options: i32: Write the integer INT into the send parcel. s16: Write the UTF-16 string STR into the send parcel. $ adb shell service list Phone Application appears in foreground. Found 71 services: parameter “1” → dial() s16 "123" → String("123") ... 9 phone: [com.android.internal.telephony.ITelephony]
  • 34. “I can call you after getService() from SystemManager." “I can call you after getService() from SystemManager." Even if you don't know the phone number (= memory address) of Even if you don't know the phone number (= memory address) of that girl, you can still make phone call because SM exists. that girl, you can still make phone call because SM exists.
  • 35. Binder and Android Framework
  • 36. Implementation Layers of Binder Implemented in Java Implemented in C++ Implemented in C
  • 37. API Layer • AIDL (Android Interface Definition Language) – Ease the implementation of Android remote services – Defines an interface with method of remote services – AIDL parser generates Java class • Proxy class for Client • Stub class for Service • Java API Wrapper Introduce facilities to the binder – Wraps the middleware layer
  • 38. AIDL • Data Types – Java Primitives – Containers • String, List, Map, CharSequence • List<> • Multidimensional Array – Parcelable – Interface Reference • Direction: in, out, inout • oneway – android.os.IBinder.FLAG_ONEWAY 38
  • 39. AIDL Compiler • Full-fledged Java(-only) Support • Stub and Proxy Generator // Interface interface IRemoteService { void ping(); } IRemoteService mService = Client IRemoteService.Stub.asInterface(service); public class RemoteService extends Service { public IBinder onBind(Intent intent) { return mBinder; } private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { public void ping() { // Nothing } }; } Server 39
  • 40. General Architecture IDL Compiler in args operation() Client OBJ Object REF out args, return IDL skeleton IDL Binder stubs INTERFACE Object Adapter Binder
  • 41.
  • 42. Parcels and Marshalling • Simple inter process messaging system • In an object oriented view, the transaction data is called parcel. • The procedure of building a parcel is called marshalling an object. • The procedure of rebuilding a object from a parcel is called unmarshalling an object.
  • 43. Parcel • Marshalling – The transferring of data across process boundaries – Represented in native binary encoding • Mostly handled by AIDL-generated code • Extensible – Parcelable 43
  • 44. android.os.Parcel Delivering arguments of method ”flatten” ”unflatten” Transmit object as FAX Source: Inter-process communication of Android, Tetsuyuki Kobayashi Source: Inter-process communication of Android, Tetsuyuki Kobayashi
  • 45. public class TaskInfo implements android.os.Parcelable { public long mPss, mTotalMemory, mElapsedTime; public int mPid, mUid; public String mPackageName; class TypeInfo as example TaskInfo() { ... } public void writeToParcel(Parcel out, int flags) { … } public static final Parcelable.Creator<TaskInfo>CREATOR = new Parcelable.Creator<TaskInfo>() { … } public TaskInfo createFromParcel(Parcel in) { return TaskInfo(in); } private TaskInfo(Parcel in) { … }
  • 46. Application Remote Service Binder is the media to transmit ”flatten” ”unflatten” Transmit object as FAX
  • 47. Parcel Definition • Container for a message (data and object references) that can be sent through an IBinder. • A Parcel can contain both flattened data that will be unflattened on the other side of the IPC (using the various methods here for writing specific types, or the general Parcelable interface), and references to live IBinder objects that will result in the other side receiving a proxy IBinder connected with the original IBinder in the Parcel.
  • 48. Representation of Parcel • Parcel is not for general-purpose serialization – This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. – Not appropriate to place any Parcel data into persistent storage • Functions for writing/reading primitive data types: – writeByte(byte) / readByte() – writeDouble(double) / readDouble() – writeFloat(float) / readFloat() – writeInt(int) / readInt() – writeLong(long) / readLong() – writeString(String) / readString()
  • 49. Parcelable • The Parcelable protocol provides an extremely efficient (but low-level) protocol for objects to write and read themselves from Parcels. • Use the direct methods to write/read – writeParcelable(Parcelable, int) readParcelable(ClassLoader) – writeParcelableArray(T[],int) readParcelableArray(ClassLoader) • These methods write both the class type and its data to the Parcel, allowing that class to be reconstructed from the appropriate class loader when later reading.
  • 50. Parcelable • Implement the Parcelable interface. – implement writeToParcel() and readFromParcel(). – Note: the order in which you write properties must be the same as the order in which you read them. • Add a static final property to the class with the name CREATOR . – The property needs to implement the android.os.Parcelable.Creator<T> interface. • Provide a constructor for the Parcelable that knows how to create the object from the Parcel. • Define a Parcelable class in an .aidl file that matches the .java file containing the complex type . – AIDL compiler will look for this file when compiling your AIDL files.
  • 51. Bundles • A special type-safe container, called Bundle, is available for key/value maps of heterogeneous values. • This has many optimizations for improved performance when reading and writing data, and its type-safe API avoids difficult to debug type errors when finally marshalling the data contents into a Parcel. 51
  • 52. RPC Implementation in Binder Process A Process B [call remote method] [real method] Marshalling Unmarshalling reply reply Marshalling Unmarshaling request request Binder Driver
  • 53. • Parcel • Parcelable • Bundle "May II pack you back to my home by Parcel?" "May pack you back to my home by Parcel?"
  • 54. Middleware Layer • Implements the user space facilities of the Binder framework in C++ • Implements structures and methods to spawn and manage new threads • Marshalling and unmarshalling of specific data • Provides interaction with the Binder kernel driver
  • 55. • frameworks/base/include/binder/IServiceManager.h sp<IServiceManager> defaultServiceManager() • frameworks/base/include/binder/IInterface.h template BpInterface
  • 56. Kernel Driver Layer • Binder Driver supports the file operations open, mmap, release, poll and the system call ioctl • ioctl arguments – Binder driver command code – Data buffer • Command codes – BINDER_WRITE_READ – BINDER_SET_MAX_THREADS – BINDER_SET_CONTEXT_MGR – BINDER_THREAD_EXIT – BINDER_VERSION 56
  • 57. Binder Driver • Multi-thread aware – Have internal status per thead – Compare to UNIX socket: sockets have internal status per file descriptor (FD)
  • 58. Binder Driver • A pool of threads is associated to each service application to process incoming IPC • Binder performs mapping of object between two processes. • Binder uses an object reference as an address in a process’s memory space. • Synchronous call, reference counting
  • 59. Binder is different from UNIX socket socket binder internal status associated to FD associated to PID (FD can be shared among threads in the same process) read & write stream I/O done at once by operation ioctl network Yes No transparency expected local only
  • 60. $ adb cat /sys/devices/virtual/misc/binder/uevent MAJOR=10 Binder MINOR=47 DEVNAME=binder
  • 61. from SM to Binder Driver Client Service Manager service list 1 Server IXXX Name:Handle onTransact(…) 2 Name:Handle thread pool Handle=0 Name:Handle transact(…) 3 4 5 User Space Kernel Space Binder Driver: /dev/binder memory mapping
  • 62. Transaction BR → BinderDriverReturnProtocol BC → BinderDriverCommandProtocol binder_write_read write_size write buffer write_consumed write_buffer read_size read_consumed read buffer read_buffer if (ioctl(fd, BINDER_WRITE_READ, &bwt ) >= 0) err = NO_ERROR; else err = -errno;
  • 63. Transaction of Binder Process A and B have different memory space. They can not see each other. Kernel Process B Process A Binder Copy memory by copy_from _user Then, wake up process B Kernel Process B Binder Process A Copy memory by copy_to_user Internally, Android uses Binder for graphics data transaction across processes. It is fairly efficient.
  • 64. Process A Process Process B Process Transaction Kernel Space Binder Driver: /dev/binder Binder driver manipulates memory mapping for userspace transaction. Binder driver manipulates memory mapping for userspace transaction.
  • 65. Limitation of Binder IPC • Binders are used to to communicate over process boundaries since different processes don't share a common VM context – no more direct access to each others Objects (memory). • Binders are not ideal for transferring large data streams (like audio/video) since every object has to be converted to (and back from) a Parcel. 65
  • 66. Binder Performance • Good – Compact method index – Native binary marshalling – Support of ashmem shortcut – No GUID • Bad – Dalvik Parcel overhead – ioctl() path is not optimal – Interface name overhead – Global lock 66
  • 67. Binder Security • Binder’s Security Features – Securely Determined Client Identity • Binder.getCallingUid(), Binder.getCallingPid() • Similar to Unix Domain Socket getsockopt(..., SO_PEERCRED, ...) – Interface Reference Security • Client cannot guess Interface Reference • Service Manager – Directory Service for System Services • Server should check client permission Context.checkPermission(permission, pid, uid) 67
  • 68. Binder is not ideally perfect, but it makes busy world work. Binder is not ideally perfect, but it makes busy world work.
  • 69. Binder sample program • Build binder benchmark program cd system/extras/tests/binder/benchmarks mm adb push ../../../../out/target/product/crespo/data/nativebenchmark/binderAddInts /data/local/ • Execute adb shell su /data/local/binderAddInts -d 5 -n 5 & ps ... root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts
  • 70. Binder sample program • Execute /data/local/binderAddInts -d 5 -n 5 & ps ... root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts cat /sys/kernel/debug/binder/transaction_log transaction_log:3439847: call from 17133:17133 to 72:0 node 1 handle 0 size 124:4 transaction_log:3439850: reply from 72:72 to 17133:17133 node 0 handle 0 size 4:0 transaction_log:3439855: call from 17135:17135 to 17133:0 node 3439848 handle 1 size 8:0 ...
  • 71. Binder sysfs entries • adb shell ls /sys/kernel/debug/binder failed_transaction_log proc state stats transaction_log transactions
  • 72. Activities and Services are communicating with each other by Binder! Activities and Services are communicating with each other by Binder!
  • 75. • Target Method – handle : Remote Interface Binder Transaction – ptr & cookie : Local Interface – code : Method ID • Parcel - Input/Output Parameters – data.ptr.buffer – data_size • Object Reference Management – data.ptr.offsets – offsets_size • Security – sender_pid – sender_euid • No Transaction GUID – Transparent Recursion
  • 77. Service Registration and Discovery • System service is executed by IServiceManager::addService() calls. – Parameter: handle to Binder Driver • Look up the name of specific service in Binder Driver Map – IServiceManager::getService() returns the handle of the found registered services • android.os.IBinder.INTERFACE_TRANSACTION: the actual name
  • 78. Let's take a break! Let's take a break!
  • 79. Binder use case: Android Graphics
  • 80. Real Case Binder IPC is used for communicating between Graphics client and server. Taken from http://www.cnblogs.com/xl19862005/archive/2011/11/17/2215363.html
  • 81. Surface Source: frameworks/base/core/java/android/view/Surface.java • /* Handle on to a raw buffer that is being managed by the screen compositor */ public class Surface implements Parcelable { public Surface() { mCanvas = new CompatibleCanvas(); } private class CompatibleCanvas extends Canvas { /* ... */ } } Surface instances can be written to and restored from a Parcel. Surface instances can be written to and restored from a Parcel.
  • 82. Delivering arguments of method ”flatten” ”unflatten” transmit
  • 83. from SurfaceFlinger to Framebuffer
  • 84. from EGL to SurfaceFlinger hgl = hardware hgl = hardware agl = android software agl = android software OpenGL|ES OpenGL|ES OpenGL|ES renderer OpenGL|ES renderer
  • 85.
  • 86. Properties Android SurfaceFlinger  Can combine 2D/3D surfaces and surfaces from multiple applications  Surfaces passed as buffers via Binder IPC calls  Can use OpenGL ES and 2D hardware accelerator for its compositions  Double-buffering using page-flip
  • 87. Everything is Everything is around Binder around Binder
  • 89. Binder use case: Android Power Management
  • 90. Base: Linux Kernel Android does rely on Linux Kernel for core system services ● Memory/Process Management ● Device Driver Model ● sysfs, kobject/uevent, netlink Android Kernel extensions ● Binder Key Idea: Android attempts to provide Key Idea: Android attempts to provide an abstraction layer between an abstraction layer between ● android_power hardware and the related software stack. hardware and the related software stack. – /sys/android_power/, /sys/power/
  • 91. Android's PM Concepts Android PM is built on top of standard Linux Power Management. It can support more aggressive PM, but looks fairly simple now. Components make requests to keep the power on through “Wake Locks”. ● PM does support several types of “Wake Locks”. If there are no active wake locks, CPU will be turned off. If there is are partial wake locks, screen and keyboard will be turned off.
  • 92.
  • 93. PM State Machine Touchscreen or keyboard user activity Touchscreen or keyboard user activity event or full wake locks acquired. event or full wake locks acquired. All partial wake locks All partial wake locks released released Partial wake locks acquired Partial wake locks acquired
  • 94. Design and Implementation IBinder as interface IBinder as interface to PowerManager to PowerManager
  • 95. Sample WakeLocks usage: AudioFlinger • File frameworks/base/services/audioflinger/AudioFlinger.cpp void AudioFlinger::ThreadBase::acquireWakeLock_l() { if (mPowerManager == 0) { sp<IBinder> binder = defaultServiceManager()->checkService(String16("power")); if (binder == 0) { LOGW("Thread %s can't connect to the PM service", mName); } else { mPowerManager = interface_cast<IPowerManager>(binder); binder->linkToDeath(mDeathRecipient); } } if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, binder, String16(mName)); if (status == NO_ERROR) { mWakeLockToken = binder; } LOGV("acquireWakeLock_l() %s status %d", mName, status); } }
  • 96. android_os_Power frameworks/base/core/jni/android_os_Power.cpp frameworks/base/core/jni/android_os_Power.cpp ... ... static JNINativeMethod method_table[] = { static JNINativeMethod method_table[] = { { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setLightBrightness", "(II)I", (void*)setLightBrightness }, { "setLightBrightness", "(II)I", (void*)setLightBrightness }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, }; }; int register_android_os_Power(JNIEnv *env) int register_android_os_Power(JNIEnv *env) {{ return AndroidRuntime::registerNativeMethods( return AndroidRuntime::registerNativeMethods( env, "android/os/Power", env, "android/os/Power", method_table, NELEM(method_table)); method_table, NELEM(method_table)); }} static void static void acquireWakeLock(JNIEnv *env, jobject clazz, acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) jint lock, jstring idObj) { { if (idObj == NULL) { if (idObj == NULL) { throw_NullPointerException(env, "id is null"); throw_NullPointerException(env, "id is null"); return ; return ; } } const char *id = env->GetStringUTFChars(idObj, NULL); const char *id = env->GetStringUTFChars(idObj, NULL); acquire_wake_lock(lock, id); acquire_wake_lock(lock, id); env->ReleaseStringUTFChars(idObj, id); env->ReleaseStringUTFChars(idObj, id); } }
  • 97. Power hardware/libhardware_legacy/power/power.c hardware/libhardware_legacy/power/power.c ... ... int int acquire_wake_lock(int lock, const char* id) acquire_wake_lock(int lock, const char* id) { { initialize_fds(); initialize_fds(); const char * const OLD_PATHS[] = { const char * const OLD_PATHS[] = { if (g_error) return g_error; if (g_error) return g_error; "/sys/android_power/acquire_partial_wake_lock", "/sys/android_power/acquire_partial_wake_lock", "/sys/android_power/release_wake_lock", "/sys/android_power/release_wake_lock", int fd; int fd; "/sys/android_power/request_state" "/sys/android_power/request_state" if (lock == PARTIAL_WAKE_LOCK) { if (lock == PARTIAL_WAKE_LOCK) { }; }; fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; } } const char * const NEW_PATHS[] = { const char * const NEW_PATHS[] = { else { else { "/sys/power/wake_lock", "/sys/power/wake_lock", return EINVAL; return EINVAL; "/sys/power/wake_unlock", "/sys/power/wake_unlock", } } "/sys/power/state" "/sys/power/state" return write(fd, id, strlen(id)); return write(fd, id, strlen(id)); }; }; } } (Kernel interface changes in Android Cupcake) (Kernel interface changes in Android Cupcake) static inline void static inline void initialize_fds(void) initialize_fds(void) { { if (g_initialized == 0) { if (g_initialized == 0) { if(open_file_descriptors(NEW_PATHS) < 0) { if(open_file_descriptors(NEW_PATHS) < 0) { open_file_descriptors(OLD_PATHS); open_file_descriptors(OLD_PATHS); on_state = "wake"; on_state = "wake"; off_state = "standby"; off_state = "standby"; } } g_initialized = 1; g_initialized = 1; } } } }
  • 98. Android PM Kernel APIs Source code static long has_wake_lock_locked(int type) static long has_wake_lock_locked(int type) { { struct wake_lock *lock, *n; struct wake_lock *lock, *n; long max_timeout = 0; long max_timeout = 0; ● kernel/power/userwake.c BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); list_for_each_entry_safe(lock, n, list_for_each_entry_safe(lock, n, ● /kernel/power/wakelock.c &active_wake_locks[type], link) { &active_wake_locks[type], link) { if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { long timeout = lock->expires - jiffies; long timeout = lock->expires - jiffies; if (timeout <= 0) if (timeout <= 0) expire_wake_lock(lock); expire_wake_lock(lock); else if (timeout > max_timeout) else if (timeout > max_timeout) static int power_suspend_late( static int power_suspend_late( max_timeout = timeout; struct platform_device *pdev, max_timeout = timeout; struct platform_device *pdev, } else } else pm_message_t state) pm_message_t state) return -1; { return -1; { } } int ret = int ret = return max_timeout; has_wake_lock(WAKE_LOCK_SUSPEND) ? return max_timeout; has_wake_lock(WAKE_LOCK_SUSPEND) ? } } -EAGAIN : 0; -EAGAIN : 0; return ret; return ret; long has_wake_lock(int type) } long has_wake_lock(int type) } { { long ret; long ret; static struct platform_driver power_driver = { static struct platform_driver power_driver = { unsigned long irqflags; .driver.name = "power", unsigned long irqflags; .driver.name = "power", spin_lock_irqsave(&list_lock, irqflags); spin_lock_irqsave(&list_lock, irqflags); .suspend_late = power_suspend_late, .suspend_late = power_suspend_late, ret = has_wake_lock_locked(type); }; ret = has_wake_lock_locked(type); }; spin_unlock_irqrestore(&list_lock, irqflags); spin_unlock_irqrestore(&list_lock, irqflags); static struct platform_device power_device = { static struct platform_device power_device = { return ret; .name = "power", return ret; .name = "power", } } }; };
  • 99. Android PM Kernel APIs kernel/power/wakelock.c static int __init wakelocks_init(void) static int __init wakelocks_init(void) { { int ret; int ret; int i; int i; for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) INIT_LIST_HEAD(&active_wake_locks[i]); INIT_LIST_HEAD(&active_wake_locks[i]); wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); wake_lock(&main_wake_lock); wake_lock(&main_wake_lock); wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); ret = platform_device_register(&power_device); ret = platform_device_register(&power_device); if (ret) { if (ret) { pr_err("wakelocks_init: platform_device_register failedn"); pr_err("wakelocks_init: platform_device_register failedn"); goto err_platform_device_register; goto err_platform_device_register; } } ret = platform_driver_register(&power_driver); ret = platform_driver_register(&power_driver); if (ret) { if (ret) { pr_err("wakelocks_init: platform_driver_register failedn"); pr_err("wakelocks_init: platform_driver_register failedn"); goto err_platform_driver_register; goto err_platform_driver_register; } } suspend_work_queue = create_singlethread_workqueue("suspend"); suspend_work_queue = create_singlethread_workqueue("suspend"); if (suspend_work_queue == NULL) { if (suspend_work_queue == NULL) { ret = -ENOMEM; ret = -ENOMEM; goto err_suspend_work_queue; goto err_suspend_work_queue; } }
  • 100. Review • Low-level parts • Process, Thread, system call • Memory operations • Binder IPC • interactions with frameworks
  • 101. Reference • Inter-process communication of Android, Tetsuyuki Kobayashi • 淺談 Android 系統進程間通信( IPC )機制 Binder 中 的 Server 和 Client 獲得 Service Manager 接口之路 http://blog.goggb.com/?post=1580 • Service 與 Android 系統設計,宋寶華 • Android Binder – Android Interprocess Communication, Thorsten Schreiber