Android启动流程简析(三)
接上一篇文章:Android启动流程简析(二)
7. SystemServer启动介绍
SystemServer需要从Zygote fork SystemServer开始分析,主要是设置参数,然后调用Zygote的forkSystemServer方法,再判断是否有SecondaryZygote启动,有则等待其启动,无则返回
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_IPC_LOCK, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_PTRACE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG, OsConstants.CAP_WAKE_ALARM ); /* Containers run without this capability, so avoid setting it in that case */ if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) { capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND); } /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } zygoteServer.closeServerSocket(); return handleSystemServerProcess(parsedArgs); } return null;}
Zygote的forkSystemServer方法主要是调用了native方法nativeForkSystemServer,在native层进行fork动作,并设置pid、gid、selinux安全上下文等,最后启动com.android.server.SystemServer
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { VM_HOOKS.preFork(); // Resets nice priority for zygote process. resetNicePriority(); int pid = nativeForkSystemServer( uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true, debugFlags); } VM_HOOKS.postForkCommon(); return pid;}
static const JNINativeMethod gMethods[] = { { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer }, { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork }, { "nativeUnmountStorageOnInit", "()V", (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit }, { "nativePreApplicationInit", "()V", (void *) com_android_internal_os_Zygote_nativePreApplicationInit }};
static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) { pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL, NULL, NULL, NULL); if (pid > 0) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); gSystemServerPid = pid; // There is a slight window that the system server process has crashed // but it went unnoticed because we haven't published its pid yet. So // we recheck here just to make sure that all is well. int status; if (waitpid(pid, &status, WNOHANG) == pid) { ALOGE("System server process %d has died. Restarting Zygote!", pid); RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); } // Assign system_server to the correct memory cgroup. if (!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) { ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid); } } return pid;}
SystemServer是一个Java类,从main函数入口分析,主要调用run方法,主要工作是:
- 调整时间,如果系统时间比1970还要早,调整到1970年
- 设置语言
- 调整虚拟机堆内存大小和内存利用率
- 初始化Looper为mainLooper
- 装载库libandroid_server.so
- 初始化系统Context
- 创建SystemServiceManager负责系统Service启动
- 创建和启动Java服务
- 调用Looper.loop(),进入处理消息的循环
public static void main(String[] args) { new SystemServer().run();}public SystemServer() { // Check for factory test mode. mFactoryTestMode = FactoryTest.getMode(); // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));}private void run() { try { traceBeginAndSlog("InitBeforeStartServices"); if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } String timezoneProperty = SystemProperties.get("persist.sys.timezone"); if (timezoneProperty == null || timezoneProperty.isEmpty()) { Slog.w(TAG, "Timezone not set; setting to GMT."); SystemProperties.set("persist.sys.timezone", "GMT"); } 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", ""); } // The system server should never make non-oneway calls Binder.setWarnOnBlocking(true); // Here we go! Slog.i(TAG, "Entered the Android system server!"); int uptimeMillis = (int) SystemClock.elapsedRealtime(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis); } SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true); // Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true); // Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true); // Increase the number of binder threads in system_server BinderInternal.setMaxThreads(sMaxBinderThreads); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. try { traceBeginAndSlog("StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } // For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { int uptimeMillis = (int) SystemClock.elapsedRealtime(); MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis); final int MAX_UPTIME_MILLIS = 60 * 1000; if (uptimeMillis > MAX_UPTIME_MILLIS) { Slog.wtf(SYSTEM_SERVER_TIMING_TAG, "SystemServer init took too long. uptimeMillis=" + uptimeMillis); } } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");}
Java服务 7.1 ActivityManagerService启动
AMS在SystemServer的startBootstrapServices中启动,主要是创建了一个Lifecycle对象创建AMS。
创建AMS后会调用AMS的start方法。setSystemServiceManager方法是把AMS纳入SystemServerManager的管理。
在AMS的构造函数中初始化了很多变量和一些服务,如果管理广播的队列、电池和CPU等相关服务,服务会在start方法中启动,并等待启动完成。
最后,调用AMS的systemReady方法完成初始化,在SystemReady中启动桌面。
// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);traceEnd();
public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context); } @Override public void onStart() { mService.start(); } @Override public void onCleanupUser(int userId) { mService.mBatteryStatsService.onCleanupUser(userId); } public ActivityManagerService getService() { return mService; }}
systemReady在SystemServer的startOtherServices的最后被调用,主要是动作是标记和等待各个服务启动完成如等待PMS启动结束,接着启动SystemUI和启动HomeActivity。在Android N之后引入DirectBoot,DirectBoot是一种安全模式,是开机完成但用户还没有解锁的时候处于的一种运行环境。
mActivityManagerService.systemReady(() -> { Slog.i(TAG, "Making services ready"); traceBeginAndSlog("StartActivityManagerReadyPhase"); mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY); traceEnd(); traceBeginAndSlog("StartObservingNativeCrashes"); try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } traceEnd(); // No dependency on Webview preparation in system server. But this should // be completed before allowring 3rd party final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation"; Future<?> webviewPrep = null; if (!mOnlyCore) { webviewPrep = SystemServerInitThreadPool.get().submit(() -> { Slog.i(TAG, WEBVIEW_PREPARATION); TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(WEBVIEW_PREPARATION); ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload"); mZygotePreload = null; mWebViewUpdateService.prepareWebViewInSystemServer(); traceLog.traceEnd(); }, WEBVIEW_PREPARATION); } if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { traceBeginAndSlog("StartCarServiceHelperService"); mSystemServiceManager.startService(CarServiceHelperService.class); traceEnd(); } traceBeginAndSlog("StartSystemUI"); try { startSystemUi(context, windowManagerF); } catch (Throwable e) { reportWtf("starting System UI", e); } traceEnd(); ... traceBeginAndSlog("StartWatchdog"); Watchdog.getInstance().start(); traceEnd(); // Wait for all packages to be prepared mPackageManagerService.waitForAppDataPrepared(); // It is now okay to let the various system services start their third party code... traceBeginAndSlog("PhaseThirdPartyAppsCanStart"); // confirm webview completion before starting 3rd party if (webviewPrep != null) { ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION); } mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); traceEnd(); ... traceBeginAndSlog("MakeTelephonyRegistryReady"); try { if (telephonyRegistryF != null) telephonyRegistryF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying TelephonyRegistry running", e); } traceEnd(); traceBeginAndSlog("MakeMediaRouterServiceReady"); try { if (mediaRouterF != null) mediaRouterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MediaRouterService running", e); } traceEnd(); traceBeginAndSlog("MakeMmsServiceReady"); try { if (mmsServiceF != null) mmsServiceF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MmsService running", e); } traceEnd(); traceBeginAndSlog("MakeNetworkScoreServiceReady"); try { if (networkScoreF != null) networkScoreF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying NetworkScoreService running", e); } traceEnd(); traceBeginAndSlog("IncidentDaemonReady"); try { // TODO: Switch from checkService to getService once it's always // in the build and should reliably be there. final IIncidentManager incident = IIncidentManager.Stub.asInterface( ServiceManager.checkService("incident")); if (incident != null) incident.systemRunning(); } catch (Throwable e) { reportWtf("Notifying incident daemon running", e); } traceEnd();}, BOOT_TIMINGS_TRACE_LOG);
AMS初始化在启动完成后,在锁屏界面Keyguard绘制完成后(finishKeyguardDrawn),然后调用WindowManagerService的enableScreenAfterBoot,WMS会接着调用performEnableScreen通知SurfaceFlinger关闭开机动画,接着WMS调用AMS的bootAnimationComplete通知AMS开机动画结束,AMS最后通过调用finishBooting设置属性sys.boot_complete通知系统开机完成,可以执行属性sys.boot_complete设置之后的任务
private void performEnableScreen() { synchronized(mWindowMap) { try { IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); if (surfaceFlinger != null) { Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); Parcel data = Parcel.obtain(); data.writeInterfaceToken("android.ui.ISurfaceComposer"); surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED data, null, 0); data.recycle(); if (mWindowManagerDebugger.WMS_DEBUG_ENG) { Slog.d(TAG, "Tell SurfaceFlinger finish boot animation"); } } } catch (RemoteException ex) { Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!"); } mDisplayEnabled = true; mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled); } try { mActivityManager.bootAnimationComplete(); } catch (RemoteException e) { } mPolicy.enableScreenAfterBoot(); updateRotationUnchecked(false, false);}
final void finishBooting() { synchronized (this) { if (!mBootAnimationComplete) { mCallFinishBooting = true; return; } mCallFinishBooting = false; } // Let system services know. mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); synchronized (this) { SystemProperties.set("sys.boot_completed", "1"); }}
WMS与SurfaceFlingerBinder进行Binder通信的协议:
class BnSurfaceComposer: public BnInterface {public: enum { // Note: BOOT_FINISHED must remain this value, it is called from // Java by ActivityManagerService. BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, CREATE_CONNECTION, UNUSED, // formerly CREATE_GRAPHIC_BUFFER_ALLOC CREATE_DISPLAY_EVENT_CONNECTION, CREATE_DISPLAY, DESTROY_DISPLAY, GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, GET_SUPPORTED_FRAME_TIMESTAMPS, GET_DISPLAY_CONFIGS, GET_ACTIVE_CONFIG, SET_ACTIVE_CONFIG, CONNECT_DISPLAY, CAPTURE_SCREEN, CLEAR_ANIMATION_FRAME_STATS, GET_ANIMATION_FRAME_STATS, SET_POWER_MODE, GET_DISPLAY_STATS, GET_HDR_CAPABILITIES, GET_DISPLAY_COLOR_MODES, GET_ACTIVE_COLOR_MODE, SET_ACTIVE_COLOR_MODE, ENABLE_VSYNC_INJECTIONS, INJECT_VSYNC, CREATE_SCOPED_CONNECTION }; virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);};
class BpSurfaceComposer : public BpInterface{public: explicit BpSurfaceComposer(const sp& impl) : BpInterface(impl) { } virtual ~BpSurfaceComposer(); virtual void bootFinished() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); }}
可以看到WMS通过binder通信,调用IBinder.FIRST_CALL_TRANSACTION函数,也就是android.ui.ISurfaceComposer的BOOT_FINISHED对应的函数bootFinished(),SurfaceFlinger是继承BpSurfaceComposer的,所以最后调用的是SurfaceFlinger::bootFinished(),通过设置属性service.bootanim.exit标记开机动画结束
void SurfaceFlinger::bootFinished(){ if (mStartPropertySetThread->join() != NO_ERROR) { ALOGE("Join StartPropertySetThread failed!"); } const nsecs_t now = systemTime(); const nsecs_t duration = now - mBootTime; ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); // wait patiently for the window manager death const String16 name("window"); sp window(defaultServiceManager()->getService(name)); if (window != 0) { window->linkToDeath(static_cast(this)); } if (mVrFlinger) { mVrFlinger->OnBootFinished(); } // stop boot animation // formerly we would just kill the process, but we now ask it to exit so it // can choose where to stop the animation. property_set("service.bootanim.exit", "1"); const int LOGTAG_SF_STOP_BOOTANIM = 60110; LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); sp readProperties = new LambdaMessage([&]() { readPersistentProperties(); }); postMessageAsync(readProperties);}
7.2 PackageManagerService启动
PMS是在SystemServer的startBootstrapServices中启动,启动时构建一个PMS实例,初始化相关服务,主要的动作有扫描app目录包括system/app、system/priv-app、vendor/app等,首次启动会调用DexManager对获取到的Package进行load操作,主要是通过SCAN_FIRST_BOOT_OR_UPGRADE这个scanFlag进行区分,而判断设备是否是第一次启动是通过判断文件data/system/packages.xml是否存在进行判断
traceBeginAndSlog("StartPackageManagerService");mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);mFirstBoot = mPackageManagerService.isFirstBoot();mPackageManager = mSystemContext.getPackageManager();traceEnd();
public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { // Self-check for initial settings. PackageManagerServiceCompilerMapping.checkProperties(); PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); m.enableSystemUserPackages(); ServiceManager.addService("package", m); final PackageManagerNative pmn = m.new PackageManagerNative(); ServiceManager.addService("package_native", pmn); return m;}
首次开机和非首次开机区别就在于扫描app目录时,首次开机做了dex2ota的动作,相对来说就要较非首次开机耗时
// Set flag to monitor and not change apk file paths when scanning install directories.int scanFlags = SCAN_BOOTING | SCAN_INITIAL;if (mIsUpgrade || mFirstBoot) { scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;}
PMS的systemReady调用在SystemServer的startOtherServices的最后AMS的systemReady调用之前,也就是说PSM的初始化需要先于AMS,PMS标记systemReady主要是使UserManager和InstallerService等服务标记为systemReady
@Overridepublic void systemReady() { enforceSystemOrRoot("Only the system can claim the system is ready"); mSystemReady = true; final ContentResolver resolver = mContext.getContentResolver(); ContentObserver co = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { mEphemeralAppsDisabled = (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) || (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0); } }; mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE), false, co, UserHandle.USER_SYSTEM); mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM); co.onChange(true); // Disable any carrier apps. We do this very early in boot to prevent the apps from being // disabled after already being started. CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, mContext.getContentResolver(), UserHandle.USER_SYSTEM); // Read the compatibilty setting when the system is ready. boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); } int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; synchronized (mPackages) { ArrayList removed = new ArrayList(); for (int i=0; i 0) { for (int r=0; r
8. Launcher启动介绍
8.1SystemUI启动
SystemUI在AMS执行systemReady时启动,主要是通过Intent启动包名为com.android.systemui组件名为SystemUIService的服务,然后通过调用WindowManager的onSystemUiStarted方法调用KeyguardService启动锁屏服务。SystemUI启动成功后表示系统的通知栏和导航栏已经初始化成功,接下来就是启动Launcher
traceBeginAndSlog("StartSystemUI");try { startSystemUi(context, windowManagerF);} catch (Throwable e) { reportWtf("starting System UI", e);}traceEnd();
static final void startSystemUi(Context context, WindowManagerService windowManager) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.SYSTEM); windowManager.onSystemUiStarted();}
8.2Launcher启动
Launcher的启动在AMS的最后,通过startHomeActivityLocked把启动Launcher的Activity并将其置于Activity栈顶,然后通过resumeFocusedStackTopActivityLocked将栈顶的Activity显示到界面上,launcher的启动就已经完成了
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { traceLog.traceBegin("PhaseActivityManagerReady"); synchronized(this) { if (mSystemReady) { // If we're done calling all the receivers, run the next "boot phase" passed in // by the SystemServer if (goingCallback != null) { goingCallback.run(); } return; } mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); mAssistUtils = new AssistUtils(mContext); mVrController.onSystemReady(); // Make sure we have the current profile info, since it is needed for security checks. mUserController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mAppOpsService.systemReady(); mSystemReady = true; } try { sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface( ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)) .getSerial(); } catch (RemoteException e) {} ArrayList procsToKill = null; synchronized(mPidsSelfLocked) { for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); if (!isAllowedWhileBooting(proc.info)){ if (procsToKill == null) { procsToKill = new ArrayList(); } procsToKill.add(proc); } } } synchronized(this) { if (procsToKill != null) { for (int i=procsToKill.size()-1; i>=0; i--) { ProcessRecord proc = procsToKill.get(i); Slog.i(TAG, "Removing system update proc: " + proc); removeProcessLocked(proc, true, false, "system update done"); } } // Now that we have cleaned up any update processes, we // are ready to start launching real processes and know that // we won't trample on them any more. mProcessesReady = true; } Slog.i(TAG, "System now ready"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis()); ... traceLog.traceBegin("ActivityManagerStartApps"); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); mSystemServiceManager.startUser(currentUserId); synchronized (this) { // Only start up encryption-aware persistent apps; once user is // unlocked we'll come back around and start unaware apps startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); // Start up initial activity. mBooting = true; // Enable home activity for system user, so that the system can always boot. We don't // do this when the system user is not setup since the setup wizard should be the one // to handle home activity in this case. if (UserManager.isSplitSystemUser() && Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) { ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); try { AppGlobals.getPackageManager().setComponentEnabledSetting(cName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, UserHandle.USER_SYSTEM); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } startHomeActivityLocked(currentUserId, "systemReady"); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" + " data partition or your device will be unstable."); mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); } } catch (RemoteException e) { } if (!Build.isBuildConsistent()) { Slog.e(TAG, "Build fingerprint is not consistent, warning user"); mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget(); } long ident = Binder.clearCallingIdentity(); try { Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, currentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { Binder.restoreCallingIdentity(ident); } mStackSupervisor.resumeFocusedStackTopActivityLocked(); mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); traceLog.traceEnd(); // ActivityManagerStartApps traceLog.traceEnd(); // PhaseActivityManagerReady }}
boolean startHomeActivityLocked(int userId, String reason) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) { // We are running in factory test mode, but unable to find // the factory test app, so just sit around displaying the // error message and don't try to start anything. return false; } Intent intent = getHomeIntent(); ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); if (aInfo != null) { intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); // Don't do this if the home app is currently being instrumented. aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true); if (app == null || app.instr == null) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid); // For ANR debugging to verify if the user activity is the one that actually launched. final String myReason = reason + ":" + userId + ":" + resolvedUserId; mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); } } else { Slog.wtf(TAG, "No home screen found for " + intent, new Throwable()); } return true;}
Intent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } return intent;}
9. Log抓取与分析方法
开机时间主要分析kernel log、events log、logcat log
adb shell dmesg > dmesg.txtadb logcat –v threadtime –b events –d > logcat_events.logadb logcat –v threadtime –d *:V > logcat.txt
高通平台分析kernel log:
01-01 13:32:28.012 I/KPI ( 0): Bootloader start count = 2643701-01 13:32:28.012 I/KPI ( 0): Bootloader end count = 19938801-01 13:32:28.012 I/KPI ( 0): Bootloader display count = 10176401-01 13:32:28.012 I/KPI ( 0): Bootloader load kernel count = 309701-01 13:32:28.012 I/KPI ( 0): Kernel MPM timestamp = 22687601-01 13:32:28.012 I/KPI ( 0): Kernel MPM Clock frequency = 32768
根据log可以获取以下信息:
- NHLOS时间:Bootloader start count / Kernel MPM Clock frequency = 26437 / 32768 = 0.807s
- lk启动时间:(Bootloader end count-Bootloader start count) / Kernel MPM Clock frequency = (199388 - 26437) / 32768 = 5.278s
- bootloader启动时间:Kernel MPM timestamp / Kernel MPM Clock frequency = 226876 / 32768 = 6.924s
MTK平台分析bootprof:
<< /proc/bootprof >>:----------------------------------------0 BOOT PROF (unit:msec)---------------------------------------- 5074 : preloader 2808 : lk (Start->Show logo: 1282)
根据log可以获取以下信息:
- perloader启动时间是5074ms
- lk启动时间是2808ms
Events Log分析:
01-01 13:14:19.129 674 674 I boot_progress_start: 1240101-01 13:14:20.135 674 674 I boot_progress_preload_start: 1340801-01 13:14:21.025 675 675 I boot_progress_preload_start: 1429701-01 13:14:21.935 674 674 I boot_progress_preload_end: 1520801-01 13:14:22.519 675 675 I boot_progress_preload_end: 1579201-01 13:14:22.660 1370 1370 I boot_progress_system_run: 1593201-01 13:14:23.152 1370 1370 I boot_progress_pms_start: 1642501-01 13:14:23.794 1370 1370 I boot_progress_pms_system_scan_start: 1706701-01 13:14:25.566 1370 1370 I boot_progress_pms_data_scan_start: 1883801-01 13:14:25.619 1370 1370 I boot_progress_pms_scan_end: 1889201-01 13:14:27.060 1370 1370 I boot_progress_pms_ready: 2033201-01 13:14:29.302 1370 1370 I boot_progress_ams_ready: 2257401-01 13:14:30.472 1370 1455 I boot_progress_enable_screen: 2374401-01 13:14:32.181 492 535 I sf_stop_bootanim: 2545301-01 13:14:32.254 492 492 I sf_frame_dur: [BootAnimation,12,331,3,1,0,1,1] // 25506 01-01 13:14:32.343 1370 1480 I wm_boot_animation_done: 25616
Kernel part: boot_progress_start = 12401msZygote time: boot_progress_preload_end - boot_progress_preload_start = 15792 - 13408 = 2384msSystem folder Scan time: boot_progress_pms_data_scan_start- boot_progress_pms_system_scan_start = 18838 - 17067 = 1771msData folder scan time: boot_progress_pms_scan_end- boot_progress_pms_data_scan_start = 18892 - 18838 = 54msHome activity start time: boot_progress_enable_screen- boot_progress_ams_ready = 23744 - 22574 = 1170msHome activity idle to Bootanimation finish: sf_frame_dur - boot_progress_enable_screen = 25506 - 23744 = 1762msHome activity idle to SF stop bootanim: sf_stop_bootanim - boot_progress_enable_screen = 25453 - 23744 = 1709msBootanim end time: wm_boot_animation_done - sf_stop_bootanim = 25616 - 25453 = 163ms
Log含义 结束语
到此Android的开机流程就分析完了,比较仓促,有许多不足的地方,开机过程中涉及的许多文件未有说明,如kernel下的defconfig文件,通过配置config文件的宏控,打开某些功能,这些config都会影响到开机的时间,eng、userdebug和user版的差异最大的地方就是这个defconfig的配置,调试的宏控开多了,会大大影响开机时间,曾经试过在eng版本上开机时间长达十分钟的,所以说,要优化开机时间,可以考虑从defconfig文件的配置入手。
了解开机时间流程是为了解Android的整体架构,在此做一下记录,与大家共勉。
更多相关文章
- Android:Android(安卓)Studio 优化
- android 画图之bitmap(一)
- Android(安卓)app ERR_UNKNOWN_URL_SCHEME
- Android之Handler的postDelayed()方法的用法
- Android(安卓)MediaPlayer 常用方法介绍
- someone's android note
- Android判断两个时间的间隔
- 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(二)
- 【翻译】Android中的AOP编程