[fix] drop FLAG_ACTIVITY_NEW_TASK when launching BugReportActivity from an Activity context#252
Conversation
…om an Activity context Xiaomi/MIUI silently blocks startActivity calls that pair FLAG_ACTIVITY_NEW_TASK with a transparent destination via its pop-up window gate, causing the "Create Report" button in DebugPanelDialog to do nothing when a draft already exists (#251). The flag was added for the FAB's overlay (non-Activity) context and was applied indiscriminately to the in-Activity caller; now it is only added when the caller context does not unwrap to an Activity. Also collapses the throwing Context.findActivity() into a single nullable findActivityOrNull(), since its only caller (Views.kt) was wrapping it in runCatching to get nullable semantics anyway. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a nullable Context.findActivityOrNull() helper and updates View utilities, OverlayViewManager checks, and BugReportActivity launch helpers to use null-safe activity resolution; launch helpers now add FLAG_ACTIVITY_NEW_TASK only when no Activity is found on the provided Context. ChangesSafe Activity Resolution in Launches
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Claude finished @Manabu-GT's task in 3m 51s —— View job PR Review — drop
|
| Caller | LocalContext.current resolves to |
New behavior |
|---|---|---|
BugReporterFab (in overlay window via OverlayViewManager, application context) |
non‑Activity | NEW_TASK still added — unchanged ✅ |
DebugPanelTopAppBar inside DebugPanelDialog hosted by DebugPanelActivity |
Activity | NEW_TASK omitted — this is the fix ✅ |
Confirmed via debugoverlay-core/src/main/AndroidManifest.xml:9-18 that both DebugPanelActivity and BugReportActivity use debugoverlay_Theme.Transparent, which lines up with the MIUI symptom you described.
Code quality
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/util/Contexts.kt:14-18 — Rename to findActivityOrNull is the right call. The OrNull suffix follows Kotlin stdlib convention (toIntOrNull, firstOrNull, etc.), tailrec is preserved (the recursive call remains in tail position), and returning null instead of throwing IllegalArgumentException removes the "exceptions for control flow" smell. Net positive.
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/util/Views.kt:11 — Dropping runCatching { context.findActivity() }.getOrNull() in favor of the direct context.findActivityOrNull() is behaviorally equivalent and clearer. Also slightly faster on the hot path (no try/catch object allocation when traversal misses).
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/bugreport/ui/BugReportActivity.kt:335,343 — The conditional flag logic reads cleanly. Two minor nits below; both optional.
Nits / follow-up suggestions
-
Naming inconsistency — After this PR, you have:
Context.findActivityOrNull(): Activity?(renamed, suffix matches return)View.findActivity(): Activity?(unchanged, no suffix despite nullable return)
Consider renaming
View.findActivity()→View.findActivityOrNull()for symmetry. Strictly cosmetic. -
DebugOverlay.openPanelhas the same pattern but wasn't updated —DebugOverlay.kt:146-150unconditionally addsFLAG_ACTIVITY_NEW_TASKwhen launchingDebugPanelActivity, which is also declared withdebugoverlay_Theme.Transparent(manifest:9). If MIUI's gate is what's blockingBugReportActivity, it could theoretically affectopenPanel(activity)calls from user code too. Out of scope for [BUG] Create Report button is unresponsive when a report already exists #251, but worth a tracking issue/follow-up PR — the symmetry argument is the same and the change would be identically harmless on other devices.public fun openPanel(context: Context) { val intent = Intent(context, DebugPanelActivity::class.java).apply { if (context.findActivityOrNull() == null) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } context.startActivity(intent) }
-
Test coverage — A small Robolectric unit test on
BugReportActivity.launchWithDraftPicker/launchWithMetadataDialogwould lock the behavior in, without needing a real Xiaomi device. Something like:@Test fun `launchWithDraftPicker omits NEW_TASK when called from Activity`() { val activity = Robolectric.buildActivity(DebugPanelActivity::class.java).get() BugReportActivity.launchWithDraftPicker(activity) val started = shadowOf(activity).nextStartedActivity assertThat(started.flags and Intent.FLAG_ACTIVITY_NEW_TASK).isEqualTo(0) } @Test fun `launchWithDraftPicker adds NEW_TASK when called from non-Activity context`() { val appContext = RuntimeEnvironment.getApplication() BugReportActivity.launchWithDraftPicker(appContext) val started = shadowOf(appContext).nextStartedActivity assertThat(started.flags and Intent.FLAG_ACTIVITY_NEW_TASK).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) }
This mirrors the existing
openPanel launches DebugPanelActivity with NEW_TASK flagtest atDebugOverlayTest.kt:142.
Things I checked but found no issue with
tailrecsafety: preserved — the recursive call is still in tail position (Contexts.kt:16).- Internal API churn:
Context.findActivity()isinternal; the only caller wasViews.kt, which was updated. No public‑API impact. - Coroutine lifecycle (
launchWithMetadataDialog): called insiderememberCoroutineScope().launch { … }with anisActiveguard atDebugPanelDialog.kt:172andBugReporterFab.kt:111, so the capturedcontextisn't used after the host is gone. No regression from omitting the flag. - Security: nothing changes the trust boundary. The intent target is still the same internal, non‑exported activity.
LGTM with the optional follow-ups above.
· bugfix/issue-251
Qodana for JVMIt seems all right 👌 No new problems were found according to the checks applied 💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
Pairs with the Context.findActivityOrNull rename in the parent commit so both extensions communicate their nullable return type consistently via the OrNull suffix. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary - Bump dependency coordinate examples in README from `2.6.0` to `2.6.1`. - Add CHANGELOG entry for v2.6.1 covering the speculative MIUI fix from #252; framed as exploratory since the symptom reported in #251 could not be reproduced on the maintainer's devices. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
It seems Xiaomi/MIUI could silently block startActivity calls that pair FLAG_ACTIVITY_NEW_TASK with a transparent destination via its pop-up window gate, causing the "Create Report" button in DebugPanelDialog to do nothing when a draft already exists (#251). The flag was added for the FAB's overlay (non-Activity) context and was applied indiscriminately to the in-Activity caller; now it is only added when the caller context does not unwrap to an Activity.
Not sure if this fixes the issue 100% as I don't own Xiaomi devices, but trying as this should be harmless for other devices.