1.简介

学习下体系首次发动的时分那个引导app咋设置的

1.1.体系默许的

  • 源码里自带的是 packages/apps/Provision
  • device/generic/goldfish/provision/SdkSetup覆写了,看下android.bp文件如下,所以直接看这个就行
  • SdkSetup里就一个activity,仍是空完成,继承的是EmulatorProvisonLib库里的类,所以直接看库里的类即可
  • 默许的引导程序不清楚是哪个,不太熟悉mk的配置,咱们这边用的谷歌的setupwizard
    android13#setupwizard

2.DefaultActivity

先看下源码里自带的引导程序(没有界面的)

public class DefaultActivity extends com.android.emulatorprovisionlib.ProvisionActivity {
    @Override
    protected String TAG() { return "SdkSetup"; }
}
  • 不管默许的,谷歌的,仍是自定义的发动app,终究都会履行末节2.5的逻辑:disable自己而且修正2个settings的值

2.1.AndroidManifest.xml

这儿的优先级是3

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.sdksetup">
    <!-- For miscellaneous settings -->
    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
    <uses-permission android:name="android.permission.BACKUP" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" />
    <uses-permission android:name="android.permission.STATUS_BAR" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SYSTEM_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <application>
        <activity android:name="DefaultActivity"
                android:excludeFromRecents="true"
                android:exported="True"
                android:launchMode="singleTask">
            <intent-filter android:priority="3">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.SETUP_WIZARD" />
            </intent-filter>
        </activity>
    </application>
</manifest>

activity直接看lib里的即可 device/generic/goldfish/provision/EmulatorProvisonLib/src/com/android/sdksetup/ProvisionActivity.java

public abstract class ProvisionActivity extends Activity {

2.2.onCreate

    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        //device_provisioned
        if (Settings.Global.getInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 1) {
            preProvivion();
            doProvision();
            postProvision();
        } else {
            Log.w(TAG(), "Already provisioned, remove itself.");
            removeSelf();
        }
        finish();  // terminate the activity.
    }

2.3.preProvivion

    protected void preProvivion() {
        final Context appContext = getApplicationContext();
        mStatusBarManager = appContext.getSystemService(StatusBarManager.class);
        //引导过程中,状态栏是不可用的
        mStatusBarManager.setDisabledForSetup(true);
    }

>1.setDisabledForSetup

终究给到各种回调里处理,便是禁止状态栏的操作

    public void setDisabledForSetup(boolean disabled) {
        try {
            final int userId = Binder.getCallingUserHandle().getIdentifier();
            final IStatusBarService svc = getService();
            if (svc != null) {
                svc.disableForUser(disabled ? DEFAULT_SETUP_DISABLE_FLAGS : DISABLE_NONE,
                        mToken, mContext.getPackageName(), userId);
                svc.disable2ForUser(disabled ? DEFAULT_SETUP_DISABLE2_FLAGS : DISABLE2_NONE,
                        mToken, mContext.getPackageName(), userId);
            }
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

2.4.doProvision

    protected void doProvision() {
        provisionWifi("AndroidWifi");
        provisionKeyboard("qwerty2");
        provisionDisplay();
        provisionTelephony();
        provisionLocation();
        provisionAdb();
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
    }

>1.provisionWifi

    protected void provisionWifi(final String ssid) {
        Settings.Global.putInt(getContentResolver(), Settings.Global.TETHER_OFFLOAD_DISABLED, 1);
        final int ADD_NETWORK_FAIL = -1;
        final String quotedSsid = """ + ssid + """;
        final WifiConfiguration config = new WifiConfiguration();
        config.SSID = quotedSsid;
        config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
        final WifiManager mWifiManager = getApplicationContext().getSystemService(WifiManager.class);
        final int netId = mWifiManager.addNetwork(config);
        if (netId == ADD_NETWORK_FAIL || !mWifiManager.enableNetwork(netId, true)) {
            Log.e(TAG(), "Unable to add Wi-Fi network " + quotedSsid + ".");
        }
    }

>2.provisionKeyboard

    // Set physical keyboard layout based on the system property set by emulator host.
    protected void provisionKeyboard(final String deviceName) {
        final String layoutName = SystemProperties.get("vendor.qemu.keyboard_layout");
        final InputDevice device = getKeyboardDevice(deviceName);
        if (device != null && !layoutName.isEmpty()) {
            setKeyboardLayout(device, layoutName);
        }
    }
    protected InputDevice getKeyboardDevice(final String keyboardDeviceName) {
        final int[] deviceIds = InputDevice.getDeviceIds();
        for (int deviceId : deviceIds) {
            InputDevice inputDevice = InputDevice.getDevice(deviceId);
            if (inputDevice != null
                    && inputDevice.supportsSource(InputDevice.SOURCE_KEYBOARD)
                    && inputDevice.getName().equals(keyboardDeviceName)) {
                return inputDevice;
            }
        }
        return null;
    }
    protected void setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName) {
        final InputManager im = InputManager.getInstance();
        final KeyboardLayout[] keyboardLayouts =
                im.getKeyboardLayoutsForInputDevice(keyboardDevice.getIdentifier());
        for (KeyboardLayout keyboardLayout : keyboardLayouts) {
            if (keyboardLayout.getDescriptor().endsWith(layoutName)) {
                im.setCurrentKeyboardLayoutForInputDevice(
                        keyboardDevice.getIdentifier(), keyboardLayout.getDescriptor());
                return;
            }
        }
    }

>3.provisionDisplay

    protected void provisionDisplay() {
        final int screen_off_timeout =
            SystemProperties.getInt("ro.boot.qemu.settings.system.screen_off_timeout", 0);
            //息屏时间设置
        if (screen_off_timeout > 0) {
            Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, screen_off_timeout);
        }
        //禁止锁屏,在没有设置pin,password,pattern的状况下
        (new LockPatternUtils(this)).setLockScreenDisabled(true,
            android.os.Process.myUserHandle().getIdentifier());
        final String displaySettingsProp = "ro.boot.qemu.display.settings.xml";
        final String displaySettingsName = SystemProperties.get(displaySettingsProp);
        if ("freeform".equals(displaySettingsName)) {
            Settings.Global.putInt(getContentResolver(), "sf", 1);
            Settings.Global.putString(getContentResolver(),
                                      Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, "1");
            Settings.Global.putString(getContentResolver(),
                                      Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, "1");
            Settings.Global.putString(getContentResolver(),
                                      Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH,
                                      "vendor/etc/display_settings_freeform.xml");
        } else if ("resizable".equals(displaySettingsName)) {
            //可变尺寸,翻开自动选装
            Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, "1");
        } else if (!displaySettingsName.isEmpty()) {
            //不支撑的
        }
    }

补白1:这个终究是存储在数据库里的

    public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
    /**
     * Disable showing lock screen at all for a given user.
     * This is only meaningful if pattern, pin or password are not set.
     *
     * @param disable Disables lock screen when true
     * @param userId User ID of the user this has effect on
     */
    public void setLockScreenDisabled(boolean disable, int userId) {
        setBoolean(DISABLE_LOCKSCREEN_KEY, disable, userId);
    }

>4.provisionTelephony

    protected void provisionTelephony() {
        // b/193418404
        // the following blocks, TODO: find out why and fix it. disable this for now.
        // TelephonyManager mTelephony = getApplicationContext().getSystemService(TelephonyManager.class);
        // mTelephony.setPreferredNetworkTypeBitmask(TelephonyManager.NETWORK_TYPE_BITMASK_NR);
    }

>5.provisionLocation

    protected void provisionLocation() {
        final LocationManager lm = getSystemService(LocationManager.class);
        lm.setLocationEnabledForUser(true, Process.myUserHandle());
        // Enable the GPS.
        // Not needed since this SDK will contain the Settings app.
        Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                LocationManager.GPS_PROVIDER);
    }

>6.provisionAdb

    protected void provisionAdb() {
        Settings.Global.putInt(getContentResolver(), Settings.Global.ADB_ENABLED, 1);
        Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0);
    }

2.5.postProvision

    protected void postProvision() {
    //康复状态栏
        mStatusBarManager.setDisabledForSetup(false);
        removeSelf();
        //修正这两个设置,告知其他使用知道设备已经配置好了。
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
    }

2.5.removeSelf

使自己不可用,这样下边发动的便是正常的桌面app了。

    // remove this activity from the package manager.
    protected void removeSelf() {
        getPackageManager().setComponentEnabledSetting(
                new ComponentName(this, this.getClass()),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }

2.6.补白

//状态栏不可用
mStatusBarManager.setDisabledForSetup(true);
//禁止锁屏,在没有设置pin,password,pattern的状况下
(new LockPatternUtils(this)).setLockScreenDisabled(true,
    android.os.Process.myUserHandle().getIdentifier());

下边剖析下源码里,引导程序发动的整个流程。

3.ActivityManagerService

参阅juejin.cn/post/684490… ,曾经只要一个ActivityManagerService.java(AMS),现在多了个ActivityTaskManagerService.java(ATMS),所以老的帖子里找不到的办法,能够在新的ATMS里找

3.1.Lifecycle

AMS的静态内部类,构造办法里实例化了一个AMS

    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;
        private static ActivityTaskManagerService sAtm;
        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context, sAtm);
        }

>1.startService

        public static ActivityManagerService startService(
                SystemServiceManager ssm, ActivityTaskManagerService atm) {
            sAtm = atm;
            //先反射获取Lifecycle目标,再调用弥补2,回来AMS目标
            return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
        }

>2.getService

        public ActivityManagerService getService() {
            return mService;
        }

3.2.相关流程

SystemServer里初始化发动的

>1.startBootstrapServices

    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        //..
        // Activity manager runs the show.
        t.traceBegin("StartActivityManager");
        //先反射获取Lifecycle目标,完事调用其办法获取ATMS,见4.1.1
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
        //见3.1.1获取AMS目标        
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        mWindowManagerGlobalLock = atm.getGlobalLock();
        t.traceEnd();

>2.startOtherServices

    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    //...
        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        //调用AMS的systemReady办法,见3.3,履行这儿的runnable办法
        mActivityManagerService.systemReady(() -> {
            //告知其他service抵达这个阶段了
            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
            try {
                mActivityManagerService.startObservingNativeCrashes();
            }
           //注册AppOpsPolicy
            try {
                mActivityManagerService.setAppOpsPolicy(new AppOpsPolicy(mSystemContext));
            } 
            //安全形式下设置为飞行形式
            if (safeMode) {
                try {
                    connectivityF.setAirplaneMode(true);
                } 
            }
            try {
                if (networkManagementF != null) {
                    networkManagementF.systemReady();
                }
            }
            CountDownLatch networkPolicyInitReadySignal = null;
            if (networkPolicyF != null) {
                networkPolicyInitReadySignal = networkPolicyF
                        .networkScoreAndNetworkManagementServiceReady();
            }
        //ConnectivityManager
            try {
                if (connectivityF != null) {
                    connectivityF.systemReady();
                }
            } 
//VpnManagerService
            try {
                if (vpnManagerF != null) {
                    vpnManagerF.systemReady();
                }
            } 
            //VcnManagementService
            try {
                if (vcnManagementF != null) {
                    vcnManagementF.systemReady();
                }
            }
            t.traceBegin("MakeNetworkPolicyServiceReady");
            try {
                if (networkPolicyF != null) {
                    networkPolicyF.systemReady(networkPolicyInitReadySignal);
                }
            }
            // Wait for all packages to be prepared
            mPackageManagerService.waitForAppDataPrepared();
            //到这儿各种体系服务就能够履行他们的第三部分代码了
            t.traceBegin("PhaseThirdPartyAppsCanStart");
            // confirm webview completion before starting 3rd party
            if (webviewPrep != null) {
                ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
            }
            //告知各种服务,当时到了这个阶段了
            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            t.traceEnd();
            if (UserManager.isHeadlessSystemUserMode() && !isAutomotive) {
                // TODO(b/204091126): remove isAutomotive check once the workflow is finalized
                t.traceBegin("BootUserInitializer");
                new BootUserInitializer(mActivityManagerService, mContentResolver).init(t);
                t.traceEnd();
            }
            t.traceBegin("StartNetworkStack");
            try {
                // Note : the network stack is creating on-demand objects that need to send
                // broadcasts, which means it currently depends on being started after
                // ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady
                // are set to true. Be careful if moving this to a different place in the
                // startup sequence.
                NetworkStackClient.getInstance().start();
            }
            t.traceBegin("StartTethering");
            try {
                ConnectivityModuleConnector.getInstance().startModuleService(
                        TETHERING_CONNECTOR_CLASS,
                        PERMISSION_MAINLINE_NETWORK_STACK, service -> {
                            ServiceManager.addService(Context.TETHERING_SERVICE, service,
                                    false /* allowIsolated */,
                                    DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
                        });
            }
            t.traceBegin("MakeCountryDetectionServiceReady");
            try {
                if (countryDetectorF != null) {
                    countryDetectorF.systemRunning();
                }
            }
            t.traceBegin("MakeNetworkTimeUpdateReady");
            try {
                if (networkTimeUpdaterF != null) {
                    networkTimeUpdaterF.systemRunning();
                }
            }
            t.traceBegin("MakeInputManagerServiceReady");
            try {
                if (inputManagerF != null) {
                    inputManagerF.systemRunning();
                }
            }
            t.traceBegin("MakeTelephonyRegistryReady");
            try {
                if (telephonyRegistryF != null) {
                    telephonyRegistryF.systemRunning();
                }
            } 
            t.traceBegin("MakeMediaRouterServiceReady");
            try {
                if (mediaRouterF != null) {
                    mediaRouterF.systemRunning();
                }
            }
            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
                t.traceBegin("MakeMmsServiceReady");
                try {
                    if (mmsServiceF != null) mmsServiceF.systemRunning();
                }
            }
            t.traceBegin("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.getService(Context.INCIDENT_SERVICE));
                if (incident != null) {
                    incident.systemRunning();
                }
            }
            if (mIncrementalServiceHandle != 0) {
                t.traceBegin("MakeIncrementalServiceReady");
                setIncrementalServiceSystemReady(mIncrementalServiceHandle);
                t.traceEnd();
            }
            t.traceBegin("OdsignStatsLogger");
            try {
                OdsignStatsLogger.triggerStatsWrite();
            } catch (Throwable e) {
                reportWtf("Triggering OdsignStatsLogger", e);
            }
            t.traceEnd();
        }, t);
        t.traceBegin("StartSystemUI");
        try {
        //发动systemUi,经过startService
            startSystemUi(context, windowManagerF);
        }
    }

3.3.systemReady

    public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
        mSystemServiceManager.preSystemReady();
        synchronized(this) {
            if (mSystemReady) {
            //已经ready了,直接履行runnable办法
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }
            //调用各种controller的ready办法
            mLocalDeviceIdleController =
                    LocalServices.getService(DeviceIdleInternal.class);
            //ATMA的对应办法
            mActivityTaskManager.onSystemReady();
            // Make sure we have the current profile info, since it is needed for security checks.
            mUserController.onSystemReady();
            mAppOpsService.systemReady();
            mProcessList.onSystemReady();
            mAppRestrictionController.onSystemReady();
            //修正标志
            mSystemReady = true;
            t.traceEnd();
        }
        try {
            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
                    .getSerial();
        } catch (RemoteException e) {}
       //下边是找到boot阶段不允许发动的进程,然后杀死
        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);
                    mProcessList.removeProcessLocked(proc, true, false,
                            ApplicationExitInfo.REASON_OTHER,
                            ApplicationExitInfo.SUBREASON_SYSTEM_UPDATE_DONE,
                            "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;
        }
//..
        mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver);
        t.traceBegin("watchDeviceProvisioning");
        watchDeviceProvisioning(mContext);
        t.traceBegin("retrieveSettings");
        retrieveSettings();
        t.traceBegin("Ugm.onSystemReady");
        mUgmInternal.onSystemReady();
       //注册监听低电量,看是否stop后台服务
        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
        if (pmi != null) {
            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
            updateForceBackgroundCheck(
                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
        } 
        //履行runnable
        if (goingCallback != null) goingCallback.run();
        //获取当时user
        final int currentUserId = mUserController.getCurrentUserId();
        //非体系用户,而且体系用户还没发动,抛出反常
        if (currentUserId != UserHandle.USER_SYSTEM && !mUserController.isSystemUserStarted()) {
            throw new RuntimeException("System user not started while current user is:"
                    + currentUserId);
        }
        //电池状态服务
        mBatteryStatsService.onSystemReady();
        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.onUserStarting(t, currentUserId);
        synchronized (this) {
            // Only start up encryption-aware persistent apps; once user is
            // unlocked we'll come back around and start unaware apps
            //只发动支撑加密的耐久app
            //清单文件里有声明 android:directBootAware="true"的app
            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
            // Start up initial activity.
            mBooting = true;
            // 不看,
            if (UserManager.isSplitSystemUser() &&
                    Settings.Secure.getIntForUser(mContext.getContentResolver(),
                         Settings.Secure.USER_SETUP_COMPLETE, 0, currentUserId) != 0
                    || SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) {
                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
                try {
                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
                            UserHandle.USER_SYSTEM);
                }
            }
            boolean isBootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
            // Some systems - like automotive - will explicitly unlock system user then switch
            // to a secondary user.
            // 见4.4,发动home intent
            if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) {
                mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
            }
            //需求的话显现体系错误弹框
            mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
            if (isBootingSystemUser) {
                //需求发送用户发动播送
                t.traceBegin("sendUserStartBroadcast");
                final int callingUid = Binder.getCallingUid();
                final int callingPid = Binder.getCallingPid();
                final 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, null, intent,
                            null, null, 0, null, null, null, null, null, OP_NONE,
                            null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
                            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, null, intent, null,
                            new IIntentReceiver.Stub() {
                                @Override
                                public void performReceive(Intent intent, int resultCode,
                                        String data, Bundle extras, boolean ordered, boolean sticky,
                                        int sendingUser) {}
                            }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, null, null,
                            OP_NONE, null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
                            UserHandle.USER_ALL);
                }
            }
            //康复顶层的activity,如果没找到top activity,终究会发动home intent
            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
            if (isBootingSystemUser) {
               //发送用户switch播送
                mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
            }
            //
            BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK,
                    BINDER_PROXY_LOW_WATERMARK);
            BinderInternal.nSetBinderProxyCountEnabled(true);
            BinderInternal.setBinderProxyCountCallback(
                    (uid) -> {
                        BinderProxy.dumpProxyDebugInfo();
                        if (uid == Process.SYSTEM_UID) {
                            Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
                        } else {
                            killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
                                    "Too many Binders sent to SYSTEM");
                            VMRuntime.getRuntime().requestConcurrentGC();
                        }
                    }, mHandler);
            // Load the component aliases.
            t.traceBegin("componentAlias");
            mComponentAliasResolver.onSystemReady(mConstants.mEnableComponentAlias,
                    mConstants.mComponentAliasOverrides);
            t.traceEnd(); // componentAlias
            t.traceEnd(); // PhaseActivityManagerReady
        }
    }

>1.watchDeviceProvisioning

如果Settings.Global.DEVICE_PROVISIONED已经是1,直接修正体系属性,没有的话注册observer,监听改动

    private void watchDeviceProvisioning(Context context) {
        // setting system property based on whether device is provisioned
        if (isDeviceProvisioned(context)) {
            SystemProperties.set(SYSTEM_PROPERTY_DEVICE_PROVISIONED, "1");
        } else {
            // watch for device provisioning change
            context.getContentResolver().registerContentObserver(
                    Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), false,
                    new ContentObserver(new Handler(Looper.getMainLooper())) {
                        @Override
                        public void onChange(boolean selfChange) {
                            if (isDeviceProvisioned(context)) {
                                SystemProperties.set(SYSTEM_PROPERTY_DEVICE_PROVISIONED, "1");
                                context.getContentResolver().unregisterContentObserver(this);
                            }
                        }
                    });
        }
    }

>2.startPersistentApps

依据flag查找persisitent使用并创立进程

    void startPersistentApps(int matchFlags) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
        synchronized (this) {
            try {
                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
                for (ApplicationInfo app : apps) {
                    if (!"android".equals(app.packageName)) {
                        final ProcessRecord proc = addAppLocked(
                                app, null, false, null /* ABI override */,
                                ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
                        if (proc != null) {
                            proc.mProfile.addHostingComponentType(
                                    HOSTING_COMPONENT_TYPE_PERSISTENT);
                        }
                    }
                }
            } catch (RemoteException ex) {
            }
        }
    }

4.ActivityTaskManagerService

4.1.Lifecycle

ATMS的静态内部类,构造办法里实例化了一个ATMS

    public static final class Lifecycle extends SystemService {
        private final ActivityTaskManagerService mService;
        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityTaskManagerService(context);
        }

>1.getService

        public ActivityTaskManagerService getService() {
            return mService;
        }

4.2.onSystemReady

    public void onSystemReady() {
        synchronized (mGlobalLock) {
            final PackageManager pm = mContext.getPackageManager();
            mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE);
            mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK);
            mVrController.onSystemReady();
            mRecentTasks.onSystemReadyLocked();
            mTaskSupervisor.onSystemReady();
            mActivityClientController.onSystemReady();
        }
    }

4.3.getHomeIntent

正常状况下,便是Intent.ACTION_MAIN,Intent.CATEGORY_HOME

//默许便是main,工厂测验形式下会修正这个,正常状况便是这个
    String mTopAction = Intent.ACTION_MAIN;
    Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        //这个默许也是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;
    }

4.4.startHomeOnAllDisplays

        public boolean startHomeOnAllDisplays(int userId, String reason) {
            synchronized (mGlobalLock) {
            //见5.1
                return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
            }
        }

5.RootWindowContainer.java

5.1.startHomeOnAllDisplays

循环一切的display发动home页

    boolean startHomeOnAllDisplays(int userId, String reason) {
        boolean homeStarted = false;
        for (int i = getChildCount() - 1; i >= 0; i--) {
            final int displayId = getChildAt(i).mDisplayId;
            homeStarted |= startHomeOnDisplay(userId, reason, displayId);
        }
        return homeStarted;
    }

>1.startHomeOnDisplay

    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
                false /* fromHomeKey */);
    }

>2.startHomeOnDisplay

    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
            boolean fromHomeKey) {
        // Fallback to top focused display or default display if the displayId is invalid.
        if (displayId == INVALID_DISPLAY) {
            final Task rootTask = getTopDisplayFocusedRootTask();
            displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
        }
        final DisplayContent display = getDisplayContent(displayId);
        return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
        //见5.2
                        result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
                                allowInstrumenting, fromHomeKey),
                false /* initValue */);
    }

5.2.startHomeOnTaskDisplayArea

发动home页

    boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
            boolean allowInstrumenting, boolean fromHomeKey) {
        // Fallback to top focused display area if the provided one is invalid.
        if (taskDisplayArea == null) {
            final Task rootTask = getTopDisplayFocusedRootTask();
            taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
                    : getDefaultTaskDisplayArea();
        }
        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        //默许的屏幕
        if (taskDisplayArea == getDefaultTaskDisplayArea()) {
            //见4.3
            homeIntent = mService.getHomeIntent();
            //依据intent获取最匹配的ActivityInfo,见弥补1
            aInfo = resolveHomeActivity(userId, homeIntent);
            //日志见末节6
            System.out.println("mylog========home info==="+aInfo.packageName+","+aInfo.name);
        } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
            aInfo = info.first;
            homeIntent = info.second;
        }
        if (aInfo == null || homeIntent == null) {
            return false;
        }
        //见弥补2
        if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
            return false;
        }
        // Updates the home component of the intent.
        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
        // Updates the extra information of the intent.
        if (fromHomeKey) {
            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
            if (mWindowManager.getRecentsAnimationController() != null) {
                mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
            }
        }
        homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);
        // Update the reason for ANR debugging to verify if the user activity is the one that
        // actually launched.
        final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
                aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
        //发动home页
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                taskDisplayArea);
        return true;
    }

>1.resolveHomeActivity

依据intent查找activityInfo,咱们这儿走的else,intent里只配置了action和category

    ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
        //GET_SHARED_LIBRARY_FILES    = 0x00000400;
        final int flags = ActivityManagerService.STOCK_PM_FLAGS;
        final ComponentName comp = homeIntent.getComponent();
        ActivityInfo aInfo = null;
        try {
            if (comp != null) {
                // Factory test.
                aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
            } else {
                final String resolvedType =
                        homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
                //走这儿,逻辑见弥补代码
                final ResolveInfo info = AppGlobals.getPackageManager()//便是IPackageManager
                        .resolveIntent(homeIntent, resolvedType, flags, userId);
                if (info != null) {
                    aInfo = info.activityInfo;
                }
            }
        } catch (RemoteException e) {
            // ignore
        }
        if (aInfo == null) {
            Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
            return null;
        }
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
        return aInfo;
    }

>2.canStartHomeOnDisplayArea

看下这个activity是否允许发动

    boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea,
            boolean allowInstrumenting) {
        if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mService.mTopAction == null) {
               //工程测验形式
            return false;
        }
        final WindowProcessController app =
                mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
        if (!allowInstrumenting && app != null && app.isInstrumenting()) {
            //已经在发动中了.
            return false;
        }
        final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId()
                : INVALID_DISPLAY;
        if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
                && displayId == mService.mVr2dDisplayId)) {
            //默许屏幕或许虚拟的第二个屏幕是允许发动的
            return true;
        }
        if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
            return false;
        }
        final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
                && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
        if (!supportMultipleInstance) {
            //activity不支撑多个实例
            return false;
        }
        return true;
    }

5.3.intent查activityInfo

>1.ActivityThread

ActivityThread

    public static IPackageManager getPackageManager() {
        if (sPackageManager != null) {
            return sPackageManager;
        }
        //见下边的弥补代码2,能够看到binder便是IPackageManagerImpl
        final IBinder b = ServiceManager.getService("package");
        sPackageManager = IPackageManager.Stub.asInterface(b);
        return sPackageManager;
    }

>2.PackageManagerService.java

        IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
        ServiceManager.addService("package", iPackageManager);
    public class IPackageManagerImpl extends IPackageManagerBase {

父类

    public final ResolveInfo resolveIntent(Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
        return mResolveIntentHelper.resolveIntentInternal(snapshot(), intent,
                resolvedType, flags, 0 /*privateResolveFlags*/, userId, false,
                Binder.getCallingUid());
    }

>3.ResolveIntentHelper.java

上边的办法终究走到这儿

    public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags,
            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
            boolean resolveForStart, int filterCallingUid) {
//..
//这儿是依据intent查找可用的info
            final List<ResolveInfo> query = computer.queryIntentActivitiesInternal(intent,
                    resolvedType, flags, privateResolveFlags, filterCallingUid, userId,
                    resolveForStart, true /*allowDynamicSplits*/);
//..
//如果有多个的话,这儿挑选一个最匹配的
            final ResolveInfo bestChoice = chooseBestActivity(computer, intent, resolvedType, flags,
                    privateResolveFlags, query, userId, queryMayBeFiltered);
//..                    

>4.ComputerEngine.java

    public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
    //..
        } else {
        //走这儿
            QueryIntentActivitiesResult lockedResult =
                    queryIntentActivitiesInternalBody(
                            intent, resolvedType, flags, filterCallingUid, userId,
                            resolveForStart, allowDynamicSplits, pkgName, instantAppPkgName);
//..
//咱们这儿走的是else
        return skipPostResolution ? list : applyPostResolutionFilter(
                list, instantAppPkgName, allowDynamicSplits, filterCallingUid,
                resolveForStart, userId, intent);
    }

//

    private final ComponentResolverApi mComponentResolver;
    public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
    //..
            List<ResolveInfo> result = null;
      //..      
            //见弥补5
            result = filterIfNotSystemUser(mComponentResolver.queryActivities(this,
                    intent, resolvedType, flags, userId), userId);    

>5.ComponentResolverBase

public abstract class ComponentResolverBase extends WatchableImpl implements ComponentResolverApi {
    protected ComponentResolver.ActivityIntentResolver mActivities;
    public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
            @Nullable String resolvedType, long flags, int userId) {
        return mActivities.queryIntent(computer, intent, resolvedType, flags, userId);
    }

>6.ComponentResolver.java

    public static class ActivityIntentResolver
            extends MimeGroupsAwareIntentResolver<Pair<ParsedActivity, ParsedIntentInfo>, ResolveInfo> {
        List<ResolveInfo> queryIntent(@NonNull Computer computer, Intent intent,
                String resolvedType, long flags, int userId) {
            if (!mUserManager.exists(userId)) {
                return null;
            }
            //父类处理
            return super.queryIntent(computer, intent, resolvedType,
                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId, flags);
        }

上边的父类是这个,queryIntent的详细完成在这个的父类IntentResolver里处理的

    private abstract static class MimeGroupsAwareIntentResolver<F extends Pair<?
            extends ParsedComponent, ParsedIntentInfo>, R>
            extends IntentResolver<F, R> {

>6.1.ActivityIntentResolver

弥补6ComponentResolver的内部类

    public static class ActivityIntentResolver
            extends MimeGroupsAwareIntentResolver<Pair<ParsedActivity, ParsedIntentInfo>, ResolveInfo> {
    //...
        protected ResolveInfo newResult(@NonNull Computer computer,
                Pair<ParsedActivity, ParsedIntentInfo> pair, int match, int userId,
                long customFlags) {
            ParsedActivity activity = pair.first;
            ParsedIntentInfo info = pair.second;
            IntentFilter intentFilter = info.getIntentFilter();
            final PackageStateInternal packageState =
                    computer.getPackageStateInternal(activity.getPackageName());
            if (packageState == null || packageState.getPkg() == null
                    || !PackageStateUtils.isEnabledAndMatches(packageState, activity, customFlags,
                    userId)) {
//com.android.launcher3/.uioverrides.QuickstepLauncher ,在isEnabledAndMatches办法里回来了false,看弥补8
                return null;
            }

>7.IntentResolver.java

    protected final List<R> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
//..
        if (resolvedType == null && scheme == null && intent.getAction() != null) {
            firstTypeCut = mActionToFilter.get(intent.getAction());
            //咱们只要action和category,所以会走这儿
        }
//.
        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
        Computer computer = (Computer) snapshot;
        if (firstTypeCut != null) {
            buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType,
                    scheme, firstTypeCut, finalList, userId, customFlags);
        }
//..        

buildResolveList

    private void buildResolveList(@NonNull Computer computer, Intent intent,
    //..
        F filter;//下边有贴是个Pair目标,存储的activity组件以及解析器目标
        for (i=0; i<N && (filter=src[i]) != null; i++) {
            //依据filter数据获取intentFilter
            IntentFilter intentFilter = getIntentFilter(filter);        
//.
        //这儿看下data,scheme是否匹配
            match = intentFilter.match(action, resolvedType, scheme, data, categories, TAG);
            if (match >= 0) {
                if (!defaultOnly || intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) {
                //这儿便是验证组件是否是咱们要的,详细完成见末节6的内部类
                    final R oneResult = newResult(computer, filter, match, userId, customFlags);            
  • firstTypeCut是个数组,里面的数据是这样的
Pair{Activity{ad74d61 com.android.settings/.FallbackHome} com.android.server.pm.pkg.component.ParsedIntentInfoImpl@145b086}

>8.PackageStateUtils

    public static boolean isEnabledAndMatches(@Nullable PackageStateInternal packageState,
            @NonNull ParsedMainComponent component, long flags, int userId) {
        if (packageState == null) {
            return false;
        }
        final AndroidPackage pkg = packageState.getPkg();
        if (pkg == null) {
            return false;
        }
        final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId);
        return PackageUserStateUtils.isMatch(userState, packageState.isSystem(),
                pkg.isEnabled(), component, flags);
    }

>9.PackageUserStateUtils.java

homeIntent满足条件的有两个,见6.1.2,6.1.3,

  • 在这儿launcher被过滤掉了,因为isComponentDirectBootAware是false,而咱们的flags是要求MATCH_DIRECT_BOOT_AWARE的,所以终究的matchesUnaware和matchesAware都false
  • FallbackHome这儿回来的是true,因为它的isComponentDirectBootAware是true
    /**
     * Test if the given component is considered installed, enabled and a match for the given
     * flags.
     *
     * <p>
     * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and {@link
     * PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
     * </p>
     */
    public static boolean isMatch(@NonNull PackageUserState state, boolean isSystem,
            boolean isPackageEnabled, boolean isComponentEnabled,
            boolean isComponentDirectBootAware, String componentName, long flags) {
        final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
        if (!isAvailable(state, flags) && !(isSystem && matchUninstalled)) {
            return reportIfDebug(false, flags);
        }
        if (!isEnabled(state, isPackageEnabled, isComponentEnabled, componentName, flags)) {
            return reportIfDebug(false, flags);
        }
        if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
            if (!isSystem) {
                return reportIfDebug(false, flags);
            }
        }
        final boolean matchesUnaware = ((flags & PackageManager.MATCH_DIRECT_BOOT_UNAWARE) != 0)
                && !isComponentDirectBootAware;
        final boolean matchesAware = ((flags & PackageManager.MATCH_DIRECT_BOOT_AWARE) != 0)
                && isComponentDirectBootAware;
        return reportIfDebug(matchesUnaware || matchesAware, flags);
    }

6.日志剖析

6.1.配置

>1.google setupwizard

  • priority是5
  • activity里有声明directBootAware
<activity
    android:theme="@ref/0x7f1301d3"
    android:label="@ref/0x7f120030"
    android:name="com.google.android.setupwizard.SetupWizardActivity"
    android:exported="true"
    android:excludeFromRecents="true"
    android:launchMode="2"
    android:configChanges="0x47b3"
    android:immersive="true"
    android:directBootAware="true">
    <intent-filter
        android:priority="5">
        <action
            android:name="android.intent.action.MAIN" />
        <action
            android:name="android.intent.action.DEVICE_INITIALIZATION_WIZARD" />
        <category
            android:name="android.intent.category.HOME" />
        <category
            android:name="android.intent.category.DEFAULT" />
        <category
            android:name="android.intent.category.SETUP_WIZARD" />
    </intent-filter>
</activity>

>2.settings

  • priority=”-1000″
  • application里有声明directBootAware
    <application
            android:name=".SettingsApplication"
            android:directBootAware="true">
        <!-- Triggered when user-selected home app isn't encryption aware -->
        <activity android:name=".FallbackHome"
                  android:excludeFromRecents="true"
                  android:label=""
                  android:screenOrientation="nosensor"
                  android:taskAffinity="com.android.settings.FallbackHome"
                  android:exported="true"
                  android:theme="@style/FallbackHome"
                  android:configChanges="keyboardHidden">
            <intent-filter android:priority="-1000">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

>3.SearchLauncher

  • priority没有设置,那么便是默许值0
        <activity
            android:name="com.android.searchlauncher.SearchLauncher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:theme="@style/LauncherTheme"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="unspecified"
            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
            android:resizeableActivity="true"
            android:resumeWhilePausing="true"
            android:taskAffinity=""
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.SHOW_WORK_APPS" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
                <category android:name="android.intent.category.LAUNCHER_APP" />
            </intent-filter>
            <meta-data
                android:name="com.android.launcher3.grid.control"
                android:value="${packageName}.grid_control" />
            <meta-data
                android:name="com.android.launcher3.themedicon.option"
                android:value="${packageName}.grid_control" />
        </activity>

6.2.log

>1.factory reset

  • 6.1有贴3种home,factory reset今后,setupwizard的优先级最高,所以回来的是这个。
  • 引导页出现后20多秒才收到pre_boot_complete播送,LOCKED_BOOT_COMPLETED播送更晚
17:51:31.903 mylog========home info===com.google.android.setupwizard,com.google.android.setupwizard.SetupWizardActivity
17:52:01.107 com.android.settings  mylog===SettingsInitialize==action=android.intent.action.PRE_BOOT_COMPLETED
17:52:08.325 mylog========sendBootCompleted===Intent { act=android.intent.action.LOCKED_BOOT_COMPLETED flg=0x89000010 (has extras) }

>2.正常发动

  • setupwizard流程走完今后就被disable调用了,这时分home类型的就只要2个了。
  • FallbackHome先发动,尽管优先级是负的,5.3里有剖析,因为它支撑boot aware,boot阶段只要它满足条件,那个launcher不支撑boot aware,所以boot阶段不满足条件
17:50:52.381 mylog========home info===com.android.settings,com.android.settings.FallbackHome
17:51:01.101 mylog========home info===com.android.launcher3,com.android.searchlauncher.SearchLauncher
17:51:05.636 mylog========sendBootCompleted===Intent { act=android.intent.action.LOCKED_BOOT_COMPLETED flg=0x89000010 (has extras) }

6.3.FallbackHome.java

    private void maybeFinish() {
        if (getSystemService(UserManager.class).isUserUnlocked()) {
            final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
                    .addCategory(Intent.CATEGORY_HOME);
            //见弥补代码,看怎么获取info
            final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);
            //要保证查询出来的结果不是FallbackHome,才会关闭这个页面
            if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {
                Log.d(TAG, "User unlocked but no home; let's hope someone enables one soon?");
                mHandler.sendEmptyMessageDelayed(0, 500);
            } else {
                Log.d(TAG, "User unlocked and real home found; let's go!");
                getSystemService(PowerManager.class).userActivity(
                        SystemClock.uptimeMillis(), false);
                finish();
            }
        }
    }

>1.ContextImpl

    public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }
        //这个见5.3.1
        final IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }
        return null;
    }

>2.ApplicationPackageManager

resolveActivity办法,详细见上边的末节5.3

    public ResolveInfo resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId) {
        try {
            return mPM.resolveIntent(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                updateFlagsForComponent(flags.getValue(), userId, intent),
                userId);
        } 
    }

6.4.log剖析

  • AMS的systemReady办法里,如下代码,
if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) { mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); }
  • 然后走到4.4

  • 再走到5.1,5.2

  • 5.2里查找home intent,查找的详细逻辑在末节6.3.4的办法里

  • factory reset今后,home intent回来的便是setupwizard使用

  • 正常发动的时分,回来的FallbackHome