Hotfix 24.2.1: cherry-pick onboarding telemetry (#3088, #3111, #3117), Fixes AB#3462876#3119
Merged
wzhipan merged 4 commits intoMay 16, 2026
Conversation
… store for mobile onboarding flow, Fixes AB#3462876 (#3088) Adds shared Android infrastructure for tracking mobile onboarding telemetry — the E2E flow where users hit Conditional Access (CA) blocking errors (broker install, MDM enrollment, device registration) and must remediate before completing sign-in. Consumed by both OneAuth (non-brokered flows) and broker (brokered flows) to construct a JSON telemetry blob emitted through MATS. Linked Feature: [AB#3462876](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3462876) Linked PBI: [AB#3568356](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3568356) - JSON field key constants for the onboarding blob — all snake_case matching MATS convention (EntityStore prepends `mo_` to produce final MATS columns, e.g. `blocking_errors` → `mo_blocking_errors`) - Step ID constants (`AuthenticationStarted`, `BrokerInstallPrompted`, `DeviceRegistrationStarted`, etc.) - Blocking error value constants (`BROKER_INSTALLATION_TRIGGERED`, `MDM_FLOW`) — must match C++ hardcoded strings in OneAuth''s `InteractiveRequest.cpp` - Records steps, blocking errors, and domain tracking during interactive auth flows - Constructs the blob from a seed JSON provided by C++ xplat core - `addStep(stepId)` captures the current ISO-8601 timestamp internally — callers no longer pass a timestamp - `finalizeBlob()` returns populated JSON only if blocking errors were recorded AND `sessionCorrelationId` is non-empty (empty string otherwise); logs at verbose/warn/error level for diagnostics - Persists `sessionCorrelationId` to SharedPreferences on block detection for app-kill resilience - SharedPreferences-backed persistence for session correlation IDs (per-app sandbox; same schema/file name across apps for consistency) - Used by OneAuth''s Djinni `SessionCachePersistence` adapter (JNI bridge to C++ `SessionCorrelationIdCache`) - **Kotlin**: Implemented in Kotlin, consistent with recent additions to Common (e.g. `BrowserRedirectValidator`, `DeviceRegistrationClientApplication`). Public surface remains JVM-compatible for Java callers. - **Snake_case blob keys**: All internal JSON keys use snake_case (`session_correlation_id`, `blocking_errors`, etc.) so EntityStore can use simple `"mo_" + key` concatenation for MATS columns — no mapping table needed, follows established MATS convention - **Recorder, not builder**: The class records events incrementally during WebView navigation with mid-flow side effects (SharedPreferences persistence), so it''s named `OnboardingTelemetryRecorder` rather than following the builder pattern - **No `remediationNeeded` field**: Redundant — implied by the presence of `blocking_errors` - **`apply()` over `commit()` for persistence**: Telemetry tolerates rare loss; blocking errors leave the app alive for seconds-to-minutes of user remediation, so the async flush window is far longer than typical loss. Avoids main-thread disk I/O. - 20 Common Android/Robolectric unit tests pass (recorder + store) - OneAuth C++ unit tests pass (794 tests, 0 failures) including 41 new onboarding-specific tests - E2E tested with OneAuthTestApp: CA-blocked user triggers `BROKER_INSTALLATION_TRIGGERED`, blob emitted with correct fields and `sessionCorrelationId` - Renamed `OnboardingBlobFieldKeys` → `OnboardingTelemetryConstants` - Renamed `OnboardingSessionCachePersistence` → `OnboardingSessionCorrelationStore` - `addStep()` now captures timestamp internally (single-arg signature) - Added Logger calls in `finalizeBlob()` (verbose/error), seed-parse `init` catch (warn), and `persistSessionCorrelation()` catch (warn) - `finalizeBlob()` now early-returns with a warn log if `sessionCorrelationId` is empty (avoids emitting uncorrelatable telemetry) - Replaced `java.time.Instant` with `SimpleDateFormat` (desugaring disabled, minSdk 24) - Extracted `FIELD_ID` constant for the cache entry key - Clarified `OnboardingSessionCorrelationStore` Javadoc (per-app SharedPreferences sandbox) - Updated `addBlockingError` Javadoc to reference correct constant values - Full MIT license headers - Converted to Kotlin - **Upstream of**: OneAuth onboarding telemetry PR (Djinni + C++ core + Android platform layer) - **No breaking changes**: all new files, no modifications to existing code
…3111) Adds the IPC plumbing for the onboarding telemetry blob to flow client↔broker. Independent of PR #3088 (which adds the recorder/store/constants); both are needed together for end-to-end brokered onboarding telemetry. Linked Feature: [AB#3462876](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3462876) Linked PBI: [AB#3568357](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3568357) | File | Change | |---|---| | `BrokerRequest.java` | Add `onboarding_seed_json` field (client → broker) | | `BrokerResult.java` | Add `onboarding_blob` field + builder + getter (broker → client) | | `InteractiveTokenCommandParameters.java` | Add `onboardingSeedJson` field on the params builder | | `AcquireTokenResult.java` | Add `onboardingBlob` field for carrying the populated blob through the result chain | | `MsalBrokerRequestAdapter.java` | Serialize `onboardingSeedJson` from command parameters into `BrokerRequest` | | `MsalBrokerResultAdapter.java` | Extract `onboardingBlob` from `BrokerResult` into `AcquireTokenResult` | All additions are pure data fields + adapter wiring. No behavior change for existing callers (fields default to empty/null when not set). - **Direction `client → broker`**: OneAuth/MSAL builds the seed JSON (containing `sessionCorrelationId`, `onboardingMode`, `schema_version`) and attaches it to the interactive request. The broker reads it via the new field on `BrokerInteractiveTokenCommandParameters`, constructs its own `OnboardingTelemetryRecorder` from the seed, and uses the same correlation ID for its onboarding telemetry events. - **Direction `broker → client`**: When the broker emits the populated onboarding blob (after `finalizeBlob()`), it places it into `BrokerResult.onboarding_blob`. The client extracts it into `AcquireTokenResult.onboardingBlob`, where downstream OneAuth code reads it and emits the blob through MATS. See full design: [Mobile Onboarding Telemetry Design](https://identitydivision.visualstudio.com/Engineering/_workitems/edit/3462876) §6.6 (persistence and propagation) and §11.2 (broker → OneAuth blob delivery). - **Pairs with**: PR #3088 (`OnboardingTelemetryRecorder` + `OnboardingTelemetryConstants` + `OnboardingSessionCorrelationStore`). The recorder consumes the seed JSON read out of these IPC fields. - **Consumers**: - OneAuth: [`shared/mobile-onboarding-android-fixes`](https://office.visualstudio.com/OneAuth/_git/OneAuth) updates `BrokerRequestConverter` / `BrokerResultConverter` to read/write these fields. - Broker (`ad-accounts-for-android`): `MsalAndroidBrokerCommandParameterAdapter` reads `onboardingSeedJson`; broker error handler / SSO controller will write `onboarding_blob` once the recorder lifecycle is wired (separate PBI, [AB#3568359](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3568359)). - **No breaking changes**: all new optional fields, no modifications to existing serialization order or field semantics. - Round-trip serialization is exercised by existing `BrokerRequest` / `BrokerResult` tests (Gson + Bundle); new fields default to empty/null when not set, so no existing test should regress. - E2E validated locally via OneAuth `local-only-onboarding-telemetry` branch + a combined Common build (`mavenLocal` `0.0.0-zhipan-mot-7`): seed JSON flows OneAuth → BrokerRequest → broker → BrokerResult → OneAuth.
…lemetry, Fixes AB#3462876 (#3117) Adds the remaining step ID and blocking error constants from the Mobile Onboarding Telemetry design (section 9 Step Taxonomy) to `OnboardingTelemetryConstants`. Pure additive - no behavior change, no caller wiring in this PR. Linked Feature: [AB#3462876](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3462876) PR #3088 shipped the recorder + the 5 step/blocking-error constants OneAuth needed for non-brokered (`STEP_AUTHENTICATION_STARTED`, `STEP_BROKER_INSTALL_PROMPTED`, `STEP_DEVICE_REGISTRATION_STARTED`, `BLOCKING_ERROR_BROKER_INSTALL`, `BLOCKING_ERROR_MDM_FLOW`). The remaining ~20 step IDs from the design will be needed by: - The WebView hooks PR (follow-up) - emits `MDMEnrollmentStarted`, `CompanyPortalLaunched`, `WebCpEnrollmentStarted`, etc. from `AzureActiveDirectoryWebViewClient` URL-handler sites. - Broker-side step emission (follow-up) - `AccountSelectionStarted`, `InterruptFlowStarted`, `PrtAcquired`, `TokenIssued`, etc. - OneAuth follow-ups for AM API + WebCP detection (Veena's request) - needs `MDMEnrollmentStarted` constant. - Termination steps - `UserCanceled`, `AuthorizationTimedOut`. Landing the constants ahead of caller wiring lets downstream PRs reference typed constants instead of hardcoded strings, and avoids a chicken-and-egg sequencing problem. Grouped by onboarding flow phase (matching design section 9): - **Authentication / WebView**: `STEP_ACCOUNT_SELECTION_STARTED`, `STEP_PASSKEY_AUTH_STARTED`, `STEP_CERT_BASED_AUTH_STARTED` - **MFA / Strong Auth**: `STEP_STRONG_AUTH_SETUP_STARTED`, `STEP_STRONG_AUTH_SETUP_COMPLETED`, `STEP_AUTHENTICATOR_MFA_LINKING_STARTED` - **CA Block & Remediation**: `STEP_CA_BLOCK_RECEIVED`, `STEP_INTERRUPT_FLOW_STARTED`, `STEP_CONSENT_PROMPT_SHOWN`, `STEP_TERMS_OF_USE_SHOWN`, `STEP_PASSWORD_RESET_REQUIRED` - **Device Registration**: `STEP_DEVICE_REGISTRATION_UPGRADE_STARTED` - **MDM Enrollment**: `STEP_MDM_ENROLLMENT_STARTED` (value `MDMEnrollmentStarted`), `STEP_COMPANY_PORTAL_LAUNCHED`, `STEP_WEB_CP_ENROLLMENT_STARTED`, `STEP_GOOGLE_ENROLLMENT_STARTED` - **Intune App Protection**: `STEP_INTUNE_APP_PROTECTION_REQUIRED` - **Compliance Remediation**: `STEP_COMPLIANCE_REMEDIATION_STARTED`, `STEP_COMPLIANCE_REMEDIATION_COMPLETED` - **Token Acquisition**: `STEP_PRT_ACQUIRED`, `STEP_TOKEN_ISSUED` - **Termination**: `STEP_USER_CANCELED`, `STEP_AUTHORIZATION_TIMED_OUT` - **Blocking error**: `BLOCKING_ERROR_DEVICE_REGISTRATION` (`"DEVICE_REGISTRATION_REQUIRED"`) All values are PascalCase (consistent with the existing `STEP_*` constants and matching what eSTS/MATS expect for these enum-like step values). - No new tests - pure constant additions; existing `OnboardingTelemetryRecorderTest` and `OnboardingSessionCorrelationStoreTest` continue to pass. - Built locally; constants compile cleanly. - **Builds on**: PR #3088 (already merged) - extends `OnboardingTelemetryConstants` added there. - **Consumed by** (follow-up PRs): - WebView page-tracking hooks (`AzureActiveDirectoryWebViewClient` setter + emissions) - Broker step emission (`BrokerSsoController`, `PrtController`, error handler) - OneAuth caller updates (AM API + WebCP detection per Veena's PR #3088 comment) - **No breaking changes** - purely additive to the existing `object`.
|
✅ Work item link check complete. Description contains link AB#3462876 to an Azure Boards work item. |
2 similar comments
|
✅ Work item link check complete. Description contains link AB#3462876 to an Azure Boards work item. |
|
✅ Work item link check complete. Description contains link AB#3462876 to an Azure Boards work item. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cherry-picks the onboarding telemetry feature into the 24.2.1 hotfix release branch.
Cherry-picked from
dev(in order):543578aa40965c25ca1fe87aaa5All three are part of the same feature (mobile onboarding telemetry, AB#3462876 / AB#3568357) and are bundled here so OneAuth can take a single hotfix dependency.
Conflicts resolved:
changelog.txtonly — entries moved fromvNexttoVersion 24.2.1-RC1. No code conflicts.Fixes AB#3462876