Android Architecture Essentials For Android Platform Developers
Android is an open software platform intended for use in mobile devices. It all started with Google acquiring a startup firm called Android Inc. in the year 2005. Android Inc. was a startup working towards open software framework targeting mobile platforms. Soon after the acquisition Google started building up a healthy eco-system around android platform that included Handset manufactures, Mobile operators, semiconductor companies, Application software companies. Though Android was originally envisioned and built for mobile platform; it is quickly making its way as software framework into variety of devices like Tablets, Netbooks, In-car infotainment, Televisions, Gaming consoles and other consumer electronic devices.
This Document introduces Android Architecture and presents various components with in android software framework. We will look at android framework from platform developer’s point of view.
Components of Android Stack
Android Linux Kernel
All Linux based operating system distributions for Desktop, Server, and Enterprise platforms (Ubuntu, Red hat, Novell) use open source Linux kernel as system software. Linux kernel community Maintains and releases Linux kernel sources (called “vanilla kernel “). Linux distributors are free to customize kernel sources as per the needs of target platforms. Android is no different in this aspect, it uses forked Linux kernel with android specific modifications as its system software component. Android Linux kernel contains unique facilities like wake locks, Low memory Killer, Binder, ashmem, alarm, logger, pmem, paranoid networking, and RAM console.
All the other components of Android stack rely on Andoid-ified Linux kernel and would not work on vanilla kernel images. Android Linux kernel sources along with rest of android stack are hosted by Google (https://android.googlesource.com/); there has been a long drawn discussion within Linux kernel Community on merging android patches into mainline vanilla kernel. Long debates and discussions ended with Linux Torvalds approving the merge with release Version 3.3 of the Linux kernel and is the beginning of the end of isolation between Linux kernel and android projects.
Android stack hosts a number of native libraries that directly interact with Android Linux kernel to export various kernel facilities to rest of the components. All of these libraries are implemented as shared objects (.so files). Virtual machines in Android Runtime layer (Dalvik) use Java Native Interface to access these library services.
This layer includes two categories of libraries
- Libraries implemented as part of Android Open Source Project (ASOP)
- Libraries integrated into ASOP from external open source projects.
ASOP libraries include libs like Bionic which includes services from libc.so, libmath.so, libdl.so, libstdc++.so, libthreaddb.so , Android core libs (libui.so, libgui.so, liblog.so, libandoird_runtime.so, libibinder.so, libcamera_client.so, libsystem_server.so, libandroid_server.so, libsensorservice.so, libcameraservice.so, libutils.so, libsysutils.so,libnetutils.so ..) dalvik virtual machine libs (libdvm.so, libnativehelper.so), media libs(libmediaplayerservice.so, libmedia.so,..), and Android OpenGL implementations (libEGL.so, libETC1.so, libGLESv1_CM.so, libGLESv2.so and others )
Integrated Externals libs include open SSL projects libcypto.so, libssl.so, D-Bus projects libdbus.so, libjpeg.so, sql lite database libsqlite.so and many others.
Hardware Abstraction Layer (HAL)
Under Linux Device drivers are implemented as kernel services. Driver developers can implement driver services either by linking them statically into kernel image during kernel build or load them dynamically as kernel modules when corresponding devices are found. Linux driver model exposes driver services to applications through special files called “device nodes” located in /dev. Applications and various other user land frameworks like X window system, Alsa sound libs use device files in /dev to interface with required drivers and initiate operations on corresponding hardware. (Watch more about Linux driver architecture here). Though Android depends on Linux kernel’s hardware abstraction services, its subsystems and libraries do not entirely depend on Linux driver model rather they use services of Hardware Abstraction layer. HAL contains various vendor specific shared libraries that abstract hardware access.
When Linux kernel finishes its boot operations it initializes process called init with a process id 1. Init then spawns various service daemons and other startup processes as per pre-defined system configuration. Linux Distributions for desktop generally use System V init; Embedded Linux builds often use busybox provided init. Android uses its own custom init process that starts up Android specific daemons.
Following is a partial list of android daemons started by android init
||Volume manager daemon
||Network manager daemon
||Android’s system server
||Dbus messaging daemon
||Blutetooth device management deamon
||Media server daemon
Android Runtime (The Dalvik virtual machine)
Google has chosen java as programming language and run time environment for Android Applications. Java has always been marketed as “write once, run anywhere.” The capability has largely been made possible by the Java Platform, the foundation of which is the Java Virtual Machine (JVM). Although this goal has largely been met for the Java platform on desktop (JSE) and server (JEE) environments, the mobile Java ecosystem (JME) is a bit more fragmented with various conﬁgurations, proﬁles, and packages causing signiﬁcant modiﬁcations to applications in order to support different devices. Android uses standard java compiler for compiling application sources into class files but doesn’t use standard java library and standard java runtime. Android java based applications run on Dalvik virtual machine which is implemented to run on platforms with Risc processors with limited memory and battery powered.
In standard Java environments, Java source code is compiled into Java bytecode, which is stored within .class ﬁles. The .class ﬁles are read by the JVM at runtime.On the Android platform, Java source code is still compiled into .class ﬁles. But after .class ﬁles are generated, the “dx” tool is used to convert the .class ﬁles into a .dex, or Dalvik Executable, ﬁle. Whereas a .class ﬁle contains only one class, a .dex ﬁle contains multiple classes. It is the .dex ﬁle that is executed on the Dalvik VM. The .dex ﬁle has been optimized for memory usage and the design is primarily driven by sharing of data. The Dalvik VM relies on the Linux kernel for underlying functionality such as threading and low-level memory management
Given that the Android application runtime must support a diverse set of devices and that applications must be sandboxed for security, performance, and reliability, to achieve this feat google has designed runtime to allow each and every Android application to run in its own process space, with its own instance of the Dalvik virtual machine. Dalvik has been written so that a device can run multiple VMs efﬁciently.
Since every application runs in its own instance of the VM, VM instances must be able to start quickly when a new application is launched and the memory footprint of the VM must be minimal. Android uses a concept called the Zygote to enable both sharing of code across VM instances and to provide fast startup time of new VM instances.
The Zygote is a VM process that starts at system boot time. When the Zygote process starts, it initializes a Dalvik VM, which preloads and pre-initializes core library classes.
Core java libs
Android does not support default java libraries that are distributed with JDK’s. It instead provides its own set of java library classes for Application developers. Android libraries include a subset of java libraries from open source “Apache harmony” project. Embedded Android developers do not have much to do with the java library classes.
Native Linux applications depend on Linux kernel services for access to various resources like memory, device, Processor time, file etc. Kernel services are important kernel subsystems that handle application resource allocations and perform resource management operations.
Android Applications use system services in a similar way. System services in android are core android subsystems that handle all application system resource requests. One can assume android system services to be extensions of Linux kernel services; components that we visited earlier like native libraries, startup daemons, HAL have been implemented to support Android system services through JNI interface.
Android System services are fully object oriented implementations that support remote method invocation. Android stack provides a special interface called Binder through which applications can bind a specific system service and invoke its methods through remote method invocation process.
This article introduced android architecture and various important components of it from point of view of platform developer. We will follow up this article with a series of articles on android stack and issues to be addressed by embedded android platform developers.