Archive for February, 2011

How does Dalvik worked in Android?

First we take a look at the non-Dalvik process (via “adb shell” and “ps” to identify the processes, and then “cat /proc/xxxx/” to go to the specific running process. For example, for ServiceManager, the virtual memory layout gives:

# cat maps
00008000-0000a000 r-xp 00000000 1f:00 405 /system/bin/servicemanager
0000a000-0000b000 rwxp 00002000 1f:00 405 /system/bin/servicemanager
0000b000-0000c000 rwxp 0000b000 00:00 0 [heap]
40000000-40008000 r-xs 00000000 00:07 187 /dev/ashmem/system_properties (deleted)
40008000-40028000 r-xp 00000000 00:0a 52 /dev/binder
<…>
b0000000-b000f000 r-xp 00000000 1f:00 417 /system/bin/linker
b000f000-b0010000 rwxp 0000f000 1f:00 417 /system/bin/linker
b0010000-b0019000 rwxp b0010000 00:00 0
bef47000-bef5c000 rwxp befeb000 00:00 0 [stack]

And then for Debuggerd, the virtual memory address gives:

# cat /proc/28/maps
00008000-0000c000 r-xp 00000000 1f:00 402 /system/bin/debuggerd
0000c000-0000d000 rwxp 00004000 1f:00 402 /system/bin/debuggerd
40000000-40008000 r-xs 00000000 00:07 187 /dev/ashmem/system_properties (deleted)
<…>
b0000000-b000f000 r-xp 00000000 1f:00 417 /system/bin/linker
b000f000-b0010000 rwxp 0000f000 1f:00 417 /system/bin/linker
b0010000-b0019000 rwxp b0010000 00:00 0
bec8e000-beca3000 rwxp befeb000 00:00 0 [stack]

And next we take a look at the Dalvik-controlled process, eg, Softkeyboard – looking into softkeyboard virtual address space:

# cat maps
00008000-00009000 r-xp 00000000 1f:00 400 /system/bin/app_process
00009000-0000a000 rwxp 00001000 1f:00 400 /system/bin/app_process
0000a000-002d3000 rwxp 0000a000 00:00 0 [heap]
10000000-10001000 —p 10000000 00:00 0
10001000-10100000 rwxp 10001000 00:00 0
40000000-40008000 r-xs 00000000 00:07 187 /dev/ashmem/system_properties (deleted)
40008000-40009000 r-xp 40008000 00:00 0
40009000-402aa000 rwxp 00000000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
402aa000-41009000 —p 002a1000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
41009000-41038000 r-xs 00000000 1f:00 433 /system/fonts/DroidSans.ttf
41038000-4104c000 rwxp 41038000 00:00 0
4104c000-4104d000 —p 00000000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
4104d000-412c2000 rwxp 00001000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
412c2000-4154c000 —p 00276000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
4154c000-416d0000 r-xs 00000000 1f:00 620 /system/framework/core.jar
416d0000-41a5d000 r-xs 00000000 1f:01 275 /data/dalvik-cache/system@framework@core.jar@classes.dex
41a5d000-41a91000 rwxp 41a5d000 00:00 0
41a91000-41af6000 r-xs 00000000 1f:00 629 /system/framework/ext.jar
41af6000-41bee000 r-xs 00000000 1f:01 276 /data/dalvik-cache/system@framework@ext.jar@classes.dex
41bee000-41e6c000 r-xs 00000000 1f:00 632 /system/framework/framework.jar
41e6c000-42456000 r-xs 00000000 1f:01 277 /data/dalvik-cache/system@framework@framework.jar@classes.dex
42456000-424d4000 rwxp 42456000 00:00 0
<…>
42e1f000-42e60000 rwxp 00000000 00:07 379 /dev/ashmem/mspace/dalvik-heap/zygote/1 (deleted)
42e60000-43b7f000 —p 00041000 00:07 379 /dev/ashmem/mspace/dalvik-heap/zygote/1 (deleted)
43b7f000-43bc0000 rwxp 00000000 00:07 574 /dev/ashmem/mspace/dalvik-heap/2 (deleted)
43bc0000-4489f000 —p 00041000 00:07 574 /dev/ashmem/mspace/dalvik-heap/2 (deleted)
44a9f000-44b9d000 r-xp 00000000 00:0a 52 /dev/binder
44d9d000-44e9d000 rwxs 00000000 00:07 617 /dev/ashmem/CursorWindow (deleted)
44e9d000-44f9d000 rwxs 00000000 00:07 768 /dev/ashmem/CursorWindow (deleted)
<…>
afe00000-afe38000 r-xp 00000000 1f:00 479 /system/lib/libc.so
afe38000-afe3b000 rwxp 00038000 1f:00 479 /system/lib/libc.so
afe3b000-afe46000 rwxp afe3b000 00:00 0
b0000000-b000f000 r-xp 00000000 1f:00 417 /system/bin/linker
b000f000-b0010000 rwxp 0000f000 1f:00 417 /system/bin/linker
b0010000-b0019000 rwxp b0010000 00:00 0
be7ee000-be803000 rwxp befeb000 00:00 0 [stack]

We can see that it is headed by “app_process”.

Reading the source code for “app_process” (notice the comment “interpreted runtime”) – frameworks/base/cmds/app_process/app_main.cpp – we can see that app_process is the thin layer of interpretation for the DEX bytecode:

/*
* Main entry of app process.
*
* Starts the interpreted runtime, then starts up the application.
*
*/

void app_usage()
{
fprintf(stderr,
“Usage: app_process [java-options] cmd-dir start-class-name [options]\n”);
}

status_t app_init(const char* className, int argc, const char* const argv[])
{
LOGV(“Entered app_init()!\n”);

AndroidRuntime* jr = AndroidRuntime::getRuntime();
jr->callMain(className, argc, argv);

LOGV(“Exiting app_init()!\n”);
return NO_ERROR;}

As “jr” AndroidRuntime is already started, callMain() will be called:

status_t AndroidRuntime::callMain(
const char* className, int argc, const char* const argv[])
{
JNIEnv* env;
jclass clazz;
jmethodID methodId;

LOGD(“Calling main entry %s”, className);

env = getJNIEnv();
if (env == NULL)
return UNKNOWN_ERROR;

clazz = findClass(env, className);
if (clazz == NULL) {
LOGE(“ERROR: could not find class ‘%s’\n”, className);
return UNKNOWN_ERROR;
}

methodId = env->GetStaticMethodID(clazz, “main”, “([Ljava/lang/String;)V”);
if (methodId == NULL) {
LOGE(“ERROR: could not find method %s.main(String[])\n”, className);
return UNKNOWN_ERROR;
}
<…>
env->CallStaticVoidMethod(clazz, methodId, strArray);
return NO_ERROR;
}

From above, we can see how the DEX classes’ codes are loaded and CallStaticVoidMethod() will start interpreting the DEX codes.

The possible conclusion is that any C program that does not call the AndroidRuntime() therefore cannot use DalvikVM.

Analysing the softkeyboard in Android

After connecting to the Android device via “adb shell”, and “ps” to identify the softkeyboard:

app_24 99 30 105168 17108 ffffffff afe0da04 S com.example.android.softkeyboard

We do a strace attach:

# strace -p 99
Process 99 attached – interrupt to quit
recv(1176084, NULL, 4294967261, 0) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
ioctl(21, 0xc0186201, 0xbeea17f8) = 0
ioctl(21, 0xc0186201, 0xbeea17f8) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
msgget(0x3, 0xbeea16d8, 0, 0xa9d214e8) = 0
SYS_224(0, 0xc0000001, 0x138b24, 0) = 99
SYS_224(0, 0x3141592, 0x80a030dc, 0x138b24) = 99
SYS_224(0, 0xc0000001, 0x138b24, 0) = 99
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0
SYS_224(0, 0x3141592, 0x80a030dc, 0x138b24) = 99
recv(1114697732, ptrace: umoven: I/O error
0x1, 2147483647, 0) = 0
msgget(0x3, 0xbeea1880, 0, 0xa9d214e8) = 0
ioctl(21, 0xc0186201, 0xbeea1708) = 0
msgget(0x1, 0xbeea1930, 0, 0xa9d214e8) = 0

If it curious you, SYS_224() is actually gettid() – from “kernel/arch-arm/asm/unistd.h” in Android download:

#define __NR_gettid (__NR_SYSCALL_BASE+224)

Not easily understood. Using DDMS to attach to the softkeyboard (must have source codes available, in order for DDMS to work), and tracing the execution:

mysoftkeyboard1 [Android Application]
DalvikVM[localhost:8613]
Thread [<3> main] (Suspended (entry into method onKeyDown in SoftKeyboard))
SoftKeyboard.onKeyDown(int, KeyEvent) line: 338
KeyEvent.dispatch(KeyEvent$Callback, KeyEvent$DispatcherState, Object) line: 1037
InputMethodService$InputMethodSessionImpl(AbstractInputMethodService$AbstractInputMethodSessionImpl).dispatchKeyEvent(int, KeyEvent, InputMethodSession$EventCallback) line: 135
IInputMethodSessionWrapper.executeMessage(Message) line: 76
HandlerCaller$MyHandler.handleMessage(Message) line: 45
HandlerCaller$MyHandler(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4363
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object…) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 860
ZygoteInit.main(String[]) line: 618
NativeStart.main(String[]) line: not available [native
method]
Thread [<13> Binder Thread #2] (Running)
Thread [<11> Binder Thread #1] (Running)
Thread [<15> Binder Thread #3] (Running)

Further analysis of “KeyEvent.dispatch(KeyEvent$Callback, KeyEvent$DispatcherState, Object)” took another post.

What is this “system_server” inside Android?

Looking into the Android processes (via “ps” inside the “adb shell” environment):

radio 29 1 5420 468 ffffffff afe0d0ec S /system/bin/rild
root 30 1 82016 15536 c009a694 afe0cba4 S zygote
media 31 1 20948 1020 ffffffff afe0ca7c S /system/bin/mediaserver
root 32 1 784 240 c02094ac afe0c7dc S /system/bin/installd
keystore 33 1 1616 188 c01a65e8 afe0d40c S /system/bin/keystore
root 34 1 728 180 c003d444 afe0d6ac S /system/bin/sh
root 35 1 824 256 c00b7dd0 afe0d7fc S /system/bin/qemud
root 37 1 3380 188 ffffffff 0000eca4 S /sbin/adbd
root 44 34 780 224 c02094ac afe0c7dc S /system/bin/qemu-props
system 52 30 157544 28996 ffffffff afe0ca7c S system_server
app_24 95 30 104100 14668 ffffffff afe0da04 S com.example.android.softkeyboard
radio 98 30 122060 17124 ffffffff afe0da04 S com.android.phone
app_7 102 30 127904 22164 ffffffff afe0da04 S android.process.acore

We can see that system_server is started of by the zygote process. And looking into the system_server memory:


# cat maps
00008000-00009000 r-xp 00000000 1f:00 400 /system/bin/app_process
00009000-0000a000 rwxp 00001000 1f:00 400 /system/bin/app_process
0000a000-004d6000 rwxp 0000a000 00:00 0 [heap]
10000000-10001000 ---p 10000000 00:00 0
10001000-10100000 rwxp 10001000 00:00 0
40000000-40008000 r-xs 00000000 00:07 187 /dev/ashmem/system_properties (deleted)
40008000-40009000 r-xp 40008000 00:00 0
40009000-402aa000 rwxp 00000000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
402aa000-41009000 ---p 002a1000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
41009000-41038000 r-xs 00000000 1f:00 433 /system/fonts/DroidSans.ttf
41038000-4104c000 rwxp 41038000 00:00 0
4104c000-4104d000 ---p 00000000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
4104d000-41330000 rwxp 00001000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
41330000-4154c000 ---p 002e4000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
4154c000-416d0000 r-xs 00000000 1f:00 620 /system/framework/core.jar
416d0000-41a5d000 r-xs 00000000 1f:01 275 /data/dalvik-cache/system@framework@core.jar@classes.dex
41a5d000-41a91000 rwxp 41a5d000 00:00 0
41a91000-41af6000 r-xs 00000000 1f:00 629 /system/framework/ext.jar
41af6000-41bee000 r-xs 00000000 1f:01 276 /data/dalvik-cache/system@framework@ext.jar@classes.dex
41bee000-41e6c000 r-xs 00000000 1f:00 632 /system/framework/framework.jar
41e6c000-42456000 r-xs 00000000 1f:01 277 /data/dalvik-cache/system@framework@framework.jar@classes.dex
42456000-424d4000 rwxp 42456000 00:00 0
424d4000-424e7000 r-xs 00000000 1f:00 624 /system/framework/android.policy.jar
424e7000-42510000 r-xs 00000000 1f:01 278 /data/dalvik-cache/system@framework@android.policy.jar@classes.dex
42510000-4258b000 r-xs 00000000 1f:00 623 /system/framework/services.jar
4258b000-42697000 r-xs 00000000 1f:01 279 /data/dalvik-cache/system@framework@services.jar@classes.dex
42697000-426c1000 rwxp 42697000 00:00 0
426c1000-426cb000 r-xs 00000000 1f:00 291 /system/app/SettingsProvider.apk
426cb000-426cd000 r-xs 00008000 1f:00 291 /system/app/SettingsProvider.apk
426cd000-426d7000 r-xs 00000000 1f:00 291 /system/app/SettingsProvider.apk
426d7000-426e2000 r-xs 00000000 1f:01 386 /data/dalvik-cache/system@app@SettingsProvider.apk@classes.dex
426e2000-426ee000 rwxp 426e2000 00:00 0
426ee000-426fd000 rwxp 426ee000 00:00 0
426fd000-426fe000 rwxs 00000000 00:07 390 /dev/ashmem/SurfaceFlinger read-only heap (deleted)
426fe000-42704000 rwxp 426fe000 00:00 0
42705000-42711000 rwxp 42705000 00:00 0
42711000-42748000 rwxp 42711000 00:00 0
42748000-42749000 rwxs 00000000 00:07 565 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
42749000-4274c000 rwxp 42749000 00:00 0
4274c000-4274d000 rwxs 00000000 00:07 619 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
4274d000-4274f000 r-xs 00000000 1f:00 434 /system/fonts/Clockopia.ttf
4274f000-42750000 rwxs 00000000 00:07 836 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
42752000-42754000 r-xs 00000000 1f:00 434 /system/fonts/Clockopia.ttf
42754000-42757000 rwxp 42754000 00:00 0
42757000-4275b000 rwxs 00000000 00:07 776 /dev/ashmem/gralloc-buffer (deleted)
4275e000-42776000 rwxs 00000000 00:07 1052 /dev/ashmem/gralloc-buffer (deleted)
42777000-4277b000 rwxs 00000000 00:07 764 /dev/ashmem/gralloc-buffer (deleted)
4277d000-4277f000 r-xs 00000000 1f:00 434 /system/fonts/Clockopia.ttf

And extracting all the ashmem:


40000000-40008000 r-xs 00000000 00:07 187 /dev/ashmem/system_properties (deleted)
40009000-402aa000 rwxp 00000000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
402aa000-41009000 ---p 002a1000 00:07 283 /dev/ashmem/mspace/dalvik-heap/zygote/0 (deleted)
4104c000-4104d000 ---p 00000000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
4104d000-41330000 rwxp 00001000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
41330000-4154c000 ---p 002e4000 00:07 285 /dev/ashmem/dalvik-LinearAlloc (deleted)
426fd000-426fe000 rwxs 00000000 00:07 390 /dev/ashmem/SurfaceFlinger read-only heap (deleted)
42748000-42749000 rwxs 00000000 00:07 565 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
4274c000-4274d000 rwxs 00000000 00:07 619 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
4274f000-42750000 rwxs 00000000 00:07 836 /dev/ashmem/SurfaceFlinger Client control-block (deleted)
42757000-4275b000 rwxs 00000000 00:07 776 /dev/ashmem/gralloc-buffer (deleted)
4275e000-42776000 rwxs 00000000 00:07 1052 /dev/ashmem/gralloc-buffer (deleted)
42777000-4277b000 rwxs 00000000 00:07 764 /dev/ashmem/gralloc-buffer (deleted)
42e1f000-42e60000 rwxp 00000000 00:07 379 /dev/ashmem/mspace/dalvik-heap/zygote/1 (deleted)
42e60000-43b7f000 ---p 00041000 00:07 379 /dev/ashmem/mspace/dalvik-heap/zygote/1 (deleted)
43b7f000-43de0000 rwxp 00000000 00:07 381 /dev/ashmem/mspace/dalvik-heap/2 (deleted)
43de0000-4489f000 ---p 00261000 00:07 381 /dev/ashmem/mspace/dalvik-heap/2 (deleted)
45436000-4544e000 rwxs 00000000 00:07 1061 /dev/ashmem/gralloc-buffer (deleted)
45478000-454ad000 rwxp 00000000 00:07 1155 /dev/ashmem/dalvik-heap-bitmap/mark/0 (deleted)
45823000-45859000 rwxp 00000000 00:07 1156 /dev/ashmem/dalvik-heap-bitmap/mark/1 (deleted)
45b74000-45c74000 rwxs 00000000 00:07 481 /dev/ashmem/CursorWindow (deleted)
46074000-46174000 rwxs 00000000 00:07 497 /dev/ashmem/CursorWindow (deleted)
464b0000-4653f000 rwxs 00000000 00:07 709 /dev/ashmem/gralloc-buffer (deleted)
465a4000-465e4000 rwxp 00000000 00:07 1157 /dev/ashmem/dalvik-heap-bitmap/mark/2 (deleted)
471a1000-471ec000 rwxs 00000000 00:07 704 /dev/ashmem/gralloc-buffer (deleted)
471ec000-4727b000 rwxs 00000000 00:07 708 /dev/ashmem/gralloc-buffer (deleted)
4800e000-4810e000 rwxs 00000000 00:07 761 /dev/ashmem/CursorWindow (deleted)
48489000-484d4000 rwxs 00000000 00:07 839 /dev/ashmem/gralloc-buffer (deleted)

We can see that a lot of different types of shared memory categories under the /dev/ashmem virtual drives.

The role and design of the system_server is blogged here:

http://www.androidenea.com/2009/07/system-server-in-android.html

http://www.androidenea.com/2009/12/adding-system-server-to-android.html

And looking the contents of the frameworks/base/cmds/system_server/system_main.cpp file, which implement the system_server module, it mainly called system_init() in system_init.cpp:


extern "C" status_t system_init()
{
LOGI("Entered system_init()");

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());

sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);

char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}

// Start the sensor service
SensorService::instantiate();

// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {

// Start the AudioFlinger
AudioFlinger::instantiate();

// Start the media playback service
MediaPlayerService::instantiate();

// Start the camera service
CameraService::instantiate();

// Start the audio policy service
AudioPolicyService::instantiate();
}

// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");

AndroidRuntime* runtime = AndroidRuntime::getRuntime();

LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");=========================>SystemServer running under Dalvik JVM.

// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}

And looking into the SystemServer.java implementation:

String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);

LightsService lights = null;
PowerManagerService power = null;
BatteryService battery = null;
ConnectivityService connectivity = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
BluetoothService bluetooth = null;
BluetoothA2dpService bluetoothA2dp = null;
HeadsetObserver headset = null;
DockObserver dock = null;
UsbObserver usb = null;
UiModeManagerService uiMode = null;
RecognitionManagerService recognition = null;
ThrottleService throttle = null;

// Critical services...
try {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());

Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);

Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);

Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));

AttributeCache.init(context);

Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);

ActivityManagerService.setSystemProcess();

mContentResolver = context.getContentResolver();

// The AccountManager must come before the ContentService
try {
Slog.i(TAG, "Account Manager");
ServiceManager.addService(Context.ACCOUNT_SERVICE,
new AccountManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Account Manager", e);
}

Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();

Slog.i(TAG, "Battery Service");
battery = new BatteryService(context);
ServiceManager.addService("battery", battery);

Slog.i(TAG, "Lights Service");
lights = new LightsService(context);

Slog.i(TAG, "Vibrator Service");
ServiceManager.addService("vibrator", new VibratorService(context));

// only initialize the power service after we have started the
// lights service, content providers and the battery service.
power.init(context, lights, ActivityManagerService.getDefault(), battery);

Slog.i(TAG, "Alarm Manager");
AlarmManagerService alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);

Slog.i(TAG, "Init Watchdog");
Watchdog.getInstance().init(context, battery, power, alarm,
ActivityManagerService.self());

Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);

((ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);

// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
// support Bluetooth - see bug 988521
if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
Slog.i(TAG, "Registering null Bluetooth Service (emulator)");
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
Slog.i(TAG, "Registering null Bluetooth Service (factory test)");
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else {
Slog.i(TAG, "Bluetooth Service");
bluetooth = new BluetoothService(context);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
bluetooth.initAfterRegistration();
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
bluetoothA2dp);

int bluetoothOn = Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_ON, 0);
if (bluetoothOn > 0) {
bluetooth.enable();
}
}

} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}

DevicePolicyManagerService devicePolicy = null;
StatusBarManagerService statusBar = null;
InputMethodManagerService imm = null;
AppWidgetService appWidget = null;
NotificationManagerService notification = null;
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;

if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
Slog.i(TAG, "Device Policy");
devicePolicy = new DevicePolicyManagerService(context);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DevicePolicyService", e);
}

try {
Slog.i(TAG, "Status Bar");
statusBar = new StatusBarManagerService(context);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting StatusBarManagerService", e);
}

try {
Slog.i(TAG, "Clipboard Service");
ServiceManager.addService(Context.CLIPBOARD_SERVICE,
new ClipboardService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Clipboard Service", e);
}

try {
Slog.i(TAG, "Input Method Service");
imm = new InputMethodManagerService(context, statusBar);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Input Manager Service", e);
}

try {
Slog.i(TAG, "NetStat Service");
ServiceManager.addService("netstat", new NetStatService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting NetStat Service", e);
}

try {
Slog.i(TAG, "NetworkManagement Service");
ServiceManager.addService(
Context.NETWORKMANAGEMENT_SERVICE,
NetworkManagementService.create(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting NetworkManagement Service", e);
}

try {
Slog.i(TAG, "Connectivity Service");
connectivity = ConnectivityService.getInstance(context);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Connectivity Service", e);
}

try {
Slog.i(TAG, "Throttle Service");
throttle = new ThrottleService(context);
ServiceManager.addService(
Context.THROTTLE_SERVICE, throttle);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting ThrottleService", e);
}

try {
Slog.i(TAG, "Accessibility Manager");
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
new AccessibilityManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Accessibility Manager", e);
}

try {
/*
* NotificationManagerService is dependant on MountService,
* (for media / usb notifications) so we must start MountService first.
*/
Slog.i(TAG, "Mount Service");
ServiceManager.addService("mount", new MountService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Mount Service", e);
}

try {
Slog.i(TAG, "Notification Manager");
notification = new NotificationManagerService(context, statusBar, lights);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Notification Manager", e);
}

try {
Slog.i(TAG, "Device Storage Monitor");
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
new DeviceStorageMonitorService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DeviceStorageMonitor service", e);
}

try {
Slog.i(TAG, "Location Manager");
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Location Manager", e);
}

try {
Slog.i(TAG, "Search Service");
ServiceManager.addService(Context.SEARCH_SERVICE,
new SearchManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Search Service", e);
}

if (INCLUDE_DEMO) {
Slog.i(TAG, "Installing demo data...");
(new DemoThread(context)).start();
}

try {
Slog.i(TAG, "DropBox Service");
ServiceManager.addService(Context.DROPBOX_SERVICE,
new DropBoxManagerService(context, new File("/data/system/dropbox")));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DropBoxManagerService", e);
}

try {
Slog.i(TAG, "Wallpaper Service");
wallpaper = new WallpaperManagerService(context);
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Wallpaper Service", e);
}

try {
Slog.i(TAG, "Audio Service");
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Audio Service", e);
}

try {
Slog.i(TAG, "Headset Observer");
// Listen for wired headset changes
headset = new HeadsetObserver(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting HeadsetObserver", e);
}

try {
Slog.i(TAG, "Dock Observer");
// Listen for dock station changes
dock = new DockObserver(context, power);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DockObserver", e);
}

try {
Slog.i(TAG, "USB Observer");
// Listen for USB changes
usb = new UsbObserver(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting UsbObserver", e);
}

try {
Slog.i(TAG, "UI Mode Manager Service");
// Listen for UI mode changes
uiMode = new UiModeManagerService(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting UiModeManagerService", e);
}

try {
Slog.i(TAG, "Backup Service");
ServiceManager.addService(Context.BACKUP_SERVICE,
new BackupManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Backup Service", e);
}

try {
Slog.i(TAG, "AppWidget Service");
appWidget = new AppWidgetService(context);
ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting AppWidget Service", e);
}

try {
Slog.i(TAG, "Recognition Service");
recognition = new RecognitionManagerService(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Recognition Service", e);
}

try {
Slog.i(TAG, "DiskStats Service");
ServiceManager.addService("diskstats", new DiskStatsService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DiskStats Service", e);
}
}

And extracting from logcat output (via “logcat” inside “adb shell” environment):


I/SystemServer(   52): Entered the Android system server!
I/SystemServer(   52): Entropy Service
I/SystemServer(   52): Power Manager
I/SystemServer(   52): Activity Manager
I/SystemServer(   52): Telephony Registry
I/SystemServer(   52): Package Manager
I/SystemServer(   52): Account Manager
I/SystemServer(   52): Content Manager
I/SystemServer(   52): System Content Providers
I/SystemServer(   52): Battery Service
I/SystemServer(   52): Hardware Service
I/SystemServer(   52): Alarm Manager
I/SystemServer(   52): Init Watchdog
I/SystemServer(   52): Sensor Service
I/SystemServer(   52): Window Manager
I/SystemServer(   52): Registering null Bluetooth Service (emulator)
E/System  (   52): 	at com.android.server.ServerThread.run(SystemServer.java:176)
I/SystemServer(   52): Status Bar
I/SystemServer(   52): Clipboard Service
I/SystemServer(   52): Input Method Service
I/SystemServer(   52): NetStat Service
I/SystemServer(   52): Connectivity Service
I/SystemServer(   52): Accessibility Manager
I/SystemServer(   52): Notification Manager
I/SystemServer(   52): Mount Service
I/SystemServer(   52): Device Storage Monitor
I/SystemServer(   52): Location Manager
I/SystemServer(   52): Search Service
I/SystemServer(   52): Checkin Service
W/SystemServer(   52): Using fallback Checkin Service.
I/SystemServer(   52): Wallpaper Service
I/SystemServer(   52): Audio Service
I/SystemServer(   52): Headset Observer
I/SystemServer(   52): Dock Observer
I/SystemServer(   52): Backup Service
I/SystemServer(   52): AppWidget Service
I/SystemServer(   52): Making services ready

Hm….understand? Only a little!!!!! Essentially adding all essential services and running it. And if you need to add a new service to SystemServer (VERY GOOD READ):

http://www.androidenea.com/2009/12/adding-system-server-to-android.html

Other system_server related blogs:

http://cphacker0901.wordpress.com/category/google-android/page/2/ (with a good diagram summary)

http://justanapplication.wordpress.com/2009/08/21/a-standalone-android-runtime-systemserver-startup/

http://justanapplication.wordpress.com/2009/08/19/a-standalone-android-runtime-getting-started/

http://www.google.com/search?num=100&hl=en&q=android+site:wordpress.com+system_server&aq=f&aqi=&aql=&oq=

http://www.google.com/search?num=100&hl=en&q=android+site:blogspot.com+system_server&aq=f&aqi=&aql=&oq=

 

%d bloggers like this: