系统的选择弹窗是:
    frameworks/base/core/java/com/android/internal/app/ResolverActivity.java

    1. protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
    2. ///......
    3. if (alwaysCheck) {
    4. final int userId = getUserId();
    5. final PackageManager pm = getPackageManager();
    6. android.util.Log.e("XShawn, "+TAG, "filter="+filter); // android.content.IntentFilter@3544861
    7. for(int i = 0 ; i < filter.countActions(); i++){
    8. android.util.Log.e("XShawn, "+TAG, "filter.getAction["+i+"]="+filter.getAction(i));
    9. }
    10. for(int i = 0 ; i < filter.countCategories(); i++){
    11. android.util.Log.e("XShawn, "+TAG, "filter.getCategory["+i+"]="+filter.getCategory(i));
    12. }
    13. android.util.Log.e("XShawn, "+TAG, "bestMatch="+bestMatch); // 1081344
    14. android.util.Log.e("XShawn, "+TAG, "set="+set); // [Landroid.content.ComponentName;@4f68f86
    15. android.util.Log.e("XShawn, "+TAG, "getComponent="+intent.getComponent()); // com.ordissimo.android.tablet.launcher/com.ordissimo.android.tablet.launcher.home.HomeActivity
    16. // Set the preferred Activity
    17. pm.addPreferredActivity(filter, bestMatch, set, intent.getComponent());
    18. if (ri.handleAllWebDataURI) {
    19. // Set default Browser if needed
    20. final String packageName = pm.getDefaultBrowserPackageNameAsUser(userId);
    21. if (TextUtils.isEmpty(packageName)) {
    22. pm.setDefaultBrowserPackageNameAsUser(ri.activityInfo.packageName, userId);
    23. }
    24. }
    25. } else {
    26. try {
    27. mMultiProfilePagerAdapter.getActiveListAdapter()
    28. .mResolverListController.setLastChosen(intent, filter, bestMatch);
    29. } catch (RemoteException re) {
    30. Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
    31. }
    32. }
    33. ///......
    34. }

    这里适合打印系统处理时产生的各种参数,进而拿到设置默认Launcher的关键参数。


    尝试在SystemServer中 startSystemUI之后设置默认launcher,但首次开机时设置不上,可能是开机向导还没走完,系统没有初始化完的原因。
    尝试在SystemServer中startOtherService之前设置,也不太理想。


    设置默认Launcher,设置方法可参考PackageManagerService.setHomeActivity方法。
    采用监听开机广播的方式处理:
    MtkSettings\src\com\emdoor\customization\PreferredActivityReceiver.java

    1. /*
    2. * ****** Copyright © 2015-2022 XShawn ********
    3. * Q Q:930226956 (请备注您的信息)
    4. * 邮箱:shawn.xiafei@foxmail.com
    5. * 语雀:https://www.yuque.com/xshawn
    6. * 更新:2022-03-31 10:21
    7. * ********** All Rights Reserved. ************
    8. */
    9. package com.emdoor.customization;
    10. import android.content.BroadcastReceiver;
    11. import android.content.ComponentName;
    12. import android.content.Context;
    13. import android.content.Intent;
    14. import android.content.IntentFilter;
    15. import android.content.pm.PackageManager;
    16. import android.content.pm.ResolveInfo;
    17. import android.os.SystemProperties;
    18. import android.provider.Settings;
    19. import android.util.Log;
    20. import java.util.ArrayList;
    21. import java.util.List;
    22. public class PreferredActivityReceiver extends BroadcastReceiver {
    23. private static final String TAG = "XShawn, PreferredActivityReceiver";
    24. private static final String KEY_ORDISSIMO_SUPPORT = "ro.com.ordissimo.support";
    25. private static final String KEY_ORDISSIMO_INIT = "ordissimo_init";
    26. @Override
    27. public void onReceive(Context context, Intent intent) {
    28. Log.w(TAG, "action: " + intent.getAction());
    29. if (SystemProperties.getBoolean(KEY_ORDISSIMO_SUPPORT, false)) {
    30. setDefaultHome(context);
    31. }
    32. }
    33. private static void setDefaultHome(Context context) {
    34. if (isOrdissimoInit(context)) {
    35. Log.w(TAG, "default home has already been set.");
    36. return;
    37. }
    38. Log.w(TAG, "try to set default home...");
    39. // target activity
    40. final ComponentName targetHome = new ComponentName(
    41. "com.ordissimo.android.tablet.launcher",
    42. "com.ordissimo.android.tablet.launcher.home.HomeActivity"
    43. );
    44. final PackageManager pm = context.getPackageManager();
    45. List<ResolveInfo> homeActivities = new ArrayList<>();
    46. ComponentName currentHome = pm.getHomeActivities(homeActivities);
    47. // pre-check status
    48. if (targetHome.equals(currentHome)) {
    49. Log.w(TAG, "default home has already been set.");
    50. setOrdissimoInit(context, true);
    51. return;
    52. }
    53. // available set
    54. ComponentName[] set = homeActivities.parallelStream()
    55. .map(resolveInfo -> resolveInfo.activityInfo.getComponentName())
    56. .toArray(ComponentName[]::new);
    57. // set default home
    58. context.getPackageManager().replacePreferredActivity(
    59. getHomeFilter(),
    60. IntentFilter.MATCH_CATEGORY_EMPTY,
    61. set,
    62. targetHome
    63. );
    64. // after-check status.
    65. currentHome = pm.getHomeActivities(homeActivities);
    66. if (targetHome.equals(currentHome)) {
    67. Log.w(TAG, "set default home success.");
    68. setOrdissimoInit(context, true);
    69. }
    70. }
    71. private static IntentFilter getHomeFilter() {
    72. IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
    73. filter.addCategory(Intent.CATEGORY_HOME);
    74. filter.addCategory(Intent.CATEGORY_DEFAULT);
    75. return filter;
    76. }
    77. private static boolean isOrdissimoInit(Context context) {
    78. return Settings.Global.getInt(context.getContentResolver(), KEY_ORDISSIMO_INIT, 0) == 1;
    79. }
    80. private static void setOrdissimoInit(Context context, boolean done) {
    81. Settings.Global.putInt(context.getContentResolver(), KEY_ORDISSIMO_INIT, done ? 1 : 0);
    82. }
    83. }

    注册广播接收器:

    1. <!-- START. For Ordissimo-Customization. By XShawn@20220331. -->
    2. <receiver
    3. android:name="com.emdoor.customization.PreferredActivityReceiver"
    4. android:enabled="true"
    5. android:exported="true">
    6. <intent-filter>
    7. <action android:name="android.intent.action.BOOT_COMPLETED" />
    8. <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
    9. <action android:name="android.intent.action.USER_PRESENT" />
    10. </intent-filter>
    11. </receiver>
    12. <!-- END. For Ordissimo-Customization. By XShawn@20220331. -->

    但开机广播是有延时性的,在有开机向导的前提下,能够成功设置默认launcher。
    若没有开机向导,开机后直接就进了launcher,此时开机广播还没有发出来,所以默认不成功。


    优化方案
    找到安装APP的位置,安装完成,主动发广播去修改默认launcher,但这样每次安装都会自动默认上。

    1. //frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
    2. try {
    3. PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
    4. System.currentTimeMillis(), user);
    5. updateSettingsLI(newPackage, installerPackageName, null, res, user);
    6. if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
    7. prepareAppDataAfterInstallLIF(newPackage);
    8. //------------------------
    9. if (pkgName.equals("com.dianxinos.dxhome")){
    10. //发送广播
    11. Intent intent = new Intent("emdoor.intent.action.UPDATE_LANUCHER_APPS");
    12. mContext.sendBroadcast(intent);
    13. }
    14. //------------------------
    15. } else {
    16. // Remove package from internal structures, but keep around any
    17. // data that might have already existed
    18. deletePackageLIF(pkgName, UserHandle.ALL, false, null,
    19. PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
    20. }
    21. } catch (PackageManagerException e) {
    22. res.setError("Package couldn't be installed in " + pkg.codePath, e);
    23. }