From a80a2a9c8d0de6641e33ef4cb0e9c14884f618a0 Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Sun, 23 Nov 2025 02:09:46 +0700 Subject: [PATCH] fix: Android 12.0/12.1/13 crash --- GITHUB_CHANGELOG.md | 13 +++++++- .../LauncherRestoreEventLoggerImpl.kt | 7 +++- .../quickstep/util/BaseDepthController.java | 33 ++++++++++--------- .../launcher3/model/data/WorkspaceData.kt | 2 +- .../system/InteractionJankMonitorWrapper.java | 23 ++++++------- .../shared/desktopmode/DesktopModeStatus.java | 19 +++++++++-- .../shared/desktopmode/DesktopStateImpl.kt | 19 +++++++++-- 7 files changed, 81 insertions(+), 35 deletions(-) diff --git a/GITHUB_CHANGELOG.md b/GITHUB_CHANGELOG.md index 938eabc7e8..7be6d5aa24 100644 --- a/GITHUB_CHANGELOG.md +++ b/GITHUB_CHANGELOG.md @@ -8,6 +8,17 @@ Bug fixes only Build: BS10.2111 (latest), BS10.2011 +Compatibility list: + +| 🏗️ Crash | 💫 Limited features | 🥞 Fully supported | +|-------------|---------------------|--------------------| +| Android 8.1 | | Android 12.0 | +| Android 9 | | Android 12.1 | +| Android 10 | | Android 13 | +| Android 11 | | Android 14 | +| | | Android 15 | +| | | Android 16 | + This is a developer-focused change log: * Fix a lot of internal basic functionality * Re-added some Lawnchair-specific code @@ -22,7 +33,7 @@ This is a developer-focused change log: * Variable font for Launcher3 (????????) * Dynamically get app widget popup icon * Foldable support (for real) -* Support Android 14/15 +* Support Android 12.0/12.1/13/14/15 ### 🥞 Snapshot 9 (Development 4 Release 1) diff --git a/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt index 8bb6e17b4b..a253e3e54f 100644 --- a/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt +++ b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt @@ -36,7 +36,12 @@ constructor(@ApplicationContext private val context: Context) : LauncherRestoreE } private val restoreEventLogger: BackupRestoreEventLogger? = if (Utilities.ATLEAST_S) { - BackupManager(context).delayedRestoreLogger + try { + BackupManager(context).delayedRestoreLogger + } catch (e: NoSuchMethodError) { + // Lawnchair-TODO: pE-TODO: wtf? + null + } } else { null } diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java index 0ea360115e..56c45d02c6 100644 --- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java +++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java @@ -128,8 +128,12 @@ public class BaseDepthController { public BaseDepthController(QuickstepLauncher activity) { mLauncher = activity; if (Flags.allAppsBlur() || enableOverviewBackgroundWallpaperBlur()) { - mCrossWindowBlursEnabled = - CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled(); + if (Utilities.ATLEAST_S) { + mCrossWindowBlursEnabled = + CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled(); + } else { + mCrossWindowBlursEnabled = false; + } mMaxBlurRadius = activity.getResources().getDimensionPixelSize( R.dimen.max_depth_blur_radius_enhanced); } else { @@ -251,11 +255,17 @@ public class BaseDepthController { final SurfaceControl.Transaction finalTransaction = transaction == null ? createTransaction() : transaction; + + // LC: Fix blur effect on Android 12.1/12.0 try (finalTransaction) { - finalTransaction.setBackgroundBlurRadius(blurSurface, mCurrentBlur) - .setOpaque(blurSurface, isSurfaceOpaque); - // Set early wake-up flags when we know we're executing an expensive operation, this way - // SurfaceFlinger will adjust its internal offsets to avoid jank. + if (blurSurface != null && blurSurface.isValid()) { + finalTransaction.setBackgroundBlurRadius(blurSurface, mCurrentBlur) + .setOpaque(blurSurface, isSurfaceOpaque); + } else { + // GRASP + return; + } + boolean wantsEarlyWakeUp = blurAmount > 0 && blurAmount < 1; if (wantsEarlyWakeUp && !mInEarlyWakeUp) { try { @@ -271,15 +281,8 @@ public class BaseDepthController { } } - if (applyImmediately) { - finalTransaction.apply(); - } else { - AttachedSurfaceControl rootSurfaceControl = - mLauncher.getRootView().getRootSurfaceControl(); - if (rootSurfaceControl != null) { - rootSurfaceControl.applyTransactionOnDraw(finalTransaction); - } - } + // LC: Always apply immediately. + finalTransaction.apply(); } blurWorkspaceDepthTargets(); diff --git a/src/com/android/launcher3/model/data/WorkspaceData.kt b/src/com/android/launcher3/model/data/WorkspaceData.kt index e235c27859..ab7ec6bf90 100644 --- a/src/com/android/launcher3/model/data/WorkspaceData.kt +++ b/src/com/android/launcher3/model/data/WorkspaceData.kt @@ -151,7 +151,7 @@ sealed class WorkspaceData : Iterable { private fun pushUpdate(update: WorkspaceChangeEvent) { modificationId++ changeHistory.add(0, update) - if (changeHistory.size > MAX_HISTORY_SIZE) changeHistory.removeLast() + if (changeHistory.size > MAX_HISTORY_SIZE) changeHistory.removeAt(changeHistory.lastIndex) } override fun copy(): WorkspaceData = diff --git a/systemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/systemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java index 3250a0cbb3..0f72d34ee0 100644 --- a/systemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java +++ b/systemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java @@ -33,7 +33,7 @@ public final class InteractionJankMonitorWrapper { */ public static void begin(View v, @Cuj.CujType int cujType) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return; - InteractionJankMonitor.getInstance().begin(v, cujType); +// InteractionJankMonitor.getInstance().begin(v, cujType); } /** @@ -48,7 +48,7 @@ public final class InteractionJankMonitorWrapper { Configuration.Builder builder = Configuration.Builder.withView(cujType, v) .setTimeout(timeout); - InteractionJankMonitor.getInstance().begin(builder); +// InteractionJankMonitor.getInstance().begin(builder); } /** @@ -60,12 +60,12 @@ public final class InteractionJankMonitorWrapper { */ public static void begin(View v, @Cuj.CujType int cujType, String tag) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return; - Configuration.Builder builder = - Configuration.Builder.withView(cujType, v); - if (!TextUtils.isEmpty(tag)) { - builder.setTag(tag); - } - InteractionJankMonitor.getInstance().begin(builder); +// Configuration.Builder builder = +// Configuration.Builder.withView(cujType, v); +// if (!TextUtils.isEmpty(tag)) { +// builder.setTag(tag); +// } +// InteractionJankMonitor.getInstance().begin(builder); } /** @@ -75,7 +75,7 @@ public final class InteractionJankMonitorWrapper { */ public static void end(@Cuj.CujType int cujType) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return; - InteractionJankMonitor.getInstance().end(cujType); +// InteractionJankMonitor.getInstance().end(cujType); } /** @@ -83,12 +83,13 @@ public final class InteractionJankMonitorWrapper { */ public static void cancel(@Cuj.CujType int cujType) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return; - InteractionJankMonitor.getInstance().cancel(cujType); +// InteractionJankMonitor.getInstance().cancel(cujType); } /** Return true if currently instrumenting a trace session. */ public static boolean isInstrumenting(@Cuj.CujType int cujType) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return false; - return InteractionJankMonitor.getInstance().isInstrumenting(cujType); +// return InteractionJankMonitor.getInstance().isInstrumenting(cujType); + return false; } } diff --git a/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java index 1912613a59..79b6fa3128 100644 --- a/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +++ b/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java @@ -20,6 +20,7 @@ import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLU import static com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper.enableBubbleToFullscreen; +import android.content.res.Resources.NotFoundException; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import android.content.Context; @@ -88,21 +89,33 @@ public class DesktopModeStatus { * Return {@code true} if the current device supports desktop mode. */ private static boolean isDesktopModeSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); + try { + return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); + } catch (NotFoundException e) { + return false; + } } /** * Return {@code true} if the current device supports the developer option for desktop mode. */ private static boolean isDesktopModeDevOptionSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_isDesktopModeDevOptionSupported); + try { + return context.getResources().getBoolean(R.bool.config_isDesktopModeDevOptionSupported); + } catch (NotFoundException e) { + return false; + } } /** * Return {@code true} if the current device can host desktop sessions on its internal display. */ private static boolean canInternalDisplayHostDesktops(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops); + try { + return context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops); + } catch (NotFoundException e) { + return false; + } } diff --git a/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopStateImpl.kt b/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopStateImpl.kt index ed2a95abc3..786037b7d4 100644 --- a/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopStateImpl.kt +++ b/wmshell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopStateImpl.kt @@ -18,6 +18,7 @@ package com.android.wm.shell.shared.desktopmode import android.content.Context import android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT +import android.content.res.Resources import android.hardware.display.DisplayManager import android.os.SystemProperties import android.provider.Settings @@ -40,13 +41,25 @@ class DesktopStateImpl(context: Context) : DesktopState { SystemProperties.getBoolean(ENFORCE_DEVICE_RESTRICTIONS_SYS_PROP, true) private val isDesktopModeDevOptionSupported = - context.getResources().getBoolean(R.bool.config_isDesktopModeDevOptionSupported) + try { + context.getResources().getBoolean(R.bool.config_isDesktopModeDevOptionSupported) + } catch (e: Resources.NotFoundException) { + false + } private val isDesktopModeSupported = - context.getResources().getBoolean(R.bool.config_isDesktopModeSupported) + try { + context.getResources().getBoolean(R.bool.config_isDesktopModeSupported) + } catch (e: Resources.NotFoundException) { + false + } private val canInternalDisplayHostDesktops = - context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops) + try { + context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops) + } catch (e: Resources.NotFoundException) { + false + } private val isDeviceEligibleForDesktopModeDevOption = if (!enforceDeviceRestrictions) {