Skip to content

feat: [SDK-5382] enqueue a session create when a new session starts - #2780

Closed
fadi-george wants to merge 22 commits into
fadi/sdk-5378from
fadi/sdk-5382
Closed

fadi-george wants to merge 22 commits into
fadi/sdk-5378from
fadi/sdk-5382

Conversation

@fadi-george

@fadi-george fadi-george commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

One Line Summary

When the sessions API flag is on, enqueue a CreateSessionOperation when a new session starts.

Details

Motivation

Part of the SDK Sessions stack (SDK-5382). New sessions need a POST /apps/{app_id}/sessions, sent through the persistent queue added in #2794 (base of this one).

Scope

  • SessionService enqueues one CreateSessionOperation on the new-session path when the session's captured usesSessionsApi is true. It carries the app ID, the session's local ID, the pinned OneSignal and push subscription IDs, start_time, and a new idempotency key.
  • Enqueued on SerialIO where the session is set up, so there is exactly one create per session, consistent with the pinned IDs.
  • Resuming within sessionFocusTimeout (30 s) continues the session and sends no create. Cold start still ends a persisted valid session before starting a new one.
  • Skipped with a warning if the pinned OneSignal ID or subscription ID is missing.
  • Flag off: nothing new is sent. The legacy TrackSessionStartOperation is unchanged in both cases; turning off legacy reporting is SDK-5388.
  • Not included: direct_attribution_id (SDK-5399), session end (SDK-5390).

Testing

Unit testing

Added SessionServiceTests cases: create fields when the flag is on, a new create and idempotency key per session, no create on resume within the timeout, cold start with a persisted valid session, no create when the flag is off, and no create without a push subscription ID.

spotlessCheck, detekt, testDebugUnitTest, and assembleRelease pass locally.

Manual testing

Not tested on device yet; end-to-end verification is planned in the Android Rollout & QA ticket (SDK-5405).

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

🤖 Generated with Claude Code

…is missing (#2759)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fadi-george
fadi-george requested a review from a team as a code owner October 9, 2026 21:41
@fadi-george
fadi-george added this pull request to stack #2776 October 9, 2026 21:42
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

📊 Diff Coverage Report

Diff Coverage Report (Changed Lines Only)

Gate: aggregate coverage on changed executable lines must be ≥ 80% (JaCoCo line data for lines touched in the diff).

Changed Files Coverage

  • SessionService.kt: 18/18 touched executable lines (100.0%) (26 touched lines in diff)

Overall (aggregate gate)

18/18 touched executable lines covered (100.0% — requires ≥ 80%)

📥 View workflow run

…alidator (#2778)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@abdulraqeeb33 abdulraqeeb33 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Requesting changes.

A create is dropped when appId, onesignalId, or subscriptionId is null, and this only runs at session start. The subscription id is copied once there. A first launch usually focuses before the push subscription id exists, so that session is never created and nothing retries when the id arrives.

iOS #1770 enqueues and lets the executor hold until the ids exist. Enqueue here too, or retry when pushSubscriptionId is set. The tests currently assert the drop.

val appId = config?.appId
val onesignalId = session.onesignalId
val subscriptionId = session.subscriptionId
if (appId == null || onesignalId == null || subscriptionId == null) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This returns without enqueueing. The subscription id is often still null on the first focus, and nothing calls this again when it arrives, so the session never reaches the server. Hold the create until the ids exist, the way iOS #1770 does.

abdulraqeeb33 and others added 2 commits October 13, 2026 00:51
…te User POST (#2743)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…notification prompt (#2779)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
abdulraqeeb33 and others added 17 commits October 15, 2026 00:28
Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…2790)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…2791)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/time/ITime.kt
#	OneSignalSDK/onesignal/testhelpers/src/main/java/com/onesignal/mocks/MockHelper.kt
…rowing (#2788)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ntries (#2796)

Co-authored-by: AR Abdul Azeez <abdul@onesignal.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
… token API is disabled (#2789)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Fadi George <fadi-george@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he SDK (#2795)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ationRepo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eue rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the session uses the sessions API, enqueue a CreateSessionOperation
with the start time and pinned IDs. Continuing within the session timeout
sends none, and the legacy start path is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y on session create

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fadi-george

Copy link
Copy Markdown
Contributor Author

Replaced by a PR against fadi/SDK-5378-android-persistent-queue-retry, since this one can't be retargeted out of its stack.

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.

2 participants