Skip to content

[fix] drop FLAG_ACTIVITY_NEW_TASK when launching BugReportActivity from an Activity context#252

Merged
Manabu-GT merged 2 commits into
mainfrom
bugfix/issue-251
May 21, 2026
Merged

[fix] drop FLAG_ACTIVITY_NEW_TASK when launching BugReportActivity from an Activity context#252
Manabu-GT merged 2 commits into
mainfrom
bugfix/issue-251

Conversation

@Manabu-GT

@Manabu-GT Manabu-GT commented May 21, 2026

Copy link
Copy Markdown
Owner

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.

…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>
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds 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.

Changes

Safe Activity Resolution in Launches

Layer / File(s) Summary
Safe Activity resolution utility
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/util/Contexts.kt
Introduces Context.findActivityOrNull() as a tail-recursive extension that traverses ContextWrapper chains and returns the Activity if found, or null otherwise.
View activity lookup integration
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/util/Views.kt
Replaces the previous View.findActivity() with findActivityOrNull() usage, keeping callback-first checks and using context.findActivityOrNull() as the nullable fallback.
Overlay window activity checks
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/OverlayViewManager.kt
Switches OverlayViewManager checks to use findActivityOrNull() when excluding DebugOverlay activities (isDebugOverlayActivity()) and when comparing current target activity.
Conditional activity launch flags
debugoverlay-core/src/main/kotlin/com/ms/square/debugoverlay/internal/bugreport/ui/BugReportActivity.kt
Modifies launchWithDraftPicker() and launchWithMetadataDialog() to add Intent.FLAG_ACTIVITY_NEW_TASK only when context.findActivityOrNull() returns null.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Manabu-GT/DebugOverlay-Android#119: Earlier context-to-activity unwrapping refactor in Contexts.kt and Views.kt that this PR extends with the new nullable variant.
  • Manabu-GT/DebugOverlay-Android#114: Introduced the launchWithDraftPicker and launchWithMetadataDialog launch helpers that this PR now refines with conditional intent flag application.
  • Manabu-GT/DebugOverlay-Android#147: Related changes to OverlayViewManager target-window selection and DebugOverlay activity exclusions that overlap with the nullable lookup updates.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: conditionally applying FLAG_ACTIVITY_NEW_TASK only when the context is not already associated with an Activity, which is the core fix addressing the Xiaomi/MIUI blocking issue.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/issue-251

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented May 21, 2026

Copy link
Copy Markdown

Claude finished @Manabu-GT's task in 3m 51s —— View job


PR Review — drop FLAG_ACTIVITY_NEW_TASK when launched from an Activity

  • Read PR diff and changed files
  • Analyze the fix logic
  • Review for bugs, edge cases, and side-effects
  • Post review feedback

Summary

The fix is sound, minimal, and harmless on non-affected devices. The premise matches both Android best practice (FLAG_ACTIVITY_NEW_TASK is only required when launching from a non‑Activity Context) and the AndroidManifest reality (BugReportActivity is declared with debugoverlay_Theme.Transparent, which is exactly the kind of destination that MIUI's pop‑up window gate intercepts when paired with NEW_TASK). Renaming Context.findActivity() to findActivityOrNull() is also a nice Kotlin‑idiomatic cleanup — it lets Views.kt drop the runCatching { … }.getOrNull() wrapper while preserving the exact same null‑on‑miss semantics.

I traced every call path and the behavior matches the intent:

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

  1. 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.

  2. DebugOverlay.openPanel has the same pattern but wasn't updatedDebugOverlay.kt:146-150 unconditionally adds FLAG_ACTIVITY_NEW_TASK when launching DebugPanelActivity, which is also declared with debugoverlay_Theme.Transparent (manifest:9). If MIUI's gate is what's blocking BugReportActivity, it could theoretically affect openPanel(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)
    }

    Apply the same fix to openPanel →

  3. Test coverage — A small Robolectric unit test on BugReportActivity.launchWithDraftPicker / launchWithMetadataDialog would 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 flag test at DebugOverlayTest.kt:142.


Things I checked but found no issue with

  • tailrec safety: preserved — the recursive call is still in tail position (Contexts.kt:16).
  • Internal API churn: Context.findActivity() is internal; the only caller was Views.kt, which was updated. No public‑API impact.
  • Coroutine lifecycle (launchWithMetadataDialog): called inside rememberCoroutineScope().launch { … } with an isActive guard at DebugPanelDialog.kt:172 and BugReporterFab.kt:111, so the captured context isn'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

@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown

Qodana for JVM

It 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
☁️ View the detailed Qodana report

Contact Qodana team

Contact 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>
@Manabu-GT Manabu-GT self-assigned this May 21, 2026
@Manabu-GT Manabu-GT merged commit 05f5f52 into main May 21, 2026
5 checks passed
@Manabu-GT Manabu-GT mentioned this pull request May 22, 2026
2 tasks
Manabu-GT added a commit that referenced this pull request May 22, 2026
## 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant