android8.1启动过程 SystemServer启动FallbackHome

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android8.1启动过程 SystemServer启动FallbackHome相关的知识,希望对你有一定的参考价值。

SystemServer进程在启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。在此前已经启动的AMS会将Launcher启动起来。

Launcher的入口为AMSsystemReady方法


ActivityManagerDebugConfig    frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java

这里首先分享一个技巧  可以把这个类里面的这个属性设置为true这样就可以把ActivityManager相关的log打开了

// Enable all debug log categories.
// static final boolean DEBUG_ALL = false;
static final boolean DEBUG_ALL = true;

startOtherServices()    frameworks/base/services/java/com/android/server/SystemServer.java

  此处是一个Lambda表达式省略的部分是一个回调方法

mActivityManagerService.systemReady(
                                     ...
                                    )

systemReady()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  这里关于EventLog分享一个查看log的链接https://www.jianshu.com/p/1c9106dd8284

  android日志主要分为  kernel、radio、event、main

  adb logcat -b  xxx

130|generic_x86_64:/ # logcat -b events | grep "3040"                          
06-02 00:18:02.017  1541  1556 I am_pss  : [2069,10015,com.android.launcher,31063040,17305600,0]
06-02 00:22:02.033  1541  1556 I am_pss  : [2069,10015,com.android.launcher,31063040,17305600,0]
06-02 04:48:12.311  1541  1556 I am_pss  : [2069,10015,com.android.launcher,32285696,18903040,0]
06-02 09:19:17.510  1541  1556 I am_pss  : [2069,10015,com.android.launcher,33040384,19652608,0]
06-02 17:51:00.018  1541  1556 I am_pss  : [1710,1001,com.android.phone,31703040,20111360,0]
06-02 19:26:00.039  1541  1556 I am_pss  : [2069,10015,com.android.launcher,34850816,21463040,0]
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
        traceLog.traceBegin("PhaseActivityManagerReady");
        ...

        Slog.i(TAG, "System now ready");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
            SystemClock.uptimeMillis());
        ...
}

关于工厂模式FactoryTest可参考这篇文章  https://blog.csdn.net/thl789/article/details/8053574 这里是正常模式

...
//判断工厂模式
synchronized(this) {
    // Make sure we have no pre-ready processes sitting around.

    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL)
...

 startPersistentApps    只启动加密感知的持久应用程序;一旦用户被解锁,我们将返回并启动不知情的应用程序可参考这篇文章    

https://blog.csdn.net/yaobao888/article/details/77824950

https://www.jianshu.com/p/c9e43905e6b6

https://www.jianshu.com/p/3db7809f231e

...
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);
...

启动Launcher 

startHomeActivityLocked(currentUserId, "systemReady");

startHomeActivityLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

这里介绍来自这篇  https://blog.csdn.net/learnframework?spm=1001.2014.3001.5509

    这里看到了startHomeActivityLocked(currentUserId, “systemReady”);被调用,从名字既可以看得出他是要启动Home类型的Activtiy,常见的Launcher就是一种Home类型的Activity,但这里其实并不是Launcher,而是设置中的FallbackHome类型的,它也是一个Home类型的Activity,这里FallbackHome是google新加入的,主要就是因为涉及整个android系统的加密等原因,系统在还没有完全解锁前,不可以启动Launcher,因为Launcher中明显和各个第三方应用耦合较多(比如桌面可能显示着一堆的各个应用的Widget),如果直接Launcher作为FallbackHome启动,相对就会要求Launcher依赖的应用也是支持直接解密类型,那就肯定不现实。所以就先启动了FallbackHome一个什么也不显示的界面来作为启动真正Launcher的一个过度

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();
        ...
}

getHomeIntent()  frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

在这个方法中创建了Intent  并将mTopActionmTopData传入,

String mTopAction = Intent.ACTION_MAIN;

和若是系统运行模式不是低级工厂模式则将Intent的Category设置为Intent.CATEGORY_HOME后返回。

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;
    }

startHomeActivityLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  继续来分析startHomeActivityLocked方法

  resolveActivityInfo  此前已经说过,系统在还没有完全解锁前,不可以启动Launcher。所以这里其实并不是Launcher,而是设置中的FallbackHome类型的,它也是一个Home类型的Activity

  ProcessRecord  Android系统中用于描述进程的数据结构是ProcessRecord对象,AMS便是管理进程的核心模块  可以参考https://www.cnblogs.com/mingfeng002/p/10573298.html

  此处的ProcessRecord app  应该是设置的包名  此时调用getProcessRecordLocked获取的就是设置的进程因为目前android程序还没有启动所以这是获取不到的  app就返回为null再调用后面的启动

boolean startHomeActivityLocked(int userId, String reason) {
        ...
        Intent intent = getHomeIntent();
        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            ...
            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;
    }

mActivityStarter.startHomeActivityLocked()       frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

  这里目前就调用了startActivityLocked()

void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
        mSupervisor.moveHomeStackTaskToTop(reason);
        mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
                null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
                null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
                null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
                null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
                0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
                false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
                null /*inTask*/, "startHomeActivity: " + reason);
        ...
        }
    }

startActivityLocked()   frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

      ...
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);
        ...
    }

startActivity()  frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

   这里更新一个知识点,frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java

  // Enable all debug log categories.

  static final boolean DEBUG_ALL = false;     打开debuglog

ActivityRecord  Activity的信息记录在ActivityRecord对象, 并通过通过成员变量task指向TaskRecord    可以参考https://blog.csdn.net/b1480521874/article/details/84637592

注意这块最后调用startActivity的第六个参数为 true

/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
            ...
                ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        ...
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

startActivity()  frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

  显然这个doResume参数为true  继续调用startActivityUnchecked

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ...
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        ...
    }

startActivityUnchecked()  frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

  这里面调用的setInitialState会将mDoResume这个字段置为 true

  接下来调用了mSupervisor.resumeFocusedStackTopActivityLocked

// Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

...
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
...

       if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ...
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            ...
        }
}

resumeFocusedStackTopActivityLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

  这块调用到了targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        ...

        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        ...

        return false;
    }

resumeTopActivityUncheckedLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

  这块调用到了result = resumeTopActivityInnerLocked(prev, options);

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        ...
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }

        ...
        return result;
    }

resumeTopActivityInnerLocked()      frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

  由于这块代码实在是太多太复杂了  这里只给出结论,无论这中间代码是如何调用的在这个方法的最后打出了一个log

  “resumeTopActivityLocked: Restarting”    显然这里面最后调用了  mStackSupervisor.startSpecificActivityLocked(next, true, true);

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...

        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
}

startSpecificActivityLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

  此部分代码进程为空  接下来调用 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);

  注意这个地方倒数第二个参数  isolated 传递的为  false

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

        if (app != null && app.thread != null) {
           ...
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

startProcessLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  调用自己的重载方法 

  此时  isolated 为  false 

           entryPoint 为 null

startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, null /* crashHandler */);

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

startProcessLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  这个方法主要接下来创建进程

  isolated 为  false 

  entryPoint 为 null

  最后调用了startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        if (!isolated) {
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            //这里app还是为null
            checkTime(startTime, "startProcess: after getProcessRecord");

            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                ...//不走
            } else {
                // When the user is explicitly starting a process, then clear its
                // crash count so that we won't make it bad until they see at
                // least one crash dialog again, and make the process good again
                // if it had been bad.
                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                        + "/" + info.processName);
                mAppErrors.resetProcessCrashTimeLocked(info);
                if (mAppErrors.isBadProcessLocked(info)) {
                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                            UserHandle.getUserId(info.uid), info.uid,
                            info.processName);
                    mAppErrors.clearBadProcessLocked(info);
                    if (app != null) {
                        app.bad = false;
                    }
                }
            }
        } else {
            ...
        }
        ...
        if (app == null) {
            checkTime(startTime, "startProcess: creating new process record");
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            if (app == null) {
                ...//不走
            }
            app.crashHandler = crashHandler;
            checkTime(startTime, "startProcess: done creating new process record");
        } else {
            ...//不走
        }
        ...
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
}

startProcessLocked()    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  entryPoint 为 null

  最后调用了这个  Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs);

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ...
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                ...//不走
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
        ...
}

Process.start()    frameworks/base/core/java/android/os/Process.java

  一眼望去  zygoteProcess.start(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs);

public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

 start()    frameworks/base/core/java/android/os/ZygoteProcess.java

    public final Process.ProcessStartResult start(final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, int[] gids,
                                                  int debugFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

 

以上是关于android8.1启动过程 SystemServer启动FallbackHome的主要内容,如果未能解决你的问题,请参考以下文章

android8.1启动过程 SystemServer

android8.1启动过程 SystemServer启动FallbackHome2

android8.1启动过程 zygote进程分析2

android8.1开机动画启动分析

App启动流程

Android Framework实战视频--BootAnimation的启动源码分析(Android8.1)