本文從SystemServer的main函數開始研究。
/*** SystemServer.java ***/
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
mFactoryTestMode = FactoryTest.getMode();
}
SystemServer的初始化,只是簡單的檢查了一下是否處於工廠測試模式。關於工廠測試模式請參考“Android FactoryTest框架”一文。
創建了SystemServer對象後,直接調用它的run函數。
/*** SystemServer.java ***/
private void run() {
//如果系統時間早於1970,則設置系統時間爲1970年。
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//設置區域,語言等選項
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
//虛擬機使用 dvm 或 art。參考“Android ART運行時無縫替換Dalvik虛擬機的過程分析”一文
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
//啓動採樣分析,分析性能時使用
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
//清除vm內存增長上限,由於啓動過程需要較多的虛擬機內存空間
VMRuntime.getRuntime().clearGrowthLimit();
//設置堆棧利用率。GC後會重新計算堆棧空間大小。
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//針對部分設備依賴於運行時就產生指紋信息,因此需要在開機完成前已經定義
Build.ensureFingerprintProperty();
//訪問環境變量前,需要明確地指定用戶
Environment.setUserRequired(true);
//確保當前系統進程的binder調用,總是運行在前臺優先級(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize native services.
//frameworks/base/services/Android.mk
//LOCAL_MODULE:= libandroid_servers
System.loadLibrary("android_servers");
//檢測上次關機過程是否失敗,該方法可能不會返回
performPendingShutdown();
//初始化系統上下文
createSystemContext();
//創建系統服務管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//啓動各種系統服務
try {
startBootstrapServices(); //啓動引導服務
startCoreServices(); //啓動核心服務
startOtherServices(); //啓動其他服務
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
//用於debug版本,將log事件不斷循環地輸出到dropbox(用於分析)
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
//一直循環執行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
去掉一些初始化設置,簡化後的run函數如下:/*** SystemServer.java ***/
private void run() {
Looper.prepareMainLooper();
//初始化系統上下文
createSystemContext();
//創建系統服務管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//啓動各種系統服務
try {
startBootstrapServices(); //啓動引導服務
startCoreServices(); //啓動核心服務
startOtherServices(); //啓動其他服務
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
簡單來看,SystemServer啓動時主要做了以下幾件事:1. 初始化系統上下文
2. 創建系統服務管理
3. 啓動各種系統服務
1. 初始化系統上下文
/*** SystemServer.java ***/
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
1.創建ActivityThread2.獲取系統上下文
3.設置主題
1.1 創建ActivityThread
/*** ActivityThread.java ***/
public static ActivityThread systemMain() {
//對於低內存的設備,禁用硬件加速
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(true);
} else {
HardwareRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
ActivityThread() {
//使用單例模式獲得一個ResourcesManager實例
mResourcesManager = ResourcesManager.getInstance();
}
/*** ActivityThread.java ***/
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
} else {
//設置SystemServer進程在DDMS中顯示的名字爲"system_process"
//如不設置,則顯示"?",無法調試該進程。app一般顯示包名。
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
//首先通過getSystemContext()創建系統上下文,然後創建應用上下文
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//創建Application
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
//調用Application的onCreate()
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
attach做的主要事情有:1.創建系統上下文 getSystemContext()-->ContextImpl.createSystemContext()-->new ContextImpl()
2.創建應用上下文 ContextImpl.createAppContext()-->new ContextImpl(),由應用上下文創建Application,並調用其onCreate()方法
3.添加回調ComponentCallbacks2到ViewRootImpl上
創建系統上下文/應用上下文
/*** ContextImpl.java ***/
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetricsLocked());
return context;
}
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
return new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
}
new ContextImpl時,系統上下文和應用上下文的參數是一樣的,createAppContext()的參數packageInfo,就是createSystemContext()中new的LoadedApk。創建完成之後,系統上下文賦值給了ActivityThread的成員變量mSystemContext,而應用上下文只是作爲函數中的局部變量臨時使用。
/*** ActivityThread.java ***/
private ContextImpl mSystemContext;
創建Application
/*** LoadedApk.java ***/
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
//參數forceDefaultAppClass爲true
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
//此LoadedApk對象是createSystemContext時new的,mPackageName="android"
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
//又創建了一個局部應用上下文
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//創建Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
//將前面創建的app添加到應用列表。
mActivityThread.mAllApplications.add(app);
mApplication = app;
...
return app;
}
這一步主要創建了一個ActivityThread對象,然後執行了該對象的attach()方法。
attach()方法中創建了系統上下文mSystemContext(類型爲ContextImpl),並創建Application對象。
系統上下文中,new了一個LoadedApk的成員變量,並將ActivityThread對象傳給LoadedApk成員。
後面的Application對象就是LoadedApk使用ActivityThread創建的。
LoadedApk創建了Application對象後,將Application添加到ActivityThread的應用列表中。
2. 創建系統服務管理
/*** SystemServer.java ***/
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
這一步比較簡單,只是new了一個SystemServiceManager,並將其添加到本地服務列表中。mSystemContext爲第一步中創建的系統上下文。
本地服務列表是以類爲key保存的一個列表,即列表中某種類型的對象最多只能有一個。
/*** SystemServiceManager.java ***/
//系統服務列表,系統服務必須繼承SystemService
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
//當前處於開機過程的哪個階段,SystemService.PHASE_XXXXX
private int mCurrentPhase = -1;
//通過類名啓動系統服務,可能會找不到類而拋異常
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
throw new RuntimeException("Failed to create service " + className
+ ": service class not found, usually indicates that the caller should "
+ "have called PackageManager.hasSystemFeature() to check whether the "
+ "feature is available on this device before trying to start the "
+ "services that implement it", ex);
}
return startService(serviceClass);
}
//創建並啓動系統服務,系統服務類必須繼承SystemService
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
// Register it.
mServices.add(service);
// Start it.
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;
}
//通知系統服務到了開機的哪個階段,會遍歷調用所有系統服務的onBootPhase()函數
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
try {
service.onBootPhase(mCurrentPhase);
} catch (Exception ex) {
throw new RuntimeException("Failed to boot service "
+ service.getClass().getName()
+ ": onBootPhase threw an exception during phase "
+ mCurrentPhase, ex);
}
}
}
/*** SystemService.java ***/
/*
* Boot Phases
*/
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?
/**
* After receiving this boot phase, services can obtain lock settings data.
*/
public static final int PHASE_LOCK_SETTINGS_READY = 480;
/**
* After receiving this boot phase, services can safely call into core system services
* such as the PowerManager or PackageManager.
*/
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
/**
* After receiving this boot phase, services can broadcast Intents.
*/
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
/**
* After receiving this boot phase, services can start/bind to third party apps.
* Apps will be able to make Binder calls into services at this point.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
/**
* After receiving this boot phase, services can allow user interaction with the device.
* This phase occurs when boot has completed and the home application has started.
* System services may prefer to listen to this phase rather than registering a
* broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
*/
public static final int PHASE_BOOT_COMPLETED = 1000;
//子類必須定義只有一個Context參數的構造,並調用父類的此構造將Context參數傳給父類。
//SystemServiceManager創建SystemService時,使用反射機制調用的此構造方法
public SystemService(Context context) {
mContext = context;
}
//啓動系統服務時,調用
public abstract void onStart();
//開機的每個階段都會調用
public void onBootPhase(int phase) {}
系統服務區別於普通服務,普通服務由ServiceManager來管理。ServiceManager涉及到Binder機制,是如何管理普通服務的,後續再研究。
3. 啓動各種系統服務
/*** SystemServer.java ***/
startBootstrapServices(); //啓動引導服務
startCoreServices(); //啓動核心服務
startOtherServices(); //啓動其他服務
3.1 啓動引導服務
/*** SystemServer.java ***/
private void startBootstrapServices() {
//啓動Installer服務,阻塞等待與installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
//啓動AMS(後面做詳細分析)
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//啓動PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//PowerManagerService就緒,AMS初始化電源管理
mActivityManagerService.initPowerManagement();
//啓動LightsService
mSystemServiceManager.startService(LightsService.class);
//啓動DisplayManagerService(before package manager)
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//初始化package manager之前,需要默認顯示。阻塞,10s超時,see DisplayManagerService.onBootPhase()
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
//當設備正在加密時,僅運行核心應用
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
//啓動PackageManagerService
Slog.i(TAG, "Package Manager");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//將UserManagerService添加到服務列表,該服務是在PackageManagerService中初始化的
Slog.i(TAG, "User Service");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
//初始化用來緩存包資源的屬性緩存
AttributeCache.init(mSystemContext);
//設置AMS
mActivityManagerService.setSystemProcess();
//啓動傳感器服務(native 服務,依賴PackageManagerService、AppOpsService、permissions service)
startSensorService();
}
這步首先等待installd啓動完成,然後啓動一些相互依賴的關鍵服務。所創建的服務:ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,sensor服務。
3.2 啓動核心服務
/*** SystemServer.java ***/
/**
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
//啓動BatteryService,用於統計電池電量,需要LightService
mSystemServiceManager.startService(BatteryService.class);
//啓動UsageStatsService,用於統計應用使用情況
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update after UsageStatsService is available, needed before performBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
//啓動WebViewUpdateService
mSystemServiceManager.startService(WebViewUpdateService.class);
}
啓動服務BatteryService,UsageStatsService,WebViewUpdateService。3.3 啓動其他服務
此函數代碼較長,但是邏輯簡單,主要是啓動各種服務。以下代碼僅按順序列出啓動的服務,有些服務根據條件,如是否是工廠模式,或系統屬性配置,選擇性啓動,這裏不考慮條件判斷和異常處理。
/*** SystemServer.java ***/
private void startOtherServices() {
...
try {
SchedulingPolicyService // 調度策略
TelecomLoaderService //
TelephonyRegistry // 提供電話註冊、管理服務,可以獲取電話的鏈接狀態、信號強度等
EntropyMixer // 隨機數相關,原名EntropyService。 參考“EntropyService分析”
CameraService //
AccountManagerService // 提供所有賬號、密碼、認證管理等等的服務
ContentService // ContentProvider服務,提供跨進程數據交換
VibratorService // 振動器服務
ConsumerIrService // 紅外遠程控制服務
AlarmManagerService // 提供鬧鈴和定時器等功能
//初始化 Watchdog。是在AMS的systemReady回調中運行的:Watchdog.getInstance().start();
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
WindowManagerService // 窗口管理服務
InputManagerService // 事件傳遞分發服務
BluetoothService // 藍牙服務
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
InputMethodManagerService // 輸入法服務
AccessibilityManagerService // 輔助管理程序截獲所有的用戶輸入,並根據這些輸入給用戶一些額外的反饋,起到輔助的效果
MountService // 掛載服務
UiModeManagerService // 管理當前Android設備的夜間模式和行車模式
//frameworks/base/core/res/res/values-zh-rCN/strings.xml
ActivityManagerNative.getDefault().showBootMessage(
context.getResources().getText(
com.android.internal.R.string.android_upgrading_starting_apps),
false);
LockSettingsService // 屏幕鎖定服務,管理每個用戶的相關鎖屏信息
PersistentDataBlockService //
DeviceIdleController // Doze模式的主要驅動,參考“深入Android 'M' Doze”
DevicePolicyManagerService // 提供一些系統級別的設置及屬性
StatusBarManagerService // 狀態欄管理服務
ClipboardService // 系統剪切板服務
NetworkManagementService // 網絡管理服務
TextServicesManagerService // 文本服務,例如文本檢查等
NetworkScoreService // 網絡評分服務
NetworkStatsService // 網絡狀態服務
NetworkPolicyManagerService // 網絡策略服務
WifiP2pService // Wifi Direct服務
WifiService // Wifi服務
WifiScanningService // Wifi掃描服務
RttService // Wifi相關
EthernetService // 以太網服務
ConnectivityService // 網絡連接管理服務
NsdService // 網絡發現服務(Network Service Discovery Service)
UpdateLockService //
//等待MountService完全啓動,後面有些依賴
mountService.waitForAsecScan();
accountManager.systemReady();
contentService.systemReady();
NotificationManagerService // 通知欄管理服務
DeviceStorageMonitorService // 磁盤空間狀態檢測服務
LocationManagerService // 位置服務,GPS、定位等
CountryDetectorService // 檢測用戶國家
SearchManagerService // 搜索管理服務
DropBoxManagerService // 用於系統運行時日誌的存儲於管理
WallpaperManagerService // 壁紙管理服務
AudioService // AudioFlinger的上層管理封裝,主要是音量、音效、聲道及鈴聲等的管理
DockObserver // 如果系統有個座子,當手機裝上或拔出這個座子的話,就得靠他來管理了
WiredAccessoryManager // 監視手機和底座上的耳機
MidiService //
UsbService // USB服務
SerialService // 串口服務
TwilightService // 指出用戶當前所在位置是否爲晚上,被UiModeManager等用來調整夜間模式。
JobSchedulerService //
BackupManagerService // 備份服務
AppWidgetService // 提供Widget的管理和相關服務
VoiceInteractionManagerService // 語音交互管理服務
DiskStatsService // 磁盤統計服務,供dumpsys使用
SamplingProfilerService // 用於耗時統計等
NetworkTimeUpdateService // 監視網絡時間,當網絡時間變化時更新本地時間。
CommonTimeManagementService // 管理本地常見的時間服務的配置,在網絡配置變化時重新配置本地服務。
CertBlacklister // 提供一種機制更新SSL certificate blacklist
DreamManagerService // 屏幕保護
AssetAtlasService // 負責將預加載的bitmap組裝成紋理貼圖,生成的紋理貼圖可以被用來跨進程使用,以減少內存。
GraphicsStatsService //
PrintManagerService // 打印服務
RestrictionsManagerService //
MediaSessionService //
HdmiControlService // HDMI控制服務
TvInputManagerService //
MediaRouterService //
TrustManagerService //
FingerprintService // 指紋服務
BackgroundDexOptService // 主要用於classes文件的odex優化
LauncherAppsService //
MediaProjectionManagerService // 管理媒體投影會話
MmsServiceBroker // MmsService的代理
// It is now time to start up the app processes...
vibrator.systemReady();
lockSettings.systemReady();
// Needed by DevicePolicyManager for initialization
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
wm.systemReady();
if (safeMode) {
mActivityManagerService.showSafeModeOverlay();
}
// Update the configuration for this context by hand
context.getResources().updateConfiguration(config, metrics);
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(safeMode, mOnlyCore);
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
mActivityManagerService.startObservingNativeCrashes();
WebViewFactory.prepareWebViewInSystemServer();
startSystemUi(context);
networkScoreF.systemReady();
networkManagementF.systemReady();
networkStatsF.systemReady();
networkPolicyF.systemReady();
connectivityF.systemReady();
audioServiceF.systemReady();
//開啓 Watchdog
Watchdog.getInstance().start();
mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
wallpaperF.systemRunning();
immF.systemRunning(statusBarF);
locationF.systemRunning();
countryDetectorF.systemRunning();
networkTimeUpdaterF.systemRunning();
commonTimeMgmtServiceF.systemRunning();
textServiceManagerServiceF.systemRunning();
atlasF.systemRunning();
inputManagerF.systemRunning();
telephonyRegistryF.systemRunning();
mediaRouterF.systemRunning();
mmsServiceF.systemRunning();
}
});
}