Skip to content

Conversation

@Jignesh-dimagi
Copy link
Contributor

Technical Summary

https://dimagi.atlassian.net/browse/QA-8230

CommCareActivity has handling for edge to edge issue, which might arise between Android versions greater and less than 15. PushNotificationActivity was showing correctly for Android 15+ but having this issue for <Android 15. So now PushNotificationActivity is extended from CommCareActivity. As PushNotification is extended from CommCareActivity, changes have been made to show the blocking loading await popup also whenever API is being called.

Labels and Review

  • Do we need to enhance the manual QA test coverage ? If yes, the "QA Note" label is set correctly
  • Does the PR introduce any major changes worth communicating ? If yes, the "Release Note" label is set and a "Release Note" is specified in PR description.
  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@coderabbitai
Copy link

coderabbitai bot commented Nov 14, 2025

📝 Walkthrough

Walkthrough

The PR refactors the push notification activity architecture by migrating PushNotificationActivity from AppCompatActivity to CommCareActivity base class, implementing progress dialog handling through the parent framework. All loadNotifications calls in the ViewModel are updated to accept an additional Context parameter, and DB/API operations now use the provided context instead of getApplication(). The notification broadcast receiver registration is reformatted with multiline syntax. The immediate onNewNotification() callback previously triggered on activity resume is removed, and padding/margin constraints are removed from the notification list RecyclerView layout.

Sequence Diagram

sequenceDiagram
    participant Activity as PushNotificationActivity
    participant VM as PushNotificationViewModel
    participant DB as Database/API

    Note over Activity,DB: Before: AppCompatActivity, context via getApplication()
    Activity->>VM: loadNotifications(isRefreshed)
    VM->>DB: Access via getApplication()
    
    Note over Activity,DB: After: CommCareActivity, context passed explicitly
    Activity->>VM: loadNotifications(isRefreshed, context)
    VM->>DB: Access via provided context
    Activity->>Activity: generateProgressDialog(taskId)
    
    Note over Activity: onResume: No immediate callback
    Note over Activity: onPause: Broadcast receiver unregistered
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Base class migration from AppCompatActivity to CommCareActivity<PushNotificationActivity> requires verification of compatibility and inherited functionality
  • loadNotifications signature change propagates across multiple call sites; verify all callers pass context correctly
  • Progress dialog override implementation and its interaction with CommCareActivity lifecycle
  • Behavioral change: removed onNewNotification() invocation from onResume requires testing to ensure notifications still trigger appropriately
  • RecyclerView padding/margin removal may affect UI spacing; verify layout appearance on multiple screen sizes

Possibly related PRs

Suggested labels

QA Note

Suggested reviewers

  • OrangeAndGreen
  • avazirna
  • shubham1g5

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: fixing Android 15 edge-to-edge issues and adding a blocking loading UI, which aligns with the primary objectives in the changeset.
Description check ✅ Passed The PR description includes the technical summary with a ticket reference, rationale for the change, and design decisions. However, several template sections are incomplete: Product Description is missing, Safety Assurance details are absent, Automated test coverage is not addressed, and QA Plan is not provided.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jignesh/fix/qa-8230

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/src/org/commcare/activities/PushNotificationActivity.kt (1)

123-123: Use named parameter for consistency.

Line 123 uses a positional argument while lines 34 and 111 use the named parameter isRefreshed =. For consistency and readability, use the named parameter here as well.

Apply this diff:

-            pushNotificationViewModel.loadNotifications(false, this)
+            pushNotificationViewModel.loadNotifications(isRefreshed = false, this)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d43bdd0 and dd86248.

📒 Files selected for processing (4)
  • app/res/layout/activity_push_notification.xml (0 hunks)
  • app/src/org/commcare/activities/PushNotificationActivity.kt (4 hunks)
  • app/src/org/commcare/activities/connect/viewmodel/PushNotificationViewModel.kt (3 hunks)
  • app/src/org/commcare/pn/helper/NotificationBroadcastHelper.kt (1 hunks)
💤 Files with no reviewable changes (1)
  • app/res/layout/activity_push_notification.xml
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: shubham1g5
Repo: dimagi/commcare-android PR: 0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.
📚 Learning: 2025-04-21T15:02:17.492Z
Learnt from: shubham1g5
Repo: dimagi/commcare-android PR: 3042
File: app/src/org/commcare/fragments/BreadcrumbBarViewModel.java:50-55
Timestamp: 2025-04-21T15:02:17.492Z
Learning: ViewModels should not store View or Activity references as this can cause memory leaks. Unlike Fragments with setRetainInstance(true), ViewModels don't have automatic view detachment mechanisms. When migrating from Fragments to ViewModels, view references should be replaced with data-only state in the ViewModel.

Applied to files:

  • app/src/org/commcare/activities/connect/viewmodel/PushNotificationViewModel.kt
📚 Learning: 2025-05-08T11:08:18.530Z
Learnt from: shubham1g5
Repo: dimagi/commcare-android PR: 0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.

Applied to files:

  • app/src/org/commcare/activities/PushNotificationActivity.kt
🧬 Code graph analysis (1)
app/src/org/commcare/activities/connect/viewmodel/PushNotificationViewModel.kt (1)
app/src/org/commcare/utils/PushNotificationApiHelper.kt (1)
  • retrieveLatestPushNotifications (62-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint Code Base
🔇 Additional comments (5)
app/src/org/commcare/pn/helper/NotificationBroadcastHelper.kt (1)

10-41: LGTM! Formatting improvements follow Kotlin conventions.

The multiline formatting with trailing commas improves readability and follows Kotlin best practices. The lifecycle management with receiver registration/unregistration remains correct.

app/src/org/commcare/activities/connect/viewmodel/PushNotificationViewModel.kt (2)

17-19: LGTM! Constructor formatting improved.

The multiline formatting enhances readability without changing behavior.


30-68: No action required—code is correct.

The NotificationsSyncWorkerManager has a secondary constructor (line 145–152) that accepts (Context, List<PushNotificationRecord>?, Boolean, Boolean?). The call at line 54 passes application (a Context subclass), the API response list, and false—matching the signature exactly. Using Application instead of the activity context is intentional and correct for WorkManager to avoid context leaks.

app/src/org/commcare/activities/PushNotificationActivity.kt (2)

21-21: LGTM! Inheritance change addresses Android 15 edge-to-edge issue.

Migrating from AppCompatActivity to CommCareActivity enables reuse of the edge-to-edge handling logic, addressing the primary PR objective.


127-128: Progress dialog implementation verified and properly integrated.

The generateProgressDialog override is correctly wired into the CommCareActivity dialog lifecycle. When BaseApi initiates network calls, it invokes showProgressDialog(NETWORK_ACTIVITY_ID), which calls your override to create the CustomProgressDialog with the taskId, then displays it via showNow(). Upon completion, BaseApi calls dismissProgressDialogForTask(NETWORK_ACTIVITY_ID), which retrieves the dialog by taskId and dismisses it. The dialog lifecycle is properly managed and blocking as intended.

Copy link
Contributor

@OrangeAndGreen OrangeAndGreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple nits and one thing to verify but otherwise looks good to me

observeRetrieveNotificationApi()
registerForNewNotification()
pushNotificationViewModel.loadNotifications(isRefreshed = false)
pushNotificationViewModel.loadNotifications(isRefreshed = false, this)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Having an unlabeled input after a labeled one feels odd to me, thinking maybe better to remove the label here? So it looks like line 123


R.id.notification_cloud_sync -> {
pushNotificationViewModel.loadNotifications(isRefreshed = true)
pushNotificationViewModel.loadNotifications(isRefreshed = true, this)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: same as above

owner.lifecycle.addObserver(
object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
manager.registerReceiver(receiver, IntentFilter(ACTION_NEW_NOTIFICATIONS))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see onNewNotification was removed here, just making sure that was intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it was intentional. Whenever any activity register for new notification broadcast, it was calling onNewNotification even though there were no new notifications.

@Jignesh-dimagi Jignesh-dimagi merged commit 471aa37 into master Nov 14, 2025
8 checks passed
@Jignesh-dimagi Jignesh-dimagi deleted the jignesh/fix/qa-8230 branch November 14, 2025 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-integration-tests Skip android tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants