Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1ad6f36
fix: [SDK-5305] prompt on the host activity when PermissionsActivity …
abdulraqeeb33 Oct 6, 2026
7ec595c
chore: [SDK-4986] gate public API changes with binary-compatibility-v…
abdulraqeeb33 Oct 12, 2026
64b9270
feat: [SDK-5024] add composite login(externalId, profile) as one Crea…
abdulraqeeb33 Oct 12, 2026
26decb3
fix: [SDK-4952] stop the settings fallback from stacking on Huawei's …
abdulraqeeb33 Oct 12, 2026
5528c3d
chore: [SDK-5024] dump core.api for composite login (#2787)
abdulraqeeb33 Oct 14, 2026
906bb15
fix: [SDK-5535] retry failed operations without blocking the queue (#…
fadi-george Oct 14, 2026
e79040a
test: [SDK-5535] add a fault-injection harness for operation retries …
fadi-george Oct 14, 2026
9673c8c
Merge remote-tracking branch 'origin/main' into new-session-events
fadi-george Oct 14, 2026
2d5bdac
fix: [SDK-5024] composite login returns NOT_INITIALIZED instead of th…
abdulraqeeb33 Oct 15, 2026
ab2ee7e
fix: [SDK-5552] composite login rejects empty or null tag and alias e…
abdulraqeeb33 Oct 15, 2026
d1246a4
feat: register push with Firebase Installation ID when the legacy FCM…
fadi-george Oct 15, 2026
330726b
test: [SDK-5535] match retry report success codes and gap checks to t…
fadi-george Oct 15, 2026
f8181e6
Merge branch 'main' into new-session-events
fadi-george Oct 15, 2026
8556e1a
feat: [SDK-5378] persist and retry sessions API requests through Oper…
fadi-george Oct 14, 2026
60eccf8
fix: [SDK-5378] retry offline session requests and tighten session qu…
fadi-george Oct 14, 2026
b02b574
fix(session): avoid stalling queue on create delay
fadi-george Oct 15, 2026
34f233c
fix(session): tighten queue rules for updates/consent
fadi-george Oct 15, 2026
ee433af
fix(session): drop anonymous creates at enqueue and record restored ends
fadi-george Oct 15, 2026
e03fff6
test: deflake post-create delay and enqueue debounce tests
fadi-george Oct 15, 2026
95f3c22
test: clear prefs before each SDKInitTests case
fadi-george Oct 15, 2026
09beba7
feat: [SDK-5382] enqueue a session create when a new session starts
fadi-george Oct 9, 2026
40db92c
fix: [SDK-5382] send subscription_type and a bare UUID idempotency ke…
fadi-george Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ jobs:
working-directory: OneSignalSDK
run: |
./gradlew detekt --console=plain
# Explicit paths: a bare `apiCheck` silently skips any module that stops registering the task.
- name: "[Public API] Binary compatibility check"
id: api_check
working-directory: OneSignalSDK
run: |
./gradlew \
:OneSignal:apiCheck \
:OneSignal:core:apiCheck \
:OneSignal:notifications:apiCheck \
:OneSignal:in-app-messages:apiCheck \
:OneSignal:location:apiCheck \
--console=plain
- name: "[Public API] Explain a failure"
if: failure() && steps.api_check.outcome == 'failure'
run: |
echo "If apiCheck failed, the public API changed. Review the diff it printed."
echo "If the change is intended, run './gradlew apiDump' in OneSignalSDK and commit the updated api/*.api files."
echo "If the new lines are internal (not customer or wrapper API), add them to ignoredPackages or ignoredClasses in OneSignalSDK/build.gradle instead."

test:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ build/
local.properties
OneSignalSDK/local.properties
examples/demo/local.properties
google-services.json

# Google services
google-services.json
Expand Down
23 changes: 23 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,29 @@ flowchart TD

The only manual actions in Flow B are **Run workflow** and **merge the bump PR**; everything in between is automated.

### Public API changes

The published modules track their public API in committed dumps under `<module>/api/*.api`, generated by the [binary compatibility validator](https://github.com/Kotlin/binary-compatibility-validator). CI runs `apiCheck` alongside Spotless and Detekt, so any change to the public surface fails the build until the dump is regenerated. The point is that a breaking change has to appear as a reviewable diff rather than be caught by eye.

If you change the public API on purpose, regenerate and commit the dumps:

```bash
cd OneSignalSDK
./gradlew apiDump
```

Then read the resulting diff before committing it. A removed or altered line is a breaking change for customers. An added line is usually safe, with one important exception: a new method on an interface customers implement (listeners such as `INotificationClickListener` or `IUserJwtInvalidatedListener`) breaks every existing implementation.

Two things about the dumps are worth knowing up front:

- They cover customer and wrapper-SDK API only. Kotlin has no cross-module "internal", so `com.onesignal.**.internal.*` and most of `com.onesignal.common.*` compile as public; `apiValidation` in `OneSignalSDK/build.gradle` excludes them so internal refactors don't trip `apiCheck`. `OneSignalWrapper`, `IHostPermissionPrompt`, and `debug.internal.logging.Logging` stay in because the wrapper SDKs (Flutter, React Native, Cordova, Capacitor, Unity, .NET) call them, so treat them as public API. If you add a new internal package, or a new class at the root of `com.onesignal.common`, add it to `ignoredPackages` or `ignoredClasses` rather than dumping it.
- `in-app-messages.api` and `location.api` are empty because their customer-facing interfaces live in `core`. That is expected, not a misconfiguration. `notifications.api` also records manifest components (receivers, activities, HMS/ADM services).
- `Logging.setLoggerTelemetry` takes a KMP type, so a KMP submodule bump (Flow B above) that changes `ILogTelemetryRemote` will fail `apiCheck`. Run `apiDump` on the bump PR if so.

The validator hooks into the `kotlin-android` plugin, and CI calls each module's `apiCheck` by path. If a module moves to AGP 9's built-in Kotlin, its task stops being registered and CI fails with "task not found" rather than skipping it. See [BCV#312](https://github.com/Kotlin/binary-compatibility-validator/issues/312).

The eventual replacement is the [ABI validation built into the Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle-binary-compatibility-validation.html) (`kotlin { abiValidation { } }`, experimental since Kotlin 2.2). It keeps the same `api/*.api` dump format, so the move is mostly porting the `apiValidation` filters. It needs Kotlin 2.2+, so it is planned alongside the AGP 9 move for v6.

#### Before Submitting A Bug Report
Before creating bug reports, please check this list of steps to follow.

Expand Down
60 changes: 58 additions & 2 deletions OneSignalSDK/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
]
androidGradlePluginVersion = '8.8.2'
detektVersion = '1.21.0'
googleServicesGradlePluginVersion = '4.3.10'
googleServicesGradlePluginVersion = '4.4.2'
huaweiAgconnectVersion = '1.9.1.304'
huaweiHMSPushVersion = '6.3.0.304'
huaweiHMSLocationVersion = '4.0.0.300'
Expand All @@ -26,6 +26,9 @@ buildscript {
startupVersion = '1.1.1'
ktlintVersion = '0.50.0' // Used by Spotless for Kotlin formatting (compatible with Kotlin 1.7.10)
spotlessVersion = '6.25.0'
// BCV hooks into 'kotlin-android', so AGP 9's built-in Kotlin stops it registering tasks.
// See https://github.com/Kotlin/binary-compatibility-validator/issues/312
binaryCompatibilityValidatorVersion = '0.16.3'
tdunningJsonForTest = '1.0' // DO NOT upgrade for tests, using an old version so it matches AOSP

sharedRepos = {
Expand All @@ -44,7 +47,8 @@ buildscript {
"org.jetbrains.dokka:dokka-gradle-plugin:$dokkaVersion",
"io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detektVersion",
"com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion",
"com.vanniktech.maven.publish:com.vanniktech.maven.publish.gradle.plugin:0.32.0"
"com.vanniktech.maven.publish:com.vanniktech.maven.publish.gradle.plugin:0.32.0",
"org.jetbrains.kotlinx:binary-compatibility-validator:$binaryCompatibilityValidatorVersion"
]
}

Expand All @@ -54,6 +58,58 @@ buildscript {
}
}

apply plugin: 'org.jetbrains.kotlinx.binary-compatibility-validator'

// Tracks the public API of the published modules as committed `api/*.api` dumps, so a breaking
// change has to show up as a reviewable diff instead of being spotted by eye.
apiValidation {
// Not published, so they have no customer-facing surface to protect.
ignoredProjects += ['app', 'testhelpers']
// :kmp is a git submodule; its API is owned by OneSignal-KMP-SDK.
ignoredProjects += ['kmp']

// Public only because Kotlin has no cross-module internal. Subpackages are ignored too.
ignoredPackages += [
'com.onesignal.internal',
'com.onesignal.core.internal',
// Not all of debug.internal: wrapper SDKs call debug.internal.logging.Logging.
'com.onesignal.debug.internal.crash',
'com.onesignal.debug.internal.logging.logger',
'com.onesignal.inAppMessages.internal',
'com.onesignal.location.internal',
'com.onesignal.notifications.internal',
'com.onesignal.session.internal',
'com.onesignal.user.internal',
'com.onesignal.common.consistency',
'com.onesignal.common.events',
'com.onesignal.common.exceptions',
'com.onesignal.common.modeling',
'com.onesignal.common.modules',
'com.onesignal.common.services',
'com.onesignal.common.threading',
]
// Wrapper SDKs call OneSignalWrapper and IHostPermissionPrompt, so the rest of
// com.onesignal.common is ignored class by class. Nested classes need their own entry.
ignoredClasses += [
'com.onesignal.common.AndroidUtils',
'com.onesignal.common.AndroidUtils$SchemaType',
'com.onesignal.common.AndroidUtils$SchemaType$Companion',
'com.onesignal.common.DateUtils',
'com.onesignal.common.DeviceUtils',
'com.onesignal.common.IDManager',
'com.onesignal.common.InputGuardKt',
'com.onesignal.common.JSONObjectExtensionsKt',
'com.onesignal.common.JSONUtils',
'com.onesignal.common.NetworkUtils',
'com.onesignal.common.NetworkUtils$ResponseStatusType',
'com.onesignal.common.OneSignalUtils',
'com.onesignal.common.PIIHasher',
'com.onesignal.common.RootToolsInternalMethods',
'com.onesignal.common.TimeUtils',
'com.onesignal.common.ViewUtils',
]
}

allprojects {
repositories {
google()
Expand Down
3 changes: 3 additions & 0 deletions OneSignalSDK/detekt/detekt-baseline-core.xml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_ERROR_IOEXCEPTION_OTHER$11</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_ERROR_IOEXCEPTION_SERVICE_NOT_AVAILABLE$9</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_ERROR_MISC_EXCEPTION$12</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_FID_DEFAULT_APP_MISSING$32</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_FID_REGISTER_API_UNAVAILABLE$33</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_FID_REGISTRATION_FAILED$34</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.FIREBASE_FCM_INIT_ERROR$8</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.HMS_API_EXCEPTION_OTHER$27</ID>
<ID>MagicNumber:SubscriptionModel.kt$SubscriptionStatus.HMS_ARGUMENTS_INVALID$26</ID>
Expand Down
3 changes: 3 additions & 0 deletions OneSignalSDK/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ onesignalPublishSharedKmp = true
# This is the name of the SDK to use when building your project.
# This will be fed from the GitHub Actions workflow.
SDK_VERSION=5.10.2

# Enabled parallel sync for Gradle 9.4+
org.gradle.tooling.parallel=true
Empty file.
Loading
Loading