jQuery鼠标指针特效

Android 13 about launcher3 (1)

Android 13 Launcher3
android13#launcher3#分屏相关

Launcher3修改 wm density界面布局不改变

/packages/apps/Launcher3/src/com/android/launcher3/InvariantDeviceProfile.java
Launcher的默认配置加载类,通过InvariantDeviceProfile方法可以看出,
CellLayout显示的应用行数和列数可以通过findClosestDeviceProfiles查询XML配置来读取配参

Launcher3图标布局原理解析

Android 13 diff

index 02ebb15cd1..36ce9bf7bf 100644
--- a/packages/apps/Launcher3/src/com/android/launcher3/util/DisplayController.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/util/DisplayController.java
@@ -284,7 +284,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
         if (change != 0) {
             mInfo = newInfo;
             final int flags = change;
-            MAIN_EXECUTOR.execute(() -> notifyChange(displayInfoContext, flags));
+            //MAIN_EXECUTOR.execute(() -> notifyChange(displayInfoContext, flags));
         }
     }
  

Android 11 diff

./packages/apps/Launcher3/src/com/android/launcher3/util/ConfigMonitor.java

   @Override
    public void onDisplayChanged(int displayId) {
        if (displayId != mDisplayId) {
            return;
        }
        Display display = getDefaultDisplay(mContext);
        display.getRealSize(mTmpPoint1);
 
        if (!mRealSize.equals(mTmpPoint1) && !mRealSize.equals(mTmpPoint1.y, mTmpPoint1.x)) {
            LogUtils.d(TAG, String.format("Display size changed from %s to %s", mRealSize, mTmpPoint1));
            notifyChange();
            return;
        }
 
        display.getCurrentSizeRange(mTmpPoint1, mTmpPoint2);
        if (!mSmallestSize.equals(mTmpPoint1) || !mLargestSize.equals(mTmpPoint2)) {
            LogUtils.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
                    mSmallestSize, mLargestSize, mTmpPoint1, mTmpPoint2));
            notifyChange();
        }
    }
 
    public synchronized void notifyChange() {
 
        if (mCallback != null) {
            Consumer<Context> callback = mCallback;
            mCallback = null;
            new MainThreadExecutor().execute(() -> {
 
        //add text
        //LauncherAppMonitor.getInstance(mContext).onUIConfigChanged();
        //callback.accept(mContext);
        //add text
 
            });
        }
    }

Launcher3 的Hotseat选择显示在底部/右边

Launcher3的HotSeat的位置,是由DeviceProfile::isVerticalBarLayout里面的两个变量isLandscape && transposeLayoutWithOrientation去决定的.
如果想强制HotSeat位于底部,把isVerticalBarLayout的返回值默认为false.

/packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java

/**
     * When {@code true}, the device is in landscape mode and the hotseat is on the right column. 右边
     * When {@code false}, either device is in portrait mode or the device is in landscape mode and
     * the hotseat is on the bottom row. 底部
     */
    public boolean isVerticalBarLayout() {
        return isLandscape && transposeLayoutWithOrientation;
    }

原生设计:workspace和allapps界面图标大小、文字大小、间隔大小完全一致.
如果横屏时高度不够,可能会影响图标的展示(因为它俩在同一个界面,如果HotSeat展示在下方,会导致workspace空间被压缩),可以优化垂直方向的高度的思路.

Android 11 Launcher3旋转Hotseat显示在底部
Launcher3图标布局原理解析【原创】

Android 13 关于旋转屏幕之后,按home键回Launcher3失效

//自动旋转
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
adb shell settings get system accelerometer_rotation  --> 0 off 1 on

Android 12之后,Launcher3有两个模式,一个是平板,另一个是手机.
手机模式:桌面默认是不可以旋转的.

桌面设置页面:桌面空白处长按,进入home settings,有个allow home screen rotation就是旋转开关,手机模式默认是关闭的,平板模式这个偏好隐藏了.

./packages/apps/Launcher3/res/values/config.xml    
<string name="settings_fragment_name" translatable="false">com.android.launcher3.settings.SettingsActivity$LauncherSettingsFragment</string>

./packages/apps/Launcher3/src/com/android/launcher3/settings/SettingsActivity.java
public static class LauncherSettingsFragment extends PreferenceFragmentCompat 
{
    protected boolean initPreference(Preference preference) {
            switch (preference.getKey()) {
                case NOTIFICATION_DOTS_PREFERENCE_KEY:
                    return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;

                case ALLOW_ROTATION_PREFERENCE_KEY:
                    DisplayController.Info info =
                            DisplayController.INSTANCE.get(getContext()).getInfo();
                    if (info.isTablet(info.realBounds)) {
                        // Launcher supports rotation by default. No need to show this setting.
                        //是平板,不显示这个选项
                        return false;
                    }
                    // Initialize the UI once //非平板,默认显示,
                    preference.setDefaultValue(RotationHelper.getAllowRotationDefaultValue(info));//控制是否旋转
                    return true;
                    ...
                    
    }
}

./packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
    public static boolean getAllowRotationDefaultValue(DisplayController.Info info) {
        android.util.Log.d("tag","info.currentSize.x: " +info.currentSize.x);
        android.util.Log.d("tag","info.currentSize.y: " +info.currentSize.y);
        float originalSmallestWidth = dpiFromPx(Math.min(info.currentSize.x, info.currentSize.y),
                DENSITY_DEVICE_STABLE);
        return originalSmallestWidth >= MIN_TABLET_WIDTH;//MIN_TABLET_WIDTH = 600;
    }
    
    
    public static float dpiFromPx(float size, int densityDpi) {
        float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT;//DENSITY_DEFAULT=160;
        return (size / densityRatio);
    }
    
    //关于DENSITY_DEVICE_STABLE
    private static int getDeviceDensity() {
        //ro.sf.lcd_density的值在初始化进程的时候从build.prop里读取写入一次,之后不会修改
        //qemu.sf.lcd_density覆写上边的值,目的是在模拟器的时候可以动态修改
        return SystemProperties.getInt("qemu.sf.lcd_density",
                SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
    }
    
    initialize()->初始化setIgnoreAutoRotateSettings
    
    private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings,
            DisplayController.Info info) {
        // On large devices we do not handle auto-rotate differently.
        mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
        if (!mIgnoreAutoRotateSettings) {
            mHomeRotationEnabled = LauncherPrefs.get(mActivity).get(ALLOW_ROTATION);
            LauncherPrefs.get(mActivity).addListener(this, ALLOW_ROTATION);
        } else {
            LauncherPrefs.get(mActivity).removeListener(this, ALLOW_ROTATION);
        }
    }
    

    //手动控制屏幕旋转的方式
    
    private void setOritation(int i) {
        try {
            IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
 		if (i == 0) {
                windowManagerService.freezeRotation(0);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);//关闭自动旋转
            } else if (i == 90) {
                windowManagerService.freezeRotation(1);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == 180) {
                windowManagerService.freezeRotation(2);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == 270) {
                windowManagerService.freezeRotation(3);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == -1) {
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 1);//打开自动旋转
            }
        } catch (Exception e) {
		...
       }
    }
    
    Settings.System.getInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, 0);
    adb shell settings get system user_rotation(修改后查询)
    
    
//修改  默认打开主界面旋转
+++ b/packages/apps/Launcher3/res/xml/launcher_preferences.xml
@@ -45,7 +45,7 @@
         android:key="pref_allowRotation"
         android:title="@string/allow_rotation_title"
         android:summary="@string/allow_rotation_desc"
-        android:defaultValue="false"
+        android:defaultValue="true"
         android:persistent="true"
         launcher:logIdOn="615"
         launcher:logIdOff="616" />
diff --git a/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java b/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
index 7b4e2485ce..6693f9f123 100644
--- a/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
@@ -55,7 +55,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
         // original dimensions to determine if rotation is allowed of not.
         float originalSmallestWidth = dpiFromPx(Math.min(info.currentSize.x, info.currentSize.y),
                 DENSITY_DEVICE_STABLE);
-        return originalSmallestWidth >= MIN_TABLET_WIDTH;
+        return true;//originalSmallestWidth >= MIN_TABLET_WIDTH;//add text
     }
    

从源头隐藏某个apk不在最近应用(RecentView)显示

//这个改法:再需要隐藏的app,按Recent,有动画时显得卡顿,建议可以在Launcher3内尝试隐藏
frameworks/base/services/core/java/com/android/server/wm/RecentTasks.java

    /**
     * @return the list of recent tasks for presentation.
     */
    private ArrayList<ActivityManager.RecentTaskInfo> getRecentTasksImpl(int maxNum, int flags,
            boolean getTasksAllowed, int userId, int callingUid) {
        final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;

        if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
            Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
            return new ArrayList<>();
        }
        loadUserRecentsLocked(userId);

        final Set<Integer> includedUsers = getProfileIds(userId);
        includedUsers.add(Integer.valueOf(userId));

        final ArrayList<ActivityManager.RecentTaskInfo> res = new ArrayList<>();
        final int size = mTasks.size();
        int numVisibleTasks = 0;
        for (int i = 0; i < size; i++) {
            final Task task = mTasks.get(i);

            if (isVisibleRecentTask(task)) {
                numVisibleTasks++;
                if (isInVisibleRange(task, i, numVisibleTasks, withExcluded)) {
                    // Fall through
                } else {
                    // Not in visible range
                    continue;
                }
            } else {
                // Not visible
                continue;
            }

            // Skip remaining tasks once we reach the requested size
            if (res.size() >= maxNum) {
                continue;
            }

            // Only add calling user or related users recent tasks
            if (!includedUsers.contains(Integer.valueOf(task.mUserId))) {
                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + task);
                continue;
            }

            ...

            //add text
            ComponentName cn = task.intent.getComponent();
            if(cn != null && cn.getPackageName().equals("com.xxx.xxx")){
                continue;
            }else{
                res.add(createRecentTaskInfo(task, true /* stripExtras */));
            }
            //add text
            
        }
        return res;
    }
    

Android T Launcher3
Android T Launcher3_recentView

T replace default launcher

关于3.0Ver 利用role不需要删除旧Launcher栈的补充.
case 1: 单独使用role,确实不需要删除旧Launcher栈,唯一需要注意点的是要在Launcher启动之前,把android.app.role.HOME替换,
所以需要在framework里某个必经之路上做文章..

//about home role
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java

packages/modules/Permission/service/java/com/android/role/RoleService.java
addRoleHolderAsUser(...)
removeRoleHolderAsUser(...)
getRoleHoldersAsUser(...)


frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

+import android.app.role.RoleManager;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+

    @Override
    public void systemReady() {
        // In normal flow, systemReady is called before other system services are ready.
        // So it is better not to bind keyguard here.
        mKeyguardDelegate.onSystemReady();
        ...
        mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
        mGestureLauncherService = LocalServices.getService(GestureLauncherService.class);
+        setDefaultLauncherItemToHomeRole(mContext);//add
    }
    
    public void setDefaultLauncherItemToHomeRole(Context context) {
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        String packageName = SystemProperties.get("persist.xx.def_xxx_launcher", null);
        
        List<String> list = roleManager_1.getRoleHolders("android.app.role.HOME");
        boolean repeat_flag = false;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals(packageName)) {
                flag = true;
            }
        }
        
        if (repeat_flag) return;
        
        if (packageName != null && !"".equals(packageName)) {
            String roleName = "android.app.role.HOME";
            boolean add = true;
            int flags = 0;
            UserHandle user = Process.myUserHandle();
            Log.d("tag", "role: " + roleName + ", package: " + packageName);
            Executor executor = context.getMainExecutor();
            Consumer<Boolean> callback = successful -> {
                if (successful) {
                    Log.d("tag", "Success , role: " + roleName + ", package: " + packageName);
                } else {
                    Log.d("tag", "Failed , role: " + roleName + ", package: " + packageName);
                }
            };
            roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
        }
    }

case 2:ResolverActivity

frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
onCreate()->rebuildList()->onPostListReady()->isAutolaunching()...                        

    protected void onCreate(Bundle savedInstanceState, Intent intent,
            CharSequence title, int defaultTitleRes, Intent[] initialIntents,
            List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
        setTheme(appliedThemeResId());
        super.onCreate(savedInstanceState);
        //add text
        if(true){
            setDefaultLauncher("com.xx.xxx");
            finish();
            return;
        }
        //add text
        mQuietModeManager = createQuietModeManager();
        ...
    }    
    
    //add text
    private List<ResolveInfo> getResolveInfoList() {
        PackageManager pm = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        return pm.queryIntentActivities(intent, 0);
    }

    private ResolveInfo getCurrentLauncher() {
        PackageManager pm = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        return pm.resolveActivity(intent, 0);
    }

    private void setDefaultLauncher(String packageName) {
        PackageManager pm = getPackageManager();
        ResolveInfo oldCurrentLauncher = getCurrentLauncher();
        List<ResolveInfo> packageInfos = getResolveInfoList();

        ResolveInfo customerLauncher = null;

        for (ResolveInfo ri : packageInfos) {
            if (!TextUtils.isEmpty(ri.activityInfo.packageName) && !TextUtils.isEmpty(packageName)
                    && TextUtils.equals(ri.activityInfo.packageName, packageName)) {
                customerLauncher = ri;
            }
        }

        if (customerLauncher == null) return;

        pm.clearPackagePreferredActivities(oldCurrentLauncher.activityInfo.packageName);//clear old Launcher
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_MAIN);
        intentFilter.addCategory(Intent.CATEGORY_HOME);
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        ComponentName componentName = new ComponentName(customerLauncher.activityInfo.packageName,
                customerLauncher.activityInfo.name);
        ComponentName[] componentNames = new ComponentName[packageInfos.size()];
        int defaultMatch = 0;
        for (int i = 0; i < packageInfos.size(); i++) {
            ResolveInfo resolveInfo = packageInfos.get(i);
            componentNames[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
            if (defaultMatch < resolveInfo.match) {
                defaultMatch = resolveInfo.match;
            }
        }
        pm.clearPackagePreferredActivities(oldCurrentLauncher.activityInfo.packageName);
        pm.addPreferredActivity(intentFilter, defaultMatch, componentNames, componentName);
    }
    //add text

Android13设置默认Launcher分析
Android13设置默认Launcher分析
RK3588 Android13 预安装自己的apk应用及把这个应用设置为默认桌面
Android R设置默认桌面

Android T update wm density 导致 Launcher3 ANR/SystemUI nav bar消失

点击Settings app 的 display 选项, 里面有个功能可以修改字体大小和屏幕密度.
发现修改屏幕密度为最小值时,Launcher3 停止运行,触发ANR和SystemUI nav bar消失.
下面是日志:

10-15 03:36:35.078  5241  5241 E AndroidRuntime: FATAL EXCEPTION: main
10-15 03:36:35.078  5241  5241 E AndroidRuntime: Process: com.android.launcher3, PID: 5241
...
10-15 03:36:35.078  5241  5241 E AndroidRuntime: Caused by: java.lang.ArithmeticException: divide by zero
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.DeviceProfile.calculateHotseatBorderSpace(DeviceProfile.java:1009)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.DeviceProfile.recalculateHotseatWidthAndBorderSpace(DeviceProfile.java:670)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile.lambda$initGrid$7(InvariantDeviceProfile.java:444)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile$$ExternalSyntheticLambda5.accept(Unknown Source:4)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:185)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1390)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:475)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:133)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:236)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:435)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile.initGrid(InvariantDeviceProfile.java:442)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile.initGrid(InvariantDeviceProfile.java:329)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile.<init>(InvariantDeviceProfile.java:205)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile.$r8$lambda$DNcXzmawjoq65q3wgQi9M48DryY(Unknown Source:2)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.InvariantDeviceProfile$$ExternalSyntheticLambda0.get(Unknown Source:0)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject.lambda$get$0$com-android-launcher3-util-MainThreadInitializedObject(MainThreadInitializedObject.java:58)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject$$ExternalSyntheticLambda0.get(Unknown Source:4)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.TraceHelper.allowIpcs(TraceHelper.java:84)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject.get(MainThreadInitializedObject.java:57)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.LauncherAppState.<init>(LauncherAppState.java:154)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.LauncherAppState.<init>(LauncherAppState.java:96)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.LauncherAppState$$ExternalSyntheticLambda8.get(Unknown Source:2)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject.lambda$get$0$com-android-launcher3-util-MainThreadInitializedObject(MainThreadInitializedObject.java:58)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject$$ExternalSyntheticLambda0.get(Unknown Source:4)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.TraceHelper.allowIpcs(TraceHelper.java:84)
10-15 03:36:35.078  5241  5241 E AndroidRuntime: 	at com.android.launcher3.util.MainThreadInitializedObject.get(MainThreadInitializedObject.java:57)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at com.android.launcher3.LauncherAppState.getInstance(LauncherAppState.java:84)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at com.android.launcher3.Launcher.onCreate(Launcher.java:482)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at com.android.launcher3.uioverrides.QuickstepLauncher.onCreate(QuickstepLauncher.java:585)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8357)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8336)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1417)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3626)
10-15 03:36:35.079  5241  5241 E AndroidRuntime: 	... 12 more

根据日志跟踪,再对应代码处添加日志

+++ b/packages/apps/Launcher3/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -436,11 +436,13 @@ public class InvariantDeviceProfile {
                 .min()
                 .orElse(0);


         supportedProfiles
                 .stream()
                 .filter(deviceProfile -> deviceProfile.isTablet)
                 .forEach(deviceProfile -> {
                     deviceProfile.numShownHotseatIcons = numMinShownHotseatIconsForTablet;
+                    android.util.Log.d("tag","numMinShownHotseatIconsForTablet:"+numMinShownHotseatIconsForTablet);
+                   android.util.Log.d("tag","deviceProfile.isTablet:"+deviceProfile.isTablet);
                     deviceProfile.recalculateHotseatWidthAndBorderSpace();
                 });

根据打印,发现只有修改屏幕密度为最小值(114)时,才会打印tag numMinShownHotseatIconsForTablet 和 deviceProfile.isTablet 为 true.
但是当设备调节为其他屏幕密度时,代码不走这里,不打印.

bingo,问题点已经被发现了,可能是isTablet影响的一切,后面就是修改验证了...

ps:验证之后,确认是isTablet的问题.

/packages/apps/Launcher3/src/com/android/launcher3/util/window/WindowManagerProxy.java

boolean isTablet = config.smallestScreenWidthDp > MIN_TABLET_WIDTH;

当前设备config.smallestScreenWidthDp 打印为 674 > MIN_TABLET_WIDTH(600),isTablet 为true,其他屏幕密度为false,
Launcher3判断当前设备是tablet,导致了问题.

如何修改:
找到Launcher3 / SystemUI 判断isTablet ,返回false即可.
具体请点击下方链接.
isTablet影响

posted @ 2024-08-17 16:32  僵小七  阅读(115)  评论(0编辑  收藏  举报