Android Service

Native Service and Android Service

  • Native Service:In every main() method of NativeService, which is called by init process through parseing init.rc, the globale object of ProcessState will be created by calling ProcessState::self(),and then startThreadPool and created main thread by calling IPCThreadPool.self()->joinThreadPool().
  • Android Service:All Android Service is created by SystemServer and running with the same parent process which is system server.

Init Process starts

      Reference: http://my.oschina.net/u/561492/blog/144730

  • init.rc
  •   1 import init.usb.rc
      2 import init.xlog.rc
      3 
      4 on early-init
      5     # Set init and its forked children's oom_adj.
      6     write /proc/1/oom_adj -16
      7     start ueventd
      8     
      9 # create mountpoints
     10     mkdir /mnt 0775 root system
     11     mkdir /mnt/sdcard 0000 system system
     12     mkdir /mnt/sdcard2 0000 system system
     13 
     14 on early_property:ro.build.type=user
     15     write /proc/bootprof "INIT: user build setting"
     16 
     17 on early_property:ro.build.type=eng
     18     write /proc/bootprof "INIT: eng build setting"
     19 
     20 on init
     21 
     22 sysclktz 0
     23 
     24 loglevel 5
     25     write /proc/bootprof "INIT: on init start"
     26 
     27 # setup the global environment
     28     export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
     29     export LD_LIBRARY_PATH /vendor/lib:/system/lib
     30     export ANDROID_BOOTLOGO 1
     31     export ANDROID_ROOT /system
     32     export ANDROID_ASSETS /system/app
     33     export ANDROID_DATA /data
     34     export EXTERNAL_STORAGE /mnt/sdcard
     35     export ASEC_MOUNTPOINT /mnt/asec
     36     export LOOP_MOUNTPOINT /mnt/obb
     37     export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar:/system/framework/mediatek-framework.jar:/system/framework/secondary_framework.jar
     38 
     39 # Backward compatibility
     40     symlink /system/etc /etc
     41     symlink /sys/kernel/debug /d
     42 
     43 # Right now vendor lives on the same filesystem as system,
     44 # but someday that may change.
     45     symlink /system/vendor /vendor
     46 
     47 # Create cgroup mount point for cpu accounting
     48     mkdir /acct
     49     mount cgroup none /acct cpuacct
     50     mkdir /acct/uid
     51 
     52 # Backwards Compat - XXX: Going away in G*
     53     symlink /mnt/sdcard /sdcard
     54 
     55     mkdir /system
     56     mkdir /data 0771 system system
     57     mkdir /cache 0770 system cache
     58     mkdir /config 0500 root root
     59 
     60     # Directory for putting things only root should see.
     61     mkdir /mnt/secure 0700 root root
     62 
     63     # Directory for staging bindmounts
     64     mkdir /mnt/secure/staging 0700 root root
     65 
     66     # Directory-target for where the secure container
     67     # imagefile directory will be bind-mounted
     68     mkdir /mnt/secure/asec  0700 root root
     69 
     70     # Secure container public mount points.
     71     mkdir /mnt/asec  0700 root system
     72     mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
     73 
     74     # Filesystem image public mount points.
     75     mkdir /mnt/obb 0700 root system
     76     mount tmpfs tmpfs /mnt/obb mode=0755,gid=1000
     77 
     78     write /proc/sys/kernel/panic_on_oops 1
     79     write /proc/sys/kernel/hung_task_timeout_secs 0
     80     write /proc/cpu/alignment 4
     81     write /proc/sys/kernel/sched_latency_ns 10000000
     82     write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000
     83     write /proc/sys/kernel/sched_compat_yield 1
     84     write /proc/sys/kernel/sched_child_runs_first 0
     85     write /proc/sys/kernel/randomize_va_space 2
     86 
     87 # Create cgroup mount points for process groups
     88     mkdir /dev/cpuctl
     89     mount cgroup none /dev/cpuctl cpu
     90     chown system system /dev/cpuctl
     91     chown system system /dev/cpuctl/tasks
     92     chmod 0777 /dev/cpuctl/tasks
     93     write /dev/cpuctl/cpu.shares 1024
     94 
     95     mkdir /dev/cpuctl/fg_boost
     96     chown system system /dev/cpuctl/fg_boost/tasks
     97     chmod 0777 /dev/cpuctl/fg_boost/tasks
     98     write /dev/cpuctl/fg_boost/cpu.shares 1024
     99 
    100     mkdir /dev/cpuctl/bg_non_interactive
    101     chown system system /dev/cpuctl/bg_non_interactive/tasks
    102     chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
    103     # 5.0 %
    104     write /dev/cpuctl/bg_non_interactive/cpu.shares 52
    105 
    106 # Allow everybody to read the xt_qtaguid resource tracking misc dev.
    107 # This is needed by any process that uses socket tagging.
    108     chmod 0644 /dev/xt_qtaguid
    109 
    110 on fs
    111 # mount mtd partitions
    112     # Mount /system rw first to give the filesystem a chance to save a checkpoint
    113     write /proc/bootprof "INIT:NAND:Mount_START"
    114     mount yaffs2 mtd@system /system
    115     mount yaffs2 mtd@system /system ro remount
    116     mount yaffs2 mtd@userdata /data nosuid nodev
    117     mount yaffs2 mtd@cache /cache nosuid nodev
    118     write /proc/bootprof "INIT:NAND:Mount_END"
    119 # mount mtd partitions
    120     write /proc/bootprof "INIT:eMMC:Mount_START"
    121     exec /sbin/e2fsck -p /emmc@android
    122     # Mount /system rw first to give the filesystem a chance to save a checkpoint
    123     #mount ext4 emmc@android /system commit=1,data=journal,noauto_da_alloc
    124     mount ext4 /emmc@android /system commit=1,noauto_da_alloc
    125     mkdir /system/secro 0600 system system
    126     # RIL need to do this before the folder /system changed to read only
    127     chown radio system /system/etc/ril
    128     chmod 0770 /system/etc/ril
    129     chmod 0444 /system/etc/ril/oper.lis
    130     mount ext4 /emmc@android /system noatime ro remount 
    131     exec /sbin/e2fsck -pfD /emmc@usrdata
    132     exec /sbin/tune2fs -O has_journal /emmc@usrdata
    133     mount ext4 /emmc@usrdata /data noatime nosuid nodev noauto_da_alloc
    134     exec /sbin/e2fsck -p /emmc@cache
    135     exec /sbin/tune2fs -O has_journal /emmc@cache
    136     mount ext4 /emmc@cache /cache noatime nosuid nodev noauto_da_alloc
    137     write /proc/bootprof "INIT:eMMC:Mount_END"
    138 
    139 on post-fs
    140     # once everything is setup, no need to modify /
    141     mount rootfs rootfs / ro remount
    142 
    143 # Add by Mtk
    144     mount ext4 /emmc@sec_ro /system/secro ro remount
    145     
    146     # We chown/chmod /cache again so because mount is run as root + defaults
    147     chown system cache /cache
    148     chmod 0770 /cache
    149 
    150     # This may have been created by the recovery system with odd permissions
    151     chown system cache /cache/recovery
    152     chmod 0770 /cache/recovery
    153 
    154     #change permissions on vmallocinfo so we can grab it from bugreports
    155     chown root log /proc/vmallocinfo
    156     chmod 0440 /proc/vmallocinfo
    157 
    158     #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks
    159     chown root system /proc/kmsg
    160     chmod 0440 /proc/kmsg
    161     chown root system /proc/sysrq-trigger
    162     chmod 0220 /proc/sysrq-trigger
    163 
    164     # create the lost+found directories, so as to enforce our permissions
    165     mkdir /cache/lost+found 0770 root root
    166 
    167 # Add by Mtk
    168     mount yaffs2 mtd@secstatic /system/secro ro remount
    169 
    170 on post-fs-data
    171     # We chown/chmod /data again so because mount is run as root + defaults
    172     chown system system /data
    173     chmod 0771 /data
    174 
    175     # Create dump dir and collect dumps.
    176     # Do this before we mount cache so eventually we can use cache for
    177     # storing dumps on platforms which do not have a dedicated dump partition.
    178     mkdir /data/dontpanic 0750 root log
    179 
    180     # Collect apanic data, free resources and re-arm trigger
    181     copy /proc/apanic_console /data/dontpanic/apanic_console
    182     chown root log /data/dontpanic/apanic_console
    183     chmod 0640 /data/dontpanic/apanic_console
    184 
    185     copy /proc/apanic_threads /data/dontpanic/apanic_threads
    186     chown root log /data/dontpanic/apanic_threads
    187     chmod 0640 /data/dontpanic/apanic_threads
    188 
    189     write /proc/apanic_console 1
    190 
    191     # create basic filesystem structure
    192     mkdir /data/nvram 0770 root nvram
    193     mkdir /data/misc 01771 system misc
    194     mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth
    195     mkdir /data/misc/bluetooth 0770 system system
    196     mkdir /data/misc/keystore 0700 keystore keystore
    197     mkdir /data/misc/keychain 0771 system system
    198     mkdir /data/misc/vpn 0770 system vpn
    199     mkdir /data/misc/systemkeys 0700 system system
    200     # give system access to wpa_supplicant.conf for backup and restore
    201     mkdir /data/misc/wifi 0770 wifi wifi
    202     chmod 0660 /data/misc/wifi/wpa_supplicant.conf
    203     chmod 0660 /data/misc/wifi/p2p_supplicant.conf
    204     mkdir /data/local 0751 root root
    205     mkdir /data/local/tmp 0771 shell shell
    206     mkdir /data/data 0771 system system
    207     mkdir /data/app-private 0771 system system
    208     mkdir /data/app 0771 system system
    209     mkdir /data/property 0700 root root
    210 
    211     #give system access to rfkill device node
    212     chmod 0660 /dev/rfkill
    213 
    214     # create dalvik-cache, so as to enforce our permissions
    215     mkdir /data/dalvik-cache 0771 system system
    216 
    217     # create resource-cache and double-check the perms
    218     mkdir /data/resource-cache 0771 system system
    219     chown system system /data/resource-cache
    220     chmod 0771 /data/resource-cache
    221 
    222     # create the lost+found directories, so as to enforce our permissions
    223     mkdir /data/lost+found 0770 root root
    224 
    225     # create directory for DRM plug-ins
    226     mkdir /data/drm 0774 drm drm
    227 
    228     # If there is no fs-post-data action in the init.<device>.rc file, you
    229     # must uncomment this line, otherwise encrypted filesystems
    230     # won't work.
    231     # Set indication (checked by vold) that we have finished this action
    232     #setprop vold.post_fs_data_done 1
    233 
    234 # -----------------------
    235 # Add by MTK 
    236 
    237     # hwe
    238     insmod /system/lib/modules/mtk_hwe.ko
    239 
    240     # alps core
    241     # insmod /system/lib/modules/alps_core.ko
    242 
    243     # dhcp server 
    244     mkdir /data/misc/dhcp 0770 dhcp dhcp
    245     chown dhcp dhcp /data/misc/dhcp
    246 
    247     # SGX
    248     insmod /system/lib/modules/pvrsrvkm.ko
    249     insmod /system/lib/modules/mtklfb.ko
    250 
    251     # Permissions for System Server and daemons.
    252     chown root   radio  /sys/class/leds/lcd-backlight/brightness
    253     chown root   radio  /sys/class/leds/lcd-backlight/duty
    254     chown root   radio  /sys/class/leds/lcd-backlight/div
    255 
    256     # Touch Panel 
    257     chmod 0664 /dev/touch
    258     chown root diag /sys/module/tpd_setting/parameters/tpd_calmat
    259     chown root diag /sys/module/tpd_setting/parameters/tpd_em_debounce_time
    260     chown root diag /sys/module/tpd_setting/parameters/tpd_mode
    261     chown root diag /sys/module/tpd_setting/parameters/tpd_em_debounce_time0
    262     chown root diag /sys/module/tpd_setting/parameters/tpd_em_debounce_time1
    263     chown root diag /sys/module/tpd_setting/parameters/tpd_em_spl_num
    264     chown root diag /sys/module/tpd_setting/parameters/tpd_em_pressure_threshold
    265     chown root diag /sys/module/tpd_setting/parameters/tpd_em_auto_time_interval
    266     chown root diag /sys/module/tpd_setting/parameters/tpd_em_sample_cnt
    267     chown root diag /sys/module/tpd_setting/parameters/tpd_em_asamp
    268     chown root diag /sys/module/tpd_debug/parameters/tpd_em_log
    269     chown root diag /sys/module/tpd_debug/parameters/tpd_em_log_to_fs
    270     
    271     chmod 0666 /dev/pmem_multimedia
    272     # load driver base driver
    273     insmod /system/lib/modules/mtk_drvb_77.ko
    274     mknod /dev/drvb c 176 0
    275     chmod 0666 /dev/drvb
    276 
    277     # watch dog kicker
    278     write /proc/wdk "0 20 30"
    279 
    280     
    281 
    282     # RTC
    283     mkdir /data/misc/rtc 0770 system system
    284 
    285     # Modem related device nodes
    286     mkdir /data/nvram/md 0700 root root
    287 
    288     insmod /system/lib/modules/ccci_plat.ko
    289     insmod /system/lib/modules/ccci.ko
    290     insmod /system/lib/modules/ccmni.ko
    291 
    292     mknod /dev/ccci c 184 0
    293     mknod /dev/ccci_fs c 178 0
    294     mknod /dev/ccci_sys_rx c 184 2
    295     mknod /dev/ccci_sys_tx c 184 3
    296     mknod /dev/ccci_pcm_rx c 184 4
    297     mknod /dev/ccci_pcm_tx c 184 5
    298     mknod /dev/ccci_uart1_rx c 184 6
    299     mknod /dev/ccci_uart1_rx_ack c 184 7
    300     
    301     mknod /dev/ccci_uem_rx c 184 18
    302     mknod /dev/ccci_uem_tx c 184 19
    303     chmod 0666 /dev/ccci_uem_rx
    304     chmod 0666 /dev/ccci_uem_tx
    305 
    306     mknod /dev/ccci_md_log_rx c 184 42
    307     mknod /dev/ccci_md_log_tx c 184 43
    308     chmod 0666 /dev/ccci_md_log_rx
    309     chmod 0666 /dev/ccci_md_log_tx
    310 
    311     chmod 0666 /dev/ccci
    312     chmod 0660 /dev/ccci_fs
    313     chmod 0666 /dev/ccci_pcm_rx
    314     chmod 0666 /dev/ccci_pcm_tx
    315     chmod 0600 /dev/ccci_sys_rx
    316     chmod 0600 /dev/ccci_sys_tx
    317     chmod 0600 /dev/ccci_uart1_rx
    318     chmod 0600 /dev/ccci_uart1_rx_ack
    319     chmod 0660 /dev/ttyC0
    320 
    321     # M4U
    322     insmod /system/lib/modules/m4u.ko
    323     mknod /dev/M4U_device c 188 0
    324     chmod 0666 /dev/M4U_device
    325     
    326     # Sensor
    327     chmod 0666 /dev/hwmsensor
    328     chmod 0666 /dev/msensor
    329     chmod 0666 /dev/gsensor
    330     chmod 0666 /dev/alsps
    331 
    332     #VideoCodec
    333     insmod /system/lib/modules/vcodec_kernel_driver.ko
    334     mknod /dev/Vcodec c 160 0
    335     chmod 0666 /dev/Vcodec
    336 
    337 
    338     
    339     mkdir /data/amit/
    340     mkdir /data/misc/sensors 0777 system system
    341     mkdir /data/misc/akmd 0777 compass compass
    342     chown system /sys/class/input/input4/enable
    343     chown system /sys/class/input/input4/delay
    344     chown system /sys/class/input/input4/wake
    345     chown system /sys/class/input/input2/enable
    346     chown system /sys/class/input/input2/wake
    347     chown compass /sys/class/input/input3/offsets    
    348 
    349     # GPIO
    350     chmod 0666 /dev/mtgpio
    351     
    352         #EM eint
    353     chown root diag /sys/bus/platform/drivers/eint/current_eint
    354 
    355     # change MTKFB permission for Settings App JNI functions to set TVOut related status
    356     chmod 0666 /dev/graphics/fb0
    357     
    358     # EM baseband file
    359     chown root diag /system/bin/baseband_regdump
    360     chmod 4750 /system/bin/baseband_regdump
    361 
    362     #pmu
    363     chown root radio /sys/devices/platform/mt-pmic/pmic_access_bank0
    364     chown root radio /sys/devices/platform/mt-pmic/pmic_access_bank1
    365     chmod 0664 /sys/devices/platform/mt-pmic/pmic_access_bank0
    366     chmod 0664 /sys/devices/platform/mt-pmic/pmic_access_bank1
    367 
    368     
    369     #EM eint
    370     chown root diag /sys/bus/platform/drivers/eint/current_eint
    371 
    372     # for ppp options file
    373     mkdir /data/misc/ppp
    374     chmod 0777 /data/misc/ppp
    375 
    376     # Android SEC related device nodes
    377     insmod /system/lib/modules/sec.ko
    378     mknod /dev/sec c 182 0
    379     chmod 0660 /dev/sec
    380 
    381     # device apc settings
    382     insmod /system/lib/modules/devapc.ko
    383 
    384     # device info /proc interface
    385     insmod /system/lib/modules/devinfo.ko
    386     
    387     # bluetooth
    388     mkdir /data/@btmtk 0770 bluetooth net_bt
    389     chown bluetooth bluetooth /dev/hid-keyboard
    390     chmod 0660 /dev/hid-keyboard
    391     chown bluetooth bluetooth /dev/btn
    392     chmod 0660 /dev/btn
    393     #Use uinput's default permission
    394     chown system net_bt_admin /dev/uinput
    395 
    396     #TV-out
    397     chmod 0666 /dev/TV-out
    398 
    399     #HDMI
    400     chmod 0666 /dev/hdmitx
    401 
    402     # JPEG
    403     chmod 0666 /dev/mtk_jpeg
    404     
    405     #SYSRAM
    406     chmod 0666 /dev/camera-sysram
    407 
    408     #ISP
    409     chmod 0666 /dev/camera-isp
    410 
    411     #ResMar
    412     chmod 0666 /dev/camera-resmgr
    413 
    414     # otg_test
    415     chmod 0777 /dev/mt_otg_test
    416     
    417     # MDP
    418     chmod 0666 /dev/mt6575-MDP
    419 
    420 # End of adding by MTK drivers   
    421 # -----------------------
    422 
    423 on boot
    424 
    425     # xlog
    426     chmod 0666 /dev/xLog
    427     start xlogboot
    428     
    429 # basic network init
    430     ifup lo
    431     hostname localhost
    432     domainname localdomain
    433 
    434 # set RLIMIT_NICE to allow priorities from 19 to -20
    435     setrlimit 13 40 40
    436 
    437 # Memory management.  Basic kernel parameters, and allow the high
    438 # level system server to be able to adjust the kernel OOM driver
    439 # paramters to match how it is managing things.
    440     write /proc/sys/vm/overcommit_memory 1
    441     write /proc/sys/vm/min_free_order_shift 4
    442     chown root system /sys/module/lowmemorykiller/parameters/adj
    443     chmod 0664 /sys/module/lowmemorykiller/parameters/adj
    444     chown root system /sys/module/lowmemorykiller/parameters/minfree
    445     chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
    446 
    447     # Tweak background writeout
    448     write /proc/sys/vm/dirty_expire_centisecs 100
    449     write /proc/sys/vm/dirty_writeback_centisecs 300
    450     write /proc/sys/vm/dirty_background_ratio  5
    451 
    452     # Permissions for System Server and daemons.
    453     chown radio system /sys/android_power/state
    454     chown radio system /sys/android_power/request_state
    455     chown radio system /sys/android_power/acquire_full_wake_lock
    456     chown radio system /sys/android_power/acquire_partial_wake_lock
    457     chown radio system /sys/android_power/release_wake_lock
    458     chown radio system /sys/power/state
    459     chown radio system /sys/power/wake_lock
    460     chown radio system /sys/power/wake_unlock
    461     chmod 0660 /sys/power/state
    462     chmod 0660 /sys/power/wake_lock
    463     chmod 0660 /sys/power/wake_unlock
    464     chmod 0664 /sys/class/leds/lcd-backlight/brightness
    465     chown system system /sys/class/timed_output/vibrator/enable
    466     chown system system /sys/class/leds/keyboard-backlight/brightness
    467     chown system radio  /sys/class/leds/lcd-backlight/brightness
    468     chown system system /sys/class/leds/button-backlight/brightness
    469     chown system system /sys/class/leds/jogball-backlight/brightness
    470     chown system system /sys/class/leds/red/brightness
    471     chown system system /sys/class/leds/green/brightness
    472     chown system system /sys/class/leds/blue/brightness
    473     chown system system /sys/class/leds/red/device/grpfreq
    474     chown system system /sys/class/leds/red/device/grppwm
    475     chown system system /sys/class/leds/red/device/blink
    476     chown system system /sys/class/leds/red/brightness
    477     chown system system /sys/class/leds/green/brightness
    478     chown system system /sys/class/leds/blue/brightness
    479     chown system system /sys/class/leds/red/device/grpfreq
    480     chown system system /sys/class/leds/red/device/grppwm
    481     chown system system /sys/class/leds/red/device/blink
    482     chown system system /sys/class/timed_output/vibrator/enable
    483     chown system system /sys/module/sco/parameters/disable_esco
    484     chown system system /sys/kernel/ipv4/tcp_wmem_min
    485     chown system system /sys/kernel/ipv4/tcp_wmem_def
    486     chown system system /sys/kernel/ipv4/tcp_wmem_max
    487     chown system system /sys/kernel/ipv4/tcp_rmem_min
    488     chown system system /sys/kernel/ipv4/tcp_rmem_def
    489     chown system system /sys/kernel/ipv4/tcp_rmem_max
    490     chown root radio /proc/cmdline
    491 
    492     chown root   radio  /sys/class/leds/lcd-backlight/duty
    493     chown root   radio  /sys/class/leds/lcd-backlight/div
    494     chown system system /sys/class/leds/lcd-backlight/trigger
    495     chown system system /sys/class/leds/button-backlight/trigger
    496     chown system system /sys/class/leds/keyboard-backlight/trigger
    497     chown system system /sys/class/leds/jogball-backlight/trigger
    498     chown system system /sys/class/leds/red/trigger
    499     chown system system /sys/class/leds/green/trigger
    500     chown system system /sys/class/leds/blue/trigger
    501 # AGPS
    502 chmod 0777 /system/bin/mtk_agpsd
    503 
    504 ## Thermal
    505   #change permissions on thermal devices
    506   chown root system /proc/mtktscpu/mtktscpu
    507   chmod 0660 /proc/mtktscpu/mtktscpu
    508   chown root system /proc/mtktsabb/mtktsabb
    509   chmod 0660 /proc/mtktsabb/mtktsabb
    510   chown root system /proc/mtktsbattery/mtktsbattery
    511   chmod 0660 /proc/mtktsbattery/mtktsbattery
    512   chown root system /proc/mtktspa/mtktspa
    513   chmod 0660 /proc/mtktspa/mtktspa
    514   chown root system /proc/mtktspmic/mtktspmic
    515   chmod 0660 /proc/mtktspmic/mtktspmic
    516   chown root system /proc/wmt_tm/wmt_tm
    517   chmod 0660 /proc/wmt_tm/wmt_tm
    518   chown root system /proc/driver/mtk_thermal_monitor
    519   chmod 0660 /proc/driver/mtk_thermal_monitor
    520 
    521 # Define TCP buffer sizes for various networks
    522 #   ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,
    523     setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208
    524     setprop net.tcp.buffersize.wifi    524288,1048576,2097152,262144,524288,1048576
    525     setprop net.tcp.buffersize.lte     524288,1048576,2097152,262144,524288,1048576
    526     setprop net.tcp.buffersize.umts    4094,87380,110208,4096,16384,110208
    527     setprop net.tcp.buffersize.hspa    4094,87380,262144,4096,16384,262144
    528     setprop net.tcp.buffersize.edge    4093,26280,35040,4096,16384,35040
    529     setprop net.tcp.buffersize.gprs    4092,8760,11680,4096,8760,11680
    530 
    531 # Set this property so surfaceflinger is not started by system_init
    532     setprop system_init.startsurfaceflinger 0
    533 
    534     class_start core
    535     class_start main
    536     class_start default
    537 
    538 on nonencrypted
    539     class_start late_start
    540 
    541 on charger
    542     class_start charger
    543 
    544 on property:vold.decrypt=trigger_reset_main
    545     class_reset main
    546 
    547 on property:vold.decrypt=trigger_load_persist_props
    548     load_persist_props
    549 
    550 on property:vold.decrypt=trigger_post_fs_data
    551     trigger post-fs-data
    552 
    553 on property:vold.decrypt=trigger_restart_min_framework
    554     class_start main
    555 
    556 on property:vold.decrypt=trigger_restart_framework
    557     class_start main
    558     class_start late_start
    559 
    560 on property:vold.decrypt=trigger_shutdown_framework
    561     class_reset late_start
    562     class_reset main
    563 
    564 on property:vold.decrypt=trigger_stop_modem_and_default
    565     stop gsm0710muxd
    566     stop rild
    567     stop ccci_fsd
    568     stop ccci_mdinit
    569     class_reset default
    570 
    571 ## Daemon processes to be run by init.
    572 ##
    573 
    574 # Update the second boot logo
    575 service bootlogoupdater /system/bin/boot_logo_updater
    576     oneshot
    577 
    578 service ueventd /sbin/ueventd
    579     class core
    580     critical
    581 
    582 service console /system/bin/sh
    583     class core
    584     console
    585     disabled
    586     user root
    587     group log
    588 
    589 on property:ro.debuggable=1
    590     start console
    591 
    592 # adbd is controlled via property triggers in init.<platform>.usb.rc
    593 service adbd /sbin/adbd
    594     class core
    595     disabled
    596 
    597 # adbd on at boot in emulator
    598 on property:ro.kernel.qemu=1
    599     start adbd
    600 
    601 service debuggerd /system/bin/debuggerd
    602     class main
    603 
    604 service mobile_log_d /system/bin/mobile_log_d
    605     class main
    606 
    607 # SGX init
    608 service pvrsrvinit /system/vendor/bin/pvrsrvinit
    609     class main
    610     user root
    611     group root
    612     oneshot
    613 
    614 service servicemanager /system/bin/servicemanager
    615     class core
    616     user system
    617     group system
    618     critical
    619     onrestart restart zygote
    620     onrestart restart media
    621     onrestart restart surfaceflinger
    622     onrestart restart drm
    623 
    624 service vold /system/bin/vold
    625     class core
    626     socket vold stream 0660 root mount
    627     ioprio be 2
    628 
    629 service netd /system/bin/netd
    630     class main
    631     socket netd stream 0660 root system
    632     socket dnsproxyd stream 0660 root inet
    633     
    634 service netdiag /system/bin/netdiag
    635     class main
    636     socket netdiag stream 0666 root system 
    637     
    638 
    639 service nvram_daemon /system/bin/nvram_daemon
    640     class main
    641     user root
    642     group nvram
    643     oneshot
    644 service gsm0710muxd /system/bin/gsm0710muxd -s /dev/ttyC0 -f 512 -n 8 -m basic
    645     class core
    646     user root
    647     group radio cache inet misc
    648     disabled
    649 
    650 service muxreport-daemon /system/bin/muxreport
    651     class core
    652     user root
    653     group radio cache inet misc
    654         disabled
    655         oneshot
    656 
    657 service ril-daemon /system/bin/rild
    658     class core
    659     socket rild stream 660 root radio
    660     socket rild2 stream 660 root radio
    661     socket rild-debug stream 666 radio system
    662     socket rild-mtk-ut stream 660 radio net_bt
    663     socket rild-mtk-ut-2 stream 660 radio net_bt
    664     socket rild-mtk-modem stream 660 radio system
    665     socket rild-atci stream 660 root radio
    666     user root
    667     group radio cache inet misc audio sdcard_rw log
    668     disabled
    669 
    670 service atci_service /system/bin/atci_service 
    671     socket atci-service stream 660 radio system 
    672     socket atci-service-framework stream 660 radio system 
    673     user root 
    674     group radio system                         
    675 
    676 
    677 service atcid-daemon /system/bin/atcid 
    678     user root 
    679     group radio system
    680     
    681 service audio-daemon /system/bin/audiocmdservice_atci
    682     class main
    683     socket atci-audio stream 660 root system
    684     user root
    685     disabled
    686     oneshot
    687 
    688 service md_minilog_util /system/bin/md_minilog_util
    689     user root
    690     disabled
    691     oneshot
    692 
    693 service surfaceflinger /system/bin/surfaceflinger
    694     class main
    695 #    user system
    696     group graphics
    697     onrestart restart zygote
    698 
    699 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    700     class main
    701     socket zygote stream 660 root system
    702     onrestart write /sys/android_power/request_state wake
    703     onrestart write /sys/power/state on
    704     onrestart restart media
    705     onrestart restart netd
    706 
    707 #
    708 # MT6620 related services (Begin)
    709 #
    710 
    711 service hald /system/bin/hald
    712     class main
    713     socket hald stream 0660 root system
    714     
    715 service wpa_supplicant /system/bin/logwrapper /system/bin/wpa_supplicant
    716     group wifi
    717     disabled
    718     oneshot    
    719 
    720 service p2p_supplicant /system/bin/logwrapper /system/bin/p2p_supplicant
    721     group wifi
    722     disabled
    723     oneshot
    724   
    725 #
    726 # MT6620 related services (End)
    727 #
    728 
    729 service dhcpcd_wlan0 /system/bin/logwrapper /system/bin/dhcpcd -A -BK -dd
    730     class main
    731     disabled
    732     oneshot
    733 
    734 service dhcpcd_p2p /system/bin/logwrapper /system/bin/dhcpcd -A -BK -dd
    735     class main
    736     disabled
    737     oneshot
    738 
    739 service iprenew_wlan0 /system/bin/logwrapper /system/bin/dhcpcd -n
    740     class main
    741     disabled
    742     oneshot
    743 
    744 service DMAgent /system/bin/dm_agent_binder
    745     user root
    746 
    747 service drm /system/bin/drmserver
    748     class main
    749     user drm
    750     group system audio sdcard_rw net_raw inet drmrpc
    751 
    752 service media /system/bin/mediaserver
    753     class main
    754     user root
    755     group audio camera graphics inet net_bt net_bt_admin net_bw_acct drmrpc
    756     ioprio rt 4
    757 
    758 service mtkGD /system/bin/mtkGD
    759     class main
    760     user system
    761     group system
    762 
    763 service bootanim /system/bin/bootanimation
    764     class main
    765     user graphics
    766     group graphics
    767     disabled
    768     oneshot
    769 
    770 service dbus /system/bin/dbus-daemon --system --nofork
    771     class main
    772     socket dbus stream 660 bluetooth bluetooth
    773     user bluetooth
    774     group bluetooth net_bt_admin
    775 
    776 service bluetoothd /system/bin/bluetoothd -n
    777     class main
    778     socket bluetooth stream 660 bluetooth bluetooth
    779     socket dbus_bluetooth stream 660 bluetooth bluetooth
    780     # init.rc does not yet support applying capabilities, so run as root and
    781     # let bluetoothd drop uid to bluetooth with the right linux capabilities
    782     group bluetooth net_bt_admin misc
    783     disabled
    784 
    785 service mtkbt /system/bin/mtkbt
    786     socket bt.int.adp dgram 660 bluetooth net_bt
    787     socket bt.a2dp.stream dgram 660 bluetooth net_bt
    788     user bluetooth
    789     group net_bt bluetooth net_bt_admin sdcard_rw inet net_admin nvram net_raw
    790     oneshot
    791 
    792 
    793 service mdpd /system/bin/mdpd
    794     user system
    795     group system
    796 
    797 
    798 #
    799 #  Modem related services (Begin)
    800 #
    801 
    802 service ccci_fsd /system/bin/ccci_fsd
    803     user root
    804     class core
    805     oneshot
    806 
    807 service ccci_mdinit /system/bin/ccci_mdinit
    808     user root
    809     class core
    810     oneshot
    811 
    812 
    813 service pppd_gprs /system/etc/init.gprs-pppd file /etc/ppp/ppp_options
    814     user root
    815     group radio cache inet misc
    816         disabled
    817         oneshot
    818 
    819 #Add by T.Zh for ppp daemon
    820 service pppd /system/bin/pppd file /data/misc/ppp/ppp_options
    821     user root
    822     disabled 
    823     oneshot
    824 
    825 #
    826 #
    827 #  Modem related services (End)
    828 #
    829 
    830 
    831 service installd /system/bin/installd
    832     class main
    833     socket installd stream 600 system system
    834 
    835 service flash_recovery /system/etc/install-recovery.sh
    836     class main
    837     oneshot
    838 
    839 service sbchk /system/bin/sbchk
    840     oneshot
    841 
    842 service racoon /system/bin/racoon
    843     class main
    844     socket racoon stream 600 system system
    845     # IKE uses UDP port 500. Racoon will setuid to vpn after binding the port.
    846     group vpn net_admin inet
    847     disabled
    848     oneshot
    849 
    850 service mtpd /system/bin/mtpd
    851     class main
    852     socket mtpd stream 600 system system
    853     user vpn
    854     group vpn net_admin inet net_raw
    855     disabled
    856     oneshot
    857 
    858 service keystore /system/bin/keystore /data/misc/keystore
    859     class main
    860     user keystore
    861     group keystore
    862     socket keystore stream 666
    863 
    864 service dumpstate /system/bin/dumpstate -s
    865     class main
    866     socket dumpstate stream 0660 shell log
    867     disabled
    868     oneshot
    869 
    870 service agpsd /system/bin/mtk_agpsd
    871     class main
    872     socket agpsd stream 666 system system
    873 
    874 service mnld /system/xbin/mnld
    875     socket mnld stream 666 system system
    876     disabled
    877 
    878 service ipod /system/bin/logwrapper /system/bin/ipod
    879     user root
    880     group root
    881     disabled
    882 
    883 service GoogleOtaAgent /system/bin/GoogleOtaBinder
    884     user root
    885     
    886 service SDCardUpdateA /system/bin/SDCardUpdateBinder
    887     user root
    888         
    889 service mdlogger /system/bin/mdlogger
    890     class main
    891     disabled
    892     oneshot
    893 
    894 #
    895 #sensor service (begin)
    896 #
    897 
    898 service msensord /system/bin/msensord
    899     oneshot
    900     
    901 service ami304d /system/bin/logwrapper /system/bin/ami304d
    902     disabled
    903     oneshot
    904 
    905 service memsicd /system/bin/memsicd
    906      disabled
    907      oneshot
    908 
    909 service akmd8975 /system/bin/akmd8975
    910     disabled
    911     user compass
    912     group compass
    913 
    914 service orientationd /system/bin/orientationd
    915     disabled
    916     user compass
    917     group input
    918 
    919 service geomagneticd /system/bin/geomagneticd
    920     disabled
    921     user compass
    922     group system input
    923 #
    924 #sensor service (end)
    925 #
    926 
    927 #
    928 #emsvr service (start)
    929 #
    930 service emsvr /system/bin/em_svr
    931         user root
    932         
    933 service afmsvr /system/bin/afm_server
    934         user root
    935 
    936 #
    937 #emsvr service (end)
    938 #
    939 
    940 service shutdown /system/bin/logwrapper /system/bin/shutdown
    941     user root
    942     group root
    943     disabled
    944 
    945 service NvRAMAgent /system/bin/nvram_agent_binder
    946         user root
    947 
    948 service thermal_manager /system/bin/thermal_manager
    949     user root
    950     oneshot
    951 
    952 #service init.thermal /system/etc/init.thermal.sh
    953 #    user root
    954 #    oneshot
    955 
    956 #
    957 # MMProfile service
    958 #
    959 service mmp /system/bin/mmp read_config
    960     user root
    961     oneshot
    962 
    963 service sysctl /system/xbin/sysctld
    964     user root
    965     socket sysctl stream 0666 root root
    966     disabled
    init.rc
  • Many  Services  are  started in init.rc
  • 607 # SGX init
    608 service pvrsrvinit /system/vendor/bin/pvrsrvinit
    609     class main
    610     user root
    611     group root
    612     oneshot
    613 
    614 service servicemanager /system/bin/servicemanager
    615     class core
    616     user system
    617     group system
    618     critical
    619     onrestart restart zygote
    620     onrestart restart media
    621     onrestart restart surfaceflinger
    622     onrestart restart drm
    623 
    624 service vold /system/bin/vold
    625     class core
    626     socket vold stream 0660 root mount
    627     ioprio be 2
    628 
    629 service netd /system/bin/netd
    630     class main
    631     socket netd stream 0660 root system
    632     socket dnsproxyd stream 0660 root inet
    633     
    634 service netdiag /system/bin/netdiag
    635     class main
    636     socket netdiag stream 0666 root system 
    637     
    638 
    639 service nvram_daemon /system/bin/nvram_daemon
    640     class main
    641     user root
    642     group nvram
    643     oneshot
    

     

  • install usb driver
  • 1 import init.usb.rc
    2 import init.xlog.rc
  • setup the global environment
  •  1 export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
     2     export LD_LIBRARY_PATH /vendor/lib:/system/lib
     3     export ANDROID_BOOTLOGO 1
     4     export ANDROID_ROOT /system
     5     export ANDROID_ASSETS /system/app
     6     export ANDROID_DATA /data
     7     export EXTERNAL_STORAGE /mnt/sdcard
     8     export ASEC_MOUNTPOINT /mnt/asec
     9     export LOOP_MOUNTPOINT /mnt/obb
    10     export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar:/system/framework/mediatek-framework.jar:/system/framework/secondary_framework.jar
  • make directory and write device
  •  1     # Directory-target for where the secure container
     2     # imagefile directory will be bind-mounted
     3     mkdir /mnt/secure/asec  0700 root root
     4 
     5     # Secure container public mount points.
     6     mkdir /mnt/asec  0700 root system
     7     mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
     8 
     9     # Filesystem image public mount points.
    10     mkdir /mnt/obb 0700 root system
    11     mount tmpfs tmpfs /mnt/obb mode=0755,gid=1000
    12 
    13     write /proc/sys/kernel/panic_on_oops 1
    14     write /proc/sys/kernel/hung_task_timeout_secs 0
    15     write /proc/cpu/alignment 4
     1 # Set this property so surfaceflinger is not started by system_init
     2     setprop system_init.startsurfaceflinger 0
     3     class_start core
     4     class_start main
     5     class_start default
     6 
     7 on nonencrypted
     8     class_start late_start
     9 
    10 on charger
    11     class_start charger
    12 
    13 on property:vold.decrypt=trigger_reset_main
    14     class_reset main
     1 # Update the second boot logo
     2 service bootlogoupdater /system/bin/boot_logo_updater
     3     oneshot
     4 
     5 service ueventd /sbin/ueventd
     6     class core
     7     critical
     8 
     9 service console /system/bin/sh
    10     class core
    11     console
    12     disabled
    13     user root
    14     group log
    15 
    16 on property:ro.debuggable=1
    17     start console
    18 
    19 # adbd is controlled via property triggers in init.<platform>.usb.rc
    20 service adbd /sbin/adbd
    21     class core
    22     disabled

ServiceManager(NativeService)

  • service_manager.c
  •   1 /** Copyright 2008 The Android Open Source Project
      2  */
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <errno.h>
      7 #include <fcntl.h>
      8 
      9 #include <private/android_filesystem_config.h>
     10 
     11 #include "binder.h"
     12 
     13 #if 0
     14 #define LOGI(x...) fprintf(stderr, "svcmgr: " x)
     15 #define LOGE(x...) fprintf(stderr, "svcmgr: " x)
     16 #else
     17 #define LOG_TAG "ServiceManager"
     18 #include <cutils/log.h>
     19 #endif
     20 
     21 /** TODO:
     22  * These should come from a config file or perhaps be
     23  * based on some namespace rules of some sort (media
     24  * uid can register media.*, etc)
     25  */
     26 static struct {
     27     unsigned uid;
     28     const char *name;
     29 } allowed[] = {
     30 #ifdef LVMX
     31     { AID_MEDIA, "com.lifevibes.mx.ipc" },
     32 #endif
     33     { AID_MEDIA, "media.audio_flinger" },
     34     { AID_MEDIA, "media.player" },
     35     { AID_MEDIA, "media.camera" },
     36     { AID_MEDIA, "media.audio_policy" },
     37     { AID_DRM,   "drm.drmManager" },
     38     { AID_NFC,   "nfc" },
     39     { AID_RADIO, "radio.phone" },
     40     { AID_RADIO, "radio.sms" },
     41     { AID_RADIO, "radio.phonesubinfo" },
     42     { AID_RADIO, "radio.simphonebook" },
     43 /** TODO: remove after phone services are updated: */
     44     { AID_RADIO, "phone" },
     45     { AID_RADIO, "sip" },
     46     { AID_RADIO, "isms" },
     47     { AID_RADIO, "iphonesubinfo" },
     48     { AID_RADIO, "simphonebook" },
     49 };
     50 
     51 void *svcmgr_handle;
     52 
     53 const char *str8(uint16_t *x)
     54 {
     55     static char buf[128];
     56     unsigned max = 127;
     57     char *p = buf;
     58 
     59     if (x) {
     60         while (*x && max--) {
     61             *p++ = *x++;
     62         }
     63     }
     64     *p++ = 0;
     65     return buf;
     66 }
     67 
     68 int str16eq(uint16_t *a, const char *b)
     69 {
     70     while (*a && *b)
     71         if (*a++ != *b++) return 0;
     72     if (*a || *b)
     73         return 0;
     74     return 1;
     75 }
     76 
     77 int svc_can_register(unsigned uid, uint16_t *name)
     78 {
     79     unsigned n;
     80     
     81     if ((uid == 0) || (uid == AID_SYSTEM))
     82         return 1;
     83 
     84     for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
     85         if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
     86             return 1;
     87 
     88     return 0;
     89 }
     90 
     91 struct svcinfo 
     92 {
     93     struct svcinfo *next;
     94     void *ptr;
     95     struct binder_death death;
     96     unsigned len;
     97     uint16_t name[0];
     98 };
     99 
    100 struct svcinfo *svclist = 0;
    101 
    102 struct svcinfo *find_svc(uint16_t *s16, unsigned len)
    103 {
    104     struct svcinfo *si;
    105 
    106     for (si = svclist; si; si = si->next) {
    107         if ((len == si->len) &&
    108             !memcmp(s16, si->name, len * sizeof(uint16_t))) {
    109             return si;
    110         }
    111     }
    112     return 0;
    113 }
    114 
    115 void svcinfo_death(struct binder_state *bs, void *ptr)
    116 {
    117     struct svcinfo *si = ptr;
    118     LOGI("service '%s' died\n", str8(si->name));
    119     if (si->ptr) {
    120         binder_release(bs, si->ptr);
    121         si->ptr = 0;
    122     }   
    123 }
    124 
    125 uint16_t svcmgr_id[] = { 
    126     'a','n','d','r','o','i','d','.','o','s','.',
    127     'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' 
    128 };
    129   
    130 
    131 void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
    132 {
    133     struct svcinfo *si;
    134     si = find_svc(s, len);
    135 
    136 //    LOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0);
    137     if (si && si->ptr) {
    138         return si->ptr;
    139     } else {
    140         return 0;
    141     }
    142 }
    143 
    144 int do_add_service(struct binder_state *bs,
    145                    uint16_t *s, unsigned len,
    146                    void *ptr, unsigned uid)
    147 {
    148     struct svcinfo *si;
    149 //    LOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
    150 
    151     if (!ptr || (len == 0) || (len > 127))
    152         return -1;
    153 
    154     if (!svc_can_register(uid, s)) {
    155         LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
    156              str8(s), ptr, uid);
    157         return -1;
    158     }
    159 
    160     si = find_svc(s, len);
    161     if (si) {
    162         if (si->ptr) {
    163             LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
    164                  str8(s), ptr, uid);
    165             svcinfo_death(bs, si);
    166         }
    167         si->ptr = ptr;
    168     } else {
    169         si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
    170         if (!si) {
    171             LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",
    172                  str8(s), ptr, uid);
    173             return -1;
    174         }
    175         si->ptr = ptr;
    176         si->len = len;
    177         memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
    178         si->name[len] = '\0';
    179         si->death.func = svcinfo_death;
    180         si->death.ptr = si;
    181         si->next = svclist;
    182         svclist = si;
    183     }
    184 
    185     binder_acquire(bs, ptr);
    186     binder_link_to_death(bs, ptr, &si->death);
    187     return 0;
    188 }
    189 
    190 int svcmgr_handler(struct binder_state *bs,
    191                    struct binder_txn *txn,
    192                    struct binder_io *msg,
    193                    struct binder_io *reply)
    194 {
    195     struct svcinfo *si;
    196     uint16_t *s;
    197     unsigned len;
    198     void *ptr;
    199     uint32_t strict_policy;
    200 
    201 //    LOGI("target=%p code=%d pid=%d uid=%d\n",
    202 //         txn->target, txn->code, txn->sender_pid, txn->sender_euid);
    203 
    204     if (txn->target != svcmgr_handle)
    205         return -1;
    206 
    207     // Equivalent to Parcel::enforceInterface(), reading the RPC
    208     // header with the strict mode policy mask and the interface name.
    209     // Note that we ignore the strict_policy and don't propagate it
    210     // further (since we do no outbound RPCs anyway).
    211     strict_policy = bio_get_uint32(msg);
    212     s = bio_get_string16(msg, &len);
    213     if ((len != (sizeof(svcmgr_id) / 2)) ||
    214         memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
    215         fprintf(stderr,"invalid id %s\n", str8(s));
    216         return -1;
    217     }
    218 
    219     switch(txn->code) {
    220     case SVC_MGR_GET_SERVICE:
    221     case SVC_MGR_CHECK_SERVICE:
    222         s = bio_get_string16(msg, &len);
    223         ptr = do_find_service(bs, s, len);
    224         if (!ptr)
    225             break;
    226         bio_put_ref(reply, ptr);
    227         return 0;
    228 
    229     case SVC_MGR_ADD_SERVICE:
    230         s = bio_get_string16(msg, &len);
    231         ptr = bio_get_ref(msg);
    232         if (do_add_service(bs, s, len, ptr, txn->sender_euid))
    233             return -1;
    234         break;
    235 
    236     case SVC_MGR_LIST_SERVICES: {
    237         unsigned n = bio_get_uint32(msg);
    238 
    239         si = svclist;
    240         while ((n-- > 0) && si)
    241             si = si->next;
    242         if (si) {
    243             bio_put_string16(reply, si->name);
    244             return 0;
    245         }
    246         return -1;
    247     }
    248     default:
    249         LOGE("unknown code %d\n", txn->code);
    250         return -1;
    251     }
    252 
    253     bio_put_uint32(reply, 0);
    254     return 0;
    255 }
    256 
    257 int main(int argc, char **argv)
    258 {
    259     struct binder_state *bs;
    260     void *svcmgr = BINDER_SERVICE_MANAGER;
    261 
    262     bs = binder_open(128*1024);
    263 
    264     if (binder_become_context_manager(bs)) {
    265         LOGE("cannot become context manager (%s)\n", strerror(errno));
    266         return -1;
    267     }
    268 
    269     svcmgr_handle = svcmgr;
    270     binder_loop(bs, svcmgr_handler);
    271     return 0;
    272 }
    service_manager.c
  • service in init.rc
  • 1 service servicemanager /system/bin/servicemanager
    2     class core
    3     user system
    4     group system
    5     critical
    6     onrestart restart zygote
    7     onrestart restart media
    8     onrestart restart surfaceflinger
    9     onrestart restart drm
  • main() in service_manager
  •  1 int main(int argc, char **argv)
     2 {
     3     struct binder_state *bs;
     4     void *svcmgr = BINDER_SERVICE_MANAGER;//#define BINDER_SERVICE_MANAGER ((void*) 0),magic object
     5 
     6     bs = binder_open(128*1024);
     7 
     8     if (binder_become_context_manager(bs)) {
     9         LOGE("cannot become context manager (%s)\n", strerror(errno));
    10         return -1;
    11     }
    12 
    13     svcmgr_handle = svcmgr;
    14     binder_loop(bs, svcmgr_handler);//handler to handle with adding or finding service
    15     return 0;
    16 } 
  • struct svcinfo in service manager
  • 1 struct svcinfo 
    2 {
    3     struct svcinfo *next;
    4     void *ptr;
    5     struct binder_death death;
    6     unsigned len;
    7     uint16_t name[0];
    8 };
  •  add service in service_manager

  •  1 int do_add_service(struct binder_state *bs,uint16_t *s, unsigned len,void *ptr, unsigned uid)
     2 {
     3     struct svcinfo *si;
     4     if (!ptr || (len == 0) || (len > 127))
     5         return -1;
     6     if (!svc_can_register(uid, s)) {
     7         LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
     8              str8(s), ptr, uid);
     9         return -1;
    10     }
    11     si = find_svc(s, len);
    12     if (si) {
    13         if (si->ptr) {
    14             LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
    15                  str8(s), ptr, uid);
    16             svcinfo_death(bs, si);
    17         }
    18         si->ptr = ptr;
    19     } else {
    20         si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
    21         if (!si) {
    22             LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",
    23                  str8(s), ptr, uid);
    24             return -1;
    25         }
    26         si->ptr = ptr;
    27         si->len = len;
    28         memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
    29         si->name[len] = '\0';
    30         si->death.func = svcinfo_death;
    31         si->death.ptr = si;
    32         si->next = svclist;
    33         svclist = si;
    34     }
    35     binder_acquire(bs, ptr);
    36     binder_link_to_death(bs, ptr, &si->death);
    37     return 0;
    38 }
  •  1 int svcmgr_handler(struct binder_state *bs,
     2                    struct binder_txn *txn,
     3                    struct binder_io *msg,
     4                    struct binder_io *reply)
     5 {
     6     struct svcinfo *si;
     7     uint16_t *s;
     8     unsigned len;
     9     void *ptr;
    10     uint32_t strict_policy;
    11     if (txn->target != svcmgr_handle)
    12         return -1;
    13     strict_policy = bio_get_uint32(msg);
    14     s = bio_get_string16(msg, &len);
    15     if ((len != (sizeof(svcmgr_id) / 2)) ||
    16         memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
    17         fprintf(stderr,"invalid id %s\n", str8(s));
    18         return -1;
    19     }
    20     switch(txn->code) {
    21     case SVC_MGR_GET_SERVICE:
    22     case SVC_MGR_CHECK_SERVICE:
    23         s = bio_get_string16(msg, &len);
    24         ptr = do_find_service(bs, s, len);
    25         if (!ptr) break;
    26         bio_put_ref(reply, ptr);
    27         return 0;
    28     case SVC_MGR_ADD_SERVICE:
    29         s = bio_get_string16(msg, &len);
    30         ptr = bio_get_ref(msg);
    31         if (do_add_service(bs, s, len, ptr, txn->sender_euid))
    32             return -1;
    33         break;
    34     case SVC_MGR_LIST_SERVICES: {
    35         unsigned n = bio_get_uint32(msg);
    36         si = svclist;
    37         while ((n-- > 0) && si)
    38             si = si->next;
    39         if (si) {
    40             bio_put_string16(reply, si->name);
    41             return 0;
    42         }
    43         return -1;
    44     }
    45     default:
    46         LOGE("unknown code %d\n", txn->code);
    47         return -1;
    48     }
    49     bio_put_uint32(reply, 0);
    50     return 0;
    51 }
    svcmgr_handler
  • bind.h

  •   1 /** Copyright 2008 The Android Open Source Project
      2  */
      3 
      4 #ifndef _BINDER_H_
      5 #define _BINDER_H_
      6 
      7 #include <sys/ioctl.h>
      8 #include <linux/binder.h>
      9 
     10 struct binder_state;
     11 
     12 struct binder_object
     13 {
     14     uint32_t type;
     15     uint32_t flags;
     16     void *pointer;
     17     void *cookie;
     18 };
     19 
     20 struct binder_txn
     21 {
     22     void *target;
     23     void *cookie;
     24     uint32_t code;
     25     uint32_t flags;
     26 
     27     uint32_t sender_pid;
     28     uint32_t sender_euid;
     29 
     30     uint32_t data_size;
     31     uint32_t offs_size;
     32     void *data;
     33     void *offs;
     34 };
     35 
     36 struct binder_io
     37 {
     38     char *data;            /** pointer to read/write from */
     39     uint32_t *offs;        /** array of offsets */
     40     uint32_t data_avail;   /** bytes available in data buffer */
     41     uint32_t offs_avail;   /** entries available in offsets array */
     42 
     43     char *data0;           /** start of data buffer */
     44     uint32_t *offs0;       /** start of offsets buffer */
     45     uint32_t flags;
     46     uint32_t unused;
     47 };
     48 
     49 struct binder_death {
     50     void (*func)(struct binder_state *bs, void *ptr);
     51     void *ptr;
     52 };    
     53 
     54 /** the one magic object */
     55 #define BINDER_SERVICE_MANAGER ((void*) 0)
     56 
     57 #define SVC_MGR_NAME "android.os.IServiceManager"
     58 
     59 enum {
     60     SVC_MGR_GET_SERVICE = 1,
     61     SVC_MGR_CHECK_SERVICE,
     62     SVC_MGR_ADD_SERVICE,
     63     SVC_MGR_LIST_SERVICES,
     64 };
     65 
     66 typedef int (*binder_handler)(struct binder_state *bs,
     67                               struct binder_txn *txn,
     68                               struct binder_io *msg,
     69                               struct binder_io *reply);
     70 
     71 struct binder_state *binder_open(unsigned mapsize);
     72 void binder_close(struct binder_state *bs);
     73 
     74 /** initiate a blocking binder call
     75  * - returns zero on success
     76  */
     77 int binder_call(struct binder_state *bs,
     78                 struct binder_io *msg, struct binder_io *reply,
     79                 void *target, uint32_t code);
     80 
     81 /** release any state associate with the binder_io
     82  * - call once any necessary data has been extracted from the
     83  *   binder_io after binder_call() returns
     84  * - can safely be called even if binder_call() fails
     85  */
     86 void binder_done(struct binder_state *bs,
     87                  struct binder_io *msg, struct binder_io *reply);
     88 
     89 /** manipulate strong references */
     90 void binder_acquire(struct binder_state *bs, void *ptr);
     91 void binder_release(struct binder_state *bs, void *ptr);
     92 
     93 void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death);
     94 
     95 void binder_loop(struct binder_state *bs, binder_handler func);
     96 
     97 int binder_become_context_manager(struct binder_state *bs);
     98 
     99 /** allocate a binder_io, providing a stack-allocated working
    100  * buffer, size of the working buffer, and how many object
    101  * offset entries to reserve from the buffer
    102  */
    103 void bio_init(struct binder_io *bio, void *data,
    104            uint32_t maxdata, uint32_t maxobjects);
    105 
    106 void bio_destroy(struct binder_io *bio);
    107 
    108 void bio_put_obj(struct binder_io *bio, void *ptr);
    109 void bio_put_ref(struct binder_io *bio, void *ptr);
    110 void bio_put_uint32(struct binder_io *bio, uint32_t n);
    111 void bio_put_string16(struct binder_io *bio, const uint16_t *str);
    112 void bio_put_string16_x(struct binder_io *bio, const char *_str);
    113 
    114 uint32_t bio_get_uint32(struct binder_io *bio);
    115 uint16_t *bio_get_string16(struct binder_io *bio, uint32_t *sz);
    116 void *bio_get_obj(struct binder_io *bio);
    117 void *bio_get_ref(struct binder_io *bio);
    118 
    119 #endif
    bind.h
  • struct of bind

  •  1 struct binder_state
     2 {
     3     int fd;
     4     void *mapped;
     5     unsigned mapsize;
     6 };
     7 struct binder_object
     8 {
     9     uint32_t type;
    10     uint32_t flags;
    11     void *pointer;
    12     void *cookie;
    13 };
    14 struct binder_io
    15 {
    16     char *data;            /** pointer to read/write from */
    17     uint32_t *offs;        /** array of offsets */
    18     uint32_t data_avail;   /** bytes available in data buffer */
    19     uint32_t offs_avail;   /** entries available in offsets array */
    20     char *data0;           /** start of data buffer */
    21     uint32_t *offs0;       /** start of offsets buffer */
    22     uint32_t flags;
    23     uint32_t unused;
    24 };
    25 struct binder_death {
    26     void (*func)(struct binder_state *bs, void *ptr);
    27     void *ptr;
    28 };
  • bind.c
  •   1 /** Copyright 2008 The Android Open Source Project
      2  */
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <errno.h>
      7 #include <unistd.h>
      8 #include <fcntl.h>
      9 #include <sys/mman.h>
     10 
     11 #include "binder.h"
     12 
     13 #define MAX_BIO_SIZE (1 << 30)
     14 
     15 #define TRACE 0
     16 
     17 #define LOG_TAG "Binder"
     18 #include <cutils/log.h>
     19 
     20 void bio_init_from_txn(struct binder_io *io, struct binder_txn *txn);
     21 
     22 #if TRACE
     23 void hexdump(void *_data, unsigned len)
     24 {
     25     unsigned char *data = _data;
     26     unsigned count;
     27 
     28     for (count = 0; count < len; count++) {
     29         if ((count & 15) == 0)
     30             fprintf(stderr,"%04x:", count);
     31         fprintf(stderr," %02x %c", *data,
     32                 (*data < 32) || (*data > 126) ? '.' : *data);
     33         data++;
     34         if ((count & 15) == 15)
     35             fprintf(stderr,"\n");
     36     }
     37     if ((count & 15) != 0)
     38         fprintf(stderr,"\n");
     39 }
     40 
     41 void binder_dump_txn(struct binder_txn *txn)
     42 {
     43     struct binder_object *obj;
     44     unsigned *offs = txn->offs;
     45     unsigned count = txn->offs_size / 4;
     46 
     47     fprintf(stderr,"  target %p  cookie %p  code %08x  flags %08x\n",
     48             txn->target, txn->cookie, txn->code, txn->flags);
     49     fprintf(stderr,"  pid %8d  uid %8d  data %8d  offs %8d\n",
     50             txn->sender_pid, txn->sender_euid, txn->data_size, txn->offs_size);
     51     hexdump(txn->data, txn->data_size);
     52     while (count--) {
     53         obj = (void*) (((char*) txn->data) + *offs++);
     54         fprintf(stderr,"  - type %08x  flags %08x  ptr %p  cookie %p\n",
     55                 obj->type, obj->flags, obj->pointer, obj->cookie);
     56     }
     57 }
     58 
     59 #define NAME(n) case n: return #n
     60 const char *cmd_name(uint32_t cmd)
     61 {
     62     switch(cmd) {
     63         NAME(BR_NOOP);
     64         NAME(BR_TRANSACTION_COMPLETE);
     65         NAME(BR_INCREFS);
     66         NAME(BR_ACQUIRE);
     67         NAME(BR_RELEASE);
     68         NAME(BR_DECREFS);
     69         NAME(BR_TRANSACTION);
     70         NAME(BR_REPLY);
     71         NAME(BR_FAILED_REPLY);
     72         NAME(BR_DEAD_REPLY);
     73         NAME(BR_DEAD_BINDER);
     74     default: return "???";
     75     }
     76 }
     77 #else
     78 #define hexdump(a,b) do{} while (0)
     79 #define binder_dump_txn(txn)  do{} while (0)
     80 #endif
     81 
     82 #define BIO_F_SHARED    0x01  /** needs to be buffer freed */
     83 #define BIO_F_OVERFLOW  0x02  /** ran out of space */
     84 #define BIO_F_IOERROR   0x04
     85 #define BIO_F_MALLOCED  0x08  /** needs to be free()'d */
     86 
     87 struct binder_state
     88 {
     89     int fd;
     90     void *mapped;
     91     unsigned mapsize;
     92 };
     93 
     94 struct binder_state *binder_open(unsigned mapsize)
     95 {
     96     struct binder_state *bs;
     97 
     98     bs = malloc(sizeof(*bs));
     99     if (!bs) {
    100         errno = ENOMEM;
    101         return 0;
    102     }
    103 
    104     bs->fd = open("/dev/binder", O_RDWR);
    105     if (bs->fd < 0) {
    106         fprintf(stderr,"binder: cannot open device (%s)\n",
    107                 strerror(errno));
    108         goto fail_open;
    109     }
    110 
    111     bs->mapsize = mapsize;
    112     bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    113     if (bs->mapped == MAP_FAILED) {
    114         fprintf(stderr,"binder: cannot map device (%s)\n",
    115                 strerror(errno));
    116         goto fail_map;
    117     }
    118 
    119         /** TODO: check version */
    120 
    121     return bs;
    122 
    123 fail_map:
    124     close(bs->fd);
    125 fail_open:
    126     free(bs);
    127     return 0;
    128 }
    129 
    130 void binder_close(struct binder_state *bs)
    131 {
    132     munmap(bs->mapped, bs->mapsize);
    133     close(bs->fd);
    134     free(bs);
    135 }
    136 
    137 int binder_become_context_manager(struct binder_state *bs)
    138 {
    139     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
    140 }
    141 
    142 int binder_write(struct binder_state *bs, void *data, unsigned len)
    143 {
    144     struct binder_write_read bwr;
    145     int res;
    146     bwr.write_size = len;
    147     bwr.write_consumed = 0;
    148     bwr.write_buffer = (unsigned) data;
    149     bwr.read_size = 0;
    150     bwr.read_consumed = 0;
    151     bwr.read_buffer = 0;
    152     res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    153     if (res < 0) {
    154         fprintf(stderr,"binder_write: ioctl failed (%s)\n",
    155                 strerror(errno));
    156     }
    157     return res;
    158 }
    159 
    160 void binder_send_reply(struct binder_state *bs,
    161                        struct binder_io *reply,
    162                        void *buffer_to_free,
    163                        int status)
    164 {
    165     struct {
    166         uint32_t cmd_free;
    167         void *buffer;
    168         uint32_t cmd_reply;
    169         struct binder_txn txn;
    170     } __attribute__((packed)) data;
    171 
    172     data.cmd_free = BC_FREE_BUFFER;
    173     data.buffer = buffer_to_free;
    174     data.cmd_reply = BC_REPLY;
    175     data.txn.target = 0;
    176     data.txn.cookie = 0;
    177     data.txn.code = 0;
    178     if (status) {
    179         data.txn.flags = TF_STATUS_CODE;
    180         data.txn.data_size = sizeof(int);
    181         data.txn.offs_size = 0;
    182         data.txn.data = &status;
    183         data.txn.offs = 0;
    184     } else {
    185         data.txn.flags = 0;
    186         data.txn.data_size = reply->data - reply->data0;
    187         data.txn.offs_size = ((char*) reply->offs) - ((char*) reply->offs0);
    188         data.txn.data = reply->data0;
    189         data.txn.offs = reply->offs0;
    190     }
    191     binder_write(bs, &data, sizeof(data));
    192 }
    193 
    194 int binder_parse(struct binder_state *bs, struct binder_io *bio,
    195                  uint32_t *ptr, uint32_t size, binder_handler func)
    196 {
    197     int r = 1;
    198     uint32_t *end = ptr + (size / 4);
    199 
    200     while (ptr < end) {
    201         uint32_t cmd = *ptr++;
    202 #if TRACE
    203         fprintf(stderr,"%s:\n", cmd_name(cmd));
    204 #endif
    205         switch(cmd) {
    206         case BR_NOOP:
    207             break;
    208         case BR_TRANSACTION_COMPLETE:
    209             break;
    210         case BR_INCREFS:
    211         case BR_ACQUIRE:
    212         case BR_RELEASE:
    213         case BR_DECREFS:
    214 #if TRACE
    215             fprintf(stderr,"  %08x %08x\n", ptr[0], ptr[1]);
    216 #endif
    217             ptr += 2;
    218             break;
    219         case BR_TRANSACTION: {
    220             struct binder_txn *txn = (void *) ptr;
    221             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    222                 LOGE("parse: txn too small!\n");
    223                 return -1;
    224             }
    225             binder_dump_txn(txn);
    226             if (func) {
    227                 unsigned rdata[256/4];
    228                 struct binder_io msg;
    229                 struct binder_io reply;
    230                 int res;
    231 
    232                 bio_init(&reply, rdata, sizeof(rdata), 4);
    233                 bio_init_from_txn(&msg, txn);
    234                 res = func(bs, txn, &msg, &reply);
    235                 binder_send_reply(bs, &reply, txn->data, res);
    236             }
    237             ptr += sizeof(*txn) / sizeof(uint32_t);
    238             break;
    239         }
    240         case BR_REPLY: {
    241             struct binder_txn *txn = (void*) ptr;
    242             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    243                 LOGE("parse: reply too small!\n");
    244                 return -1;
    245             }
    246             binder_dump_txn(txn);
    247             if (bio) {
    248                 bio_init_from_txn(bio, txn);
    249                 bio = 0;
    250             } else {
    251                     /** todo FREE BUFFER */
    252             }
    253             ptr += (sizeof(*txn) / sizeof(uint32_t));
    254             r = 0;
    255             break;
    256         }
    257         case BR_DEAD_BINDER: {
    258             struct binder_death *death = (void*) *ptr++;
    259             death->func(bs, death->ptr);
    260             break;
    261         }
    262         case BR_FAILED_REPLY:
    263             r = -1;
    264             break;
    265         case BR_DEAD_REPLY:
    266             r = -1;
    267             break;
    268         default:
    269             LOGE("parse: OOPS %d\n", cmd);
    270             return -1;
    271         }
    272     }
    273 
    274     return r;
    275 }
    276 
    277 void binder_acquire(struct binder_state *bs, void *ptr)
    278 {
    279     uint32_t cmd[2];
    280     cmd[0] = BC_ACQUIRE;
    281     cmd[1] = (uint32_t) ptr;
    282     binder_write(bs, cmd, sizeof(cmd));
    283 }
    284 
    285 void binder_release(struct binder_state *bs, void *ptr)
    286 {
    287     uint32_t cmd[2];
    288     cmd[0] = BC_RELEASE;
    289     cmd[1] = (uint32_t) ptr;
    290     binder_write(bs, cmd, sizeof(cmd));
    291 }
    292 
    293 void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death)
    294 {
    295     uint32_t cmd[3];
    296     cmd[0] = BC_REQUEST_DEATH_NOTIFICATION;
    297     cmd[1] = (uint32_t) ptr;
    298     cmd[2] = (uint32_t) death;
    299     binder_write(bs, cmd, sizeof(cmd));
    300 }
    301 
    302 
    303 int binder_call(struct binder_state *bs,
    304                 struct binder_io *msg, struct binder_io *reply,
    305                 void *target, uint32_t code)
    306 {
    307     int res;
    308     struct binder_write_read bwr;
    309     struct {
    310         uint32_t cmd;
    311         struct binder_txn txn;
    312     } writebuf;
    313     unsigned readbuf[32];
    314 
    315     if (msg->flags & BIO_F_OVERFLOW) {
    316         fprintf(stderr,"binder: txn buffer overflow\n");
    317         goto fail;
    318     }
    319 
    320     writebuf.cmd = BC_TRANSACTION;
    321     writebuf.txn.target = target;
    322     writebuf.txn.code = code;
    323     writebuf.txn.flags = 0;
    324     writebuf.txn.data_size = msg->data - msg->data0;
    325     writebuf.txn.offs_size = ((char*) msg->offs) - ((char*) msg->offs0);
    326     writebuf.txn.data = msg->data0;
    327     writebuf.txn.offs = msg->offs0;
    328 
    329     bwr.write_size = sizeof(writebuf);
    330     bwr.write_consumed = 0;
    331     bwr.write_buffer = (unsigned) &writebuf;
    332     
    333     hexdump(msg->data0, msg->data - msg->data0);
    334     for (;;) {
    335         bwr.read_size = sizeof(readbuf);
    336         bwr.read_consumed = 0;
    337         bwr.read_buffer = (unsigned) readbuf;
    338 
    339         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    340 
    341         if (res < 0) {
    342             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
    343             goto fail;
    344         }
    345 
    346         res = binder_parse(bs, reply, readbuf, bwr.read_consumed, 0);
    347         if (res == 0) return 0;
    348         if (res < 0) goto fail;
    349     }
    350 
    351 fail:
    352     memset(reply, 0, sizeof(*reply));
    353     reply->flags |= BIO_F_IOERROR;
    354     return -1;
    355 }
    356 
    357 void binder_loop(struct binder_state *bs, binder_handler func)
    358 {
    359     int res;
    360     struct binder_write_read bwr;
    361     unsigned readbuf[32];
    362 
    363     bwr.write_size = 0;
    364     bwr.write_consumed = 0;
    365     bwr.write_buffer = 0;
    366     
    367     readbuf[0] = BC_ENTER_LOOPER;
    368     binder_write(bs, readbuf, sizeof(unsigned));
    369 
    370     for (;;) {
    371         bwr.read_size = sizeof(readbuf);
    372         bwr.read_consumed = 0;
    373         bwr.read_buffer = (unsigned) readbuf;
    374 
    375         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    376 
    377         if (res < 0) {
    378             LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
    379             break;
    380         }
    381 
    382         res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
    383         if (res == 0) {
    384             LOGE("binder_loop: unexpected reply?!\n");
    385             break;
    386         }
    387         if (res < 0) {
    388             LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
    389             break;
    390         }
    391     }
    392 }
    393 
    394 void bio_init_from_txn(struct binder_io *bio, struct binder_txn *txn)
    395 {
    396     bio->data = bio->data0 = txn->data;
    397     bio->offs = bio->offs0 = txn->offs;
    398     bio->data_avail = txn->data_size;
    399     bio->offs_avail = txn->offs_size / 4;
    400     bio->flags = BIO_F_SHARED;
    401 }
    402 
    403 void bio_init(struct binder_io *bio, void *data,
    404               uint32_t maxdata, uint32_t maxoffs)
    405 {
    406     uint32_t n = maxoffs * sizeof(uint32_t);
    407 
    408     if (n > maxdata) {
    409         bio->flags = BIO_F_OVERFLOW;
    410         bio->data_avail = 0;
    411         bio->offs_avail = 0;
    412         return;
    413     }
    414 
    415     bio->data = bio->data0 = data + n;
    416     bio->offs = bio->offs0 = data;
    417     bio->data_avail = maxdata - n;
    418     bio->offs_avail = maxoffs;
    419     bio->flags = 0;
    420 }
    421 
    422 static void *bio_alloc(struct binder_io *bio, uint32_t size)
    423 {
    424     size = (size + 3) & (~3);
    425     if (size > bio->data_avail) {
    426         bio->flags |= BIO_F_OVERFLOW;
    427         return 0;
    428     } else {
    429         void *ptr = bio->data;
    430         bio->data += size;
    431         bio->data_avail -= size;
    432         return ptr;
    433     }
    434 }
    435 
    436 void binder_done(struct binder_state *bs,
    437                  struct binder_io *msg,
    438                  struct binder_io *reply)
    439 {
    440     if (reply->flags & BIO_F_SHARED) {
    441         uint32_t cmd[2];
    442         cmd[0] = BC_FREE_BUFFER;
    443         cmd[1] = (uint32_t) reply->data0;
    444         binder_write(bs, cmd, sizeof(cmd));
    445         reply->flags = 0;
    446     }
    447 }
    448 
    449 static struct binder_object *bio_alloc_obj(struct binder_io *bio)
    450 {
    451     struct binder_object *obj;
    452 
    453     obj = bio_alloc(bio, sizeof(*obj));
    454     
    455     if (obj && bio->offs_avail) {
    456         bio->offs_avail--;
    457         *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
    458         return obj;
    459     }
    460 
    461     bio->flags |= BIO_F_OVERFLOW;
    462     return 0;
    463 }
    464 
    465 void bio_put_uint32(struct binder_io *bio, uint32_t n)
    466 {
    467     uint32_t *ptr = bio_alloc(bio, sizeof(n));
    468     if (ptr)
    469         *ptr = n;
    470 }
    471 
    472 void bio_put_obj(struct binder_io *bio, void *ptr)
    473 {
    474     struct binder_object *obj;
    475 
    476     obj = bio_alloc_obj(bio);
    477     if (!obj)
    478         return;
    479 
    480     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    481     obj->type = BINDER_TYPE_BINDER;
    482     obj->pointer = ptr;
    483     obj->cookie = 0;
    484 }
    485 
    486 void bio_put_ref(struct binder_io *bio, void *ptr)
    487 {
    488     struct binder_object *obj;
    489 
    490     if (ptr)
    491         obj = bio_alloc_obj(bio);
    492     else
    493         obj = bio_alloc(bio, sizeof(*obj));
    494 
    495     if (!obj)
    496         return;
    497 
    498     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    499     obj->type = BINDER_TYPE_HANDLE;
    500     obj->pointer = ptr;
    501     obj->cookie = 0;
    502 }
    503 
    504 void bio_put_string16(struct binder_io *bio, const uint16_t *str)
    505 {
    506     uint32_t len;
    507     uint16_t *ptr;
    508 
    509     if (!str) {
    510         bio_put_uint32(bio, 0xffffffff);
    511         return;
    512     }
    513 
    514     len = 0;
    515     while (str[len]) len++;
    516 
    517     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    518         bio_put_uint32(bio, 0xffffffff);
    519         return;
    520     }
    521 
    522     bio_put_uint32(bio, len);
    523     len = (len + 1) * sizeof(uint16_t);
    524     ptr = bio_alloc(bio, len);
    525     if (ptr)
    526         memcpy(ptr, str, len);
    527 }
    528 
    529 void bio_put_string16_x(struct binder_io *bio, const char *_str)
    530 {
    531     unsigned char *str = (unsigned char*) _str;
    532     uint32_t len;
    533     uint16_t *ptr;
    534 
    535     if (!str) {
    536         bio_put_uint32(bio, 0xffffffff);
    537         return;
    538     }
    539 
    540     len = strlen(_str);
    541 
    542     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    543         bio_put_uint32(bio, 0xffffffff);
    544         return;
    545     }
    546 
    547     bio_put_uint32(bio, len);
    548     ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
    549     if (!ptr)
    550         return;
    551 
    552     while (*str)
    553         *ptr++ = *str++;
    554     *ptr++ = 0;
    555 }
    556 
    557 static void *bio_get(struct binder_io *bio, uint32_t size)
    558 {
    559     size = (size + 3) & (~3);
    560 
    561     if (bio->data_avail < size){
    562         bio->data_avail = 0;
    563         bio->flags |= BIO_F_OVERFLOW;
    564         return 0;
    565     }  else {
    566         void *ptr = bio->data;
    567         bio->data += size;
    568         bio->data_avail -= size;
    569         return ptr;
    570     }
    571 }
    572 
    573 uint32_t bio_get_uint32(struct binder_io *bio)
    574 {
    575     uint32_t *ptr = bio_get(bio, sizeof(*ptr));
    576     return ptr ? *ptr : 0;
    577 }
    578 
    579 uint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz)
    580 {
    581     unsigned len;
    582     len = bio_get_uint32(bio);
    583     if (sz)
    584         *sz = len;
    585     return bio_get(bio, (len + 1) * sizeof(uint16_t));
    586 }
    587 
    588 static struct binder_object *_bio_get_obj(struct binder_io *bio)
    589 {
    590     unsigned n;
    591     unsigned off = bio->data - bio->data0;
    592 
    593         /** TODO: be smarter about this? */
    594     for (n = 0; n < bio->offs_avail; n++) {
    595         if (bio->offs[n] == off)
    596             return bio_get(bio, sizeof(struct binder_object));
    597     }
    598 
    599     bio->data_avail = 0;
    600     bio->flags |= BIO_F_OVERFLOW;
    601     return 0;
    602 }
    603 
    604 void *bio_get_ref(struct binder_io *bio)
    605 {
    606     struct binder_object *obj;
    607 
    608     obj = _bio_get_obj(bio);
    609     if (!obj)
    610         return 0;
    611 
    612     if (obj->type == BINDER_TYPE_HANDLE)
    613         return obj->pointer;
    614 
    615     return 0;
    616 }
    bind.c
  • bind_loop in bind.c

  •  1 void binder_loop(struct binder_state *bs, binder_handler func)
     2 {
     3     int res;
     4     struct binder_write_read bwr;
     5     unsigned readbuf[32];
     6     bwr.write_size = 0;
     7     bwr.write_consumed = 0;
     8     bwr.write_buffer = 0;    
     9     readbuf[0] = BC_ENTER_LOOPER;
    10     binder_write(bs, readbuf, sizeof(unsigned));
    11     for (;;) {
    12         bwr.read_size = sizeof(readbuf);
    13         bwr.read_consumed = 0;
    14         bwr.read_buffer = (unsigned) readbuf;
    15         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    16         if (res < 0) {
    17             LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
    18             break;
    19         }
    20         res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
    21         if (res == 0) {
    22             LOGE("binder_loop: unexpected reply?!\n");
    23             break;
    24         }
    25         if (res < 0) {
    26             LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
    27             break;
    28         }
    29     }
    30 }
  • parse
  •  1 int binder_parse(struct binder_state *bs, struct binder_io *bio,
     2                  uint32_t *ptr, uint32_t size, binder_handler func)
     3 {
     4     int r = 1;
     5     uint32_t *end = ptr + (size / 4);
     6     while (ptr < end) {
     7         uint32_t cmd = *ptr++;
     8 #if TRACE
     9         fprintf(stderr,"%s:\n", cmd_name(cmd));
    10 #endif
    11         switch(cmd) {
    12         case BR_NOOP:
    13             break;
    14         case BR_TRANSACTION_COMPLETE:
    15             break;
    16         case BR_INCREFS:
    17         case BR_ACQUIRE:
    18         case BR_RELEASE:
    19         case BR_DECREFS:
    20 #if TRACE
    21             fprintf(stderr,"  %08x %08x\n", ptr[0], ptr[1]);
    22 #endif
    23             ptr += 2;
    24             break;
    25         case BR_TRANSACTION: {
    26             struct binder_txn *txn = (void *) ptr;
    27             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    28                 LOGE("parse: txn too small!\n");
    29                 return -1;
    30             }
    31             binder_dump_txn(txn);
    32             if (func) {
    33                 unsigned rdata[256/4];
    34                 struct binder_io msg;
    35                 struct binder_io reply;
    36                 int res;
    37                 bio_init(&reply, rdata, sizeof(rdata), 4);
    38                 bio_init_from_txn(&msg, txn);
    39                 res = func(bs, txn, &msg, &reply);
    40                 binder_send_reply(bs, &reply, txn->data, res);
    41             }
    42             ptr += sizeof(*txn) / sizeof(uint32_t);
    43             break;
    44         }
    45         case BR_REPLY: {
    46             struct binder_txn *txn = (void*) ptr;
    47             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    48                 LOGE("parse: reply too small!\n");
    49                 return -1;
    50             }
    51             binder_dump_txn(txn);
    52             if (bio) {
    53                 bio_init_from_txn(bio, txn);
    54                 bio = 0;
    55             } else {
    56                     /** todo FREE BUFFER */
    57             }
    58             ptr += (sizeof(*txn) / sizeof(uint32_t));
    59             r = 0;
    60             break;
    61         }
    62         case BR_DEAD_BINDER: {
    63             struct binder_death *death = (void*) *ptr++;
    64             death->func(bs, death->ptr);
    65             break;
    66         }
    67         case BR_FAILED_REPLY:
    68             r = -1;
    69             break;
    70         case BR_DEAD_REPLY:
    71             r = -1;
    72             break;
    73         default:
    74             LOGE("parse: OOPS %d\n", cmd);
    75             return -1;
    76         }
    77     }
    78     return r;
    79 }
    bind_parce
  • open and close
  •  1 struct binder_state *binder_open(unsigned mapsize)
     2 {
     3     struct binder_state *bs;
     4     bs = malloc(sizeof(*bs));
     5     if (!bs) {
     6         errno = ENOMEM;
     7         return 0;
     8     }
     9     bs->fd = open("/dev/binder", O_RDWR);//open device
    10     if (bs->fd < 0) {
    11         fprintf(stderr,"binder: cannot open device (%s)\n",
    12                 strerror(errno));
    13         goto fail_open;
    14     }
    15     bs->mapsize = mapsize;
    16     bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);//memory map
    17     if (bs->mapped == MAP_FAILED) {
    18         fprintf(stderr,"binder: cannot map device (%s)\n",
    19                 strerror(errno));
    20         goto fail_map;
    21     }
    22     return bs;
    23 fail_map:
    24     close(bs->fd);
    25 fail_open:
    26     free(bs);
    27     return 0;
    28 }
    29 void binder_close(struct binder_state *bs)
    30 {
    31     munmap(bs->mapped, bs->mapsize);
    32     close(bs->fd);
    33     free(bs);
    34 }
    35 int binder_become_context_manager(struct binder_state *bs)
    36 {
    37     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);//as manager
    38 } 

Service Zygote

  • start service in init.rc
  • 1 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    2     class main
    3     socket zygote stream 660 root system
    4     onrestart write /sys/android_power/request_state wake
    5     onrestart write /sys/power/state on
    6     onrestart restart media
    7     onrestart restart netd
  • app_main.cpp
  •   1 /**
      2  * Main entry of app process.
      3  *
      4  * Starts the interpreted runtime, then starts up the application.
      5  *
      6  */
      7 
      8 #define LOG_TAG "appproc"
      9 
     10 #include <binder/IPCThreadState.h>
     11 #include <binder/ProcessState.h>
     12 #include <utils/Log.h>
     13 #include <cutils/process_name.h>
     14 #include <cutils/memory.h>
     15 #include <android_runtime/AndroidRuntime.h>
     16 
     17 #include <stdio.h>
     18 #include <unistd.h>
     19 
     20 namespace android {
     21 
     22 void app_usage()
     23 {
     24     fprintf(stderr,
     25         "Usage: app_process [java-options] cmd-dir start-class-name [options]\n");
     26 }
     27 
     28 class AppRuntime : public AndroidRuntime
     29 {
     30 public:
     31     AppRuntime()
     32         : mParentDir(NULL)
     33         , mClassName(NULL)
     34         , mClass(NULL)
     35         , mArgC(0)
     36         , mArgV(NULL)
     37     {
     38     }
     39 
     40 #if 0
     41     // this appears to be unused
     42     const char* getParentDir() const
     43     {
     44         return mParentDir;
     45     }
     46 #endif
     47 
     48     const char* getClassName() const
     49     {
     50         return mClassName;
     51     }
     52 
     53     virtual void onVmCreated(JNIEnv* env)
     54     {
     55         if (mClassName == NULL) {
     56             return; // Zygote. Nothing to do here.
     57         }
     58 
     59         /**
     60          * This is a little awkward because the JNI FindClass call uses the
     61          * class loader associated with the native method we're executing in.
     62          * If called in onStarted (from RuntimeInit.finishInit because we're
     63          * launching "am", for example), FindClass would see that we're calling
     64          * from a boot class' native method, and so wouldn't look for the class
     65          * we're trying to look up in CLASSPATH. Unfortunately it needs to,
     66          * because the "am" classes are not boot classes.
     67          *
     68          * The easiest fix is to call FindClass here, early on before we start
     69          * executing boot class Java code and thereby deny ourselves access to
     70          * non-boot classes.
     71          */
     72         char* slashClassName = toSlashClassName(mClassName);
     73         mClass = env->FindClass(slashClassName);
     74         if (mClass == NULL) {
     75             LOGE("ERROR: could not find class '%s'\n", mClassName);
     76         }
     77         free(slashClassName);
     78 
     79         mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
     80     }
     81 
     82     virtual void onStarted()
     83     {
     84         sp<ProcessState> proc = ProcessState::self();
     85         LOGV("App process: starting thread pool.\n");
     86         proc->startThreadPool();
     87 
     88         AndroidRuntime* ar = AndroidRuntime::getRuntime();
     89         ar->callMain(mClassName, mClass, mArgC, mArgV);
     90 
     91         IPCThreadState::self()->stopProcess();
     92     }
     93 
     94     virtual void onZygoteInit()
     95     {
     96         sp<ProcessState> proc = ProcessState::self();
     97         LOGV("App process: starting thread pool.\n");
     98         proc->startThreadPool();
     99     }
    100 
    101     virtual void onExit(int code)
    102     {
    103         if (mClassName == NULL) {
    104             // if zygote
    105             IPCThreadState::self()->stopProcess();
    106         }
    107 
    108         AndroidRuntime::onExit(code);
    109     }
    110 
    111 
    112     const char* mParentDir;
    113     const char* mClassName;
    114     jclass mClass;
    115     int mArgC;
    116     const char* const* mArgV;
    117 };
    118 
    119 }
    120 
    121 using namespace android;
    122 
    123 /**
    124  * sets argv0 to as much of newArgv0 as will fit
    125  */
    126 static void setArgv0(const char *argv0, const char *newArgv0)
    127 {
    128     strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
    129 }
    130 
    131 int main(int argc, const char* const argv[])
    132 {
    133     // These are global variables in ProcessState.cpp
    134     mArgC = argc;
    135     mArgV = argv;
    136 
    137     mArgLen = 0;
    138     for (int i=0; i<argc; i++) {
    139         mArgLen += strlen(argv[i]) + 1;
    140     }
    141     mArgLen--;
    142 
    143     AppRuntime runtime;
    144     const char* argv0 = argv[0];
    145 
    146     // Process command line arguments
    147     // ignore argv[0]
    148     argc--;
    149     argv++;
    150 
    151     // Everything up to '--' or first non '-' arg goes to the vm
    152 
    153     int i = runtime.addVmArguments(argc, argv);
    154 
    155     // Parse runtime arguments.  Stop at first unrecognized option.
    156     bool zygote = false;
    157     bool startSystemServer = false;
    158     bool application = false;
    159     const char* parentDir = NULL;
    160     const char* niceName = NULL;
    161     const char* className = NULL;
    162     while (i < argc) {
    163         const char* arg = argv[i++];
    164         if (!parentDir) {
    165             parentDir = arg;
    166         } else if (strcmp(arg, "--zygote") == 0) {
    167             zygote = true;
    168             niceName = "zygote";
    169         } else if (strcmp(arg, "--start-system-server") == 0) {
    170             startSystemServer = true;
    171         } else if (strcmp(arg, "--application") == 0) {
    172             application = true;
    173         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
    174             niceName = arg + 12;
    175         } else {
    176             className = arg;
    177             break;
    178         }
    179     }
    180 
    181     if (niceName && *niceName) {
    182         setArgv0(argv0, niceName);
    183         set_process_name(niceName);
    184     }
    185 
    186     runtime.mParentDir = parentDir;
    187 
    188     if (zygote) {
    189         runtime.start("com.android.internal.os.ZygoteInit",
    190                 startSystemServer ? "start-system-server" : "");
    191     } else if (className) {
    192         // Remainder of args get passed to startup class main()
    193         runtime.mClassName = className;
    194         runtime.mArgC = argc - i;
    195         runtime.mArgV = argv + i;
    196         runtime.start("com.android.internal.os.RuntimeInit",
    197                 application ? "application" : "tool");
    198     } else {
    199         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
    200         app_usage();
    201         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    202         return 10;
    203     }
    204 }
    app_main.cpp
     1 int main(int argc, const char* const argv[])
     2 {
     3     // These are global variables in ProcessState.cpp
     4     mArgC = argc;
     5     mArgV = argv;
     6     mArgLen = 0;
     7     for (int i=0; i<argc; i++) {
     8         mArgLen += strlen(argv[i]) + 1;
     9     }
    10     mArgLen--;
    11     AppRuntime runtime;
    12     const char* argv0 = argv[0];
    13     argc--;
    14     argv++;
    15     int i = runtime.addVmArguments(argc, argv);
    16     bool zygote = false;
    17     bool startSystemServer = false;
    18     bool application = false;
    19     const char* parentDir = NULL;
    20     const char* niceName = NULL;
    21     const char* className = NULL;
    22     while (i < argc) {
    23         const char* arg = argv[i++];
    24         if (!parentDir) {
    25             parentDir = arg;
    26         } else if (strcmp(arg, "--zygote") == 0) {
    27             zygote = true;
    28             niceName = "zygote";
    29         } else if (strcmp(arg, "--start-system-server") == 0) {
    30             startSystemServer = true;
    31         } else if (strcmp(arg, "--application") == 0) {
    32             application = true;
    33         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
    34             niceName = arg + 12;
    35         } else {
    36             className = arg;
    37             break;
    38         }
    39     }
    40     if (niceName && *niceName) {
    41         setArgv0(argv0, niceName);
    42         set_process_name(niceName);
    43     }
    44     runtime.mParentDir = parentDir;
    45     if (zygote) {
    46runtime.start("com.android.internal.os.ZygoteInit",
    47                 startSystemServer ? "start-system-server" : "");
    48     } else if (className) {
    49         // Remainder of args get passed to startup class main()
    50         runtime.mClassName = className;
    51         runtime.mArgC = argc - i;
    52         runtime.mArgV = argv + i;
    53runtime.start("com.android.internal.os.RuntimeInit",
    54                 application ? "application" : "tool");
    55     } else {
    56         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
    57         app_usage();
    58         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    59         return 10;
    60     }
    61 } 
  • AndroidRuntime.h
  •   1 /**
      2  * Copyright (C) 2005 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //
     18 
     19 #ifndef _RUNTIME_ANDROID_RUNTIME_H
     20 #define _RUNTIME_ANDROID_RUNTIME_H
     21 
     22 #include <utils/Errors.h>
     23 #include <binder/IBinder.h>
     24 #include <utils/String8.h>
     25 #include <utils/String16.h>
     26 #include <utils/Vector.h>
     27 #include <utils/threads.h>
     28 #include <pthread.h>
     29 #include <nativehelper/jni.h>
     30 
     31 
     32 namespace android {
     33 
     34 class AndroidRuntime
     35 {
     36 public:
     37     AndroidRuntime();
     38     virtual ~AndroidRuntime();
     39 
     40     enum StartMode {
     41         Zygote,
     42         SystemServer,
     43         Application,
     44         Tool,
     45     };
     46 
     47     /***
     48      * Register a set of methods in the specified class.
     49      */
     50     static int registerNativeMethods(JNIEnv* env,
     51         const char* className, const JNINativeMethod* gMethods, int numMethods);
     52 
     53     /***
     54      * Call a class's static main method with the given arguments,
     55      */
     56     status_t callMain(const char* className, jclass clazz, int argc,
     57         const char* const argv[]);
     58 
     59     /***
     60      * Find a class, with the input either of the form
     61      * "package/class" or "package.class".
     62      */
     63     static jclass findClass(JNIEnv* env, const char* className);
     64 
     65     int addVmArguments(int argc, const char* const argv[]);
     66 
     67     void start(const char *classname, const char* options);
     68 
     69     static AndroidRuntime* getRuntime();
     70 
     71     /***
     72      * This gets called after the VM has been created, but before we
     73      * run any code. Override it to make any FindClass calls that need
     74      * to use CLASSPATH.
     75      */
     76     virtual void onVmCreated(JNIEnv* env);
     77 
     78     /***
     79      * This gets called after the JavaVM has initialized.  Override it
     80      * with the system's native entry point.
     81      */
     82     virtual void onStarted() = 0;
     83 
     84     /***
     85      * This gets called after the JavaVM has initialized after a Zygote
     86      * fork. Override it to initialize threads, etc. Upon return, the
     87      * correct static main will be invoked.
     88      */
     89     virtual void onZygoteInit() {};
     90 
     91 
     92     /***
     93      * Called when the Java application exits.  The default
     94      * implementation calls exit(code).
     95      */
     96     virtual void onExit(int code);
     97 
     98     /*** create a new thread that is visible from Java */
     99     static android_thread_id_t createJavaThread(const char* name, void (*start)(void *),
    100         void* arg);
    101 
    102     /*** return a pointer to the VM running in this process */
    103     static JavaVM* getJavaVM() { return mJavaVM; }
    104 
    105     /*** return a pointer to the JNIEnv pointer for this thread */
    106     static JNIEnv* getJNIEnv();
    107 
    108     /*** return a new string corresponding to 'className' with all '.'s replaced by '/'s. */
    109     static char* toSlashClassName(const char* className);
    110 
    111 private:
    112     static int startReg(JNIEnv* env);
    113     void parseExtraOpts(char* extraOptsBuf);
    114     int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);
    115 
    116     Vector<JavaVMOption> mOptions;
    117 
    118     /** JNI JavaVM pointer */
    119     static JavaVM* mJavaVM;
    120 
    121     /**
    122      * Thread creation helpers.
    123      */
    124     static int javaCreateThreadEtc(
    125                                 android_thread_func_t entryFunction,
    126                                 void* userData,
    127                                 const char* threadName,
    128                                 int32_t threadPriority,
    129                                 size_t threadStackSize,
    130                                 android_thread_id_t* threadId);
    131     static int javaThreadShell(void* args);
    132 };
    133 
    134 }
    135 
    136 #endif
    AndroidRuntime.h
  • AndroidRuntime.cpp
  •    1 /* //device/libs/android_runtime/AndroidRuntime.cpp
       2 **
       3 ** Copyright 2006, The Android Open Source Project
       4 **
       5 ** Licensed under the Apache License, Version 2.0 (the "License"); 
       6 ** you may not use this file except in compliance with the License. 
       7 ** You may obtain a copy of the License at 
       8 **
       9 **     http://www.apache.org/licenses/LICENSE-2.0 
      10 **
      11 ** Unless required by applicable law or agreed to in writing, software 
      12 ** distributed under the License is distributed on an "AS IS" BASIS, 
      13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
      14 ** See the License for the specific language governing permissions and 
      15 ** limitations under the License.
      16 */
      17 
      18 #define LOG_TAG "AndroidRuntime"
      19 //#define LOG_NDEBUG 0
      20 
      21 #include <android_runtime/AndroidRuntime.h>
      22 #include <utils/IBinder.h>
      23 #include <utils/IServiceManager.h>
      24 #include <utils/Log.h>
      25 #include <utils/misc.h>
      26 #include <utils/Parcel.h>
      27 #include <utils/string_array.h>
      28 #include <utils/threads.h>
      29 #include <cutils/properties.h>
      30 
      31 #include <SkGraphics.h>
      32 #include <SkImageDecoder.h>
      33 #include <SkImageRef_GlobalPool.h>
      34 
      35 #include "jni.h"
      36 #include "JNIHelp.h"
      37 #include "android_util_Binder.h"
      38 
      39 #include <stdio.h>
      40 #include <signal.h>
      41 #include <sys/stat.h>
      42 #include <sys/types.h>
      43 #include <signal.h>
      44 #include <dirent.h>
      45 #include <assert.h>
      46 
      47 
      48 using namespace android;
      49 
      50 extern void register_BindTest();
      51 
      52 extern int register_android_os_Binder(JNIEnv* env);
      53 extern int register_android_os_Process(JNIEnv* env);
      54 extern int register_android_graphics_Bitmap(JNIEnv*);
      55 extern int register_android_graphics_BitmapFactory(JNIEnv*);
      56 extern int register_android_graphics_Camera(JNIEnv* env);
      57 extern int register_android_graphics_Graphics(JNIEnv* env);
      58 extern int register_android_graphics_Interpolator(JNIEnv* env);
      59 extern int register_android_graphics_LayerRasterizer(JNIEnv*);
      60 extern int register_android_graphics_MaskFilter(JNIEnv* env);
      61 extern int register_android_graphics_Movie(JNIEnv* env);
      62 extern int register_android_graphics_NinePatch(JNIEnv*);
      63 extern int register_android_graphics_PathEffect(JNIEnv* env);
      64 extern int register_android_graphics_Region(JNIEnv* env);
      65 extern int register_android_graphics_Shader(JNIEnv* env);
      66 extern int register_android_graphics_Typeface(JNIEnv* env);
      67 
      68 extern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env);
      69 extern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env);
      70 extern int register_android_opengl_jni_GLES10(JNIEnv* env);
      71 extern int register_android_opengl_jni_GLES10Ext(JNIEnv* env);
      72 extern int register_android_opengl_jni_GLES11(JNIEnv* env);
      73 extern int register_android_opengl_jni_GLES11Ext(JNIEnv* env);
      74 
      75 extern int register_android_hardware_Camera(JNIEnv *env);
      76 
      77 extern int register_android_hardware_SensorManager(JNIEnv *env);
      78 
      79 extern int register_android_media_AudioRecord(JNIEnv *env);
      80 extern int register_android_media_AudioSystem(JNIEnv *env);
      81 extern int register_android_media_AudioTrack(JNIEnv *env);
      82 extern int register_android_media_JetPlayer(JNIEnv *env);
      83 extern int register_android_media_ToneGenerator(JNIEnv *env);
      84 
      85 extern int register_android_message_digest_sha1(JNIEnv *env);
      86 
      87 extern int register_android_util_FloatMath(JNIEnv* env);
      88 
      89 // add by nfsnfs 
      90 extern int register_android_app_ActivityThread(JNIEnv* env);
      91 extern int register_android_content_ContentResolver(JNIEnv* env);
      92 //
      93 
      94 namespace android {
      95 
      96 /*
      97  * JNI-based registration functions.  Note these are properly contained in
      98  * namespace android.
      99  */
     100 extern int register_android_content_AssetManager(JNIEnv* env);
     101 extern int register_android_util_EventLog(JNIEnv* env);
     102 extern int register_android_util_Log(JNIEnv* env);
     103 extern int register_android_content_StringBlock(JNIEnv* env);
     104 extern int register_android_content_XmlBlock(JNIEnv* env);
     105 extern int register_android_emoji_EmojiFactory(JNIEnv* env);
     106 extern int register_android_graphics_Canvas(JNIEnv* env);
     107 extern int register_android_graphics_ColorFilter(JNIEnv* env);
     108 extern int register_android_graphics_DrawFilter(JNIEnv* env);
     109 extern int register_android_graphics_Matrix(JNIEnv* env);
     110 extern int register_android_graphics_Paint(JNIEnv* env);
     111 extern int register_android_graphics_Path(JNIEnv* env);
     112 extern int register_android_graphics_PathMeasure(JNIEnv* env);
     113 extern int register_android_graphics_Picture(JNIEnv*);
     114 extern int register_android_graphics_PorterDuff(JNIEnv* env);
     115 extern int register_android_graphics_Rasterizer(JNIEnv* env);
     116 extern int register_android_graphics_Xfermode(JNIEnv* env);
     117 extern int register_android_graphics_PixelFormat(JNIEnv* env);
     118 extern int register_com_android_internal_graphics_NativeUtils(JNIEnv *env);
     119 extern int register_android_view_Display(JNIEnv* env);
     120 extern int register_android_view_Surface(JNIEnv* env);
     121 extern int register_android_view_ViewRoot(JNIEnv* env);
     122 extern int register_android_database_CursorWindow(JNIEnv* env);
     123 extern int register_android_database_SQLiteDatabase(JNIEnv* env);
     124 extern int register_android_database_SQLiteDebug(JNIEnv* env);
     125 extern int register_android_database_SQLiteProgram(JNIEnv* env);
     126 extern int register_android_database_SQLiteQuery(JNIEnv* env);
     127 extern int register_android_database_SQLiteStatement(JNIEnv* env);
     128 extern int register_android_debug_JNITest(JNIEnv* env);
     129 extern int register_android_nio_utils(JNIEnv* env);
     130 extern int register_android_pim_EventRecurrence(JNIEnv* env);
     131 extern int register_android_text_format_Time(JNIEnv* env);
     132 extern int register_android_os_Debug(JNIEnv* env);
     133 extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
     134 extern int register_android_os_Power(JNIEnv *env);
     135 extern int register_android_os_StatFs(JNIEnv *env);
     136 extern int register_android_os_SystemProperties(JNIEnv *env);
     137 extern int register_android_os_Hardware(JNIEnv* env);
     138 extern int register_android_os_Exec(JNIEnv *env);
     139 extern int register_android_os_SystemClock(JNIEnv* env);
     140 extern int register_android_os_FileObserver(JNIEnv *env);
     141 extern int register_android_os_FileUtils(JNIEnv *env);
     142 extern int register_android_os_UEventObserver(JNIEnv* env);
     143 extern int register_android_os_MemoryFile(JNIEnv* env);
     144 extern int register_android_net_LocalSocketImpl(JNIEnv* env);
     145 extern int register_android_net_NetworkUtils(JNIEnv* env);
     146 extern int register_android_net_wifi_WifiManager(JNIEnv* env);
     147 extern int register_android_security_Md5MessageDigest(JNIEnv *env);
     148 extern int register_android_text_AndroidCharacter(JNIEnv *env);
     149 extern int register_android_text_KeyCharacterMap(JNIEnv *env);
     150 extern int register_android_opengl_classes(JNIEnv *env);
     151 extern int register_android_bluetooth_Database(JNIEnv* env);
     152 extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
     153 extern int register_android_bluetooth_BluetoothAudioGateway(JNIEnv* env);
     154 extern int register_android_bluetooth_RfcommSocket(JNIEnv *env);
     155 extern int register_android_bluetooth_ScoSocket(JNIEnv *env);
     156 extern int register_android_server_BluetoothDeviceService(JNIEnv* env);
     157 extern int register_android_server_BluetoothEventLoop(JNIEnv *env);
     158 extern int register_android_server_BluetoothA2dpService(JNIEnv* env);
     159 extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
     160 extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env);
     161 extern int register_android_util_Base64(JNIEnv* env);
     162 extern int register_android_location_GpsLocationProvider(JNIEnv* env);
     163 extern int register_android_backup_BackupDataInput(JNIEnv *env);
     164 extern int register_android_backup_BackupDataOutput(JNIEnv *env);
     165 extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
     166 extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);
     167 
     168 static AndroidRuntime* gCurRuntime = NULL;
     169 
     170 static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
     171 {
     172     if (jniThrowException(env, exc, msg) != 0)
     173         assert(false);
     174 }
     175 
     176 /*
     177  * Code written in the Java Programming Language calls here from main().
     178  */
     179 static void com_android_internal_os_RuntimeInit_finishInit(JNIEnv* env, jobject clazz)
     180 {
     181     gCurRuntime->onStarted();
     182 }
     183 
     184 static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
     185 {
     186     gCurRuntime->onZygoteInit();
     187 }
     188 
     189 static jint com_android_internal_os_RuntimeInit_isComputerOn(JNIEnv* env, jobject clazz)
     190 {
     191     return 1;
     192 }
     193 
     194 static void com_android_internal_os_RuntimeInit_turnComputerOn(JNIEnv* env, jobject clazz)
     195 {
     196 }
     197 
     198 static jint com_android_internal_os_RuntimeInit_getQwertyKeyboard(JNIEnv* env, jobject clazz)
     199 {
     200     char* value = getenv("qwerty");
     201     if (value != NULL && strcmp(value, "true") == 0) {
     202         return 1;
     203     }
     204     
     205     return 0;
     206 }
     207 
     208 /*
     209  * JNI registration.
     210  */
     211 static JNINativeMethod gMethods[] = {
     212     { "finishInit", "()V",
     213         (void*) com_android_internal_os_RuntimeInit_finishInit },
     214     { "zygoteInitNative", "()V",
     215         (void*) com_android_internal_os_RuntimeInit_zygoteInit },
     216     { "isComputerOn", "()I",
     217         (void*) com_android_internal_os_RuntimeInit_isComputerOn },
     218     { "turnComputerOn", "()V",
     219         (void*) com_android_internal_os_RuntimeInit_turnComputerOn },    
     220     { "getQwertyKeyboard", "()I",
     221         (void*) com_android_internal_os_RuntimeInit_getQwertyKeyboard },
     222 };
     223 
     224 int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
     225 {
     226     return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
     227         gMethods, NELEM(gMethods));
     228 }
     229 
     230 // ----------------------------------------------------------------------
     231 
     232 /*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
     233 
     234 
     235 AndroidRuntime::AndroidRuntime()
     236 {
     237     SkGraphics::Init();
     238     // this sets our preference for 16bit images during decode
     239     // in case the src is opaque and 24bit
     240     SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
     241     // This cache is shared between browser native images, and java "purgeable"
     242     // bitmaps. This globalpool is for images that do not either use the java
     243     // heap, or are not backed by ashmem. See BitmapFactory.cpp for the key
     244     // java call site.
     245     SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
     246     // There is also a global font cache, but its budget is specified in code
     247     // see SkFontHost_android.cpp
     248 
     249     // Pre-allocate enough space to hold a fair number of options.
     250     mOptions.setCapacity(20);
     251 
     252     assert(gCurRuntime == NULL);        // one per process
     253     gCurRuntime = this;
     254 }
     255 
     256 AndroidRuntime::~AndroidRuntime()
     257 {
     258     SkGraphics::Term();
     259 }
     260 
     261 /*
     262  * Register native methods using JNI.
     263  */
     264 /*static*/ int AndroidRuntime::registerNativeMethods(JNIEnv* env,
     265     const char* className, const JNINativeMethod* gMethods, int numMethods)
     266 {
     267     return jniRegisterNativeMethods(env, className, gMethods, numMethods);
     268 }
     269 
     270 /*
     271  * Call a static Java Programming Language function that takes no arguments and returns void.
     272  */
     273 status_t AndroidRuntime::callStatic(const char* className, const char* methodName)
     274 {
     275     JNIEnv* env;
     276     jclass clazz;
     277     jmethodID methodId;
     278 
     279     env = getJNIEnv();
     280     if (env == NULL)
     281         return UNKNOWN_ERROR;
     282 
     283     clazz = findClass(env, className);
     284     if (clazz == NULL) {
     285         LOGE("ERROR: could not find class '%s'\n", className);
     286         return UNKNOWN_ERROR;
     287     }
     288     methodId = env->GetStaticMethodID(clazz, methodName, "()V");
     289     if (methodId == NULL) {
     290         LOGE("ERROR: could not find method %s.%s\n", className, methodName);
     291         return UNKNOWN_ERROR;
     292     }
     293 
     294     env->CallStaticVoidMethod(clazz, methodId);
     295 
     296     return NO_ERROR;
     297 }
     298 
     299 status_t AndroidRuntime::callMain(
     300     const char* className, int argc, const char* const argv[])
     301 {
     302     JNIEnv* env;
     303     jclass clazz;
     304     jmethodID methodId;
     305 
     306     env = getJNIEnv();
     307     if (env == NULL)
     308         return UNKNOWN_ERROR;
     309 
     310     clazz = findClass(env, className);
     311     if (clazz == NULL) {
     312         LOGE("ERROR: could not find class '%s'\n", className);
     313         return UNKNOWN_ERROR;
     314     }
     315 
     316     methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
     317     if (methodId == NULL) {
     318         LOGE("ERROR: could not find method %s.main(String[])\n", className);
     319         return UNKNOWN_ERROR;
     320     }
     321 
     322     /*
     323      * We want to call main() with a String array with our arguments in it.
     324      * Create an array and populate it.
     325      */
     326     jclass stringClass;
     327     jobjectArray strArray;
     328 
     329     stringClass = env->FindClass("java/lang/String");
     330     strArray = env->NewObjectArray(argc, stringClass, NULL);
     331 
     332     for (int i = 0; i < argc; i++) {
     333         jstring argStr = env->NewStringUTF(argv[i]);
     334         env->SetObjectArrayElement(strArray, i, argStr);
     335     }
     336 
     337     env->CallStaticVoidMethod(clazz, methodId, strArray);
     338     return NO_ERROR;
     339 }
     340 
     341 /*
     342  * Find the named class.
     343  */
     344 jclass AndroidRuntime::findClass(JNIEnv* env, const char* className)
     345 {
     346     char* convName = NULL;
     347 
     348     if (env->ExceptionCheck()) {
     349         LOGE("ERROR: exception pending on entry to findClass()\n");
     350         return NULL;
     351     }
     352 
     353     /*
     354      * JNI FindClass uses class names with slashes, but ClassLoader.loadClass
     355      * uses the dotted "binary name" format.  We don't need to convert the
     356      * name with the new approach.
     357      */
     358 #if 0
     359     /* (convName only created if necessary -- use className) */
     360     for (char* cp = const_cast<char*>(className); *cp != '\0'; cp++) {
     361         if (*cp == '.') {
     362             if (convName == NULL) {
     363                 convName = strdup(className);
     364                 cp = convName + (cp-className);
     365                 className = convName;
     366             }
     367             *cp = '/';
     368         }
     369     }
     370 #endif
     371 
     372     /*
     373      * This is a little awkward because the JNI FindClass call uses the
     374      * class loader associated with the native method we're executing in.
     375      * Because this native method is part of a "boot" class, JNI doesn't
     376      * look for the class in CLASSPATH, which unfortunately is a likely
     377      * location for it.  (Had we issued the FindClass call before calling
     378      * into the VM -- at which point there isn't a native method frame on
     379      * the stack -- the VM would have checked CLASSPATH.  We have to do
     380      * this because we call into Java Programming Language code and
     381      * bounce back out.)
     382      *
     383      * JNI lacks a "find class in a specific class loader" operation, so we
     384      * have to do things the hard way.
     385      */
     386     jclass cls = NULL;
     387     //cls = env->FindClass(className);
     388 
     389     jclass javaLangClassLoader;
     390     jmethodID getSystemClassLoader, loadClass;
     391     jobject systemClassLoader;
     392     jstring strClassName;
     393 
     394     /* find the "system" class loader; none of this is expected to fail */
     395     javaLangClassLoader = env->FindClass("java/lang/ClassLoader");
     396     assert(javaLangClassLoader != NULL);
     397     getSystemClassLoader = env->GetStaticMethodID(javaLangClassLoader,
     398         "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
     399     loadClass = env->GetMethodID(javaLangClassLoader,
     400         "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
     401     assert(getSystemClassLoader != NULL && loadClass != NULL);
     402     systemClassLoader = env->CallStaticObjectMethod(javaLangClassLoader,
     403         getSystemClassLoader);
     404     assert(systemClassLoader != NULL);
     405 
     406     /* create an object for the class name string; alloc could fail */
     407     strClassName = env->NewStringUTF(className);
     408     if (env->ExceptionCheck()) {
     409         LOGE("ERROR: unable to convert '%s' to string\n", className);
     410         goto bail;
     411     }
     412     LOGV("system class loader is %p, loading %p (%s)\n",
     413         systemClassLoader, strClassName, className);
     414 
     415     /* try to find the named class */
     416     cls = (jclass) env->CallObjectMethod(systemClassLoader, loadClass,
     417                         strClassName);
     418     if (env->ExceptionCheck()) {
     419         LOGE("ERROR: unable to load class '%s' from %p\n",
     420             className, systemClassLoader);
     421         cls = NULL;
     422         goto bail;
     423     }
     424 
     425 bail:
     426     free(convName);
     427     return cls;
     428 }
     429 
     430 /*
     431  * The VM calls this through the "exit" hook.
     432  */
     433 static void runtime_exit(int code)
     434 {
     435     gCurRuntime->onExit(code);
     436     exit(code);
     437 }
     438 
     439 /*
     440  * The VM calls this through the "vfprintf" hook.
     441  *
     442  * We ignore "fp" and just write the results to the log file.
     443  */
     444 static void runtime_vfprintf(FILE* fp, const char* format, va_list ap)
     445 {
     446     LOG_PRI_VA(ANDROID_LOG_INFO, "vm-printf", format, ap);
     447 }
     448 
     449 
     450 /**
     451  * Add VM arguments to the to-be-executed VM
     452  * Stops at first non '-' argument (also stops at an argument of '--')
     453  * Returns the number of args consumed
     454  */
     455 int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
     456 {
     457     int i;
     458     
     459     for (i = 0; i<argc; i++) {
     460         if (argv[i][0] != '-') {
     461             return i;
     462         }
     463         if (argv[i][1] == '-' && argv[i][2] == 0) {
     464             return i+1;
     465         }
     466 
     467         JavaVMOption opt;
     468         memset(&opt, 0, sizeof(opt));
     469         opt.optionString = (char*)argv[i];
     470         mOptions.add(opt);
     471     }
     472     return i;
     473 }
     474 
     475 static int hasDir(const char* dir)
     476 {
     477     struct stat s;
     478     int res = stat(dir, &s);
     479     if (res == 0) {
     480         return S_ISDIR(s.st_mode);
     481     }
     482     return 0;
     483 }
     484 
     485 /*
     486  * We just want failed write() calls to just return with an error.
     487  */
     488 static void blockSigpipe()
     489 {
     490     sigset_t mask;
     491 
     492     sigemptyset(&mask);
     493     sigaddset(&mask, SIGPIPE);
     494     if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
     495         LOGW("WARNING: SIGPIPE not blocked\n");
     496 }
     497 
     498 /*
     499  * Read the persistent locale.
     500  */
     501 static void readLocale(char* language, char* region)
     502 {
     503     char propLang[PROPERTY_VALUE_MAX], propRegn[PROPERTY_VALUE_MAX];
     504     
     505     property_get("persist.sys.language", propLang, "");
     506     property_get("persist.sys.country", propRegn, "");
     507     if (*propLang == 0 && *propRegn == 0) {
     508         /* Set to ro properties, default is en_US */
     509         property_get("ro.product.locale.language", propLang, "en");
     510         property_get("ro.product.locale.region", propRegn, "US");
     511     }
     512     strncat(language, propLang, 2);
     513     strncat(region, propRegn, 2);
     514     //LOGD("language=%s region=%s\n", language, region);
     515 }
     516 
     517 void AndroidRuntime::start(const char* className, const bool startSystemServer)
     518 {
     519     LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
     520 
     521     JNIEnv* env;
     522     JavaVMInitArgs initArgs;
     523     JavaVMOption opt;
     524     char propBuf[PROPERTY_VALUE_MAX];
     525     char stackTraceFileBuf[PROPERTY_VALUE_MAX];
     526     char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
     527     char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
     528     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
     529     char* stackTraceFile = NULL;
     530     char* slashClassName = NULL;
     531     char* cp;
     532     bool checkJni = false;
     533     bool logStdio = false;
     534     enum { kEMDefault, kEMIntPortable, kEMIntFast } executionMode = kEMDefault;
     535 
     536     blockSigpipe();
     537 
     538     /* 
     539      * 'startSystemServer == true' means runtime is obslete and not run from 
     540      * init.rc anymore, so we print out the boot start event here.
     541      */
     542     if (startSystemServer) {
     543         /* track our progress through the boot sequence */
     544         const int LOG_BOOT_PROGRESS_START = 3000;
     545         LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 
     546                        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
     547     }
     548 
     549     property_get("dalvik.vm.checkjni", propBuf, "");
     550     if (strcmp(propBuf, "true") == 0) {
     551         checkJni = true;
     552     } else if (strcmp(propBuf, "false") != 0) {
     553         /* property is neither true nor false; fall back on kernel parameter */
     554         property_get("ro.kernel.android.checkjni", propBuf, "");
     555         if (propBuf[0] == '1') {
     556             checkJni = true;
     557         }
     558     }
     559 
     560     property_get("dalvik.vm.execution-mode", propBuf, "");
     561     if (strcmp(propBuf, "int:portable") == 0) {
     562         executionMode = kEMIntPortable;
     563     } else if (strcmp(propBuf, "int:fast") == 0) {
     564         executionMode = kEMIntFast;
     565     }
     566 
     567     property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");
     568 
     569     property_get("log.redirect-stdio", propBuf, "");
     570     if (strcmp(propBuf, "true") == 0) {
     571         logStdio = true;
     572     }
     573 
     574     strcpy(enableAssertBuf, "-ea:");
     575     property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");
     576 
     577     strcpy(jniOptsBuf, "-Xjniopts:");
     578     property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");
     579 
     580     const char* rootDir = getenv("ANDROID_ROOT");
     581     if (rootDir == NULL) {
     582         rootDir = "/system";
     583         if (!hasDir("/system")) {
     584             LOG_FATAL("No root directory specified, and /android does not exist.");
     585             return;
     586         }
     587         setenv("ANDROID_ROOT", rootDir, 1);
     588     }
     589 
     590     const char* kernelHack = getenv("LD_ASSUME_KERNEL");
     591     //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
     592 
     593     /* route exit() to our handler */
     594     opt.extraInfo = (void*) runtime_exit;
     595     opt.optionString = "exit";
     596     mOptions.add(opt);
     597 
     598     /* route fprintf() to our handler */
     599     opt.extraInfo = (void*) runtime_vfprintf;
     600     opt.optionString = "vfprintf";
     601     mOptions.add(opt);
     602 
     603     opt.extraInfo = NULL;
     604 
     605     /* enable verbose; standard options are { jni, gc, class } */
     606     //options[curOpt++].optionString = "-verbose:jni";
     607     opt.optionString = "-verbose:gc";
     608     mOptions.add(opt);
     609     //options[curOpt++].optionString = "-verbose:class";
     610 
     611 #ifdef CUSTOM_RUNTIME_HEAP_MAX
     612 #define __make_max_heap_opt(val) #val
     613 #define _make_max_heap_opt(val) "-Xmx" __make_max_heap_opt(val)
     614     opt.optionString = _make_max_heap_opt(CUSTOM_RUNTIME_HEAP_MAX);
     615 #undef __make_max_heap_opt
     616 #undef _make_max_heap_opt
     617 #else
     618     /* limit memory use to 16MB */
     619     opt.optionString = "-Xmx16m";
     620 #endif
     621     mOptions.add(opt);
     622 
     623     /*
     624      * Enable or disable dexopt features, such as bytecode verification and
     625      * calculation of register maps for precise GC.
     626      */
     627     property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
     628     if (dexoptFlagsBuf[0] != '\0') {
     629         const char* opc;
     630         const char* val;
     631 
     632         opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
     633         if (opc != NULL) {
     634             switch (*(opc+2)) {
     635             case 'n':   val = "-Xverify:none";      break;
     636             case 'r':   val = "-Xverify:remote";    break;
     637             case 'a':   val = "-Xverify:all";       break;
     638             default:    val = NULL;                 break;
     639             }
     640 
     641             if (val != NULL) {
     642                 opt.optionString = val;
     643                 mOptions.add(opt);
     644             }
     645         }
     646 
     647         opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
     648         if (opc != NULL) {
     649             switch (*(opc+2)) {
     650             case 'n':   val = "-Xdexopt:none";      break;
     651             case 'v':   val = "-Xdexopt:verified";  break;
     652             case 'a':   val = "-Xdexopt:all";       break;
     653             default:    val = NULL;                 break;
     654             }
     655 
     656             if (val != NULL) {
     657                 opt.optionString = val;
     658                 mOptions.add(opt);
     659             }
     660         }
     661 
     662         opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
     663         if (opc != NULL) {
     664             opt.optionString = "-Xgenregmap";
     665             mOptions.add(opt);
     666         }
     667     }
     668 
     669     /* enable debugging; set suspend=y to pause during VM init */
     670 #ifdef HAVE_ANDROID_OS
     671     /* use android ADB transport */
     672     opt.optionString =
     673         "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
     674 #else
     675     /* use TCP socket; address=0 means start at port 8000 and probe up */
     676     LOGI("Using TCP socket for JDWP\n");
     677     opt.optionString =
     678         "-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";
     679 #endif
     680     mOptions.add(opt);
     681 
     682     char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];
     683     property_get("dalvik.vm.deadlock-predict", propBuf, "");
     684     if (strlen(propBuf) > 0) {
     685         strcpy(enableDPBuf, "-Xdeadlockpredict:");
     686         strcat(enableDPBuf, propBuf);
     687         opt.optionString = enableDPBuf;
     688         mOptions.add(opt);
     689     }
     690 
     691     LOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
     692     if (checkJni) {
     693         /* extended JNI checking */
     694         opt.optionString = "-Xcheck:jni";
     695         mOptions.add(opt);
     696 
     697         /* set a cap on JNI global references */
     698         opt.optionString = "-Xjnigreflimit:2000";
     699         mOptions.add(opt);
     700 
     701         /* with -Xcheck:jni, this provides a JNI function call trace */
     702         //opt.optionString = "-verbose:jni";
     703         //mOptions.add(opt);
     704     }
     705     if (executionMode == kEMIntPortable) {
     706         opt.optionString = "-Xint:portable";
     707         mOptions.add(opt);
     708     } else if (executionMode == kEMIntFast) {
     709         opt.optionString = "-Xint:fast";
     710         mOptions.add(opt);
     711     }
     712     if (logStdio) {
     713         /* convert stdout/stderr to log messages */
     714         opt.optionString = "-Xlog-stdio";
     715         mOptions.add(opt);
     716     }
     717 
     718     if (enableAssertBuf[4] != '\0') {
     719         /* accept "all" to mean "all classes and packages" */
     720         if (strcmp(enableAssertBuf+4, "all") == 0)
     721             enableAssertBuf[3] = '\0';
     722         LOGI("Assertions enabled: '%s'\n", enableAssertBuf);
     723         opt.optionString = enableAssertBuf;
     724         mOptions.add(opt);
     725     } else {
     726         LOGV("Assertions disabled\n");
     727     }
     728 
     729     if (jniOptsBuf[10] != '\0') {
     730         LOGI("JNI options: '%s'\n", jniOptsBuf);
     731         opt.optionString = jniOptsBuf;
     732         mOptions.add(opt);
     733     }
     734 
     735     if (stackTraceFileBuf[0] != '\0') {
     736         static const char* stfOptName = "-Xstacktracefile:";
     737 
     738         stackTraceFile = (char*) malloc(strlen(stfOptName) +
     739             strlen(stackTraceFileBuf) +1);
     740         strcpy(stackTraceFile, stfOptName);
     741         strcat(stackTraceFile, stackTraceFileBuf);
     742         opt.optionString = stackTraceFile;
     743         mOptions.add(opt);
     744     }
     745     
     746     /* Set the properties for locale */
     747     {
     748         char langOption[sizeof("-Duser.language=") + 3];
     749         char regionOption[sizeof("-Duser.region=") + 3];
     750         strcpy(langOption, "-Duser.language=");
     751         strcpy(regionOption, "-Duser.region=");
     752         readLocale(langOption, regionOption);
     753         opt.extraInfo = NULL;
     754         opt.optionString = langOption;
     755         mOptions.add(opt);
     756         opt.optionString = regionOption;
     757         mOptions.add(opt);
     758     }
     759 
     760     /*
     761      * We don't have /tmp on the device, but we often have an SD card.  Apps
     762      * shouldn't use this, but some test suites might want to exercise it.
     763      */
     764     opt.optionString = "-Djava.io.tmpdir=/sdcard";
     765     mOptions.add(opt);
     766 
     767     initArgs.version = JNI_VERSION_1_4;
     768     initArgs.options = mOptions.editArray();
     769     initArgs.nOptions = mOptions.size();
     770     initArgs.ignoreUnrecognized = JNI_FALSE;
     771 
     772     /*
     773      * Initialize the VM.
     774      *
     775      * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     776      * If this call succeeds, the VM is ready, and we can start issuing
     777      * JNI calls.
     778      */
     779     if (JNI_CreateJavaVM(&mJavaVM, &env, &initArgs) < 0) {
     780         LOGE("JNI_CreateJavaVM failed\n");
     781         goto bail;
     782     }
     783 
     784     /*
     785      * Register android functions.
     786      */
     787     if (startReg(env) < 0) {
     788         LOGE("Unable to register all android natives\n");
     789         goto bail;
     790     }
     791 
     792     /*
     793      * We want to call main() with a String array with arguments in it.
     794      * At present we only have one argument, the class name.  Create an
     795      * array to hold it.
     796      */
     797     jclass stringClass;
     798     jobjectArray strArray;
     799     jstring classNameStr;
     800     jstring startSystemServerStr;
     801 
     802     stringClass = env->FindClass("java/lang/String");
     803     assert(stringClass != NULL);
     804     strArray = env->NewObjectArray(2, stringClass, NULL);
     805     assert(strArray != NULL);
     806     classNameStr = env->NewStringUTF(className);
     807     assert(classNameStr != NULL);
     808     env->SetObjectArrayElement(strArray, 0, classNameStr);
     809     startSystemServerStr = env->NewStringUTF(startSystemServer ? 
     810                                                  "true" : "false");
     811     env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
     812 
     813     /*
     814      * Start VM.  This thread becomes the main thread of the VM, and will
     815      * not return until the VM exits.
     816      */
     817     jclass startClass;
     818     jmethodID startMeth;
     819 
     820     slashClassName = strdup(className);
     821     for (cp = slashClassName; *cp != '\0'; cp++)
     822         if (*cp == '.')
     823             *cp = '/';
     824 
     825     startClass = env->FindClass(slashClassName);
     826     if (startClass == NULL) {
     827         LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
     828         /* keep going */
     829     } else {
     830         startMeth = env->GetStaticMethodID(startClass, "main",
     831             "([Ljava/lang/String;)V");
     832         if (startMeth == NULL) {
     833             LOGE("JavaVM unable to find main() in '%s'\n", className);
     834             /* keep going */
     835         } else {
     836             env->CallStaticVoidMethod(startClass, startMeth, strArray);
     837 
     838 #if 0
     839             if (env->ExceptionCheck())
     840                 threadExitUncaughtException(env);
     841 #endif
     842         }
     843     }
     844 
     845     LOGD("Shutting down VM\n");
     846     if (mJavaVM->DetachCurrentThread() != JNI_OK)
     847         LOGW("Warning: unable to detach main thread\n");
     848     if (mJavaVM->DestroyJavaVM() != 0)
     849         LOGW("Warning: VM did not shut down cleanly\n");
     850 
     851 bail:
     852     free(slashClassName);
     853     free(stackTraceFile);
     854 }
     855 
     856 void AndroidRuntime::start()
     857 {
     858     start("com.android.internal.os.RuntimeInit",
     859         false /* Don't start the system server */);
     860 }
     861 
     862 void AndroidRuntime::onExit(int code)
     863 {
     864     LOGI("AndroidRuntime onExit calling exit(%d)", code);
     865     exit(code);
     866 }
     867 
     868 /*
     869  * Get the JNIEnv pointer for this thread.
     870  *
     871  * Returns NULL if the slot wasn't allocated or populated.
     872  */
     873 /*static*/ JNIEnv* AndroidRuntime::getJNIEnv()
     874 {
     875     JNIEnv* env;
     876     JavaVM* vm = AndroidRuntime::getJavaVM();
     877     assert(vm != NULL);
     878 
     879     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
     880         return NULL;
     881     return env;
     882 }
     883 
     884 /*
     885  * Makes the current thread visible to the VM.
     886  *
     887  * The JNIEnv pointer returned is only valid for the current thread, and
     888  * thus must be tucked into thread-local storage.
     889  */
     890 static int javaAttachThread(const char* threadName, JNIEnv** pEnv)
     891 {
     892     JavaVMAttachArgs args;
     893     JavaVM* vm;
     894     jint result;
     895 
     896     vm = AndroidRuntime::getJavaVM();
     897     assert(vm != NULL);
     898 
     899     args.version = JNI_VERSION_1_4;
     900     args.name = (char*) threadName;
     901     args.group = NULL;
     902 
     903     result = vm->AttachCurrentThread(pEnv, (void*) &args);
     904     if (result != JNI_OK)
     905         LOGE("ERROR: thread attach failed\n");
     906 
     907     return result;
     908 }
     909 
     910 /*
     911  * Detach the current thread from the set visible to the VM.
     912  */
     913 static int javaDetachThread(void)
     914 {
     915     JavaVM* vm;
     916     jint result;
     917 
     918     vm = AndroidRuntime::getJavaVM();
     919     assert(vm != NULL);
     920 
     921     result = vm->DetachCurrentThread();
     922     if (result != JNI_OK)
     923         LOGE("ERROR: thread detach failed\n");
     924     return result;
     925 }
     926 
     927 /*
     928  * When starting a native thread that will be visible from the VM, we
     929  * bounce through this to get the right attach/detach action.
     930  * Note that this function calls free(args)
     931  */
     932 /*static*/ int AndroidRuntime::javaThreadShell(void* args) {
     933     void* start = ((void**)args)[0];
     934     void* userData = ((void **)args)[1];
     935     char* name = (char*) ((void **)args)[2];        // we own this storage
     936     free(args);
     937     JNIEnv* env;
     938     int result;
     939 
     940     /* hook us into the VM */
     941     if (javaAttachThread(name, &env) != JNI_OK)
     942         return -1;
     943 
     944     /* start the thread running */
     945     result = (*(android_thread_func_t)start)(userData);
     946 
     947     /* unhook us */
     948     javaDetachThread();
     949     free(name);
     950 
     951     return result;
     952 }
     953 
     954 /*
     955  * This is invoked from androidCreateThreadEtc() via the callback
     956  * set with androidSetCreateThreadFunc().
     957  *
     958  * We need to create the new thread in such a way that it gets hooked
     959  * into the VM before it really starts executing.
     960  */
     961 /*static*/ int AndroidRuntime::javaCreateThreadEtc(
     962                                 android_thread_func_t entryFunction, 
     963                                 void* userData,
     964                                 const char* threadName,
     965                                 int32_t threadPriority,
     966                                 size_t threadStackSize,
     967                                 android_thread_id_t* threadId)
     968 {
     969     void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
     970     int result;
     971 
     972     assert(threadName != NULL);
     973 
     974     args[0] = (void*) entryFunction;
     975     args[1] = userData;
     976     args[2] = (void*) strdup(threadName);   // javaThreadShell must free
     977 
     978     result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args,
     979         threadName, threadPriority, threadStackSize, threadId);
     980     return result;
     981 }
     982 
     983 /*
     984  * Create a thread that is visible from the VM.
     985  *
     986  * This is called from elsewhere in the library.
     987  */
     988 /*static*/ void AndroidRuntime::createJavaThread(const char* name,
     989     void (*start)(void *), void* arg)
     990 {
     991     javaCreateThreadEtc((android_thread_func_t) start, arg, name,
     992         ANDROID_PRIORITY_DEFAULT, 0, NULL);
     993 }
     994 
     995 #if 0
     996 static void quickTest(void* arg)
     997 {
     998     const char* str = (const char*) arg;
     999 
    1000     printf("In quickTest: %s\n", str);
    1001 }
    1002 #endif
    1003 
    1004 #ifdef NDEBUG
    1005     #define REG_JNI(name)      { name }
    1006     struct RegJNIRec {
    1007         int (*mProc)(JNIEnv*);
    1008     };
    1009 #else
    1010     #define REG_JNI(name)      { name, #name }
    1011     struct RegJNIRec {
    1012         int (*mProc)(JNIEnv*);
    1013         const char* mName;
    1014     };
    1015 #endif
    1016 
    1017 typedef void (*RegJAMProc)();
    1018 
    1019 static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
    1020 {
    1021     for (size_t i = 0; i < count; i++) {
    1022         if (array[i].mProc(env) < 0) {
    1023 #ifndef NDEBUG
    1024             LOGD("----------!!! %s failed to load\n", array[i].mName);
    1025 #endif
    1026             return -1;
    1027         }
    1028     }
    1029     return 0;
    1030 }
    1031 
    1032 static void register_jam_procs(const RegJAMProc array[], size_t count)
    1033 {
    1034     for (size_t i = 0; i < count; i++) {
    1035         array[i]();
    1036     }
    1037 }
    1038 
    1039 static const RegJNIRec gRegJNI[] = {
    1040     REG_JNI(register_android_debug_JNITest),
    1041     REG_JNI(register_com_android_internal_os_RuntimeInit),
    1042     REG_JNI(register_android_os_SystemClock),
    1043     REG_JNI(register_android_util_EventLog),
    1044     REG_JNI(register_android_util_Log),
    1045     REG_JNI(register_android_util_FloatMath),
    1046     REG_JNI(register_android_text_format_Time),
    1047     REG_JNI(register_android_pim_EventRecurrence),
    1048     REG_JNI(register_android_content_AssetManager),
    1049     REG_JNI(register_android_content_StringBlock),
    1050     REG_JNI(register_android_content_XmlBlock),
    1051     REG_JNI(register_android_emoji_EmojiFactory),
    1052     REG_JNI(register_android_security_Md5MessageDigest),
    1053     REG_JNI(register_android_text_AndroidCharacter),
    1054     REG_JNI(register_android_text_KeyCharacterMap),
    1055     REG_JNI(register_android_os_Process),
    1056     REG_JNI(register_android_os_Binder),
    1057     REG_JNI(register_android_os_Hardware),
    1058     REG_JNI(register_android_view_Display),
    1059     REG_JNI(register_android_nio_utils),
    1060     REG_JNI(register_android_graphics_PixelFormat),
    1061     REG_JNI(register_android_graphics_Graphics),
    1062     REG_JNI(register_android_view_Surface),
    1063     REG_JNI(register_android_view_ViewRoot),
    1064     REG_JNI(register_com_google_android_gles_jni_EGLImpl),
    1065     REG_JNI(register_com_google_android_gles_jni_GLImpl),
    1066     REG_JNI(register_android_opengl_jni_GLES10),
    1067     REG_JNI(register_android_opengl_jni_GLES10Ext),
    1068     REG_JNI(register_android_opengl_jni_GLES11),
    1069     REG_JNI(register_android_opengl_jni_GLES11Ext),
    1070 
    1071     REG_JNI(register_android_graphics_Bitmap),
    1072     REG_JNI(register_android_graphics_BitmapFactory),
    1073     REG_JNI(register_android_graphics_Camera),
    1074     REG_JNI(register_android_graphics_Canvas),
    1075     REG_JNI(register_android_graphics_ColorFilter),
    1076     REG_JNI(register_android_graphics_DrawFilter),
    1077     REG_JNI(register_android_graphics_Interpolator),
    1078     REG_JNI(register_android_graphics_LayerRasterizer),
    1079     REG_JNI(register_android_graphics_MaskFilter),
    1080     REG_JNI(register_android_graphics_Matrix),
    1081     REG_JNI(register_android_graphics_Movie),
    1082     REG_JNI(register_android_graphics_NinePatch),
    1083     REG_JNI(register_android_graphics_Paint),
    1084     REG_JNI(register_android_graphics_Path),
    1085     REG_JNI(register_android_graphics_PathMeasure),
    1086     REG_JNI(register_android_graphics_PathEffect),
    1087     REG_JNI(register_android_graphics_Picture),
    1088     REG_JNI(register_android_graphics_PorterDuff),
    1089     REG_JNI(register_android_graphics_Rasterizer),
    1090     REG_JNI(register_android_graphics_Region),
    1091     REG_JNI(register_android_graphics_Shader),
    1092     REG_JNI(register_android_graphics_Typeface),
    1093     REG_JNI(register_android_graphics_Xfermode),
    1094     REG_JNI(register_com_android_internal_graphics_NativeUtils),
    1095 
    1096     REG_JNI(register_android_database_CursorWindow),
    1097     REG_JNI(register_android_database_SQLiteDatabase),
    1098     REG_JNI(register_android_database_SQLiteDebug),
    1099     REG_JNI(register_android_database_SQLiteProgram),
    1100     REG_JNI(register_android_database_SQLiteQuery),
    1101     REG_JNI(register_android_database_SQLiteStatement),
    1102     REG_JNI(register_android_os_Debug),
    1103     REG_JNI(register_android_os_Exec),
    1104     REG_JNI(register_android_os_FileObserver),
    1105     REG_JNI(register_android_os_FileUtils),
    1106     REG_JNI(register_android_os_ParcelFileDescriptor),
    1107     REG_JNI(register_android_os_Power),
    1108     REG_JNI(register_android_os_StatFs),
    1109     REG_JNI(register_android_os_SystemProperties),
    1110     REG_JNI(register_android_os_UEventObserver),
    1111     REG_JNI(register_android_net_LocalSocketImpl),
    1112     REG_JNI(register_android_net_NetworkUtils),
    1113     REG_JNI(register_android_net_wifi_WifiManager),
    1114     REG_JNI(register_android_os_MemoryFile),
    1115     REG_JNI(register_com_android_internal_os_ZygoteInit),
    1116     REG_JNI(register_android_hardware_Camera),
    1117     REG_JNI(register_android_hardware_SensorManager),
    1118     REG_JNI(register_android_media_AudioRecord),
    1119     REG_JNI(register_android_media_AudioSystem),
    1120     REG_JNI(register_android_media_AudioTrack),
    1121     REG_JNI(register_android_media_JetPlayer),
    1122     REG_JNI(register_android_media_ToneGenerator),
    1123 
    1124     REG_JNI(register_android_opengl_classes),
    1125     REG_JNI(register_android_bluetooth_Database),
    1126     REG_JNI(register_android_bluetooth_HeadsetBase),
    1127     REG_JNI(register_android_bluetooth_BluetoothAudioGateway),
    1128     REG_JNI(register_android_bluetooth_RfcommSocket),
    1129     REG_JNI(register_android_bluetooth_ScoSocket),
    1130     REG_JNI(register_android_server_BluetoothDeviceService),
    1131     REG_JNI(register_android_server_BluetoothEventLoop),
    1132     REG_JNI(register_android_server_BluetoothA2dpService),
    1133     REG_JNI(register_android_message_digest_sha1),
    1134     REG_JNI(register_android_ddm_DdmHandleNativeHeap),
    1135     REG_JNI(register_android_util_Base64),
    1136     REG_JNI(register_android_location_GpsLocationProvider),
    1137     REG_JNI(register_android_backup_BackupDataInput),
    1138     REG_JNI(register_android_backup_BackupDataOutput),
    1139     REG_JNI(register_android_backup_FileBackupHelperBase),
    1140     REG_JNI(register_android_backup_BackupHelperDispatcher),
    1141     // add by nfsnfs
    1142     REG_JNI(register_android_app_ActivityThread),
    1143     REG_JNI(register_android_content_ContentResolver),
    1144     //
    1145 };
    1146 
    1147 /*
    1148  * Register android native functions with the VM.
    1149  */
    1150 /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
    1151 {
    1152     /*
    1153      * This hook causes all future threads created in this process to be
    1154      * attached to the JavaVM.  (This needs to go away in favor of JNI
    1155      * Attach calls.)
    1156      */
    1157     androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
    1158 
    1159     LOGD("--- registering native functions ---\n");
    1160 
    1161     /*
    1162      * Every "register" function calls one or more things that return
    1163      * a local reference (e.g. FindClass).  Because we haven't really
    1164      * started the VM yet, they're all getting stored in the base frame
    1165      * and never released.  Use Push/Pop to manage the storage.
    1166      */
    1167     env->PushLocalFrame(200);
    1168 
    1169     if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
    1170         env->PopLocalFrame(NULL);
    1171         return -1;
    1172     }
    1173     env->PopLocalFrame(NULL);
    1174 
    1175     //createJavaThread("fubar", quickTest, (void*) "hello");
    1176 
    1177     return 0;
    1178 }
    1179 
    1180 AndroidRuntime* AndroidRuntime::getRuntime()
    1181 {
    1182     return gCurRuntime;
    1183 }
    1184 
    1185 /**
    1186  * Used by WithFramework to register native functions.
    1187  */
    1188 extern "C"
    1189 jint Java_com_android_internal_util_WithFramework_registerNatives(
    1190         JNIEnv* env, jclass clazz) {
    1191     return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
    1192 }
    1193 
    1194 /**
    1195  * Used by LoadClass to register native functions.
    1196  */
    1197 extern "C"
    1198 jint Java_LoadClass_registerNatives(JNIEnv* env, jclass clazz) {
    1199     return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
    1200 }
    1201 
    1202 }   // namespace android
    AndroidRuntime.cpp
  • Constructor in AndroidRuntime
  • 1 AndroidRuntime::AndroidRuntime()
    2 {
    3     SkGraphics::Init();
    4     SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
    5     SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
    6     mOptions.setCapacity(20);
    7     assert(gCurRuntime == NULL);    
    8     gCurRuntime = this;
    9 }
  • start method in AndroidRuntime
  •   1 void AndroidRuntime::start(const char* className, const bool startSystemServer)
      2 {
      3     JNIEnv* env;
      4     JavaVMInitArgs initArgs;
      5     JavaVMOption opt;
      6     char propBuf[PROPERTY_VALUE_MAX];
      7     char stackTraceFileBuf[PROPERTY_VALUE_MAX];
      8     char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
      9     char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
     10     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
     11     char* stackTraceFile = NULL;
     12     char* slashClassName = NULL;
     13     char* cp;
     14     bool checkJni = false;
     15     bool logStdio = false;
     16     enum { kEMDefault, kEMIntPortable, kEMIntFast } executionMode = kEMDefault;
     17     blockSigpipe();   
     18     if (startSystemServer) {
     19         /* track our progress through the boot sequence */
     20         const int LOG_BOOT_PROGRESS_START = 3000;
     21         LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
     22     }
     23     property_get("dalvik.vm.checkjni", propBuf, "");
     24     if (strcmp(propBuf, "true") == 0) {
     25         checkJni = true;
     26     } else if (strcmp(propBuf, "false") != 0) {
     27         property_get("ro.kernel.android.checkjni", propBuf, "");
     28         if (propBuf[0] == '1') {
     29             checkJni = true;
     30         }
     31     }
     32     property_get("dalvik.vm.execution-mode", propBuf, "");
     33     if (strcmp(propBuf, "int:portable") == 0) {
     34         executionMode = kEMIntPortable;
     35     } else if (strcmp(propBuf, "int:fast") == 0) {
     36         executionMode = kEMIntFast;
     37     }
     38     property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");
     39     property_get("log.redirect-stdio", propBuf, "");
     40     if (strcmp(propBuf, "true") == 0) {
     41         logStdio = true;
     42     }
     43     strcpy(enableAssertBuf, "-ea:");
     44     property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");
     45     strcpy(jniOptsBuf, "-Xjniopts:");
     46     property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");
     47     const char* rootDir = getenv("ANDROID_ROOT");
     48     if (rootDir == NULL) {
     49         rootDir = "/system";
     50         if (!hasDir("/system")) {
     51             LOG_FATAL("No root directory specified, and /android does not exist.");
     52             return;
     53         }
     54         setenv("ANDROID_ROOT", rootDir, 1);
     55     }
     56     const char* kernelHack = getenv("LD_ASSUME_KERNEL");
     57     opt.extraInfo = (void*) runtime_exit;
     58     opt.optionString = "exit";
     59     mOptions.add(opt);
     60     /* route fprintf() to our handler */
     61     opt.extraInfo = (void*) runtime_vfprintf;
     62     opt.optionString = "vfprintf";
     63     mOptions.add(opt);
     64     opt.extraInfo = NULL;
     65     /* enable verbose; standard options are { jni, gc, class } */
     66     //options[curOpt++].optionString = "-verbose:jni";
     67     opt.optionString = "-verbose:gc";
     68     mOptions.add(opt);
     69     //options[curOpt++].optionString = "-verbose:class";
     70 
     71 #ifdef CUSTOM_RUNTIME_HEAP_MAX
     72 #define __make_max_heap_opt(val) #val
     73 #define _make_max_heap_opt(val) "-Xmx" __make_max_heap_opt(val)
     74     opt.optionString = _make_max_heap_opt(CUSTOM_RUNTIME_HEAP_MAX);
     75 #undef __make_max_heap_opt
     76 #undef _make_max_heap_opt
     77 #else
     78     /* limit memory use to 16MB */
     79     opt.optionString = "-Xmx16m";
     80 #endif
     81     mOptions.add(opt);
     82 
     83     /*
     84      * Enable or disable dexopt features, such as bytecode verification and
     85      * calculation of register maps for precise GC.
     86      */
     87     property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
     88     if (dexoptFlagsBuf[0] != '\0') {
     89         const char* opc;
     90         const char* val;
     91 
     92         opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
     93         if (opc != NULL) {
     94             switch (*(opc+2)) {
     95             case 'n':   val = "-Xverify:none";      break;
     96             case 'r':   val = "-Xverify:remote";    break;
     97             case 'a':   val = "-Xverify:all";       break;
     98             default:    val = NULL;                 break;
     99             }
    100 
    101             if (val != NULL) {
    102                 opt.optionString = val;
    103                 mOptions.add(opt);
    104             }
    105         }
    106 
    107         opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
    108         if (opc != NULL) {
    109             switch (*(opc+2)) {
    110             case 'n':   val = "-Xdexopt:none";      break;
    111             case 'v':   val = "-Xdexopt:verified";  break;
    112             case 'a':   val = "-Xdexopt:all";       break;
    113             default:    val = NULL;                 break;
    114             }
    115 
    116             if (val != NULL) {
    117                 opt.optionString = val;
    118                 mOptions.add(opt);
    119             }
    120         }
    121 
    122         opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
    123         if (opc != NULL) {
    124             opt.optionString = "-Xgenregmap";
    125             mOptions.add(opt);
    126         }
    127     }
    128 
    129     /* enable debugging; set suspend=y to pause during VM init */
    130 #ifdef HAVE_ANDROID_OS
    131     /* use android ADB transport */
    132     opt.optionString =
    133         "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
    134 #else
    135     /* use TCP socket; address=0 means start at port 8000 and probe up */
    136     LOGI("Using TCP socket for JDWP\n");
    137     opt.optionString =
    138         "-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";
    139 #endif
    140     mOptions.add(opt);
    141 
    142     char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];
    143     property_get("dalvik.vm.deadlock-predict", propBuf, "");
    144     if (strlen(propBuf) > 0) {
    145         strcpy(enableDPBuf, "-Xdeadlockpredict:");
    146         strcat(enableDPBuf, propBuf);
    147         opt.optionString = enableDPBuf;
    148         mOptions.add(opt);
    149     }
    150 
    151     LOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
    152     if (checkJni) {
    153         /* extended JNI checking */
    154         opt.optionString = "-Xcheck:jni";
    155         mOptions.add(opt);
    156 
    157         /* set a cap on JNI global references */
    158         opt.optionString = "-Xjnigreflimit:2000";
    159         mOptions.add(opt);
    160 
    161         /* with -Xcheck:jni, this provides a JNI function call trace */
    162         //opt.optionString = "-verbose:jni";
    163         //mOptions.add(opt);
    164     }
    165     if (executionMode == kEMIntPortable) {
    166         opt.optionString = "-Xint:portable";
    167         mOptions.add(opt);
    168     } else if (executionMode == kEMIntFast) {
    169         opt.optionString = "-Xint:fast";
    170         mOptions.add(opt);
    171     }
    172     if (logStdio) {
    173         /* convert stdout/stderr to log messages */
    174         opt.optionString = "-Xlog-stdio";
    175         mOptions.add(opt);
    176     }
    177 
    178     if (enableAssertBuf[4] != '\0') {
    179         /* accept "all" to mean "all classes and packages" */
    180         if (strcmp(enableAssertBuf+4, "all") == 0)
    181             enableAssertBuf[3] = '\0';
    182         LOGI("Assertions enabled: '%s'\n", enableAssertBuf);
    183         opt.optionString = enableAssertBuf;
    184         mOptions.add(opt);
    185     } else {
    186         LOGV("Assertions disabled\n");
    187     }
    188 
    189     if (jniOptsBuf[10] != '\0') {
    190         LOGI("JNI options: '%s'\n", jniOptsBuf);
    191         opt.optionString = jniOptsBuf;
    192         mOptions.add(opt);
    193     }
    194 
    195     if (stackTraceFileBuf[0] != '\0') {
    196         static const char* stfOptName = "-Xstacktracefile:";
    197 
    198         stackTraceFile = (char*) malloc(strlen(stfOptName) +
    199             strlen(stackTraceFileBuf) +1);
    200         strcpy(stackTraceFile, stfOptName);
    201         strcat(stackTraceFile, stackTraceFileBuf);
    202         opt.optionString = stackTraceFile;
    203         mOptions.add(opt);
    204     }
    205     
    206     /* Set the properties for locale */
    207     {
    208         char langOption[sizeof("-Duser.language=") + 3];
    209         char regionOption[sizeof("-Duser.region=") + 3];
    210         strcpy(langOption, "-Duser.language=");
    211         strcpy(regionOption, "-Duser.region=");
    212         readLocale(langOption, regionOption);
    213         opt.extraInfo = NULL;
    214         opt.optionString = langOption;
    215         mOptions.add(opt);
    216         opt.optionString = regionOption;
    217         mOptions.add(opt);
    218     }
    219 
    220     /*
    221      * We don't have /tmp on the device, but we often have an SD card.  Apps
    222      * shouldn't use this, but some test suites might want to exercise it.
    223      */
    224     opt.optionString = "-Djava.io.tmpdir=/sdcard";
    225     mOptions.add(opt);
    226 
    227     initArgs.version = JNI_VERSION_1_4;
    228     initArgs.options = mOptions.editArray();
    229     initArgs.nOptions = mOptions.size();
    230     initArgs.ignoreUnrecognized = JNI_FALSE;    
    231     if (JNI_CreateJavaVM(&mJavaVM, &env, &initArgs) < 0) {
    232         LOGE("JNI_CreateJavaVM failed\n");
    233         goto bail;
    234     }
    235     /*
    236      * Register android functions.
    237      */
    238     if (startReg(env) < 0) {
    239         LOGE("Unable to register all android natives\n");
    240         goto bail;
    241     }
    242 
    243     /*
    244      * We want to call main() with a String array with arguments in it.
    245      * At present we only have one argument, the class name.  Create an
    246      * array to hold it.
    247      */
    248     jclass stringClass;
    249     jobjectArray strArray;
    250     jstring classNameStr;
    251     jstring startSystemServerStr;
    252 
    253     stringClass = env->FindClass("java/lang/String");
    254     assert(stringClass != NULL);
    255     strArray = env->NewObjectArray(2, stringClass, NULL);
    256     assert(strArray != NULL);
    257     classNameStr = env->NewStringUTF(className);
    258     assert(classNameStr != NULL);
    259     env->SetObjectArrayElement(strArray, 0, classNameStr);
    260     startSystemServerStr = env->NewStringUTF(startSystemServer ? 
    261                                                  "true" : "false");
    262     env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
    263 
    264     /*
    265      * Start VM.  This thread becomes the main thread of the VM, and will
    266      * not return until the VM exits.
    267      */
    268     jclass startClass;
    269     jmethodID startMeth;
    270 
    271     slashClassName = strdup(className);
    272     for (cp = slashClassName; *cp != '\0'; cp++)
    273         if (*cp == '.')
    274             *cp = '/';
    275 
    276     startClass = env->FindClass(slashClassName);
    277     if (startClass == NULL) {
    278         LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    279         /* keep going */
    280     } else {
    281         startMeth = env->GetStaticMethodID(startClass, "main",
    282             "([Ljava/lang/String;)V");
    283         if (startMeth == NULL) {
    284             LOGE("JavaVM unable to find main() in '%s'\n", className);
    285             /* keep going */
    286         } else {
    287             env->CallStaticVoidMethod(startClass, startMeth, strArray);
    288 
    289 #if 0
    290             if (env->ExceptionCheck())
    291                 threadExitUncaughtException(env);
    292 #endif
    293         }
    294     }
    295 
    296     LOGD("Shutting down VM\n");
    297     if (mJavaVM->DetachCurrentThread() != JNI_OK)
    298         LOGW("Warning: unable to detach main thread\n");
    299     if (mJavaVM->DestroyJavaVM() != 0)
    300         LOGW("Warning: VM did not shut down cleanly\n");
    301 
    302 bail:
    303     free(slashClassName);
    304     free(stackTraceFile);
    305 }
    306 
    307 void AndroidRuntime::start()
    308 {
    309     start("com.android.internal.os.RuntimeInit",
    310         false /* Don't start the system server */);
    311 }
    View Code
  • Zygote
  •   1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package dalvik.system;
     18 
     19 /**
     20  * Provides access to the Dalvik "zygote" feature, which allows a VM instance to
     21  * be partially initialized and then fork()'d from the partially initialized
     22  * state.
     23  *
     24  * @hide
     25  */
     26 public class Zygote {
     27     /*
     28      * Bit values for "debugFlags" argument.  The definitions are duplicated
     29      * in the native code.
     30      */
     31     /** enable debugging over JDWP */
     32     public static final int DEBUG_ENABLE_DEBUGGER   = 1;
     33     /** enable JNI checks */
     34     public static final int DEBUG_ENABLE_CHECKJNI   = 1 << 1;
     35     /** enable Java programming language "assert" statements */
     36     public static final int DEBUG_ENABLE_ASSERT     = 1 << 2;
     37     /** disable the JIT compiler */
     38     public static final int DEBUG_ENABLE_SAFEMODE   = 1 << 3;
     39 
     40     /**
     41      * When set by the system server, all subsequent apps will be launched in
     42      * VM safe mode.
     43      *
     44      * @hide
     45      */
     46     public static boolean systemInSafeMode = false;
     47 
     48     private Zygote() {}
     49 
     50     /**
     51      * Forks a new Zygote instance, but does not leave the zygote mode.
     52      * The current VM must have been started with the -Xzygote flag. The
     53      * new child is expected to eventually call forkAndSpecialize()
     54      *
     55      * @return 0 if this is the child, pid of the child
     56      * if this is the parent, or -1 on error
     57      */
     58     native public static int fork();
     59 
     60     /**
     61      * Forks a new VM instance.  The current VM must have been started
     62      * with the -Xzygote flag. <b>NOTE: new instance keeps all
     63      * root capabilities. The new process is expected to call capset()</b>.
     64      *
     65      * @param uid the UNIX uid that the new process should setuid() to after
     66      * fork()ing and and before spawning any threads.
     67      * @param gid the UNIX gid that the new process should setgid() to after
     68      * fork()ing and and before spawning any threads.
     69      * @param gids null-ok; a list of UNIX gids that the new process should
     70      * setgroups() to after fork and before spawning any threads.
     71      * @param debugFlags bit flags that enable debugging features.
     72      * @param rlimits null-ok an array of rlimit tuples, with the second
     73      * dimension having a length of 3 and representing
     74      * (resource, rlim_cur, rlim_max). These are set via the posix
     75      * setrlimit(2) call.
     76      *
     77      * @return 0 if this is the child, pid of the child
     78      * if this is the parent, or -1 on error.
     79      */
     80     native public static int forkAndSpecialize(int uid, int gid, int[] gids,
     81             int debugFlags, int[][] rlimits);
     82 
     83     /**
     84      * Forks a new VM instance.
     85      * @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
     86      */
     87     @Deprecated
     88     public static int forkAndSpecialize(int uid, int gid, int[] gids,
     89             boolean enableDebugger, int[][] rlimits) {
     90         int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
     91         return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
     92     }
     93 
     94     /**
     95      * Special method to start the system server process. In addition to the
     96      * common actions performed in forkAndSpecialize, the pid of the child
     97      * process is recorded such that the death of the child process will cause
     98      * zygote to exit.
     99      *
    100      * @param uid the UNIX uid that the new process should setuid() to after
    101      * fork()ing and and before spawning any threads.
    102      * @param gid the UNIX gid that the new process should setgid() to after
    103      * fork()ing and and before spawning any threads.
    104      * @param gids null-ok; a list of UNIX gids that the new process should
    105      * setgroups() to after fork and before spawning any threads.
    106      * @param debugFlags bit flags that enable debugging features.
    107      * @param rlimits null-ok an array of rlimit tuples, with the second
    108      * dimension having a length of 3 and representing
    109      * (resource, rlim_cur, rlim_max). These are set via the posix
    110      * setrlimit(2) call.
    111      * @param permittedCapabilities argument for setcap()
    112      * @param effectiveCapabilities argument for setcap()
    113      *
    114      * @return 0 if this is the child, pid of the child
    115      * if this is the parent, or -1 on error.
    116      */
    117     native public static int forkSystemServer(int uid, int gid,
    118             int[] gids, int debugFlags, int[][] rlimits,
    119             long permittedCapabilities, long effectiveCapabilities);
    120 
    121     /**
    122      * Special method to start the system server process.
    123      * @deprecated use {@link Zygote#forkSystemServer(int, int, int[], int, int[][])}
    124      */
    125     @Deprecated
    126     public static int forkSystemServer(int uid, int gid, int[] gids,
    127             boolean enableDebugger, int[][] rlimits) {
    128         int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
    129         return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
    130     }
    131 }
    Zygote.java
  • ZygoteInit
  •   1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.os;
     18 
     19 import android.content.pm.ActivityInfo;
     20 import android.content.res.Resources;
     21 import android.content.res.TypedArray;
     22 import android.graphics.drawable.Drawable;
     23 import android.net.LocalServerSocket;
     24 import android.os.Debug;
     25 import android.os.FileUtils;
     26 import android.os.Process;
     27 import android.os.SystemClock;
     28 import android.os.SystemProperties;
     29 import android.util.EventLog;
     30 import android.util.Log;
     31 
     32 import dalvik.system.VMRuntime;
     33 import dalvik.system.Zygote;
     34 
     35 import libcore.io.IoUtils;
     36 
     37 import java.io.BufferedReader;
     38 import java.io.FileDescriptor;
     39 import java.io.IOException;
     40 import java.io.InputStream;
     41 import java.io.InputStreamReader;
     42 import java.lang.reflect.InvocationTargetException;
     43 import java.lang.reflect.Method;
     44 import java.lang.reflect.Modifier;
     45 import java.util.ArrayList;
     46 
     47 /**
     48  * Startup class for the zygote process.
     49  *
     50  * Pre-initializes some classes, and then waits for commands on a UNIX domain
     51  * socket. Based on these commands, forks off child processes that inherit
     52  * the initial state of the VM.
     53  *
     54  * Please see {@link ZygoteConnection.Arguments} for documentation on the
     55  * client protocol.
     56  *
     57  * @hide
     58  */
     59 public class ZygoteInit {
     60 
     61     private static final String TAG = "Zygote";
     62 
     63     private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
     64 
     65     private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
     66     private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
     67 
     68     /** when preloading, GC after allocating this many bytes */
     69     private static final int PRELOAD_GC_THRESHOLD = 50000;
     70 
     71     public static final String USAGE_STRING =
     72             " <\"start-system-server\"|\"\" for startSystemServer>";
     73 
     74     private static LocalServerSocket sServerSocket;
     75 
     76     /**
     77      * Used to pre-load resources.  We hold a global reference on it so it
     78      * never gets destroyed.
     79      */
     80     private static Resources mResources;
     81 
     82     /**
     83      * The number of times that the main Zygote loop
     84      * should run before calling gc() again.
     85      */
     86     static final int GC_LOOP_COUNT = 10;
     87 
     88     /**
     89      * If true, zygote forks for each peer. If false, a select loop is used
     90      * inside a single process. The latter is preferred.
     91      */
     92     private static final boolean ZYGOTE_FORK_MODE = false;
     93 
     94     /**
     95      * The name of a resource file that contains classes to preload.
     96      */
     97     private static final String PRELOADED_CLASSES = "preloaded-classes";
     98 
     99     /** Controls whether we should preload resources during zygote init. */
    100     private static final boolean PRELOAD_RESOURCES = true;
    101 
    102     /**
    103      * Invokes a static "main(argv[]) method on class "className".
    104      * Converts various failing exceptions into RuntimeExceptions, with
    105      * the assumption that they will then cause the VM instance to exit.
    106      *
    107      * @param loader class loader to use
    108      * @param className Fully-qualified class name
    109      * @param argv Argument vector for main()
    110      */
    111     static void invokeStaticMain(ClassLoader loader,
    112             String className, String[] argv)
    113             throws ZygoteInit.MethodAndArgsCaller {
    114         Class<?> cl;
    115 
    116         try {
    117             cl = loader.loadClass(className);
    118         } catch (ClassNotFoundException ex) {
    119             throw new RuntimeException(
    120                     "Missing class when invoking static main " + className,
    121                     ex);
    122         }
    123 
    124         Method m;
    125         try {
    126             m = cl.getMethod("main", new Class[] { String[].class });
    127         } catch (NoSuchMethodException ex) {
    128             throw new RuntimeException(
    129                     "Missing static main on " + className, ex);
    130         } catch (SecurityException ex) {
    131             throw new RuntimeException(
    132                     "Problem getting static main on " + className, ex);
    133         }
    134 
    135         int modifiers = m.getModifiers();
    136         if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
    137             throw new RuntimeException(
    138                     "Main method is not public and static on " + className);
    139         }
    140 
    141         /*
    142          * This throw gets caught in ZygoteInit.main(), which responds
    143          * by invoking the exception's run() method. This arrangement
    144          * clears up all the stack frames that were required in setting
    145          * up the process.
    146          */
    147         throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    148     }
    149 
    150     /**
    151      * Registers a server socket for zygote command connections
    152      *
    153      * @throws RuntimeException when open fails
    154      */
    155     private static void registerZygoteSocket() {
    156         if (sServerSocket == null) {
    157             int fileDesc;
    158             try {
    159                 String env = System.getenv(ANDROID_SOCKET_ENV);
    160                 fileDesc = Integer.parseInt(env);
    161             } catch (RuntimeException ex) {
    162                 throw new RuntimeException(
    163                         ANDROID_SOCKET_ENV + " unset or invalid", ex);
    164             }
    165 
    166             try {
    167                 sServerSocket = new LocalServerSocket(
    168                         createFileDescriptor(fileDesc));
    169             } catch (IOException ex) {
    170                 throw new RuntimeException(
    171                         "Error binding to local socket '" + fileDesc + "'", ex);
    172             }
    173         }
    174     }
    175 
    176     /**
    177      * Waits for and accepts a single command connection. Throws
    178      * RuntimeException on failure.
    179      */
    180     private static ZygoteConnection acceptCommandPeer() {
    181         try {
    182             return new ZygoteConnection(sServerSocket.accept());
    183         } catch (IOException ex) {
    184             throw new RuntimeException(
    185                     "IOException during accept()", ex);
    186         }
    187     }
    188 
    189     /**
    190      * Close and clean up zygote sockets. Called on shutdown and on the
    191      * child's exit path.
    192      */
    193     static void closeServerSocket() {
    194         try {
    195             if (sServerSocket != null) {
    196                 sServerSocket.close();
    197             }
    198         } catch (IOException ex) {
    199             Log.e(TAG, "Zygote:  error closing sockets", ex);
    200         }
    201 
    202         sServerSocket = null;
    203     }
    204 
    205     private static final int UNPRIVILEGED_UID = 9999;
    206     private static final int UNPRIVILEGED_GID = 9999;
    207 
    208     private static final int ROOT_UID = 0;
    209     private static final int ROOT_GID = 0;
    210 
    211     /**
    212      * Sets effective user ID.
    213      */
    214     private static void setEffectiveUser(int uid) {
    215         int errno = setreuid(ROOT_UID, uid);
    216         if (errno != 0) {
    217             Log.e(TAG, "setreuid() failed. errno: " + errno);
    218         }
    219     }
    220 
    221     /**
    222      * Sets effective group ID.
    223      */
    224     private static void setEffectiveGroup(int gid) {
    225         int errno = setregid(ROOT_GID, gid);
    226         if (errno != 0) {
    227             Log.e(TAG, "setregid() failed. errno: " + errno);
    228         }
    229     }
    230 
    231     static void preload() {
    232         preloadClasses();
    233         preloadResources();
    234     }
    235 
    236     /**
    237      * Performs Zygote process initialization. Loads and initializes
    238      * commonly used classes.
    239      *
    240      * Most classes only cause a few hundred bytes to be allocated, but
    241      * a few will allocate a dozen Kbytes (in one case, 500+K).
    242      */
    243     private static void preloadClasses() {
    244         final VMRuntime runtime = VMRuntime.getRuntime();
    245 
    246         InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
    247                 PRELOADED_CLASSES);
    248         if (is == null) {
    249             Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
    250         } else {
    251             Log.i(TAG, "Preloading classes...");
    252             long startTime = SystemClock.uptimeMillis();
    253 
    254             // Drop root perms while running static initializers.
    255             setEffectiveGroup(UNPRIVILEGED_GID);
    256             setEffectiveUser(UNPRIVILEGED_UID);
    257 
    258             // Alter the target heap utilization.  With explicit GCs this
    259             // is not likely to have any effect.
    260             float defaultUtilization = runtime.getTargetHeapUtilization();
    261             runtime.setTargetHeapUtilization(0.8f);
    262 
    263             // Start with a clean slate.
    264             System.gc();
    265             runtime.runFinalizationSync();
    266             Debug.startAllocCounting();
    267 
    268             try {
    269                 BufferedReader br
    270                     = new BufferedReader(new InputStreamReader(is), 256);
    271 
    272                 int count = 0;
    273                 String line;
    274                 while ((line = br.readLine()) != null) {
    275                     // Skip comments and blank lines.
    276                     line = line.trim();
    277                     if (line.startsWith("#") || line.equals("")) {
    278                         continue;
    279                     }
    280 
    281                     try {
    282                         if (false) {
    283                             Log.v(TAG, "Preloading " + line + "...");
    284                         }
    285                         Class.forName(line);
    286                         if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
    287                             if (false) {
    288                                 Log.v(TAG,
    289                                     " GC at " + Debug.getGlobalAllocSize());
    290                             }
    291                             System.gc();
    292                             runtime.runFinalizationSync();
    293                             Debug.resetGlobalAllocSize();
    294                         }
    295                         count++;
    296                     } catch (ClassNotFoundException e) {
    297                         Log.w(TAG, "Class not found for preloading: " + line);
    298                     } catch (Throwable t) {
    299                         Log.e(TAG, "Error preloading " + line + ".", t);
    300                         if (t instanceof Error) {
    301                             throw (Error) t;
    302                         }
    303                         if (t instanceof RuntimeException) {
    304                             throw (RuntimeException) t;
    305                         }
    306                         throw new RuntimeException(t);
    307                     }
    308                 }
    309 
    310                 Log.i(TAG, "...preloaded " + count + " classes in "
    311                         + (SystemClock.uptimeMillis()-startTime) + "ms.");
    312             } catch (IOException e) {
    313                 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
    314             } finally {
    315                 IoUtils.closeQuietly(is);
    316                 // Restore default.
    317                 runtime.setTargetHeapUtilization(defaultUtilization);
    318 
    319                 Debug.stopAllocCounting();
    320 
    321                 // Bring back root. We'll need it later.
    322                 setEffectiveUser(ROOT_UID);
    323                 setEffectiveGroup(ROOT_GID);
    324             }
    325         }
    326     }
    327 
    328     /**
    329      * Load in commonly used resources, so they can be shared across
    330      * processes.
    331      *
    332      * These tend to be a few Kbytes, but are frequently in the 20-40K
    333      * range, and occasionally even larger.
    334      */
    335     private static void preloadResources() {
    336         final VMRuntime runtime = VMRuntime.getRuntime();
    337 
    338         Debug.startAllocCounting();
    339         try {
    340             System.gc();
    341             runtime.runFinalizationSync();
    342             mResources = Resources.getSystem();
    343             mResources.startPreloading();
    344             if (PRELOAD_RESOURCES) {
    345                 Log.i(TAG, "Preloading resources...");
    346 
    347                 long startTime = SystemClock.uptimeMillis();
    348                 TypedArray ar = mResources.obtainTypedArray(
    349                         com.android.internal.R.array.preloaded_drawables);
    350                 int N = preloadDrawables(runtime, ar);
    351                 Log.i(TAG, "...preloaded " + N + " resources in "
    352                         + (SystemClock.uptimeMillis()-startTime) + "ms.");
    353 
    354                 startTime = SystemClock.uptimeMillis();
    355                 ar = mResources.obtainTypedArray(
    356                         com.android.internal.R.array.preloaded_color_state_lists);
    357                 N = preloadColorStateLists(runtime, ar);
    358                 Log.i(TAG, "...preloaded " + N + " resources in "
    359                         + (SystemClock.uptimeMillis()-startTime) + "ms.");
    360             }
    361             mResources.finishPreloading();
    362         } catch (RuntimeException e) {
    363             Log.w(TAG, "Failure preloading resources", e);
    364         } finally {
    365             Debug.stopAllocCounting();
    366         }
    367     }
    368 
    369     private static int preloadColorStateLists(VMRuntime runtime, TypedArray ar) {
    370         int N = ar.length();
    371         for (int i=0; i<N; i++) {
    372             if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
    373                 if (false) {
    374                     Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
    375                 }
    376                 System.gc();
    377                 runtime.runFinalizationSync();
    378                 Debug.resetGlobalAllocSize();
    379             }
    380             int id = ar.getResourceId(i, 0);
    381             if (false) {
    382                 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
    383             }
    384             if (id != 0) {
    385                 mResources.getColorStateList(id);
    386             }
    387         }
    388         return N;
    389     }
    390 
    391 
    392     private static int preloadDrawables(VMRuntime runtime, TypedArray ar) {
    393         int N = ar.length();
    394         for (int i=0; i<N; i++) {
    395             if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
    396                 if (false) {
    397                     Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
    398                 }
    399                 System.gc();
    400                 runtime.runFinalizationSync();
    401                 Debug.resetGlobalAllocSize();
    402             }
    403             int id = ar.getResourceId(i, 0);
    404             if (false) {
    405                 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
    406             }
    407             if (id != 0) {
    408                 Drawable dr = mResources.getDrawable(id);
    409                 if ((dr.getChangingConfigurations()&~ActivityInfo.CONFIG_FONT_SCALE) != 0) {
    410                     Log.w(TAG, "Preloaded drawable resource #0x"
    411                             + Integer.toHexString(id)
    412                             + " (" + ar.getString(i) + ") that varies with configuration!!");
    413                 }
    414             }
    415         }
    416         return N;
    417     }
    418 
    419     /**
    420      * Runs several special GCs to try to clean up a few generations of
    421      * softly- and final-reachable objects, along with any other garbage.
    422      * This is only useful just before a fork().
    423      */
    424     /*package*/ static void gc() {
    425         final VMRuntime runtime = VMRuntime.getRuntime();
    426 
    427         /* runFinalizationSync() lets finalizers be called in Zygote,
    428          * which doesn't have a HeapWorker thread.
    429          */
    430         System.gc();
    431         runtime.runFinalizationSync();
    432         System.gc();
    433         runtime.runFinalizationSync();
    434         System.gc();
    435         runtime.runFinalizationSync();
    436     }
    437 
    438     /**
    439      * Finish remaining work for the newly forked system server process.
    440      */
    441     private static void handleSystemServerProcess(
    442             ZygoteConnection.Arguments parsedArgs)
    443             throws ZygoteInit.MethodAndArgsCaller {
    444 
    445         closeServerSocket();
    446 
    447         // set umask to 0077 so new files and directories will default to owner-only permissions.
    448         FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);
    449 
    450         if (parsedArgs.niceName != null) {
    451             Process.setArgV0(parsedArgs.niceName);
    452         }
    453 
    454         if (parsedArgs.invokeWith != null) {
    455             WrapperInit.execApplication(parsedArgs.invokeWith,
    456                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
    457                     null, parsedArgs.remainingArgs);
    458         } else {
    459             /*
    460              * Pass the remaining arguments to SystemServer.
    461              */
    462             RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
    463         }
    464 
    465         /* should never reach here */
    466     }
    467 
    468     /**
    469      * Prepare the arguments and fork for the system server process.
    470      */
    471     private static boolean startSystemServer()
    472             throws MethodAndArgsCaller, RuntimeException {
    473         /* Hardcoded command line to start the system server */
    474         String args[] = {
    475             "--setuid=1000",
    476             "--setgid=1000",
    477             "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
    478             "--capabilities=130104352,130104352",
    479             "--runtime-init",
    480             "--nice-name=system_server",
    481             "com.android.server.SystemServer",
    482         };
    483         ZygoteConnection.Arguments parsedArgs = null;
    484 
    485         int pid;
    486 
    487         try {
    488             parsedArgs = new ZygoteConnection.Arguments(args);
    489             ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
    490             ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
    491 
    492             /* Request to fork the system server process */
    493             pid = Zygote.forkSystemServer(
    494                     parsedArgs.uid, parsedArgs.gid,
    495                     parsedArgs.gids,
    496                     parsedArgs.debugFlags,
    497                     null,
    498                     parsedArgs.permittedCapabilities,
    499                     parsedArgs.effectiveCapabilities);
    500         } catch (IllegalArgumentException ex) {
    501             throw new RuntimeException(ex);
    502         }
    503 
    504         /* For child process */
    505         if (pid == 0) {
    506             handleSystemServerProcess(parsedArgs);
    507         }
    508 
    509         return true;
    510     }
    511 
    512     public static void main(String argv[]) {
    513         try {
    514             // Start profiling the zygote initialization.
    515             SamplingProfilerIntegration.start();
    516 
    517             registerZygoteSocket();
    518             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
    519                 SystemClock.uptimeMillis());
    520             preload();
    521             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
    522                 SystemClock.uptimeMillis());
    523 
    524             // Finish profiling the zygote initialization.
    525             SamplingProfilerIntegration.writeZygoteSnapshot();
    526 
    527             // Do an initial gc to clean up after startup
    528             gc();
    529 
    530             // If requested, start system server directly from Zygote
    531             if (argv.length != 2) {
    532                 throw new RuntimeException(argv[0] + USAGE_STRING);
    533             }
    534 
    535             if (argv[1].equals("start-system-server")) {
    536                 startSystemServer();
    537             } else if (!argv[1].equals("")) {
    538                 throw new RuntimeException(argv[0] + USAGE_STRING);
    539             }
    540 
    541             Log.i(TAG, "Accepting command socket connections");
    542 
    543             if (ZYGOTE_FORK_MODE) {
    544                 runForkMode();
    545             } else {
    546                 runSelectLoopMode();
    547             }
    548 
    549             closeServerSocket();
    550         } catch (MethodAndArgsCaller caller) {
    551             caller.run();
    552         } catch (RuntimeException ex) {
    553             Log.e(TAG, "Zygote died with exception", ex);
    554             closeServerSocket();
    555             throw ex;
    556         }
    557     }
    558 
    559     /**
    560      * Runs the zygote in accept-and-fork mode. In this mode, each peer
    561      * gets its own zygote spawner process. This code is retained for
    562      * reference only.
    563      *
    564      * @throws MethodAndArgsCaller in a child process when a main() should
    565      * be executed.
    566      */
    567     private static void runForkMode() throws MethodAndArgsCaller {
    568         while (true) {
    569             ZygoteConnection peer = acceptCommandPeer();
    570 
    571             int pid;
    572 
    573             pid = Zygote.fork();
    574 
    575             if (pid == 0) {
    576                 // The child process should handle the peer requests
    577 
    578                 // The child does not accept any more connections
    579                 try {
    580                     sServerSocket.close();
    581                 } catch (IOException ex) {
    582                     Log.e(TAG, "Zygote Child: error closing sockets", ex);
    583                 } finally {
    584                     sServerSocket = null;
    585                 }
    586 
    587                 peer.run();
    588                 break;
    589             } else if (pid > 0) {
    590                 peer.closeSocket();
    591             } else {
    592                 throw new RuntimeException("Error invoking fork()");
    593             }
    594         }
    595     }
    596 
    597     /**
    598      * Runs the zygote process's select loop. Accepts new connections as
    599      * they happen, and reads commands from connections one spawn-request's
    600      * worth at a time.
    601      *
    602      * @throws MethodAndArgsCaller in a child process when a main() should
    603      * be executed.
    604      */
    605     private static void runSelectLoopMode() throws MethodAndArgsCaller {
    606         ArrayList<FileDescriptor> fds = new ArrayList();
    607         ArrayList<ZygoteConnection> peers = new ArrayList();
    608         FileDescriptor[] fdArray = new FileDescriptor[4];
    609 
    610         fds.add(sServerSocket.getFileDescriptor());
    611         peers.add(null);
    612 
    613         int loopCount = GC_LOOP_COUNT;
    614         while (true) {
    615             int index;
    616 
    617             /*
    618              * Call gc() before we block in select().
    619              * It's work that has to be done anyway, and it's better
    620              * to avoid making every child do it.  It will also
    621              * madvise() any free memory as a side-effect.
    622              *
    623              * Don't call it every time, because walking the entire
    624              * heap is a lot of overhead to free a few hundred bytes.
    625              */
    626             if (loopCount <= 0) {
    627                 gc();
    628                 loopCount = GC_LOOP_COUNT;
    629             } else {
    630                 loopCount--;
    631             }
    632 
    633 
    634             try {
    635                 fdArray = fds.toArray(fdArray);
    636                 index = selectReadable(fdArray);
    637             } catch (IOException ex) {
    638                 throw new RuntimeException("Error in select()", ex);
    639             }
    640 
    641             if (index < 0) {
    642                 throw new RuntimeException("Error in select()");
    643             } else if (index == 0) {
    644                 ZygoteConnection newPeer = acceptCommandPeer();
    645                 peers.add(newPeer);
    646                 fds.add(newPeer.getFileDesciptor());
    647             } else {
    648                 boolean done;
    649                 done = peers.get(index).runOnce();
    650 
    651                 if (done) {
    652                     peers.remove(index);
    653                     fds.remove(index);
    654                 }
    655             }
    656         }
    657     }
    658 
    659     /**
    660      * The Linux syscall "setreuid()"
    661      * @param ruid real uid
    662      * @param euid effective uid
    663      * @return 0 on success, non-zero errno on fail
    664      */
    665     static native int setreuid(int ruid, int euid);
    666 
    667     /**
    668      * The Linux syscall "setregid()"
    669      * @param rgid real gid
    670      * @param egid effective gid
    671      * @return 0 on success, non-zero errno on fail
    672      */
    673     static native int setregid(int rgid, int egid);
    674 
    675     /**
    676      * Invokes the linux syscall "setpgid"
    677      *
    678      * @param pid pid to change
    679      * @param pgid new process group of pid
    680      * @return 0 on success or non-zero errno on fail
    681      */
    682     static native int setpgid(int pid, int pgid);
    683 
    684     /**
    685      * Invokes the linux syscall "getpgid"
    686      *
    687      * @param pid pid to query
    688      * @return pgid of pid in question
    689      * @throws IOException on error
    690      */
    691     static native int getpgid(int pid) throws IOException;
    692 
    693     /**
    694      * Invokes the syscall dup2() to copy the specified descriptors into
    695      * stdin, stdout, and stderr. The existing stdio descriptors will be
    696      * closed and errors during close will be ignored. The specified
    697      * descriptors will also remain open at their original descriptor numbers,
    698      * so the caller may want to close the original descriptors.
    699      *
    700      * @param in new stdin
    701      * @param out new stdout
    702      * @param err new stderr
    703      * @throws IOException
    704      */
    705     static native void reopenStdio(FileDescriptor in,
    706             FileDescriptor out, FileDescriptor err) throws IOException;
    707 
    708     /**
    709      * Toggles the close-on-exec flag for the specified file descriptor.
    710      *
    711      * @param fd non-null; file descriptor
    712      * @param flag desired close-on-exec flag state
    713      * @throws IOException
    714      */
    715     static native void setCloseOnExec(FileDescriptor fd, boolean flag)
    716             throws IOException;
    717 
    718     /**
    719      * Retrieves the permitted capability set from another process.
    720      *
    721      * @param pid &gt;=0 process ID or 0 for this process
    722      * @throws IOException on error
    723      */
    724     static native long capgetPermitted(int pid)
    725             throws IOException;
    726 
    727     /**
    728      * Sets the permitted and effective capability sets of this process.
    729      *
    730      * @param permittedCapabilities permitted set
    731      * @param effectiveCapabilities effective set
    732      * @throws IOException on error
    733      */
    734     static native void setCapabilities(
    735             long permittedCapabilities,
    736             long effectiveCapabilities) throws IOException;
    737 
    738     /**
    739      * Invokes select() on the provider array of file descriptors (selecting
    740      * for readability only). Array elements of null are ignored.
    741      *
    742      * @param fds non-null; array of readable file descriptors
    743      * @return index of descriptor that is now readable or -1 for empty array.
    744      * @throws IOException if an error occurs
    745      */
    746     static native int selectReadable(FileDescriptor[] fds) throws IOException;
    747 
    748     /**
    749      * Creates a file descriptor from an int fd.
    750      *
    751      * @param fd integer OS file descriptor
    752      * @return non-null; FileDescriptor instance
    753      * @throws IOException if fd is invalid
    754      */
    755     static native FileDescriptor createFileDescriptor(int fd)
    756             throws IOException;
    757 
    758     /**
    759      * Class not instantiable.
    760      */
    761     private ZygoteInit() {
    762     }
    763 
    764     /**
    765      * Helper exception class which holds a method and arguments and
    766      * can call them. This is used as part of a trampoline to get rid of
    767      * the initial process setup stack frames.
    768      */
    769     public static class MethodAndArgsCaller extends Exception
    770             implements Runnable {
    771         /** method to call */
    772         private final Method mMethod;
    773 
    774         /** argument array */
    775         private final String[] mArgs;
    776 
    777         public MethodAndArgsCaller(Method method, String[] args) {
    778             mMethod = method;
    779             mArgs = args;
    780         }
    781 
    782         public void run() {
    783             try {
    784                 mMethod.invoke(null, new Object[] { mArgs });
    785             } catch (IllegalAccessException ex) {
    786                 throw new RuntimeException(ex);
    787             } catch (InvocationTargetException ex) {
    788                 Throwable cause = ex.getCause();
    789                 if (cause instanceof RuntimeException) {
    790                     throw (RuntimeException) cause;
    791                 } else if (cause instanceof Error) {
    792                     throw (Error) cause;
    793                 }
    794                 throw new RuntimeException(ex);
    795             }
    796         }
    797     }
    798 }
    ZygoteInit.java
     1     public static void main(String argv[]) {
     2         try {
     3             // Start profiling the zygote initialization.
     4             SamplingProfilerIntegration.start();
     5             registerZygoteSocket();
     6             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
     7                 SystemClock.uptimeMillis());
     8             preload();
     9             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
    10                 SystemClock.uptimeMillis());
    11             // Finish profiling the zygote initialization.
    12             SamplingProfilerIntegration.writeZygoteSnapshot();
    13             // Do an initial gc to clean up after startup
    14             gc();
    15             // If requested, start system server directly from Zygote
    16             if (argv.length != 2) {
    17                 throw new RuntimeException(argv[0] + USAGE_STRING);
    18             }
    19             if (argv[1].equals("start-system-server")) {
    20                startSystemServer();
    21             } else if (!argv[1].equals("")) {
    22                 throw new RuntimeException(argv[0] + USAGE_STRING);
    23             }
    24             Log.i(TAG, "Accepting command socket connections");
    25             if (ZYGOTE_FORK_MODE) {
    26                 runForkMode();
    27             } else {
    28                 runSelectLoopMode();
    29             }
    30             closeServerSocket();
    31         } catch (MethodAndArgsCaller caller) {
    32             caller.run();
    33         } catch (RuntimeException ex) {
    34             Log.e(TAG, "Zygote died with exception", ex);
    35             closeServerSocket();
    36             throw ex;
    37         }
    38     }

SystemServer(androidService)

  • SystemServer.java
  •   1 /**
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server;
     18 
     19 import android.accounts.AccountManagerService;
     20 import android.app.ActivityManagerNative;
     21 import android.bluetooth.BluetoothAdapter;
     22 import android.content.ComponentName;
     23 import android.content.ContentResolver;
     24 import android.content.ContentService;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.content.pm.IPackageManager;
     28 import android.content.res.Configuration;
     29 import android.media.AudioService;
     30 import android.net.wifi.p2p.WifiP2pService;
     31 import android.os.Looper;
     32 import android.os.RemoteException;
     33 import android.os.ServiceManager;
     34 import android.os.StrictMode;
     35 import android.os.SystemClock;
     36 import android.os.SystemProperties;
     37 import android.provider.Settings;
     38 import android.server.BluetoothA2dpService;
     39 import android.server.BluetoothService;
     40 import android.server.search.SearchManagerService;
     41 import android.util.DisplayMetrics;
     42 import android.util.EventLog;
     43 import android.util.Log;
     44 import android.util.Slog;
     45 import android.view.WindowManager;
     46 
     47 import com.android.internal.app.ShutdownThread;
     48 import com.android.internal.os.BinderInternal;
     49 import com.android.internal.os.SamplingProfilerIntegration;
     50 import com.android.server.accessibility.AccessibilityManagerService;
     51 import com.android.server.am.ActivityManagerService;
     52 import com.android.server.net.NetworkPolicyManagerService;
     53 import com.android.server.net.NetworkStatsService;
     54 import com.android.server.pm.PackageManagerService;
     55 import com.android.server.usb.UsbService;
     56 import com.android.server.wm.WindowManagerService;
     57 
     58 import dalvik.system.VMRuntime;
     59 import dalvik.system.Zygote;
     60 
     61 import java.io.File;
     62 import java.util.Timer;
     63 import java.util.TimerTask;
     64 
     65 class ServerThread extends Thread {
     66     private static final String TAG = "SystemServer";
     67     private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
     68     private static final String ENCRYPTED_STATE = "1";
     69 
     70     ContentResolver mContentResolver;
     71 
     72     void reportWtf(String msg, Throwable e) {
     73         Slog.w(TAG, "***********************************************");
     74         Log.wtf(TAG, "BOOT FAILURE " + msg, e);
     75     }
     76 
     77     @Override
     78     public void run() {
     79         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
     80             SystemClock.uptimeMillis());
     81 
     82         Looper.prepare();
     83 
     84         android.os.Process.setThreadPriority(
     85                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
     86 
     87         BinderInternal.disableBackgroundScheduling(true);
     88         android.os.Process.setCanSelfBackground(false);
     89 
     90         // Check whether we failed to shut down last time we tried.
     91         {
     92             final String shutdownAction = SystemProperties.get(
     93                     ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
     94             if (shutdownAction != null && shutdownAction.length() > 0) {
     95                 boolean reboot = (shutdownAction.charAt(0) == '1');
     96 
     97                 final String reason;
     98                 if (shutdownAction.length() > 1) {
     99                     reason = shutdownAction.substring(1, shutdownAction.length());
    100                 } else {
    101                     reason = null;
    102                 }
    103 
    104                 ShutdownThread.rebootOrShutdown(reboot, reason);
    105             }
    106         }
    107 
    108         String factoryTestStr = SystemProperties.get("ro.factorytest");
    109         int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
    110                 : Integer.parseInt(factoryTestStr);
    111 
    112         LightsService lights = null;
    113         PowerManagerService power = null;
    114         BatteryService battery = null;
    115         AlarmManagerService alarm = null;
    116         NetworkManagementService networkManagement = null;
    117         NetworkStatsService networkStats = null;
    118         NetworkPolicyManagerService networkPolicy = null;
    119         ConnectivityService connectivity = null;
    120         WifiP2pService wifiP2p = null;
    121         WifiService wifi = null;
    122         IPackageManager pm = null;
    123         Context context = null;
    124         WindowManagerService wm = null;
    125         BluetoothService bluetooth = null;
    126         BluetoothA2dpService bluetoothA2dp = null;
    127         DockObserver dock = null;
    128         UsbService usb = null;
    129         UiModeManagerService uiMode = null;
    130         RecognitionManagerService recognition = null;
    131         ThrottleService throttle = null;
    132         NetworkTimeUpdateService networkTimeUpdater = null;
    133 
    134         // Critical services...
    135         try {
    136             Slog.i(TAG, "Entropy Service");
    137             ServiceManager.addService("entropy", new EntropyService());
    138 
    139             Slog.i(TAG, "Power Manager");
    140             power = new PowerManagerService();
    141             ServiceManager.addService(Context.POWER_SERVICE, power);
    142 
    143             Slog.i(TAG, "Activity Manager");
    144             context = ActivityManagerService.main(factoryTest);
    145 
    146             Slog.i(TAG, "Telephony Registry");
    147             ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
    148 
    149             AttributeCache.init(context);
    150 
    151             Slog.i(TAG, "Package Manager");
    152             // Only run "core" apps if we're encrypting the device.
    153             String cryptState = SystemProperties.get("vold.decrypt");
    154             boolean onlyCore = false;
    155             if (ENCRYPTING_STATE.equals(cryptState)) {
    156                 Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
    157                 onlyCore = true;
    158             } else if (ENCRYPTED_STATE.equals(cryptState)) {
    159                 Slog.w(TAG, "Device encrypted - only parsing core apps");
    160                 onlyCore = true;
    161             }
    162 
    163             pm = PackageManagerService.main(context,
    164                     factoryTest != SystemServer.FACTORY_TEST_OFF,
    165                     onlyCore);
    166             boolean firstBoot = false;
    167             try {
    168                 firstBoot = pm.isFirstBoot();
    169             } catch (RemoteException e) {
    170             }
    171 
    172             ActivityManagerService.setSystemProcess();
    173 
    174             mContentResolver = context.getContentResolver();
    175 
    176             // The AccountManager must come before the ContentService
    177             try {
    178                 Slog.i(TAG, "Account Manager");
    179                 ServiceManager.addService(Context.ACCOUNT_SERVICE,
    180                         new AccountManagerService(context));
    181             } catch (Throwable e) {
    182                 Slog.e(TAG, "Failure starting Account Manager", e);
    183             }
    184 
    185             Slog.i(TAG, "Content Manager");
    186             ContentService.main(context,
    187                     factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
    188 
    189             Slog.i(TAG, "System Content Providers");
    190             ActivityManagerService.installSystemProviders();
    191 
    192             Slog.i(TAG, "Lights Service");
    193             lights = new LightsService(context);
    194 
    195             Slog.i(TAG, "Battery Service");
    196             battery = new BatteryService(context, lights);
    197             ServiceManager.addService("battery", battery);
    198 
    199             Slog.i(TAG, "Vibrator Service");
    200             ServiceManager.addService("vibrator", new VibratorService(context));
    201 
    202             // only initialize the power service after we have started the
    203             // lights service, content providers and the battery service.
    204             power.init(context, lights, ActivityManagerService.self(), battery);
    205 
    206             Slog.i(TAG, "Alarm Manager");
    207             alarm = new AlarmManagerService(context);
    208             ServiceManager.addService(Context.ALARM_SERVICE, alarm);
    209 
    210             Slog.i(TAG, "Init Watchdog");
    211             Watchdog.getInstance().init(context, battery, power, alarm,
    212                     ActivityManagerService.self());
    213 
    214             Slog.i(TAG, "Window Manager");
    215             wm = WindowManagerService.main(context, power,
    216                     factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
    217                     !firstBoot);
    218             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    219 
    220             ActivityManagerService.self().setWindowManager(wm);
    221 
    222             // Skip Bluetooth if we have an emulator kernel
    223             // TODO: Use a more reliable check to see if this product should
    224             // support Bluetooth - see bug 988521
    225             if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
    226                 Slog.i(TAG, "No Bluetooh Service (emulator)");
    227             } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
    228                 Slog.i(TAG, "No Bluetooth Service (factory test)");
    229             } else {
    230                 Slog.i(TAG, "Bluetooth Service");
    231                 bluetooth = new BluetoothService(context);
    232                 ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
    233                 bluetooth.initAfterRegistration();
    234                 bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
    235                 ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
    236                                           bluetoothA2dp);
    237                 bluetooth.initAfterA2dpRegistration();
    238 
    239                 int airplaneModeOn = Settings.System.getInt(mContentResolver,
    240                         Settings.System.AIRPLANE_MODE_ON, 0);
    241                 int bluetoothOn = Settings.Secure.getInt(mContentResolver,
    242                     Settings.Secure.BLUETOOTH_ON, 0);
    243                 if (airplaneModeOn == 0 && bluetoothOn != 0) {
    244                     bluetooth.enable();
    245                 }
    246             }
    247 
    248         } catch (RuntimeException e) {
    249             Slog.e("System", "******************************************");
    250             Slog.e("System", "************ Failure starting core service", e);
    251         }
    252 
    253         DevicePolicyManagerService devicePolicy = null;
    254         StatusBarManagerService statusBar = null;
    255         InputMethodManagerService imm = null;
    256         AppWidgetService appWidget = null;
    257         NotificationManagerService notification = null;
    258         WallpaperManagerService wallpaper = null;
    259         LocationManagerService location = null;
    260         CountryDetectorService countryDetector = null;
    261         TextServicesManagerService tsms = null;
    262 
    263         // Bring up services needed for UI.
    264         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
    265             try {
    266                 Slog.i(TAG, "Input Method Service");
    267                 imm = new InputMethodManagerService(context);
    268                 ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
    269             } catch (Throwable e) {
    270                 reportWtf("starting Input Manager Service", e);
    271             }
    272 
    273             try {
    274                 Slog.i(TAG, "Accessibility Manager");
    275                 ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
    276                         new AccessibilityManagerService(context));
    277             } catch (Throwable e) {
    278                 reportWtf("starting Accessibility Manager", e);
    279             }
    280         }
    281 
    282         try {
    283             wm.displayReady();
    284         } catch (Throwable e) {
    285             reportWtf("making display ready", e);
    286         }
    287 
    288         try {
    289             pm.performBootDexOpt();
    290         } catch (Throwable e) {
    291             reportWtf("performing boot dexopt", e);
    292         }
    293 
    294         try {
    295             ActivityManagerNative.getDefault().showBootMessage(
    296                     context.getResources().getText(
    297                             com.android.internal.R.string.android_upgrading_starting_apps),
    298                             false);
    299         } catch (RemoteException e) {
    300         }
    301 
    302         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
    303             try {
    304                 Slog.i(TAG, "Device Policy");
    305                 devicePolicy = new DevicePolicyManagerService(context);
    306                 ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
    307             } catch (Throwable e) {
    308                 reportWtf("starting DevicePolicyService", e);
    309             }
    310 
    311             try {
    312                 Slog.i(TAG, "Status Bar");
    313                 statusBar = new StatusBarManagerService(context, wm);
    314                 ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
    315             } catch (Throwable e) {
    316                 reportWtf("starting StatusBarManagerService", e);
    317             }
    318 
    319             try {
    320                 Slog.i(TAG, "Clipboard Service");
    321                 ServiceManager.addService(Context.CLIPBOARD_SERVICE,
    322                         new ClipboardService(context));
    323             } catch (Throwable e) {
    324                 reportWtf("starting Clipboard Service", e);
    325             }
    326 
    327             try {
    328                 Slog.i(TAG, "NetworkManagement Service");
    329                 networkManagement = NetworkManagementService.create(context);
    330                 ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
    331             } catch (Throwable e) {
    332                 reportWtf("starting NetworkManagement Service", e);
    333             }
    334 
    335             try {
    336                 Slog.i(TAG, "Text Service Manager Service");
    337                 tsms = new TextServicesManagerService(context);
    338                 ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
    339             } catch (Throwable e) {
    340                 reportWtf("starting Text Service Manager Service", e);
    341             }
    342 
    343             try {
    344                 Slog.i(TAG, "NetworkStats Service");
    345                 networkStats = new NetworkStatsService(context, networkManagement, alarm);
    346                 ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
    347             } catch (Throwable e) {
    348                 reportWtf("starting NetworkStats Service", e);
    349             }
    350 
    351             try {
    352                 Slog.i(TAG, "NetworkPolicy Service");
    353                 networkPolicy = new NetworkPolicyManagerService(
    354                         context, ActivityManagerService.self(), power,
    355                         networkStats, networkManagement);
    356                 ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
    357             } catch (Throwable e) {
    358                 reportWtf("starting NetworkPolicy Service", e);
    359             }
    360 
    361            try {
    362                 Slog.i(TAG, "Wi-Fi P2pService");
    363                 wifiP2p = new WifiP2pService(context);
    364                 ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
    365             } catch (Throwable e) {
    366                 reportWtf("starting Wi-Fi P2pService", e);
    367             }
    368 
    369            try {
    370                 Slog.i(TAG, "Wi-Fi Service");
    371                 wifi = new WifiService(context);
    372                 ServiceManager.addService(Context.WIFI_SERVICE, wifi);
    373             } catch (Throwable e) {
    374                 reportWtf("starting Wi-Fi Service", e);
    375             }
    376 
    377             try {
    378                 Slog.i(TAG, "Connectivity Service");
    379                 connectivity = new ConnectivityService(
    380                         context, networkManagement, networkStats, networkPolicy);
    381                 ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
    382                 networkStats.bindConnectivityManager(connectivity);
    383                 networkPolicy.bindConnectivityManager(connectivity);
    384                 wifi.checkAndStartWifi();
    385                 wifiP2p.connectivityServiceReady();
    386             } catch (Throwable e) {
    387                 reportWtf("starting Connectivity Service", e);
    388             }
    389 
    390             try {
    391                 Slog.i(TAG, "Throttle Service");
    392                 throttle = new ThrottleService(context);
    393                 ServiceManager.addService(
    394                         Context.THROTTLE_SERVICE, throttle);
    395             } catch (Throwable e) {
    396                 reportWtf("starting ThrottleService", e);
    397             }
    398 
    399             try {
    400                 /**
    401                  * NotificationManagerService is dependant on MountService,
    402                  * (for media / usb notifications) so we must start MountService first.
    403                  */
    404                 Slog.i(TAG, "Mount Service");
    405                 ServiceManager.addService("mount", new MountService(context));
    406             } catch (Throwable e) {
    407                 reportWtf("starting Mount Service", e);
    408             }
    409 
    410             try {
    411                 Slog.i(TAG, "Notification Manager");
    412                 notification = new NotificationManagerService(context, statusBar, lights);
    413                 ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
    414                 networkPolicy.bindNotificationManager(notification);
    415             } catch (Throwable e) {
    416                 reportWtf("starting Notification Manager", e);
    417             }
    418 
    419             try {
    420                 Slog.i(TAG, "Device Storage Monitor");
    421                 ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
    422                         new DeviceStorageMonitorService(context));
    423             } catch (Throwable e) {
    424                 reportWtf("starting DeviceStorageMonitor service", e);
    425             }
    426 
    427             try {
    428                 Slog.i(TAG, "Location Manager");
    429                 location = new LocationManagerService(context);
    430                 ServiceManager.addService(Context.LOCATION_SERVICE, location);
    431             } catch (Throwable e) {
    432                 reportWtf("starting Location Manager", e);
    433             }
    434 
    435             try {
    436                 Slog.i(TAG, "Country Detector");
    437                 countryDetector = new CountryDetectorService(context);
    438                 ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
    439             } catch (Throwable e) {
    440                 reportWtf("starting Country Detector", e);
    441             }
    442 
    443             try {
    444                 Slog.i(TAG, "Search Service");
    445                 ServiceManager.addService(Context.SEARCH_SERVICE,
    446                         new SearchManagerService(context));
    447             } catch (Throwable e) {
    448                 reportWtf("starting Search Service", e);
    449             }
    450 
    451             try {
    452                 Slog.i(TAG, "DropBox Service");
    453                 ServiceManager.addService(Context.DROPBOX_SERVICE,
    454                         new DropBoxManagerService(context, new File("/data/system/dropbox")));
    455             } catch (Throwable e) {
    456                 reportWtf("starting DropBoxManagerService", e);
    457             }
    458 
    459             try {
    460                 Slog.i(TAG, "Wallpaper Service");
    461                 wallpaper = new WallpaperManagerService(context);
    462                 ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
    463             } catch (Throwable e) {
    464                 reportWtf("starting Wallpaper Service", e);
    465             }
    466 
    467             try {
    468                 Slog.i(TAG, "Audio Service");
    469                 ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
    470             } catch (Throwable e) {
    471                 reportWtf("starting Audio Service", e);
    472             }
    473 
    474             try {
    475                 Slog.i(TAG, "Dock Observer");
    476                 // Listen for dock station changes
    477                 dock = new DockObserver(context, power);
    478             } catch (Throwable e) {
    479                 reportWtf("starting DockObserver", e);
    480             }
    481 
    482             try {
    483                 Slog.i(TAG, "Wired Accessory Observer");
    484                 // Listen for wired headset changes
    485                 new WiredAccessoryObserver(context);
    486             } catch (Throwable e) {
    487                 reportWtf("starting WiredAccessoryObserver", e);
    488             }
    489 
    490             try {
    491                 Slog.i(TAG, "USB Service");
    492                 // Manage USB host and device support
    493                 usb = new UsbService(context);
    494                 ServiceManager.addService(Context.USB_SERVICE, usb);
    495             } catch (Throwable e) {
    496                 reportWtf("starting UsbService", e);
    497             }
    498 
    499             try {
    500                 Slog.i(TAG, "UI Mode Manager Service");
    501                 // Listen for UI mode changes
    502                 uiMode = new UiModeManagerService(context);
    503             } catch (Throwable e) {
    504                 reportWtf("starting UiModeManagerService", e);
    505             }
    506 
    507             try {
    508                 Slog.i(TAG, "Backup Service");
    509                 ServiceManager.addService(Context.BACKUP_SERVICE,
    510                         new BackupManagerService(context));
    511             } catch (Throwable e) {
    512                 Slog.e(TAG, "Failure starting Backup Service", e);
    513             }
    514 
    515             try {
    516                 Slog.i(TAG, "AppWidget Service");
    517                 appWidget = new AppWidgetService(context);
    518                 ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
    519             } catch (Throwable e) {
    520                 reportWtf("starting AppWidget Service", e);
    521             }
    522 
    523             try {
    524                 Slog.i(TAG, "Recognition Service");
    525                 recognition = new RecognitionManagerService(context);
    526             } catch (Throwable e) {
    527                 reportWtf("starting Recognition Service", e);
    528             }
    529 
    530             try {
    531                 Slog.i(TAG, "DiskStats Service");
    532                 ServiceManager.addService("diskstats", new DiskStatsService(context));
    533             } catch (Throwable e) {
    534                 reportWtf("starting DiskStats Service", e);
    535             }
    536 
    537             try {
    538                 // need to add this service even if SamplingProfilerIntegration.isEnabled()
    539                 // is false, because it is this service that detects system property change and
    540                 // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work,
    541                 // there is little overhead for running this service.
    542                 Slog.i(TAG, "SamplingProfiler Service");
    543                 ServiceManager.addService("samplingprofiler",
    544                             new SamplingProfilerService(context));
    545             } catch (Throwable e) {
    546                 reportWtf("starting SamplingProfiler Service", e);
    547             }
    548 
    549             try {
    550                 Slog.i(TAG, "NetworkTimeUpdateService");
    551                 networkTimeUpdater = new NetworkTimeUpdateService(context);
    552             } catch (Throwable e) {
    553                 reportWtf("starting NetworkTimeUpdate service", e);
    554             }
    555         }
    556 
    557         // Before things start rolling, be sure we have decided whether
    558         // we are in safe mode.
    559         final boolean safeMode = wm.detectSafeMode();
    560         if (safeMode) {
    561             ActivityManagerService.self().enterSafeMode();
    562             // Post the safe mode state in the Zygote class
    563             Zygote.systemInSafeMode = true;
    564             // Disable the JIT for the system_server process
    565             VMRuntime.getRuntime().disableJitCompilation();
    566         } else {
    567             // Enable the JIT for the system_server process
    568             VMRuntime.getRuntime().startJitCompilation();
    569         }
    570 
    571         // It is now time to start up the app processes...
    572 
    573         if (devicePolicy != null) {
    574             try {
    575                 devicePolicy.systemReady();
    576             } catch (Throwable e) {
    577                 reportWtf("making Device Policy Service ready", e);
    578             }
    579         }
    580 
    581         if (notification != null) {
    582             try {
    583                 notification.systemReady();
    584             } catch (Throwable e) {
    585                 reportWtf("making Notification Service ready", e);
    586             }
    587         }
    588 
    589         try {
    590             wm.systemReady();
    591         } catch (Throwable e) {
    592             reportWtf("making Window Manager Service ready", e);
    593         }
    594 
    595         if (safeMode) {
    596             ActivityManagerService.self().showSafeModeOverlay();
    597         }
    598 
    599         // Update the configuration for this context by hand, because we're going
    600         // to start using it before the config change done in wm.systemReady() will
    601         // propagate to it.
    602         Configuration config = wm.computeNewConfiguration();
    603         DisplayMetrics metrics = new DisplayMetrics();
    604         WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    605         w.getDefaultDisplay().getMetrics(metrics);
    606         context.getResources().updateConfiguration(config, metrics);
    607 
    608         power.systemReady();
    609         try {
    610             pm.systemReady();
    611         } catch (Throwable e) {
    612             reportWtf("making Package Manager Service ready", e);
    613         }
    614 
    615         // These are needed to propagate to the runnable below.
    616         final Context contextF = context;
    617         final BatteryService batteryF = battery;
    618         final NetworkManagementService networkManagementF = networkManagement;
    619         final NetworkStatsService networkStatsF = networkStats;
    620         final NetworkPolicyManagerService networkPolicyF = networkPolicy;
    621         final ConnectivityService connectivityF = connectivity;
    622         final DockObserver dockF = dock;
    623         final UsbService usbF = usb;
    624         final ThrottleService throttleF = throttle;
    625         final UiModeManagerService uiModeF = uiMode;
    626         final AppWidgetService appWidgetF = appWidget;
    627         final WallpaperManagerService wallpaperF = wallpaper;
    628         final InputMethodManagerService immF = imm;
    629         final RecognitionManagerService recognitionF = recognition;
    630         final LocationManagerService locationF = location;
    631         final CountryDetectorService countryDetectorF = countryDetector;
    632         final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
    633         final TextServicesManagerService textServiceManagerServiceF = tsms;
    634         final StatusBarManagerService statusBarF = statusBar;
    635 
    636         // We now tell the activity manager it is okay to run third party
    637         // code.  It will call back into us once it has gotten to the state
    638         // where third party code can really run (but before it has actually
    639         // started launching the initial applications), for us to complete our
    640         // initialization.
    641         ActivityManagerService.self().systemReady(new Runnable() {
    642             public void run() {
    643                 Slog.i(TAG, "Making services ready");
    644 
    645                 startSystemUi(contextF);
    646                 try {
    647                     if (batteryF != null) batteryF.systemReady();
    648                 } catch (Throwable e) {
    649                     reportWtf("making Battery Service ready", e);
    650                 }
    651                 try {
    652                     if (networkManagementF != null) networkManagementF.systemReady();
    653                 } catch (Throwable e) {
    654                     reportWtf("making Network Managment Service ready", e);
    655                 }
    656                 try {
    657                     if (networkStatsF != null) networkStatsF.systemReady();
    658                 } catch (Throwable e) {
    659                     reportWtf("making Network Stats Service ready", e);
    660                 }
    661                 try {
    662                     if (networkPolicyF != null) networkPolicyF.systemReady();
    663                 } catch (Throwable e) {
    664                     reportWtf("making Network Policy Service ready", e);
    665                 }
    666                 try {
    667                     if (connectivityF != null) connectivityF.systemReady();
    668                 } catch (Throwable e) {
    669                     reportWtf("making Connectivity Service ready", e);
    670                 }
    671                 try {
    672                     if (dockF != null) dockF.systemReady();
    673                 } catch (Throwable e) {
    674                     reportWtf("making Dock Service ready", e);
    675                 }
    676                 try {
    677                     if (usbF != null) usbF.systemReady();
    678                 } catch (Throwable e) {
    679                     reportWtf("making USB Service ready", e);
    680                 }
    681                 try {
    682                     if (uiModeF != null) uiModeF.systemReady();
    683                 } catch (Throwable e) {
    684                     reportWtf("making UI Mode Service ready", e);
    685                 }
    686                 try {
    687                     if (recognitionF != null) recognitionF.systemReady();
    688                 } catch (Throwable e) {
    689                     reportWtf("making Recognition Service ready", e);
    690                 }
    691                 Watchdog.getInstance().start();
    692 
    693                 // It is now okay to let the various system services start their
    694                 // third party code...
    695 
    696                 try {
    697                     if (appWidgetF != null) appWidgetF.systemReady(safeMode);
    698                 } catch (Throwable e) {
    699                     reportWtf("making App Widget Service ready", e);
    700                 }
    701                 try {
    702                     if (wallpaperF != null) wallpaperF.systemReady();
    703                 } catch (Throwable e) {
    704                     reportWtf("making Wallpaper Service ready", e);
    705                 }
    706                 try {
    707                     if (immF != null) immF.systemReady(statusBarF);
    708                 } catch (Throwable e) {
    709                     reportWtf("making Input Method Service ready", e);
    710                 }
    711                 try {
    712                     if (locationF != null) locationF.systemReady();
    713                 } catch (Throwable e) {
    714                     reportWtf("making Location Service ready", e);
    715                 }
    716                 try {
    717                     if (countryDetectorF != null) countryDetectorF.systemReady();
    718                 } catch (Throwable e) {
    719                     reportWtf("making Country Detector Service ready", e);
    720                 }
    721                 try {
    722                     if (throttleF != null) throttleF.systemReady();
    723                 } catch (Throwable e) {
    724                     reportWtf("making Throttle Service ready", e);
    725                 }
    726                 try {
    727                     if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
    728                 } catch (Throwable e) {
    729                     reportWtf("making Network Time Service ready", e);
    730                 }
    731                 try {
    732                     if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
    733                 } catch (Throwable e) {
    734                     reportWtf("making Text Services Manager Service ready", e);
    735                 }
    736             }
    737         });
    738 
    739         // For debug builds, log event loop stalls to dropbox for analysis.
    740         if (StrictMode.conditionallyEnableDebugLogging()) {
    741             Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    742         }
    743 
    744         Looper.loop();
    745         Slog.d(TAG, "System ServerThread is exiting!");
    746     }
    747 
    748     static final void startSystemUi(Context context) {
    749         Intent intent = new Intent();
    750         intent.setComponent(new ComponentName("com.android.systemui",
    751                     "com.android.systemui.SystemUIService"));
    752         Slog.d(TAG, "Starting service: " + intent);
    753         context.startService(intent);
    754     }
    755 }
    756 
    757 public class SystemServer {
    758     private static final String TAG = "SystemServer";
    759 
    760     public static final int FACTORY_TEST_OFF = 0;
    761     public static final int FACTORY_TEST_LOW_LEVEL = 1;
    762     public static final int FACTORY_TEST_HIGH_LEVEL = 2;
    763 
    764     static Timer timer;
    765     static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
    766 
    767     // The earliest supported time.  We pick one day into 1970, to
    768     // give any timezone code room without going into negative time.
    769     private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
    770 
    771     /***
    772      * This method is called from Zygote to initialize the system. This will cause the native
    773      * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
    774      * up into init2() to start the Android services.
    775      */
    776     native public static void init1(String[] args);
    777 
    778     public static void main(String[] args) {
    779         if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
    780             // If a device's clock is before 1970 (before 0), a lot of
    781             // APIs crash dealing with negative numbers, notably
    782             // java.io.File#setLastModified, so instead we fake it and
    783             // hope that time from cell towers or NTP fixes it
    784             // shortly.
    785             Slog.w(TAG, "System clock is before 1970; setting to 1970.");
    786             SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    787         }
    788 
    789         if (SamplingProfilerIntegration.isEnabled()) {
    790             SamplingProfilerIntegration.start();
    791             timer = new Timer();
    792             timer.schedule(new TimerTask() {
    793                 @Override
    794                 public void run() {
    795                     SamplingProfilerIntegration.writeSnapshot("system_server", null);
    796                 }
    797             }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
    798         }
    799 
    800         // Mmmmmm... more memory!
    801         dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
    802 
    803         // The system server has to run all of the time, so it needs to be
    804         // as efficient as possible with its memory usage.
    805         VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    806 
    807         System.loadLibrary("android_servers");
    808         init1(args);
    809     }
    810     public static final void init2() {
    811         Slog.i(TAG, "Entered the Android system server!");
    812         Thread thr = new ServerThread();
    813         thr.setName("android.server.ServerThread");
    814         thr.start();
    815     }
    816 }
    SystemServer 
  • JNI of com/android/server/SystemServer: com_android_server_SystemServer.cpp
  •  1 #include <utils/Log.h>
     2 #include <utils/misc.h>
     3 #include "jni.h"
     4 #include "JNIHelp.h"
     5 namespace android {
     6 extern "C" int system_init();
     7 static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
     8 {
     9     system_init();
    10 }
    11 static JNINativeMethod gMethods[] = {
    12     /** name, signature, funcPtr */
    13     { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
    14 };
    15 int register_android_server_SystemServer(JNIEnv* env)
    16 {
    17     return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
    18             gMethods, NELEM(gMethods));
    19 }
    20 };
  • System_Init.cpp
  •   1 /**
      2  * System server main initialization.
      3  *
      4  * The system server is responsible for becoming the Binder
      5  * context manager, supplying the root ServiceManager object
      6  * through which other services can be found.
      7  */
      8 
      9 #define LOG_TAG "sysproc"
     10 
     11 #include <binder/IPCThreadState.h>
     12 #include <binder/ProcessState.h>
     13 #include <binder/IServiceManager.h>
     14 #include <utils/TextOutput.h>
     15 #include <utils/Log.h>
     16 
     17 #include <SurfaceFlinger.h>
     18 #include <AudioFlinger.h>
     19 #include <CameraService.h>
     20 #include <AudioPolicyService.h>
     21 #include <MediaPlayerService.h>
     22 #include <SensorService.h>
     23 
     24 #include <android_runtime/AndroidRuntime.h>
     25 
     26 #include <signal.h>
     27 #include <stdlib.h>
     28 #include <stdio.h>
     29 #include <unistd.h>
     30 #include <sys/time.h>
     31 #include <cutils/properties.h>
     32 
     33 using namespace android;
     34 
     35 namespace android {
     36 /***
     37  * This class is used to kill this process when the runtime dies.
     38  */
     39 class GrimReaper : public IBinder::DeathRecipient {
     40 public:
     41     GrimReaper() { }
     42 
     43     virtual void binderDied(const wp<IBinder>& who)
     44     {
     45         LOGI("Grim Reaper killing system_server...");
     46         kill(getpid(), SIGKILL);
     47     }
     48 };
     49 
     50 } // namespace android
     51 
     52 
     53 
     54 extern "C" status_t system_init()
     55 {
     56     LOGI("Entered system_init()");
     57 
     58     sp<ProcessState> proc(ProcessState::self());
     59 
     60     sp<IServiceManager> sm = defaultServiceManager();
     61     LOGI("ServiceManager: %p\n", sm.get());
     62 
     63     sp<GrimReaper> grim = new GrimReaper();
     64     sm->asBinder()->linkToDeath(grim, grim.get(), 0);
     65 
     66     char propBuf[PROPERTY_VALUE_MAX];
     67     property_get("system_init.startsurfaceflinger", propBuf, "1");
     68     if (strcmp(propBuf, "1") == 0) {
     69         // Start the SurfaceFlinger
     70         SurfaceFlinger::instantiate();
     71     }
     72 
     73     property_get("system_init.startsensorservice", propBuf, "1");
     74     if (strcmp(propBuf, "1") == 0) {
     75         // Start the sensor service
     76         SensorService::instantiate();
     77     }
     78 
     79     // And now start the Android runtime.  We have to do this bit
     80     // of nastiness because the Android runtime initialization requires
     81     // some of the core system services to already be started.
     82     // All other servers should just start the Android runtime at
     83     // the beginning of their processes's main(), before calling
     84     // the init function.
     85     LOGI("System server: starting Android runtime.\n");
     86     AndroidRuntime* runtime = AndroidRuntime::getRuntime();
     87 
     88     LOGI("System server: starting Android services.\n");
     89     JNIEnv* env = runtime->getJNIEnv();
     90     if (env == NULL) {
     91         return UNKNOWN_ERROR;
     92     }
     93     jclass clazz = env->FindClass("com/android/server/SystemServer");
     94     if (clazz == NULL) {
     95         return UNKNOWN_ERROR;
     96     }
     97     jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
     98     if (methodId == NULL) {
     99         return UNKNOWN_ERROR;
    100     }
    101     env->CallStaticVoidMethod(clazz, methodId);
    102 
    103     LOGI("System server: entering thread pool.\n");
    104     ProcessState::self()->startThreadPool();
    105     IPCThreadState::self()->joinThreadPool();
    106     LOGI("System server: exiting thread pool.\n");
    107 
    108     return NO_ERROR;
    109 }
    system_init.cpp  
     1 extern "C" status_t system_init()//all android services run in this process
     2 {
     3     LOGI("Entered system_init()");
     4     sp<ProcessState> proc(ProcessState::self());
     5     sp<IServiceManager> sm = defaultServiceManager();
     6     sp<GrimReaper> grim = new GrimReaper();
     7     sm->asBinder()->linkToDeath(grim, grim.get(), 0);
     8     char propBuf[PROPERTY_VALUE_MAX];
     9     property_get("system_init.startsurfaceflinger", propBuf, "1");
    10     if (strcmp(propBuf, "1") == 0) { 
    11         SurfaceFlinger::instantiate();
    12     }
    13     property_get("system_init.startsensorservice", propBuf, "1");
    14     if (strcmp(propBuf, "1") == 0) {
    15         SensorService::instantiate();
    16     }
    17     AndroidRuntime* runtime = AndroidRuntime::getRuntime();
    18     LOGI("System server: starting Android services.\n");
    19     JNIEnv* env = runtime->getJNIEnv();
    20     if (env == NULL) {
    21         return UNKNOWN_ERROR;
    22     }
    23     jclass clazz = env->FindClass("com/android/server/SystemServer");
    24     if (clazz == NULL) {
    25         return UNKNOWN_ERROR;
    26     }
    27     jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");//let android runtime call java method
    28     if (methodId == NULL) {
    29         return UNKNOWN_ERROR;
    30     }
    31     env->CallStaticVoidMethod(clazz, methodId); 
    32     ProcessState::self()->startThreadPool();
    33     IPCThreadState::self()->joinThreadPool();   
    34     return NO_ERROR;
    35 }

     

posted @ 2013-08-28 11:11  iDragon  阅读(3896)  评论(0编辑  收藏  举报