From f92276da15facac9dbfc8d40ec816788f189b7d9 Mon Sep 17 00:00:00 2001 From: TMC Date: Wed, 11 Nov 2026 23:35:14 +0100 Subject: [PATCH] Ask for the home role after the launcher has finished resuming; keep failed background checks quiet First run (PRD SI-1) - The request to become the default home app never appeared. Started from onResume, it was still pending when the launcher finished resuming, and Quickstep cancels any pending request at that point. It now starts from onDeferredResumed, after that check, through Launcher3's own ApiWrapper.assignDefaultHomeRole. Updater - An automatic check that fails (phone offline, say) no longer leaves "couldn't reach the update server" on the About screen. The screen keeps what it showed before, and the check runs again in an hour. A check started by hand still reports the failure. Checked on the Android 17 emulator with the 0.2.0 release build made before this commit: swipe up and hold in gesture and in three-button navigation, the list darkening under a wave that reaches in from the right edge, and the work profile tabs. The two changes in this commit are not yet checked. Co-Authored-By: Claude Fable 5.2 --- flexera/src/app/flexera/FlexeraFirstRun.kt | 20 +++++++++---------- .../src/app/flexera/update/FlexeraUpdater.kt | 8 +++----- .../src/app/lawnchair/LawnchairLauncher.kt | 10 ++++++++-- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/flexera/src/app/flexera/FlexeraFirstRun.kt b/flexera/src/app/flexera/FlexeraFirstRun.kt index 9539805e2d..7dbc5df53a 100644 --- a/flexera/src/app/flexera/FlexeraFirstRun.kt +++ b/flexera/src/app/flexera/FlexeraFirstRun.kt @@ -5,15 +5,15 @@ import android.app.role.RoleManager import android.content.Context import android.os.Build import android.util.Log -import com.android.launcher3.LauncherConstants +import com.android.launcher3.util.ApiWrapper /** * First-run step (PRD SI-1): the first time the launcher is opened while another app is the * phone's home app, ask Android to offer Flexera Launcher as the default. * - * Android shows its own dialog for this, listing the installed home apps. It is asked once only. - * If the owner declines, the launcher's settings keep showing a reminder that leads to the same - * choice, so there is no need to ask again. + * Android shows its own dialog for this. It is asked once only. If the owner declines, Launcher3 + * shows a short hint about Android's settings, and the launcher's own settings keep a reminder + * that leads to the same choice, so there is no need to ask again. */ object FlexeraFirstRun { @@ -22,12 +22,10 @@ object FlexeraFirstRun { private const val KEY_ASKED_DEFAULT_HOME = "asked_default_home" /** - * Launcher3's own request code for this role request. Its result handler shows a short hint - * about Android's settings when the owner declines. + * Call once the launcher has finished resuming (its onDeferredResumed), not earlier: the + * launcher cancels any request for a result that is pending at that point. Does nothing + * after the first time. */ - private const val REQUEST_DEFAULT_HOME = LauncherConstants.ActivityCodes.REQUEST_HOME_ROLE - - /** Call when the launcher comes to the front. Does nothing after the first time. */ @JvmStatic fun askToBecomeDefaultHome(activity: Activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return @@ -40,7 +38,9 @@ object FlexeraFirstRun { if (roles.isRoleHeld(RoleManager.ROLE_HOME)) return try { - activity.startActivityForResult(roles.createRequestRoleIntent(RoleManager.ROLE_HOME), REQUEST_DEFAULT_HOME) + // Launcher3's own way of asking: Android's consent dialog, then a short hint about + // Android's settings if the owner declines. + ApiWrapper.INSTANCE.get(activity).assignDefaultHomeRole(activity) } catch (e: Exception) { Log.w(TAG, "Could not ask to become the default home app", e) } diff --git a/flexera/src/app/flexera/update/FlexeraUpdater.kt b/flexera/src/app/flexera/update/FlexeraUpdater.kt index d8aa21c161..d706d283f0 100644 --- a/flexera/src/app/flexera/update/FlexeraUpdater.kt +++ b/flexera/src/app/flexera/update/FlexeraUpdater.kt @@ -188,8 +188,9 @@ object FlexeraUpdater { val release = result.getOrElse { error -> Log.w(TAG, "Update check failed", error) - // A failed background check must not wipe out an update that is already waiting. - mutableState.value = if (automatic && before.holdsRelease()) before else UpdateState.Failed(UpdateFailure.CHECK) + // A background check that fails stays quiet: the About screen keeps what it showed + // before, including an update that is already waiting. It tries again in an hour. + mutableState.value = if (automatic) before else UpdateState.Failed(UpdateFailure.CHECK) return@launch } @@ -301,9 +302,6 @@ object FlexeraUpdater { private fun isBusy(): Boolean = mutableState.value.let { it is UpdateState.Checking || it is UpdateState.Downloading } - private fun UpdateState.holdsRelease(): Boolean = - this is UpdateState.Available || this is UpdateState.ReadyToInstall - /** Returns the latest published release, or null when nothing has been published yet. */ private fun fetchLatestRelease(context: Context): FlexeraRelease? { val connection = open(context, LATEST_RELEASE_URL) diff --git a/lawnchair/src/app/lawnchair/LawnchairLauncher.kt b/lawnchair/src/app/lawnchair/LawnchairLauncher.kt index a48f481657..fa31c2400b 100644 --- a/lawnchair/src/app/lawnchair/LawnchairLauncher.kt +++ b/lawnchair/src/app/lawnchair/LawnchairLauncher.kt @@ -469,10 +469,16 @@ class LawnchairLauncher : QuickstepLauncher() { return ActivityOptionsWrapper(options, callback) } + override fun onDeferredResumed() { + super.onDeferredResumed() + // Flexera Launcher: on first run, ask to become the default home app (PRD SI-1). It has + // to wait until here. Quickstep cancels any request for a result that is already pending + // when the launcher finishes resuming, which is what the call above does. + app.flexera.FlexeraFirstRun.askToBecomeDefaultHome(this) + } + override fun onResume() { super.onResume() - // Flexera Launcher: on first run, ask to become the default home app (PRD SI-1). - app.flexera.FlexeraFirstRun.askToBecomeDefaultHome(this) restartIfPending() refreshPredictionContainersFromModel()