Skip to content

Use payload transport to dispatch voip notifications to android#162

Open
enahum wants to merge 1 commit into
masterfrom
android-ring
Open

Use payload transport to dispatch voip notifications to android#162
enahum wants to merge 1 commit into
masterfrom
android-ring

Conversation

@enahum

@enahum enahum commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

this PR adds feature parity in order to receive calls on Android as we implemented for iOS

Ticket Link

TDB.

@enahum
enahum requested a review from lieut-data June 11, 2026 02:17
@enahum enahum added the 1: Dev Review Requires review by a core commiter label Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors Android notification transport handling by extracting a new buildAndroidMessage helper that resolves the push transport (with standard as default) and applies VoIP-specific FCM configuration. The SendNotification function now uses this helper and records all metrics with the resolved transport label, replacing hard-coded standard transport assumptions.

Changes

Android notification transport-aware refactoring

Layer / File(s) Summary
buildAndroidMessage helper and transport resolution
server/android_notification_server.go
New buildAndroidMessage helper resolves transport from msg.Transport with PushTransportStandard as default, and applies Android-specific VoIP config including voip dispatch flag and 30-second TTL override.
SendNotification integration and transport-aware metrics
server/android_notification_server.go
SendNotification calls buildAndroidMessage, then uses the resolved transport label for incrementNotificationTotal, unregistered device removal, and success/failure metric recording instead of always using standard transport.
Transport routing test coverage
server/android_notification_test.go
New TestBuildAndroidMessageTransportRouting validates that VoIP transport sets voip flag, calls sub_type, and 30-second TTL, while standard transport omits these overrides.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 clearly summarizes the main change: using payload transport to dispatch VoIP notifications to Android, which aligns with the refactoring of SendNotification and buildAndroidMessage helper.
Description check ✅ Passed The description is related to the changeset, mentioning adding feature parity for receiving calls on Android similar to iOS implementation, which matches the transport-based VoIP notification dispatch changes.
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.

✏️ 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 android-ring

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
server/android_notification_test.go (1)

86-119: ⚡ Quick win

Add one regression case for unsupported transport coercion.

Please add a case with Transport: "unexpected" and assert resolved transport is PushTransportStandard, no voip flag, and no TTL override. That locks in bounded-label behavior.

Suggested test addition
 func TestBuildAndroidMessageTransportRouting(t *testing.T) {
@@
 	t.Run("standard transport has no voip flag and no TTL override", func(t *testing.T) {
@@
 		require.Nil(t, fcmMsg.Android.TTL)
 	})
+
+	t.Run("unsupported transport is coerced to standard", func(t *testing.T) {
+		msg := &PushNotification{
+			DeviceID:  "tok",
+			Type:      PushTypeMessage,
+			Transport: "unexpected",
+		}
+		fcmMsg, transport := buildAndroidMessage(msg)
+
+		require.Equal(t, PushTransportStandard, transport)
+		_, hasVoIP := fcmMsg.Data["voip"]
+		require.False(t, hasVoIP)
+		require.Nil(t, fcmMsg.Android.TTL)
+	})
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/android_notification_test.go` around lines 86 - 119, Add a regression
subtest in TestBuildAndroidMessageTransportRouting that constructs a
PushNotification with Transport set to the unexpected string "unexpected", call
buildAndroidMessage(msg) and assert the returned transport equals
PushTransportStandard, that fcmMsg.Data does not contain the "voip" key, and
that fcmMsg.Android.TTL is nil; reference symbols:
TestBuildAndroidMessageTransportRouting, PushNotification, buildAndroidMessage,
PushTransportStandard, and fcmMsg.Android.TTL to locate where to add the case.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/android_notification_server.go`:
- Around line 120-123: The current code assigns transport := msg.Transport and
only defaults empty strings, which lets arbitrary values flow downstream; update
the normalization so that after reading msg.Transport you explicitly map allowed
values to the bounded set (e.g., if msg.Transport == PushTransportVoIP then
transport = PushTransportVoIP else transport = PushTransportStandard), treating
any other non-empty/unrecognized string as PushTransportStandard; ensure this
normalized transport variable (used later for Prometheus labels) is what is
returned/used by the relevant handler functions.

---

Nitpick comments:
In `@server/android_notification_test.go`:
- Around line 86-119: Add a regression subtest in
TestBuildAndroidMessageTransportRouting that constructs a PushNotification with
Transport set to the unexpected string "unexpected", call
buildAndroidMessage(msg) and assert the returned transport equals
PushTransportStandard, that fcmMsg.Data does not contain the "voip" key, and
that fcmMsg.Android.TTL is nil; reference symbols:
TestBuildAndroidMessageTransportRouting, PushNotification, buildAndroidMessage,
PushTransportStandard, and fcmMsg.Android.TTL to locate where to add the case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 85a7f796-19df-438f-9400-ee6bc0997871

📥 Commits

Reviewing files that changed from the base of the PR and between c92bd00 and 777fe45.

📒 Files selected for processing (2)
  • server/android_notification_server.go
  • server/android_notification_test.go

Comment on lines +120 to +123
transport := msg.Transport
if transport == "" {
transport = PushTransportStandard
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize unsupported transport values before returning transport.

Line [120] through Line [123] currently forwards any non-empty msg.Transport downstream. That value is later used as a Prometheus transport label (Line [195], Line [226], Line [248], Line [256], Line [258]), which can explode metric cardinality if unexpected values arrive. Coerce to a bounded set (PushTransportStandard / PushTransportVoIP) before returning.

Suggested fix
-	transport := msg.Transport
-	if transport == "" {
-		transport = PushTransportStandard
-	}
+	transport := PushTransportStandard
+	if msg.Transport == PushTransportVoIP {
+		transport = PushTransportVoIP
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transport := msg.Transport
if transport == "" {
transport = PushTransportStandard
}
transport := PushTransportStandard
if msg.Transport == PushTransportVoIP {
transport = PushTransportVoIP
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/android_notification_server.go` around lines 120 - 123, The current
code assigns transport := msg.Transport and only defaults empty strings, which
lets arbitrary values flow downstream; update the normalization so that after
reading msg.Transport you explicitly map allowed values to the bounded set
(e.g., if msg.Transport == PushTransportVoIP then transport = PushTransportVoIP
else transport = PushTransportStandard), treating any other
non-empty/unrecognized string as PushTransportStandard; ensure this normalized
transport variable (used later for Prometheus labels) is what is returned/used
by the relevant handler functions.

@lieut-data lieut-data left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, but agree with CodeRabbit's feedback that we should guard against arbitrary transport values when logging the metric (map these to "unknown" instead).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1: Dev Review Requires review by a core commiter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants