-
Notifications
You must be signed in to change notification settings - Fork 78
Add invisible FragmentHostActivity to support custom HTML in-app messages on NativeActivity #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Release Core 7.3.0, HMS 1.5.0, Push Templates 1.4.0
Release corev7.3.1
Release 7.4.0
…to host the notification when the current activity isn't a FragmentActivity.
WalkthroughA new activity, Changes
Sequence Diagram(s)sequenceDiagram
participant AppActivity as App Activity
participant InAppController
participant FragmentHostActivity
AppActivity->>InAppController: showInApp(notification)
InAppController->>InAppController: requiresFragmentHost(type)?
alt Requires Fragment Host & Not in FragmentActivity
InAppController->>InAppController: Re-queue notification
InAppController->>FragmentHostActivity: launch(current)
Note right of FragmentHostActivity: Activity starts with no animation
FragmentHostActivity->>FragmentHostActivity: onCreate/onResume (set hosting)
FragmentHostActivity->>FragmentHostActivity: Register fragment lifecycle callbacks
else
InAppController->>AppActivity: Display notification
end
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
clevertap-core/src/main/AndroidManifest.xml (1)
18-23
: Consider adding configChanges attribute for consistency.The activity declaration looks good with appropriate security and launch mode settings. However, consider adding a
configChanges
attribute similar to other activities in the manifest to handle device configuration changes properly:<activity android:name="com.clevertap.android.sdk.FragmentHostActivity" android:theme="@style/CleverTapFragmentHostTheme" android:noHistory="true" android:launchMode="singleTop" + android:configChanges="keyboardHidden|orientation|screenSize" android:exported="false" />
This ensures the activity handles configuration changes gracefully without unnecessary recreation.
clevertap-core/src/main/java/com/clevertap/android/sdk/inapp/InAppController.java (1)
796-815
: Fragment host detection logic is well-implemented.The logic correctly detects when a fragment host is needed and launches
FragmentHostActivity
when the current activity isn't aFragmentActivity
. The approach of re-queuing the notification and deferring display is sound.However, consider adding error handling for the activity launch:
if (!FragmentHostActivity.isHosting()) { - FragmentHostActivity.launch(act); + try { + FragmentHostActivity.launch(act); + } catch (Exception e) { + logger.verbose(config.getAccountId(), + "Failed to launch FragmentHostActivity: " + e.getMessage()); + // Fallback: try to show notification anyway or skip + return; + } }clevertap-core/src/main/java/com/clevertap/android/sdk/FragmentHostActivity.java (1)
15-16
: Consider thread safety for the static hosting flag.The static
hosting
flag could have thread safety issues in concurrent scenarios. Consider usingAtomicBoolean
for better thread safety:-private static boolean hosting = false; -public static boolean isHosting() { return hosting; } +private static final AtomicBoolean hosting = new AtomicBoolean(false); +public static boolean isHosting() { return hosting.get(); }Then update the assignments to use
hosting.set(true)
andhosting.set(false)
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
clevertap-core/src/main/AndroidManifest.xml
(1 hunks)clevertap-core/src/main/java/com/clevertap/android/sdk/FragmentHostActivity.java
(1 hunks)clevertap-core/src/main/java/com/clevertap/android/sdk/inapp/InAppController.java
(3 hunks)clevertap-core/src/main/res/values/styles.xml
(1 hunks)
🔇 Additional comments (6)
clevertap-core/src/main/res/values/styles.xml (1)
3-8
: LGTM! Transparent theme configuration is correct.The theme configuration properly sets up a transparent, fullscreen overlay activity that will be invisible to users while hosting fragments. All attributes are standard and correctly configured for this use case.
clevertap-core/src/main/java/com/clevertap/android/sdk/inapp/InAppController.java (2)
27-27
: LGTM! Import added correctly.The import for
FragmentHostActivity
is properly placed and necessary for the new functionality.
897-908
: Helper method is well-designed and correctly implements type checking.The
requiresFragmentHost()
method correctly identifies the in-app notification types that require fragment hosting. The implementation matches the types handled in the switch statement below.clevertap-core/src/main/java/com/clevertap/android/sdk/FragmentHostActivity.java (3)
18-25
: Launch method implementation is correct.The static launch method properly creates an intent, adds the
FLAG_ACTIVITY_NEW_TASK
flag, and suppresses transitions. This approach is appropriate for launching a utility activity from any context.
27-33
: onCreate implementation looks good.The lifecycle management correctly sets the hosting flag and suppresses transitions. The activity doesn't set a content view, which is appropriate since it's meant to be invisible and only host fragments.
51-57
: onDestroy implementation is correct.The lifecycle cleanup properly resets the hosting flag and suppresses transitions. This ensures proper state management when the activity is destroyed.
clevertap-core/src/main/java/com/clevertap/android/sdk/inapp/InAppController.java
Outdated
Show resolved
Hide resolved
clevertap-core/src/main/java/com/clevertap/android/sdk/FragmentHostActivity.java
Outdated
Show resolved
Hide resolved
clevertap-core/src/main/java/com/clevertap/android/sdk/FragmentHostActivity.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simonbullen I think this is apply changes to all SDK flows. Consider putting behind a flag which can be provided to core-sdk from Unity (any other third party) and make it configurable?
it’s only activated when the current activity doesn’t support fragments. I don’t know why you’d want to fail to display some types of inapp notifications when fragments aren’t supported in the current activity.
When the current activity does support fragments (which is the recommended setup), this patch should have no effect.
That said, the UX of this patch isn’t great, as the underlying NativeActivity can’t be interacted with while the fragment host is active.
I'm hoping the Android team can find a better solution!
…________________________________
From: CTLalit ***@***.***>
Sent: Tuesday, May 27, 2025 5:17:02 PM
To: CleverTap/clevertap-android-sdk ***@***.***>
Cc: Simon Bullen ***@***.***>; Mention ***@***.***>
Subject: Re: [CleverTap/clevertap-android-sdk] Add invisible FragmentHostActivity to support custom HTML in-app messages on NativeActivity (PR #809)
@CTLalit requested changes on this pull request.
@simonbullen<https://github.com/simonbullen> I think this is apply changes to all SDK flows. Consider putting behind a flag which can be provided to core-sdk from Unity (any other third party) and make it configurable?
—
Reply to this email directly, view it on GitHub<#809 (review)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AWMZFBJ6FS6Q63P67CQNSML3AQGO5AVCNFSM6AAAAAB5XUMKGWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDQNRZHA4TKOBXGM>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@simonbullen makes sense, i saw the code of this patch working only when underlying infra does not support fragments (via instanceOf check). We have added this in our docs to use a specific type of activity; but thanks for providing this piece, we will consider getting it checked in after discussion with my team. |
This PR adds support for rendering CleverTap’s fragment-based in-app notifications (e.g. custom HTML) in Unreal Engine projects that use a NativeActivity, which does not support fragments.
Problem
CleverTap’s SDK assumes that the current activity is a FragmentActivity, but Unreal-based Android apps typically use NativeActivity. As a result, certain in-app notification types (notably HTML-based ones) fail to display or cause runtime exceptions.
Solution
Introduced a minimal FragmentHostActivity that subclasses AppCompatActivity and provides a safe fragment container.
Added logic to detect when the current activity is not a FragmentActivity, defer the notification, and launch FragmentHostActivity instead.
Once launched, the host activity proceeds with CleverTap’s regular rendering logic.
This approach isolates fragment-specific logic to a dedicated host, without modifying the behavior for apps already using FragmentActivity.
Summary by CodeRabbit
New Features
Bug Fixes