接上一篇文章:Android啟動流程簡析(二)
7. SystemServer啟動介紹
SystemServer需要從Zygote fork SystemServer開始分析,主要是設(shè)置參數(shù),然后調(diào)用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方法主要是調(diào)用了native方法nativeForkSystemServer,在native層進(jìn)行fork動作,并設(shè)置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函數(shù)入口分析,主要調(diào)用run方法,主要工作是:
- 調(diào)整時間,如果系統(tǒng)時間比1970還要早,調(diào)整到1970年
- 設(shè)置語言
- 調(diào)整虛擬機(jī)堆內(nèi)存大小和內(nèi)存利用率
- 初始化Looper為mainLooper
- 裝載庫libandroid_server.so
- 初始化系統(tǒng)Context
- 創(chuàng)建SystemServiceManager負(fù)責(zé)系統(tǒng)Service啟動
- 創(chuàng)建和啟動Java服務(wù)
- 調(diào)用Looper.loop(),進(jìn)入處理消息的循環(huán)
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");
}

7.1 ActivityManagerService啟動
AMS在SystemServer的startBootstrapServices中啟動,主要是創(chuàng)建了一個Lifecycle對象創(chuàng)建AMS。
創(chuàng)建AMS后會調(diào)用AMS的start方法。setSystemServiceManager方法是把AMS納入SystemServerManager的管理。
在AMS的構(gòu)造函數(shù)中初始化了很多變量和一些服務(wù),如果管理廣播的隊列、電池和CPU等相關(guān)服務(wù),服務(wù)會在start方法中啟動,并等待啟動完成。
最后,調(diào)用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的最后被調(diào)用,主要是動作是標(biāo)記和等待各個服務(wù)啟動完成如等待PMS啟動結(jié)束,接著啟動SystemUI和啟動HomeActivity。在Android N之后引入DirectBoot,DirectBoot是一種安全模式,是開機(jī)完成但用戶還沒有解鎖的時候處于的一種運(yùn)行環(huán)境。
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),然后調(diào)用WindowManagerService的enableScreenAfterBoot,WMS會接著調(diào)用performEnableScreen通知SurfaceFlinger關(guān)閉開機(jī)動畫,接著WMS調(diào)用AMS的bootAnimationComplete通知AMS開機(jī)動畫結(jié)束,AMS最后通過調(diào)用finishBooting設(shè)置屬性sys.boot_complete通知系統(tǒng)開機(jī)完成,可以執(zhí)行屬性sys.boot_complete設(shè)置之后的任務(wù)
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進(jìn)行Binder通信的協(xié)議:
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
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<ISurfaceComposer>
{
public:
explicit BpSurfaceComposer(const sp<IBinder>& impl)
: BpInterface<ISurfaceComposer>(impl)
{
}
virtual ~BpSurfaceComposer();
virtual void bootFinished()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
}
}
可以看到WMS通過binder通信,調(diào)用IBinder.FIRST_CALL_TRANSACTION函數(shù),也就是android.ui.ISurfaceComposer的BOOT_FINISHED對應(yīng)的函數(shù)bootFinished(),SurfaceFlinger是繼承BpSurfaceComposer的,所以最后調(diào)用的是SurfaceFlinger::bootFinished(),通過設(shè)置屬性service.bootanim.exit標(biāo)記開機(jī)動畫結(jié)束
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<IBinder> window(defaultServiceManager()->getService(name));
if (window != 0) {
window->linkToDeath(static_cast<IBinder::DeathRecipient*>(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<LambdaMessage> readProperties = new LambdaMessage([&]() {
readPersistentProperties();
});
postMessageAsync(readProperties);
}
7.2 PackageManagerService啟動
PMS是在SystemServer的startBootstrapServices中啟動,啟動時構(gòu)建一個PMS實(shí)例,初始化相關(guān)服務(wù),主要的動作有掃描app目錄包括system/app、system/priv-app、vendor/app等,首次啟動會調(diào)用DexManager對獲取到的Package進(jìn)行l(wèi)oad操作,主要是通過SCAN_FIRST_BOOT_OR_UPGRADE這個scanFlag進(jìn)行區(qū)分,而判斷設(shè)備是否是第一次啟動是通過判斷文件data/system/packages.xml是否存在進(jìn)行判斷
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;
}
首次開機(jī)和非首次開機(jī)區(qū)別就在于掃描app目錄時,首次開機(jī)做了dex2ota的動作,相對來說就要較非首次開機(jī)耗時
// 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調(diào)用在SystemServer的startOtherServices的最后AMS的systemReady調(diào)用之前,也就是說PSM的初始化需要先于AMS,PMS標(biāo)記systemReady主要是使UserManager和InstallerService等服務(wù)標(biāo)記為systemReady
@Override
public 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<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
removed.clear();
for (PreferredActivity pa : pir.filterSet()) {
if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
removed.add(pa);
}
}
if (removed.size() > 0) {
for (int r=0; r<removed.size(); r++) {
PreferredActivity pa = removed.get(r);
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
pir.removeFilter(pa);
}
mSettings.writePackageRestrictionsLPr(
mSettings.mPreferredActivities.keyAt(i));
}
}
for (int userId : UserManagerService.getInstance().getUserIds()) {
if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
grantPermissionsUserIds = ArrayUtils.appendInt(
grantPermissionsUserIds, userId);
}
}
}
sUserManager.systemReady();
// If we upgraded grant all default permissions before kicking off.
for (int userId : grantPermissionsUserIds) {
mDefaultPermissionPolicy.grantDefaultPermissions(userId);
}
// If we did not grant default permissions, we preload from this the
// default permission exceptions lazily to ensure we don't hit the
// disk on a new user creation.
if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
}
// Kick off any messages waiting for system ready
if (mPostSystemReadyMessages != null) {
for (Message msg : mPostSystemReadyMessages) {
msg.sendToTarget();
}
mPostSystemReadyMessages = null;
}
mInstallerService.systemReady();
mPackageDexOptimizer.systemReady();
...
// Now that we're mostly running, clean up stale users and apps
sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
if (mPrivappPermissionsViolations != null) {
Slog.wtf(TAG,"Signature|privileged permissions not in "
+ "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
mPrivappPermissionsViolations = null;
}
}
8. Launcher啟動介紹
8.1SystemUI啟動
SystemUI在AMS執(zhí)行systemReady時啟動,主要是通過Intent啟動包名為com.android.systemui組件名為SystemUIService的服務(wù),然后通過調(diào)用WindowManager的onSystemUiStarted方法調(diào)用KeyguardService啟動鎖屏服務(wù)。SystemUI啟動成功后表示系統(tǒng)的通知欄和導(dǎo)航欄已經(jīng)初始化成功,接下來就是啟動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將棧頂?shù)腁ctivity顯示到界面上,launcher的啟動就已經(jīng)完成了
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<ProcessRecord> 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<ProcessRecord>();
}
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抓取與分析方法
開機(jī)時間主要分析kernel log、events log、logcat log
adb shell dmesg > dmesg.txt
adb logcat –v threadtime –b events –d > logcat_events.log
adb logcat –v threadtime –d *:V > logcat.txt
高通平臺分析kernel log:
01-01 13:32:28.012 I/KPI ( 0): Bootloader start count = 26437
01-01 13:32:28.012 I/KPI ( 0): Bootloader end count = 199388
01-01 13:32:28.012 I/KPI ( 0): Bootloader display count = 101764
01-01 13:32:28.012 I/KPI ( 0): Bootloader load kernel count = 3097
01-01 13:32:28.012 I/KPI ( 0): Kernel MPM timestamp = 226876
01-01 13:32:28.012 I/KPI ( 0): Kernel MPM Clock frequency = 32768
根據(jù)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)
根據(jù)log可以獲取以下信息:
- perloader啟動時間是5074ms
- lk啟動時間是2808ms
Events Log分析:
01-01 13:14:19.129 674 674 I boot_progress_start: 12401
01-01 13:14:20.135 674 674 I boot_progress_preload_start: 13408
01-01 13:14:21.025 675 675 I boot_progress_preload_start: 14297
01-01 13:14:21.935 674 674 I boot_progress_preload_end: 15208
01-01 13:14:22.519 675 675 I boot_progress_preload_end: 15792
01-01 13:14:22.660 1370 1370 I boot_progress_system_run: 15932
01-01 13:14:23.152 1370 1370 I boot_progress_pms_start: 16425
01-01 13:14:23.794 1370 1370 I boot_progress_pms_system_scan_start: 17067
01-01 13:14:25.566 1370 1370 I boot_progress_pms_data_scan_start: 18838
01-01 13:14:25.619 1370 1370 I boot_progress_pms_scan_end: 18892
01-01 13:14:27.060 1370 1370 I boot_progress_pms_ready: 20332
01-01 13:14:29.302 1370 1370 I boot_progress_ams_ready: 22574
01-01 13:14:30.472 1370 1455 I boot_progress_enable_screen: 23744
01-01 13:14:32.181 492 535 I sf_stop_bootanim: 25453
01-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 = 12401ms
Zygote time: boot_progress_preload_end - boot_progress_preload_start = 15792 - 13408 = 2384ms
System folder Scan time: boot_progress_pms_data_scan_start- boot_progress_pms_system_scan_start = 18838 - 17067 = 1771ms
Data folder scan time: boot_progress_pms_scan_end- boot_progress_pms_data_scan_start = 18892 - 18838 = 54ms
Home activity start time: boot_progress_enable_screen- boot_progress_ams_ready = 23744 - 22574 = 1170ms
Home activity idle to Bootanimation finish: sf_frame_dur - boot_progress_enable_screen = 25506 - 23744 = 1762ms
Home activity idle to SF stop bootanim: sf_stop_bootanim - boot_progress_enable_screen = 25453 - 23744 = 1709ms
Bootanim end time: wm_boot_animation_done - sf_stop_bootanim = 25616 - 25453 = 163ms

結(jié)束語
到此Android的開機(jī)流程就分析完了,比較倉促,有許多不足的地方,開機(jī)過程中涉及的許多文件未有說明,如kernel下的defconfig文件,通過配置config文件的宏控,打開某些功能,這些config都會影響到開機(jī)的時間,eng、userdebug和user版的差異最大的地方就是這個defconfig的配置,調(diào)試的宏控開多了,會大大影響開機(jī)時間,曾經(jīng)試過在eng版本上開機(jī)時間長達(dá)十分鐘的,所以說,要優(yōu)化開機(jī)時間,可以考慮從defconfig文件的配置入手。
了解開機(jī)時間流程是為了解Android的整體架構(gòu),在此做一下記錄,與大家共勉。