android13#setupwizard

1.简介

学习下系统首次启动的时候那个引导app咋设置的

1.1.系统默认的

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

2.DefaultActivity

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

scala 复制代码
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

ini 复制代码
<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

scala 复制代码
public abstract class ProvisionActivity extends Activity {

2.2.onCreate

scss 复制代码
    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

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

>1.setDisabledForSetup

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

java 复制代码
    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

scss 复制代码
    protected void doProvision() {
        provisionWifi("AndroidWifi");
        provisionKeyboard("qwerty2");
        provisionDisplay();
        provisionTelephony();
        provisionLocation();
        provisionAdb();

        Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
    }

>1.provisionWifi

ini 复制代码
    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

java 复制代码
    // 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);
        }
    }
java 复制代码
    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;
    }
scss 复制代码
    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

arduino 复制代码
    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:这个最终是存储在数据库里的

java 复制代码
    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

csharp 复制代码
    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

arduino 复制代码
    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

vbnet 复制代码
    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

scss 复制代码
    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了。

csharp 复制代码
    // 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.备注

arduino 复制代码
//状态栏不可用
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

scala 复制代码
    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

arduino 复制代码
        public static ActivityManagerService startService(
                SystemServiceManager ssm, ActivityTaskManagerService atm) {
            sAtm = atm;
            //先反射获取Lifecycle对象,再调用补充2,返回AMS对象
            return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
        }

>2.getService

csharp 复制代码
        public ActivityManagerService getService() {
            return mService;
        }

3.2.相关流程

SystemServer里初始化启动的

>1.startBootstrapServices

less 复制代码
    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

scss 复制代码
    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

scss 复制代码
    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,监听改变

typescript 复制代码
    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应用并创建进程

java 复制代码
    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

scala 复制代码
    public static final class Lifecycle extends SystemService {
        private final ActivityTaskManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityTaskManagerService(context);
        }

>1.getService

csharp 复制代码
        public ActivityTaskManagerService getService() {
            return mService;
        }

4.2.onSystemReady

ini 复制代码
    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

ini 复制代码
//默认就是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

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

5.RootWindowContainer.java

5.1.startHomeOnAllDisplays

循环所有的display启动home页

ini 复制代码
    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

arduino 复制代码
    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
                false /* fromHomeKey */);
    }

>2.startHomeOnDisplay

arduino 复制代码
    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页

java 复制代码
    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

ini 复制代码
    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是否允许启动

java 复制代码
    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

java 复制代码
    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

scala 复制代码
        IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
        ServiceManager.addService("package", iPackageManager);

    public class IPackageManagerImpl extends IPackageManagerBase {

父类

less 复制代码
    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

上边的方法最终走到这里

less 复制代码
    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

kotlin 复制代码
    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);
    }

//

kotlin 复制代码
    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

less 复制代码
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

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里处理的

scala 复制代码
    private abstract static class MimeGroupsAwareIntentResolver<F extends Pair<?
            extends ParsedComponent, ParsedIntentInfo>, R>
            extends IntentResolver<F, R> {

>6.1.ActivityIntentResolver

补充6ComponentResolver的内部类

java 复制代码
    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

less 复制代码
    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

less 复制代码
    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是个数组,里边的数据是这样的
bash 复制代码
Pair{Activity{ad74d61 com.android.settings/.FallbackHome} com.android.server.pm.pkg.component.ParsedIntentInfoImpl@145b086}

>8.PackageStateUtils

less 复制代码
    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
java 复制代码
    /**
     * 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
ini 复制代码
<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
ini 复制代码
    <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
ini 复制代码
        <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广播更晚
ini 复制代码
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阶段不满足条件
ini 复制代码
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

scss 复制代码
    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

kotlin 复制代码
    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

arduino 复制代码
    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方法里,如下代码,
erlang 复制代码
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

相关推荐
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android