Skip to content

[EXTERNAL] fix: ensure activity is attached before showing in-app messages (#3274) contributed by @matteinn#3275

Merged
tonidero merged 1 commit into
mainfrom
external/matteinn/fix/#3273-showinappmessagesifneeded-crash
Mar 25, 2026
Merged

[EXTERNAL] fix: ensure activity is attached before showing in-app messages (#3274) contributed by @matteinn#3275
tonidero merged 1 commit into
mainfrom
external/matteinn/fix/#3273-showinappmessagesifneeded-crash

Conversation

@tonidero

@tonidero tonidero commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Checklist

  • If applicable, unit tests
  • If applicable, create follow-up issues for purchases-ios and hybrids

Motivation

This PR adds an additional safety check in BillingWrapper.showInAppMessagesIfNeeded to ensure the activity is fully attached to a window before attempting to show Google Play in-app messages, preventing crashes.

Resolves #3273.

Description

While isFinishing and isDestroyed are already checked, NullPointerException crashes can still happen while accessing a window token from a null or detached view.
Using peekDecorView().windowToken safely ensures the activity has a decor view and is attached without accidentally triggering view creation.

contributed by @matteinn in #3274


Note

Low Risk
Low risk guard change that only adds an extra precondition before invoking Google Play Billing in-app messages; main impact is potentially skipping message display in edge lifecycle states to avoid crashes.

Overview
Prevents crashes when showing Google Play in-app messages by adding an additional lifecycle safety check in BillingWrapper.showInAppMessagesIfNeeded: it now verifies the Activity is attached to a window via activity.window?.peekDecorView()?.windowToken before calling showInAppMessages.

Updates BillingWrapperTest to use a reusable mockAttachedActivity() helper and adds coverage to ensure in-app messages are not shown when the window, decor view, or window token are missing.

Written by Cursor Bugbot for commit d3a5a90. This will update automatically on new commits. Configure here.

<!-- Thank you for contributing to Purchases! Before pressing the
"Create Pull Request" button, please provide the following: -->

### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

### Motivation
This PR adds an additional safety check in
BillingWrapper.showInAppMessagesIfNeeded to ensure the activity is fully
attached to a window before attempting to show Google Play in-app
messages, preventing crashes.

Resolves #3273.

### Description
While `isFinishing` and `isDestroyed` are already checked,
`NullPointerException` crashes can still happen while accessing a window
token from a null or detached view.
Using `peekDecorView().windowToken` safely ensures the activity has a
decor view and is attached [without accidentally triggering view
creation](https://developer.android.com/reference/android/view/Window#peekDecorView()).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: adds an extra null/attachment guard before calling Google
Play in-app messaging, reducing crash risk with minimal behavior change
(messages may be skipped in more edge cases).
> 
> **Overview**
> Prevents potential crashes when showing Google Play in-app messages by
adding a new guard in `BillingWrapper.showInAppMessagesIfNeeded` to
ensure the `Activity` is actually attached to a window
(`window.peekDecorView().windowToken` present) before calling
`showInAppMessages`.
> 
> Updates tests to use a helper for an attached `Activity` and adds
coverage for the new early-return cases when `window`, decor view, or
`windowToken` is missing.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
af9df05. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@tonidero tonidero requested a review from a team as a code owner March 25, 2026 14:53
@tonidero tonidero added the pr:fix A bug fix label Mar 25, 2026
@tonidero tonidero enabled auto-merge March 25, 2026 14:59
@tonidero tonidero added this pull request to the merge queue Mar 25, 2026
@codecov

codecov Bot commented Mar 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.38%. Comparing base (c6f7c10) to head (d3a5a90).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3275   +/-   ##
=======================================
  Coverage   79.38%   79.38%           
=======================================
  Files         357      357           
  Lines       14347    14349    +2     
  Branches     1959     1960    +1     
=======================================
+ Hits        11389    11391    +2     
  Misses       2154     2154           
  Partials      804      804           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Merged via the queue into main with commit 62e0a80 Mar 25, 2026
36 checks passed
@tonidero tonidero deleted the external/matteinn/fix/#3273-showinappmessagesifneeded-crash branch March 25, 2026 15:31
github-merge-queue Bot pushed a commit that referenced this pull request Mar 26, 2026
**This is an automatic release.**

## RevenueCat SDK
### 🐞 Bugfixes
* [EXTERNAL] fix: ensure activity is attached before showing in-app
messages (#3274) contributed by @matteinn (#3275) via Toni Rico
(@tonidero)
* Ensure MediaPlayer has dedicated thread owner that is not the main
thread (#3148) via Jacob Rakidzich (@JZDesign)
* Fix heartbeat monitor and Slack notifications for nightly integration
tests (#3259) via Rick (@rickvdl)

## RevenueCatUI SDK
### Paywallv2
#### ✨ New Features
* Feat: Restore gating in paywalls UI (#3171) via Jacob Rakidzich
(@JZDesign)

### 🔄 Other Changes
* security: pin GitHub Actions to SHA hashes (#3272) via Alfonso
Embid-Desmet (@alfondotnet)
* Bump activesupport from 8.0.2 to 8.0.4.1 (#3270) via dependabot[bot]
(@dependabot[bot])
* Merge release PR after deploy (#3269) via Antonio Pallares
(@ajpallares)
* Require PR approval before release tagging (#3268) via Antonio
Pallares (@ajpallares)
* Bump json from 2.18.1 to 2.19.2 (#3261) via dependabot[bot]
(@dependabot[bot])
* feat(ads): update admob sample app (#3264) via Peter Porfy
(@peterporfy)
* feat(ads): add vanilla-ad-tracker-sample (#3263) via Peter Porfy
(@peterporfy)
* [Purchase Tester]: Persist appUserId on login screen across app
launches (#3266) via Will Taylor (@fire-at-will)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Mostly release automation and versioning changes, but it modifies
CI/orb references and deploy/merge automation, which could affect the
release pipeline if misconfigured.
> 
> **Overview**
> Cuts the `9.28.0` release by removing `-SNAPSHOT` across version
sources (`.version`, `gradle.properties`, `Config.frameworkVersion`) and
updating sample/test-app dependency pins to `9.28.0`.
> 
> Updates release documentation: publishes Dokka docs to the `9.28.0` S3
path, updates `docs/index.html` redirect to `9.28.0`, and rolls
`CHANGELOG.latest.md` into a new `9.28.0` section in `CHANGELOG.md`.
> 
> Tweaks release tooling/CI: pins `fastlane-plugin-revenuecat_internal`
to a specific git ref (and bumps a few Ruby deps), switches the CircleCI
`revenuecat/sdks-common-config` orb to a dev commit, and adds a
temporary `test_merge_queue` workflow to exercise
`revenuecat/merge-release-pr` with `use_merge_queue: true`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5050888. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NPE BillingWrapper$showInAppMessagesIfNeeded$2$2.invoke

4 participants