Вы находитесь на странице: 1из 37

CARNEGIE MELLON UNIVERSITY, PITTSBURGH

Android architecture

Copyright © Karan Khanna


7/28/2010

We try to explore the architectural drivers that shaped Android, its architecture at a high level, and then try to relate each architectural
driver with various tactics that satisfy it.
CONTENTS
1. Introduction .............................................................................................................................................................................................................................................. 3
2. Architectural drivers ............................................................................................................................................................................................................................. 4
Functional goals ........................................................................................................................................................................................................................................... 4
Quality attributes: ....................................................................................................................................................................................................................................... 5
Constraints: .................................................................................................................................................................................................................................................... 7
3. Android mobile stack architecture [Dynamic view, 1st level decomposition]: ............................................................................................................. 9
4. Android mobile stack architecture [Dynamic view, 2nd level decomposition, Linux process and Android application]: ........................ 15
5. Android mobile stack architecture [Dynamic view, 3rd level decomposition, Android component: Activity]: ............................................ 22
6. Android mobile stack architecture [Dynamic view, 2nd level decomposition, application framework components]:.............................. 23
7. Android mobile stack architecture [Dynamic view, 2nd level decomposition, application framework start-up sequence]: .................. 30
8. Strategies and tactics to accomplish various architectural drivers:................................................................................................................................ 31
Security:........................................................................................................................................................................................................................................................ 31
Time Performance: .................................................................................................................................................................................................................................. 32
Extensibility: ............................................................................................................................................................................................................................................... 34
Be open source but keep GPL out of user space:.......................................................................................................................................................................... 35
Long battery life: ....................................................................................................................................................................................................................................... 35
Fitting short memory (RAM): .............................................................................................................................................................................................................. 36
9. References .............................................................................................................................................................................................................................................. 37

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 2


1. INTRODUCTION

Recent years have seen rapid evolution of mobile phones as computation platforms [beyond the basic voice telephony], which
could soon rival traditional desktop computing in many respects – Internet seems incipient. This has shifted focus of major
players in the area of general purpose desktop computing – Microsoft, Apple, and so on towards mobile computing, and we
have seen some very fine offerings like the iPhones, Andriod phones and Windows-mobile phones.

From my recent but brief introduction to Android and iPhone OS, I like to believe that in creating mobile software platforms,
existing expertise and knowledge in the area of desktop computing has been re-applied and desktop software systems have
been re-factored. It therefore becomes intriguing to explore what drives the architecture of a modern world mobile software
platform, and how these forces reshape the architecture of traditional desktop software platform to that of mobile software
platform.

There were several motivating factors to take this Independent study. Android is young, exciting product, and I wanted to
learn more about it. I also wanted to augment my architectural thinking on the lines advocated in the Architectures for software
systems course at Carnegie Mellon University. Also, there is not a comprehensive documentation yet available publicly, as far
as the architecture and design of Android is concerned. There is a set of videos from Google which give a high level insight, and
then there is an API reference plus the sample applications. While it may not be easy to search specific information from
within videos, API reference is sometimes hard to comprehend.

I hope to add more information, and make corrections to this initial draft, as my understanding of the architecture grows.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 3


2. ARCHITECTURAL DRIVERS

FUNCTIONAL GOALS

Android has been designed to meet amongst others, following larger functional goals:

• Ability to provide the basic Telephony service of making and receiving calls, along with a possibility of being
configurable for non-telephony usage, quite like the iPods and so forth.
• To serve as a robust network stack and Internet client
• To provide a comprehensive coding environment for mobile devices, giving application programmers freedom to take
advantage by developing using:
o Native code
o Managed code
o Web-browser based applications (so that applications can run on multiple phones)

[R1] Google I/O 2009 – How do I code Thee? Let me count the ways
http://developer.android.com/videos/index.html#v=GARMe7Km_gk

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 4


QUALITY ATTRIBUTES:

Security As in case of Desktops, and other mobile platforms, security against malicious code that may
cause bad user experience by bringing down the system is important. Additionally, in case of
mobile, also important is to guard against any malicious code that may cause bad user
experience by consuming unreasonable amount of battery, by making uncontrolled calls, and
accessing private user data like contacts.

Time performance [R2] The platform should provide a pleasing user experience by having short application launch
and switching times. Switching context becomes even more important in case of mobile
because of the limited display/screen real-estate, where a single user-interaction almost
always takes-up the entire screen. Consequently, moving from one step to another within a
single user task might mean rendering complete screen several times in a short period of
time. More specifically, Android sets guidelines such as:
• Browser should launch in < 1300 ms
• MMS/SMS should launch in < 700 ms
• Alarm clock should launch in < 650 ms
• When more than one application has been launched, re-launching an already-running
application must take les that the original launch time

Complete system software It should be possible to upgrade entire system software (Restart OK), without wiping out
upgrade [R2] user data. Any of the following is allowed:
• Over the air downloads with offline update via reboot
• Tethered updates via USB from a host PC
• Offline updates via reboot and update from a file on a removable storage

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 5


Extensibility • One of the fundamental requirements of Android application framework is the re-use
and replacement of components. If your application likes to integrate the ‘Google
Maps’ feature, it should be able to do so. On the other hand, if you like to make a
device version with custom home application, it should be possible to do so.
• Backward compatibility of the framework, as the platform stack is revised over time.
• It should be easy for the OEMs to port the stack to their hardware

Battery[R3] • The goal is to maximize the time before the phone battery must be recharged before it
can be used again. A minimum target cannot be specified here since how long the
battery lasts largely depends upon how the device gets used. However, there are some
statistics which can give a qualitative idea of the same:
HTC Dream has: 1150 mAh battery
Macbook PRO has: 5600 mAh battery
A 500 MHz CPU used at 100% clock-rate consumes around 100 mA
Using 3G at full rate consumes 150 mAh
Using WiFi at full rate consumes 275 mAh
Watching Youtube consumes 240 mAh
Typical usage: The phone on an average is used for 10 min/Hour, and the remaining
time phone is in the pocket.
Handling background tasks can be crucial to optimal usage of battery.

[R2] Android Compatibility Definition Document


http://static.googleusercontent.com/external_content/untrusted_dlcp/source.android.com/en/us/compatibility/android-2.1-
cdd.pdf
[R3] Google I/O 2009 – Coding for life, Battery life, That Is
http://developer.android.com/videos/index.html#v=OUemfrKe65c

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 6


CONSTRAINTS:

Memory and storage[R2][R4] As of Android 2.1: The minimum main memory (RAM) specified for Android compatibility is:
92 MB for kernel and user space applications, which is in addition to any memory dedicated
to hardware components such as radio, and so on.
In addition to this, the device must provide a non-volatile memory of 150 MB for user data
Further, there must be at-least 2GB of shared storage for applications

However, the original design also considers low end devices with 32-MB RAM, 32-MB non-
volatile storage, and 200 MHz online processor.

Open source, and keep Being open-source is one of the primary reasons for creating the Android Platform in first
General Public Licence out of place. Stakeholders believe that by exposing the complete software at source level, the
user-space platform will evolve with inputs from entire community.
However, OEMs that build Android devices sometimes might have software components
added to Android, which they would like not to open-source. Consequently, there do not have
to be any part of the Android framework in user-space, which is distributed under GPL. This
is because, anything software that uses another software distributed under GPL must itself
also be distributed under GPL.

Other hardware[R2] Android 2.1 compatibility mandates the following amongst others:
• 3-Axis accelerometer (with events at 50 Hz or more)
• 3-Axis compass (with events at 10 Hz or greater)
• GPS, and preferably assisted GPS
• Home, menu, and Back navigation keys to support Android’s navigation paradigm
• Dedicated search key

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 7


[R4] Andy Rubin’s interview snippet:
http://www.talkandroid.com/android-forums/android-hardware/2-android-minimum-hardware-requirements.html

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 8


3. ANDROID MOBILE STACK ARCHITECTURE [DYNAMIC VIEW, 1ST LEVEL DECOMPOSITION]:

Init Application framework

PM LMK BINDER ALARM ASHMEM KD LOGGER

Linux kernel

Power manager Binder AShMem Logger

Low memory killer Alarm Kernel debugger

Legend
Linux Group of Linux Linux kernel
process processes kernel module

Process A requests Kernel calls driver


services on behalf of
A some kernel/kernel
some user space A B A creates B
module service
process

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 9


Component & item catalogue: Android mobile stack architecture [Dynamic view, 1st level decomposition]

Linux kernel Android is a complete system stack and uses standard Linux kernel version 2.6.24 as its kernel. A set of
kernel drivers is added as patch to Linux kernel to be able to meet some special requirements of Android as
a whole.

Linux kernel is open source and provides:

• Memory and process management

• Permission based security model

• Proven driver model

Drivers/Linux These driver modules are the main part of the Android specific kernel patch, and include amongst others:
kernel modules*
1. Power management driver: This driver uses the existing power management capabilities, built
within the Linux kernel, and specialises them so that they are more suitable for an embedded usage.
Essentially, it implements a more aggressive policy that unless a user application specifically
requests CPU or any other hardware resources, they shall be turned off.

2. Binder IPC driver: This driver is a character driver, and all forms of IPC available to user
applications on Android are routed through, and facilitated by this driver module. It has been
optimized for embedded use in that it does not use the general purpose Java serialization for
marshalling objects but instead uses a more simplified protocol that is sufficient for system level IPC.
It also keeps track of what requests come from what processes, and when the requests are between
the objects of same process, no actual marshalling takes place, and objects are shared via shared
memory. How this exactly works is not completely clear.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 10


3. Low memory killer driver: It registers a couple of functions with the kernel, which get called
whenever kernel thinks that the RAM memory is low. These functions provided by this driver scan a
list of running processes, and kill one based on a heuristic approach, that decides the least important
process for the current circumstances. The default implementation of the Linux kernel’s OOM (out of
memory) killer has a process selection algorithm that seemingly may choose any application to be
killed under OOM condition, when there is no swap space. Android, like many other embedded
devices, does not use a swap space. Further, typical smart-phone usage is characterised by frequent
moves between applications, and this can quickly lead the system to OOM condition. Android
implementation of the algorithm meets the needs of a smart-phone usage better, by giving
preference to applications with which the user interacted more recently.

* What kind of structure is a Linux kernel Module: It is essentially a collection of C-functions, built into a
special format object file, whose code can be linked to and unlinked from the kernel at run-time. The module
does not run as a specific process. Instead, it is executed in kernel mode on behalf of the current process,
like any other statically linked kernel function.

** It must be noted that these are not the only kernel modules that the framework will depend upon, and we
have selected to show only those that were explicitly created to support the needs of Android.

Init process This is the first user space process that gets created after the kernel boots. Its role is similar to what it is on
all Desktop distributions: to launch the rest of the system, which may include things like launching various
background services and shell, etc. Linux kernel simply looks for an executable named Init at a designated
place in the root file system. Android uses a custom version of Init, that interprets a file called Init.rc and

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 11


launches rest of the framework services, applications, defines global environment variables, and so forth.

Android Init Language [/system/core/init/readme.txt]

Application This is the part where a lot of engineering effort has been spent to design a rich application framework aptly
framework suitable for mobile usage. We treat application framework as a collection of processes at this point, and we
will get into its details subsequently. Some interesting aspects about the framework are as follows:

• It is primarily supports development in Java language, but defines an essentially new run-time
environment and therefore much of the API differs from standard JDK.

• Native development is supported via Java Native Interface

• It is designed to promote synergy and collaboration amongst applications

This connector represents the user-space side interface for some operating system service, or some driver
service. Each such interface is a set of system-calls. Each time a request is made by a user-space process
to the kernel, it is done via a system call, which has semantics of call-return, and additionally, execution
transitions from user-mode into kernel-mode, executing within the context of the same process, and
returning back a result. Green symbolises that this is native/un-managed.

* While there are numerous interaction points between the application framework and the kernel, we only
show those corresponding to the driver modules that have been newly added to keep it simple. We also
distinguish between different instances of this type of connector by qualifying them with appropriate names.
Each such instance may differ from another because of the exact set of system-calls/API it exposes.

This connector represents the kernel-side interface for driver modules, which may be used to extend
kernel’s core functionality. This interface is a set of call-backs that are implemented by the driver, and are

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 12


called by the kernel, when required.

Once again, different instances are uniquely identified by the qualifying name. Each driver implements a
different functionality and therefore may implement a character driver interface or a block driver interface.
Further, there can be variations such as the number of IOCTLS implemented by each driver.

Entity A creates entity B. Although we show here that process A creates process B, we use this same
connector to also indicate entities other than processes, such as kernel, and assume that the semantics
remain same, unless explicitly noted.

Colors We have borrowed one thing in particular from Google’s diagrams as noted in their documentation: they use
red color for components that are part of kernel, green for all the user-space native code, and blue for
managed code very consistently across the board. Yellow is used for Dalvik virtual machine, and Zygote.
We try to incorporate the same color theme in our representations as strictly as possible, but there may be
points where it might not be clearly obvious what color an item must be shown. For e.g., when we show
application framework as one unified component in the diagram above, we shown it in blue indicating that it
is managed component. While it is true that essentially Android’s application framework is largely about
managed code, we also have native components within application framework. Consequently, wherever
there is such a situation, we try to make it explicitly clear in text.

Before we breakdown further into the application framework, it will be helpful to understand how Android uses a Linux process. We
will also introduce four elementary components that will form building-blocks for the complete framework, and for applications that
you as developers write for Android. And even before that, it will make sense to know the larger picture of what the fundamental
concept of applications on Android is. Here is the opening statement from developer’s page that aptly describes it:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 13


“A central feature of Android is that one application can make use of elements of other applications (provided those applications
permit it). For example, if your application needs to display a scrolling list of images and another application has developed a suitable
scroller and made it available to others, you can call upon that scroller to do the work, rather than develop your own. Your application
doesn't incorporate the code of the other application or link to it. Rather, it simply starts up that piece of the other application when
the need arises.

For this to work, the system must be able to start an application process when any part of it is needed, and instantiate the Java
objects for that part. Therefore, unlike applications on most other systems, Android applications don't have a single entry point for
everything in the application (no main() function, for example). Rather, they have essential components that the system can
instantiate and run as needed.”

http://developer.android.com/guide/topics/fundamentals.html

Assuming that there is some structural manifestation of what we will call as an Android component, let us see how a Linux process
relates to an Android application. We will have more to talk on Android components in subsequent sections.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 14


4. ANDROID MOBILE STACK ARCHITECTURE [DYNAMIC VIEW, 2ND LEVEL DECOMPOSITION, LINUX PROCESS AND ANDROID APPLICATION]:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 15


Component & item catalogue: Android mobile stack architecture [Dynamic view, 2nd level decomposition, Process
organization]

The APK file When you as a developer develop an Android application, you end up creating the Android APK file which is
capable of being installed and executed on Android. If you are familiar with other mobile development
environments, this is pretty much analogous to sisx files on Symbian platform for example. It bundles
execution-components, resources, meta-information describing application capabilities amongst other
things.

Android application Build Process:

http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/

Classes.dex This file is analogus to what you get as a JAR file in standard Java world. It is a collection of all the Java
classes, compiled to appropriate byte-code, understandable by Dalvik-virtual machine, which will eventually
run this code. Note that the byte-code is not compatible with Java’s JVM. So let us say you code defines two
classes, A and B. Then Classes.dex will contain all the code spanning both the classes.

Resources.arsc If you are familiar with any development environments, be it desktop or mobile, you probably know how
internationalization is achieved in an application. You export all your strings as a separate resource. This file
is the binary that carries all your string resources. You define your string resources as an xml file using an
Android specific structure, and the build tools translate them into a binary for memory efficiency purposes.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 16


res This directory is a collection of other resources such as icons, etc.

AndroidManifest. As the name indicates, this is application’s Manifesto:


xml
• It specifies what services the application is going to be using on Android – network, user-data, blue-
tooth and so on.

• It also specifies what activities and services, the application provides, along with special information
that allows Android to decide when to launch and run one or more components of your application.

• It determines which processes will host each of these components

• Permissions that others are required to have in order to communication with this application

Default APK By default, every APK is associated with one Linux process. All components included in that APK are
process executed in that one process, as and when required. In addition to the components that you develop and
provide for you application, the process also gets the entire execution machinery required to execute those
components. When discussing from a process perspective, we can think of all these components as run-
time objects loaded in the memory of the process. The diagram above shows a minimal set of components,
loaded into a process representing an Android application. We will discuss more about some of these next.

Bionic libc Bionic libc plays exactly the same role as any other version of libc on another platform – providing the basic
C-runtime. C-runtime is often used to refer to a collection of library routines providing common system
operations such as input and output, support to create environment for a C program to run, support to
provide arithmetic operations that may be missing in the underlying hardware, but required by the code
generated by the compiler and so forth.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 17


Android provides its own version of libc, which is not compatible with GNU libc, and also does not implement
all the POSIX features. Consequently all native code must be compiled against this version of libc. There are
several reasons for not using the standard libc on Android:

• Bionic libc is optimised for embedded use: faster and smaller (every process will have a copy of it).

• In case of Android, to best serve its business model, it was important to keep GPL out of user-space.
Any software that uses GPL must also be available under GPL. GLIBC is available under GPL.
Using a custom libc keeps the GPL out, and allows various OEMs that build Android devices to
integrate their proprietary technology within the stack without necessarily having to make it public.
For e.g., some OEM may want to use their graphics acceleration technology without making the
code public.

• Adds support specific to Android such as some logging capabilities.

There are other important native libraries that may become part of your process, depending upon whether or
not, your application needs them. Just to highlight the capabilities of Android, here is a listing of some of the
more important native libraries:

• Media Framework

• SQLite

• WebKit

• OpenGLES

• SSL

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 18


The reason to have these as native libraries is again to not to impede time performance because of the
inherent disadvantages of executing in a higher level environment within a VM.

Dalvik Virtual DVM seems to be the real power-house that has made it possible to use Java programming language and
Machine the virtual machine model feasible on an embedded device such as smart phone. There are several aspects
if the DVM design that are worth noting:

• To conserve memory: the DVM is compatible with a new executable file format called the DEX file,
analogous to Java’s JAR file. An uncompressed DEX file as per Google’s benchmark data is about
50% of the corresponding JAR file for the same set of JAVA classes. Small DEX files mean that each
process now occupies less RAM (as it loads its set of classes), and we maximize the number of
processes that can be launched given a small amount of RAM that is available for processes after
high level start-up (20-30 MB). Shared System libraries that are part of the managed code also then
occupy 50% less memory, leaving more room for processes to execute. This becomes even more
important as there is no swap-space.

• To improve execution speed: At install time, the dex file is subject to optimization, where-in, if
possible, symbolic references are replaced by simple vtable offsets, and empty methods are
removed

• Completely new byte-code format: The new byte-code is based on a register-machine model, which
closely resembles the RISC architecture such as that of ARM, which is a popular platform in the
Mobile segment. Closely mapping the execution model of VM to that of the actual underlying
processor gives an execution speed benefit.

Android Up-to this point we’ve learnt that Android breaks the traditional single entry point paradigm, and introduces
component the notion of components, which the frame-work calls into, as and when required. These components are
essentially Java objects, which provide implementations of the functions, that the Android application
framework expects. Having said that, there are essentially four categories of such components:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 19


• Activities

• Services

• Broadcast receivers

• Content provider

ActivityThread This object basically manages execution of the main thread of an application’s process, scheduling and
object executing components of that application, based on requests sent by the activity manager service (this is a
service provided by the framework, and we will visit is separately). These requests take the form of
messages called Intents, which are again Java objects. The activity thread implements a message queue
and an infinite loop that keeps reading messages from the queue as and when they are received. Each
message is interpreted, and in-turn an appropriate action is taken – typically, a method implemented by one
of the components of the application is executed. If the required component is not already loaded/
instantiated in the application process’s memory, it is loaded. Some peeking into the framework code
reveals the following sequence of steps:

• Application process is created

• ActivityThread.Main() is called

• Some mysterious application registration with run-time environment takes place

• Main thread of the new process (represented as a Thread object) is registered with ActivityManager
service.

• So that activity manager service can now run activities for this process

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 20


• gets into infinite loop listening on a message queue, for messages from activity manager

• Calls component life-cycle methods on components that you define in your application

Communication between different components of same application, or across process boundaries is


achieved essentially through asynchronous messages [again Java objects] called Intents. Often, Intents
might be accompanied with additional data called Bundle [another Java object provided by the framework].
Both Intents and Bundles implement an Interface called Parcelable, because of which they are able to
translate and save their state into something called a Parcel. A Parcel is essentially a C-Structure
representation of the protocol, which is understood by the Binder driver. Binder driver is then able to forward
this parcel to the destination process. Our green connector here represents the lowest level interaction with
the binder, of sending and receiving parcels.

The next diagram explicitly shows interactions between an Android activity and the ActivityThread as already described above. The
diagram only shows some of the lifecycle methods that are implemented by the activities.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 21


5. ANDROID MOBILE STACK ARCHITECTURE [DYNAMIC VIEW, 3RD LEVEL DECOMPOSITION, ANDROID COMPONENT: ACTIVITY]:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 22


6. ANDROID MOBILE STACK ARCHITECTURE [DYNAMIC VIEW, 2ND LEVEL DECOMPOSITION, APPLICATION FRAMEWORK COMPONENTS]:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 23


Component & item catalogue: Android mobile stack architecture [Dynamic view, 2nd level decomposition, Application
framework processes]

Daemons If you are familiar with Linux, you probably know what Linux daemons are. They are basically processes
that run in background [do not typically have a front-end] and typically listen on a socket for incoming
connections to the type of hardware service they are abstracting. In case of Android, after the kernel
has started-up, the first thing Init process does is to launch these daemon processes that provide initial
low-level access to things like USB connections, Radio Interface Layer, and so forth.

- usbd daemon manages USB connections, and keeps listening for incoming USB connections on
a socket

- adbd manages Android Debug Bridge connections. Android Debug Bridge is a debugging facility
provided to Android developers, which amongst other things, provides a remote shell log-in into
the system.

- rild daemon manages all communications with Radio Interface Layer. This would include your
3G connections, Bluetooth connections and so on.

[/hardware/ril/rild/rild.c]

Zygote This process is very specific to the design of Android application framework, and plays an important
role. Zygote is a pre-warmed copy of Dalvik virtual machine – meaning, that in addition to Dalvik Virtual
Machine, it also loads into its process memory a set of classes that is anticipated to be used more
frequently by other applications and service. As of Android 1.5, this list includes around 1150 classes.
After it is up and running, it sits on a socket listening for incoming requests to fork new processes.
Whenever a new process/application request is received, a Linux fork is done, and a new process is

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 24


created. This process keeps sharing all of its memory with the parent Zygote process, as long as it does
not do a write on any of the shared data [copy-on-write]. This way, the memory footprint of the complete
system is minimum at any given point in time. Typically, the new process will only have to load the new
classes specific to the APK that it is associated with, and any non-shared data that it may allocate.

Another benefit is that now we do not do a cold start, and launch time for applications is also minimized.

List of classes loaded: [/frameworks/base/preloaded-classes]

Zygote: [???]

runtime process This is the next process started-up after the Zygote is launched. Run-time process executes a C-
program called ServiceManager. As we discover that Android application framework is essentially
service oriented architecture, ServiceManager will essentially provide us the DNS-lookup kind of
services. All services are registered with the service manager. Any application that may need to obtain
services of a particular service must request a handle (also the proxy) to that service from the
ServiceManager.

Once the run-time process has started the ServiceManager operations successfully, it sends a message
[over socket] to Zygote to create the SystemServer process.

ServiceManager [/frameworks/base/cmds/servicemanager]

This is the first managed process in the system, and all of the core services of the Android platform live

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 25


SystemServer in this process. Each service that is started is also registered with the ServiceManger. Some of the
services started are indicated in the diagram, and others have been omitted for simplicity.

[/frameworks/base/services/java/com/android/server/SystemServer.java]

ActivityManagerService Amongst various other services, ActivityManagerService is an interesting one. It is responsible for
managing each Android component’s life-cycle. The one interesting thing that it implements is the ‘back-
stacks’ for user tasks. You will find a huge stress on the term “Task” being preferred over “application”
at various points in Android’s documentation. They insist, that a Task is what an end user experiences
as an application, and as far as application as a process/APK installed in system is concerned, a Task
may span more than one application. Consider for e.g. that the user selects the browser in the home
view. ActivityManager registers this as a new Task, and creates a stack for it. It creates and pushes the
Browser activity into this stack. The while browsing, user clicks on an address which causes the maps
activity to be launched and presented to the user. Activity manager pushes this activity on that same
task stack. When the user hits back key on the phone, the maps activity is closed, and the next in the
stack is launched at the same state where the user left it. All the activities live in the memory as long as
there is no memory crunch. Where there is one, activities from a stack that was used last by the user
may be removed from the memory.

[/frameworks/base/services/java/com/android/server/am/]

PowerManagerService PowerManager service allows applications to participate in a more aggressive power management
policy that is implemented using Android’s Power manager kernel module that we say earlier. The policy

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 26


is that unless explicitly requested, various hardware modules including the CPU shall be put to sleep
mode. Consequently, if an application such as Navigator requires that the LCD be run at its full
brightness even if there is no touch activity from user, it must explicitly ask for it. PowerManagerService
lets applications do this by introducing the concept of wakelocks. The relevant hardware module does
not go into sleep mode between the time you acquire a wake lock and when you release it.

/frameworks/base/services/java/com/android/server/PowerManagerService.java

PackageManagerService User applications typically do not use this service, but this service is important from the point of view of
operation of the system. It is used by the activity manager to obtain information about the APK files
installed on the system. Package manager maintains information about all the applications that are
installed on the device, and what their capabilities are.

We had discussed a little about Intents earlier. Intent will typically be a constant saying something like:
“start activity”, and a bundle that may have information on what activity to start. This information part
can be very precise, and can be loose. For example, a precise version could say “Activity in XYZ.APK
with MAIN intent”. When someone would have installed XYZ.APK, they would have indicated in its
AndroidMainfest.xml that activity ABC is the MAIN activity that should be launched when user presses
this APKs icon in the home view screen. A more loose version of an intent starting an activity could say
start an activity that has an Intent QRS. The packageManagerService would then try to find if there is an
activity that specifies such an Intent, and if found, ActivityManager would launch it.

/frameworks/base/services/java/com/android/server/PackageManagerService.java

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 27


Other services

There are other services like WindowManager and so on, but we will not discuss them.

This connector as we already know represents user-space side interface for an operating system call.
This specific instance represents that our process communicates with other processes via sockets API
as provided by the operating system.

We have the Daemon processes listening on specific sockets for incoming connections/requests. We
have Zygote process listening on incoming requests to fork new processes. System server is on the
other end of this communication, with its components like the ActivityManager asking Zygote to launch a
new process when they need to launch an activity whose process is not already running. Similarly, each
time a new service is started-up in the SystemServer process, it gets registered with ServiceManager
running in the runtime process.

The binder connector represents the relevant binder API used to negotiate IPC between processes.
Here we are only concerned with native API, and any managed components access it indirectly via
virtual machine’s native interface [JNI].

Applications almost always communicate with rest of the system through binder IPC. They use it to
obtain handles to various services from the ServiceManager object. Then they make remote calls to
services running in the SystemServer Process using Proxy objects.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 28


This connector represents the interface to power management API as provided by the Power manager
module via kernel. PowerManagerService would interact with this API indirectly via JNI to accomplish
wakelock requests.

Still exploring the real function of this component:

Here are some of the references:

Low memory killer:

[Why Linux default behavior might not be the best thing on a smart phone]

http://www.linuxjournal.com/article/8502

[Memory management approaches for swapless embedded systems]

http://delivery.acm.org/10.1145/1110000/1103152/8502.html?key1=1103152&key2=9699189721&coll
=GUIDE&dl=GUIDE&CFID=95698085&CFTOKEN=25750772

[What and why of a Linux OOM killer]

http://ubuntuforums.org/archive/index.php/t-617256.html

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 29


7. ANDROID MOBILE STACK ARCHITECTURE [DYNAMIC VIEW, 2ND LEVEL DECOMPOSITION, APPLICATION FRAMEWORK START-UP SEQUENCE]:

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 30


8. STRATEGIES AND TACTICS TO ACCOMPLISH VARIOUS ARCHITECTURAL DRIVERS:

SECURITY:

- Android application sand-box model: Android uses the process separation provided by Linux kernel as the primary
means of achieving isolation amongst mutually suspicious applications. Each application runs in its own Linux process.
Further, each managed piece of code executes under a virtual machine (DVM). As a result each application is sand-
boxed from the other applications running at any given time. All IPC is routed via the mechanisms provided by Binder.

- A second level of isolation builds upon the capability of underlying Linux to strongly isolate data/files of one user from
the other. This is achieved by allocating a unique user-id to each installed application on a particular system, and
setting-up user permissions such that data created by one is not seen by others.

- There are additional access permissions defined for various hardware and software resources. E.g., access to GPS,
access to BATTERY, access to shared data like the Contacts list, etc. Applications are required to explicitly seek these
permissions via their manifest files. This allows for the Application Installer (a tool that lets you install applications on the
system) to create a list of resources the application intends to make use of, and show it to user, and have their consent
to install it on system.

- Signed applications: All applications run by the Android application framework must be signed [self signing is enough].
The only reason self signing of applications exist is to establish mutual trust amongst application. Since Linux enforces
security at a process level, code from two different packages cannot normally run in same process [since they are two
different Linux users]. However, to have code from two applications run in same process, they are allowed to share the
same user ID, by making an explicit indication in the manifest file, and the system entertains this request only when the
two participating applications are signed by the same signature.

- Applications decide permissions for their data: An application can explicitly declare to have its data/files appropriate
global read/write permissions.

- Applications can create custom permissions: Custom permissions (applications can issue permissions for using
their components, data etc.)

- Binder IPC driver: This is the only means of achieving IPC, and tries to address security holes in the conventional IPC.
<Probably need to dig through the source code to explore what this exactly means>

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 31


- Native code subject to same security policy: Any native code that gets integrated via JNI is subject to same security
paradigm as the managed code. This is because native code fits into the complete application paradigm via Dalvik
virtual machine itself. So your application is still a Java application following the same model, but uses JNI to make calls
to native code that you may want to embed into your application.

TIME PERFORMANCE:

- Most of the core libraries are native libraries: Most of the CPU intensive work of the framework is accomplished
using native C/C++ libraries. Some of these are shown in the picture below:

- Native libraries for applications: As of the initial release, public libraries provided for application development are:
o Bionic libc
o libm

By public, it is meant that Android team is committed to preserve the public API between versions of Android. Native
development has been used for example in the standard distribution for suggestive text-input, and Android features a
really fine text input methods.
o A step further: these libraries have been custom written for an optimal embedded use: E.g., fast pthread
implementation using 4-byte mutex rather than the 12-byte mutex [since not as many total threads are expect as
are typical on a desktop environment]. There is no support for wide characters [Rely on UNICODE], and so forth.

- Activity manager: As we know Activity manager manages application and component life cycle. It tries to keep a
launched application for as long as possible in memory, so in the event that the user may return to it, it is launched with
minimal time overhead. Activity manager seems to work in conjunction with low memory killer, at-least on this regard.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 32


- Package manager: Maintains listing of various packages installed on the system, and their capabilities, so activity
manager’s task of identifying the right component to launch is simplified and faster as compared to each time doing a
scan on all installed APKs.

- Binder IPC driver: Since Android application framework is all about distributed components living in different
processes, it is crucial to be able to pass data back and forth between these components in a very time-efficient
manner. Binder driver is the main facilitator of IPC and is claimed to perform highly optimized (for memory and time
both) data transfers across process boundaries.
o It supports synchronous calls (with the semantics of call-return) across process boundaries.
o It uses a very scaled down version of something like Java serialization for marshalling data, which is just good
enough for system level (processes running on the same system) IPC.

- DVM: A completely new virtual machine for optimal performance with typical ARM based mobile hardware.
o Implemented as register based machine rather that a stack based machine for best performance on a RISC
architecture (ARM core).
o Optimised bytecode
o Uses fixed-width data structures so that parsing time is less

- Zygote: As we know, Zygote is a parent process with virtual machine and a set of libraries/classes that are expected to
be used by most applications, launch time of a new application that is not already in the memory is considerably
reduced.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 33


EXTENSIBILITY:

- Application framework design:


o We’ve already seen that the application framework on android is essentially about distributed components,
which mean a lot of flexibility in terms of how the framework can be configured and how new components can
build on strengths of existing ones.

- Easy porting: Most mobile OEMs have the basic drivers to control their audio, video etc. Android defines a second
hardware abstraction layer on top of kernel, and standardises Android’s interface to which the OEMs can implement
their drivers to. This hardware abstraction layer exists as a user-space C/C++ library. This probably means that Android
implements a standard interface for Audio, irrespective of the technology supported by the underlying hardware, just
asking implementations of features that it needs from the particular hardware.

- Core system applications and services allow replacement of default core system applications by third party/ custom
implementations.

- Codec extensions for audio and video: The media framework within the application framework supports a standard
OpenMax IO Interface which supports codec plug-in. This allows adding any unsupported codec and replacing software
codec implementation with hardware codec implementation.

- Possibility of using hardware acceleration, Open GL ES etc. for screen rendering

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 34


BE OPEN SOURCE BUT KEEP GPL OUT OF USER SPACE:

- libc has been customized picking from various BSD versions and g-libc which comes with GPL licence has not been
used.
- Standard codec are distributed under the Apache-2 licence.
- User space drivers for OEMs (facilitated by the additional HAL layer that sits above the kernel) so that they can keep
them closed source if they want to.

LONG BATTERY LIFE:

- Power management policy with the concept of wake-locks, which is available to the applications through the
PowerManagerService component introduced earlier, and which works in tandem with the power manager kernel
module.

- Default service behaviour: By default, services that need to perform some intermittent activities like checking the
network connectivity are only run when the system is already awake. This means, that even if that service is due for
running and system is sleeping, it will keep doing so unless another activity or condition in the system wakes it up. Once
the system is awake, the service takes the chance to execute. This is a good strategy, because it clubs together several
services running on a system to cause a single system wake-up rather than all of them causing the system to wake up
at random and asynchronous times, keeping it practically up at all times.

- Low battery notifications: Services can register for this notification, and can voluntarily decide to shut-down if the
battery is low. For example, it would make sense to shut down email checking every 10 minutes, if the battery is running
low, and be able to live to take calls until the phone dies!

- Battery meter: At-least with the 2.0 release and onwards, end users can see which applications cost the maximum
battery on their phone and can decide if they want those applications or not.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 35


FITTING SHORT MEMORY (RAM):

- Bionic libc: Has a small size: Approximately 200K, which is half the size of the glibc.

- Low memory killer: This is a special kernel module that kills the oldest application when no memory is left for an
incoming application, based on a carefully designed heuristic.

- Zygote: Zygote uses a copy-on-write strategy to allocate memory to new applications. Until a write occurs, the data
structures are shared with Zygote.

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 36


9. REFERENCES

[R1] Google I/O 2009 – How do I code Thee? Let me count the ways
http://developer.android.com/videos/index.html#v=GARMe7Km_gk

[R2] Android Compatibility Definition Document


http://static.googleusercontent.com/external_content/untrusted_dlcp/source.android.com/en/us/compatibility/android-2.1-
cdd.pdf
[R3] Google I/O 2009 – Coding for life, Battery life, That Is
http://developer.android.com/videos/index.html#v=OUemfrKe65c

[R4] Andy Rubin’s interview snippet:


http://www.talkandroid.com/android-forums/android-hardware/2-android-minimum-hardware-requirements.html

[R5] Sample code, API reference, Introduction on application framework, and lot more:
http://developer.android.com

[R5] Very helpful insights into the application framework:


http://mylifewithandroid.blogspot.com

[R6] OpenBinder IPC mechanism:


http://www.angryredplanet.com/~hackbod/openbinder/docs/html/BinderIPCMechanism.html

[R7] Android applications build process:


http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/

Copyright © Karan Khanna, Carnegie Mellon University, 2010 Page 37

Вам также может понравиться