Skip to content

feat: [SDK-5399] attribute a session started by a notification open - #2783

Open
fadi-george wants to merge 1 commit into
new-session-eventsfrom
fadi/SDK-5399-android-notification-attribution
Open

fadi-george wants to merge 1 commit into
new-session-eventsfrom
fadi/SDK-5399-android-notification-attribution

Conversation

@fadi-george

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

Copy link
Copy Markdown
Contributor

Description

One Line Summary

Send direct_attribution_id on the session create when a notification open starts a new session.

Details

Motivation

The sessions API attributes a session to the notification that started it. The notification open was only reaching the influence manager, so the create never carried it.

Scope

  • CreateSessionOperation carries directAttributionId again, and the executor passes it to CreateSessionRequest (the backend client already sends direct_attribution_id).
  • InfluenceManager.onDirectInfluenceFromNotification (only called for opens from the background) forwards the notification ID to ISessionService.attributeNextSessionTo.
  • SessionService.onFocus takes the pending ID on the calling thread and keeps it only if entryState is still NOTIFICATION_CLICK. It's then used only on the new-session path.
  • Ordering: the notification module sets the entry state and influence before launching the host activity, so both are set before onFocus fires. Entry state is read in onFocus instead of on the serial IO lane because an unfocus can reset it before the lane runs.
  • Every focus consumes the pending ID. An open that never focuses the app (for example, a URL notification) isn't credited to a later normal open.
  • An open during a still-valid session doesn't change the session and isn't carried over to the next one.
  • Legacy path unchanged: the create is only sent when the session uses the sessions API.

Testing

Unit testing

  • SessionServiceTests: notification open starting a new session sets the ID; open during an active session leaves the session alone and doesn't attribute the next one; a pending open followed by a normal focus is omitted.
  • InfluenceManagerTests: direct notification influence forwards the ID to the session service.
  • SessionOperationExecutorTests: the create request includes the direct attribution ID.
  • ./gradlew testDebugUnitTest spotlessCheck detekt pass.

Manual testing

Not tested on a device yet.

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

@fadi-george
fadi-george requested a review from a team as a code owner October 9, 2026 23:45
@fadi-george
fadi-george added this pull request to stack #2776 October 9, 2026 23:46
@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

  • InfluenceManager.kt: 1/1 touched executable lines (100.0%) (1 touched lines in diff)
  • SessionService.kt: 11/11 touched executable lines (100.0%) (20 touched lines in diff)
  • CreateSessionOperation.kt: 5/5 touched executable lines (100.0%) (9 touched lines in diff)
  • SessionOperationExecutor.kt: 1/1 touched executable lines (100.0%) (1 touched lines in diff)

Overall (aggregate gate)

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

📥 View workflow run

@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.

Approving.

The pending id is taken on the caller thread, kept only while entry state is still a notification click, and attached only when that focus starts a new session. An open during a session that is still valid does not carry to the next one.

@fadi-george
fadi-george removed this pull request from stack #2776 October 16, 2026 00:26
@fadi-george
fadi-george added this pull request to stack #2798 October 16, 2026 00:29
Base automatically changed from fadi/SDK-5396-android-heartbeat to new-session-events October 29, 2026 00:48
…o that notification

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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