Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion OneSignalSDK/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ buildscript {
huaweiAgconnectVersion = '1.9.1.304'
huaweiHMSPushVersion = '6.3.0.304'
huaweiHMSLocationVersion = '4.0.0.300'
kotlinVersion = '2.2.0'
kotlinVersion = '1.9.25'
dokkaVersion = '1.9.10'
coroutinesVersion = '1.7.3'
kotestVersion = '5.8.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,133 +35,128 @@ private infix fun <T> T.shouldBeOneOf(expected: List<T>) {

@RobolectricTest
@Config(sdk = [Build.VERSION_CODES.O])
class OtelIntegrationTest : FunSpec({
var appContext: Context? = null
var sharedPreferences: SharedPreferences? = null

beforeAny {
if (appContext == null) {
appContext = ApplicationProvider.getApplicationContext()
sharedPreferences = appContext!!.getSharedPreferences(PreferenceStores.ONESIGNAL, Context.MODE_PRIVATE)
class OtelIntegrationTest : FunSpec() {
private lateinit var appContext: Context
private lateinit var sharedPreferences: SharedPreferences

init {
beforeAny {
if (!::appContext.isInitialized) {
appContext = ApplicationProvider.getApplicationContext()
sharedPreferences = appContext.getSharedPreferences(PreferenceStores.ONESIGNAL, Context.MODE_PRIVATE)
}
}
}

beforeEach {
// Ensure sharedPreferences is initialized
if (sharedPreferences == null) {
appContext = ApplicationProvider.getApplicationContext()
sharedPreferences = appContext!!.getSharedPreferences(PreferenceStores.ONESIGNAL, Context.MODE_PRIVATE)
}
// Clear and set up SharedPreferences with test data
sharedPreferences!!.edit().clear().commit()

// Set up ConfigModelStore data
val configModel = JSONObject().apply {
put(ConfigModel::appId.name, "test-app-id")
put(ConfigModel::pushSubscriptionId.name, "test-subscription-id")
val remoteLoggingParams = JSONObject().apply {
put("logLevel", "ERROR")
beforeEach {
if (!::sharedPreferences.isInitialized) {
appContext = ApplicationProvider.getApplicationContext()
sharedPreferences = appContext.getSharedPreferences(PreferenceStores.ONESIGNAL, Context.MODE_PRIVATE)
}
sharedPreferences.edit().clear().commit()

val configModel = JSONObject().apply {
put(ConfigModel::appId.name, "test-app-id")
put(ConfigModel::pushSubscriptionId.name, "test-subscription-id")
val remoteLoggingParams = JSONObject().apply {
put("logLevel", "ERROR")
}
put(ConfigModel::remoteLoggingParams.name, remoteLoggingParams)
}
val configArray = JSONArray().apply {
put(configModel)
}
put(ConfigModel::remoteLoggingParams.name, remoteLoggingParams)
}
val configArray = JSONArray().apply {
put(configModel)
}

// Set up IdentityModelStore data
val identityModel = JSONObject().apply {
put(IdentityConstants.ONESIGNAL_ID, "test-onesignal-id")
}
val identityArray = JSONArray().apply {
put(identityModel)
}
val identityModel = JSONObject().apply {
put(IdentityConstants.ONESIGNAL_ID, "test-onesignal-id")
}
val identityArray = JSONArray().apply {
put(identityModel)
}

sharedPreferences.edit()
.putString(PreferenceOneSignalKeys.MODEL_STORE_PREFIX + configNameSpace, configArray.toString())
.putString(PreferenceOneSignalKeys.MODEL_STORE_PREFIX + identityNameSpace, identityArray.toString())
.putString(PreferenceOneSignalKeys.PREFS_OS_INSTALL_ID, "test-install-id")
.commit()
}
sharedPreferences.edit()
.putString(PreferenceOneSignalKeys.MODEL_STORE_PREFIX + configNameSpace, configArray.toString())
.putString(PreferenceOneSignalKeys.MODEL_STORE_PREFIX + identityNameSpace, identityArray.toString())
.putString(PreferenceOneSignalKeys.PREFS_OS_INSTALL_ID, "test-install-id")
.commit()
}

afterEach {
sharedPreferences!!.edit().clear().commit()
}
afterEach {
sharedPreferences.edit().clear().commit()
}

test("AndroidOtelPlatformProvider should provide correct Android values") {
val provider = createAndroidOtelPlatformProvider(appContext!!)
test("AndroidOtelPlatformProvider should provide correct Android values") {
val provider = createAndroidOtelPlatformProvider(appContext)

provider.shouldBeInstanceOf<IOtelPlatformProvider>()
provider.sdkBase shouldBe "android"
provider.appPackageId shouldBe appContext!!.packageName // Use actual package name from context
provider.osName shouldBe "Android"
provider.deviceManufacturer shouldBe Build.MANUFACTURER
provider.deviceModel shouldBe Build.MODEL
provider.osVersion shouldBe Build.VERSION.RELEASE
provider.osBuildId shouldBe Build.ID
provider.shouldBeInstanceOf<IOtelPlatformProvider>()
provider.sdkBase shouldBe "android"
provider.appPackageId shouldBe appContext.packageName
provider.osName shouldBe "Android"
provider.deviceManufacturer shouldBe Build.MANUFACTURER
provider.deviceModel shouldBe Build.MODEL
provider.osVersion shouldBe Build.VERSION.RELEASE
provider.osBuildId shouldBe Build.ID

runBlocking {
provider.getInstallId() shouldNotBe null
runBlocking {
provider.getInstallId() shouldNotBe null
}
}
}

test("AndroidOtelPlatformProvider should provide per-event values") {
val provider = createAndroidOtelPlatformProvider(appContext!!)
test("AndroidOtelPlatformProvider should provide per-event values") {
val provider = createAndroidOtelPlatformProvider(appContext)

provider.appId shouldBe "test-app-id"
provider.onesignalId shouldBe "test-onesignal-id"
provider.pushSubscriptionId shouldBe "test-subscription-id"
provider.appState shouldBeOneOf listOf("foreground", "background", "unknown")
(provider.processUptime > 0) shouldBe true
provider.currentThreadName shouldBe Thread.currentThread().name
}
provider.appId shouldBe "test-app-id"
provider.onesignalId shouldBe "test-onesignal-id"
provider.pushSubscriptionId shouldBe "test-subscription-id"
provider.appState shouldBeOneOf listOf("foreground", "background", "unknown")
(provider.processUptime > 0) shouldBe true
provider.currentThreadName shouldBe Thread.currentThread().name
}

test("AndroidOtelLogger should delegate to Logging") {
val logger = AndroidOtelLogger()
test("AndroidOtelLogger should delegate to Logging") {
val logger = AndroidOtelLogger()

logger.shouldBeInstanceOf<com.onesignal.otel.IOtelLogger>()
// Should not throw
logger.debug("test")
logger.info("test")
logger.warn("test")
logger.error("test")
}
logger.shouldBeInstanceOf<com.onesignal.otel.IOtelLogger>()
logger.debug("test")
logger.info("test")
logger.warn("test")
logger.error("test")
}

test("OtelFactory should create crash handler with Android provider") {
val provider = createAndroidOtelPlatformProvider(appContext!!)
val logger = AndroidOtelLogger()
test("OtelFactory should create crash handler with Android provider") {
val provider = createAndroidOtelPlatformProvider(appContext)
val logger = AndroidOtelLogger()

val handler = OtelFactory.createCrashHandler(provider, logger)
val handler = OtelFactory.createCrashHandler(provider, logger)

handler shouldNotBe null
handler.shouldBeInstanceOf<IOtelCrashHandler>()
handler.initialize() // Should not throw
}
handler shouldNotBe null
handler.shouldBeInstanceOf<IOtelCrashHandler>()
handler.initialize()
}

test("OneSignalCrashHandlerFactory should create working crash handler") {
// Note: OneSignalCrashHandlerFactory may need to be updated to use the new approach
// For now, we'll test the direct creation
val provider = createAndroidOtelPlatformProvider(appContext!!)
val logger = AndroidOtelLogger()
val handler = OtelFactory.createCrashHandler(provider, logger)
test("OneSignalCrashHandlerFactory should create working crash handler") {
val provider = createAndroidOtelPlatformProvider(appContext)
val logger = AndroidOtelLogger()
val handler = OtelFactory.createCrashHandler(provider, logger)

handler shouldNotBe null
handler.shouldBeInstanceOf<IOtelCrashHandler>()
handler.initialize() // Should not throw
}
handler shouldNotBe null
handler.shouldBeInstanceOf<IOtelCrashHandler>()
handler.initialize()
}

test("AndroidOtelPlatformProvider should provide crash storage path") {
val provider = createAndroidOtelPlatformProvider(appContext!!)
test("AndroidOtelPlatformProvider should provide crash storage path") {
val provider = createAndroidOtelPlatformProvider(appContext)

provider.crashStoragePath.contains("onesignal") shouldBe true
provider.crashStoragePath.contains("otel") shouldBe true
provider.crashStoragePath.contains("crashes") shouldBe true
provider.minFileAgeForReadMillis shouldBe 5000L
}
provider.crashStoragePath.contains("onesignal") shouldBe true
provider.crashStoragePath.contains("otel") shouldBe true
provider.crashStoragePath.contains("crashes") shouldBe true
provider.minFileAgeForReadMillis shouldBe 5000L
}

test("AndroidOtelPlatformProvider should handle remote logging config") {
val provider = createAndroidOtelPlatformProvider(appContext!!)
test("AndroidOtelPlatformProvider should handle remote logging config") {
val provider = createAndroidOtelPlatformProvider(appContext)

provider.remoteLogLevel shouldBe "ERROR"
provider.appIdForHeaders shouldBe "test-app-id"
provider.remoteLogLevel shouldBe "ERROR"
provider.appIdForHeaders shouldBe "test-app-id"
}
}
})
}
2 changes: 1 addition & 1 deletion OneSignalSDK/onesignal/otel/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ android {

kotlinOptions {
jvmTarget = '1.8'
freeCompilerArgs += ['-module-name', namespace]
freeCompilerArgs += ['-module-name', namespace, '-Xskip-metadata-version-check']
}
}

Expand Down
12 changes: 6 additions & 6 deletions examples/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ In MainViewModel.kt, implement observers:
11. **Triggers Section** (Add/Add Multiple/Remove Selected/Clear All - IN MEMORY ONLY)
12. **Track Event Section** (Track Event with JSON validation)
13. **Location Section** (Location Shared toggle, Prompt Location button)
14. **Next Activity Button**
14. **Next Screen Button**

### Prompt 2.1 - App Section

Expand Down Expand Up @@ -374,12 +374,12 @@ Location Section:
- PROMPT LOCATION button
```

### Prompt 2.14 - Secondary Activity
### Prompt 2.14 - Secondary Screen

```
Secondary Activity (launched by "Next Activity" button at bottom of main screen):
- Activity title: "Secondary Activity"
- Page content: centered text "Secondary Activity" using headlineMedium style
Secondary Screen (launched by "Next Screen" button at bottom of main screen):
- Screen title: "Secondary Screen"
- Page content: centered text "Secondary Screen" using headlineMedium style
- Simple screen, no additional functionality needed
```

Comment thread
fadi-george marked this conversation as resolved.
Expand Down Expand Up @@ -650,7 +650,7 @@ Enable Jetpack Compose in the project:

build.gradle.kts (app):
- buildFeatures { compose = true }
- composeOptions { kotlinCompilerExtensionVersion = "1.5.10" }
- composeOptions { kotlinCompilerExtensionVersion = "1.5.15" }

Dependencies (via BOM):
- composeBom = "2024.02.00"
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Send a named **event** with optional JSON properties for advanced analytics.
### Location
Toggle **location sharing** on or off and **prompt** for location permission.

### Secondary Activity
### Secondary Screen
Navigate to a second screen with buttons to **simulate a crash** (`RuntimeException`) and **simulate an ANR** (10-second main-thread block) — useful for testing crash and ANR reporting.

### Log Viewer
Expand Down
8 changes: 5 additions & 3 deletions examples/demo/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
plugins {
id("com.android.application")
id("kotlin-android")
id("org.jetbrains.kotlin.plugin.compose") version "2.2.0"
}

// Keep IDE sync stable even if root extra properties are unavailable.
val kotlinVersion: String = rootProject.findProperty("kotlinVersion") as? String ?: "2.2.0"
val kotlinVersion: String = rootProject.findProperty("kotlinVersion") as? String ?: "1.9.25"

// Apply GMS or Huawei plugin based on build variant
// Check at configuration time, not when task graph is ready
Expand Down Expand Up @@ -37,6 +35,10 @@ android {
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.15"
}

flavorDimensions += "default"

productFlavors {
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</intent-filter>
</activity>

<!-- Secondary Activity -->
<!-- Secondary Screen -->
<activity
android:name=".ui.secondary.SecondaryActivity"
android:exported="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ fun MainScreen(viewModel: MainViewModel) {

Spacer(modifier = Modifier.height(8.dp))

// === NEXT ACTIVITY BUTTON ===
// === NEXT SCREEN BUTTON ===
PrimaryButton(
text = "NEXT ACTIVITY",
text = "NEXT SCREEN",
onClick = {
context.startActivity(Intent(context, SecondaryActivity::class.java))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class SecondaryActivity : ComponentActivity() {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = { Text("Secondary Activity", color = Color.White) },
title = { Text("Secondary Screen", color = Color.White) },
navigationIcon = {
IconButton(onClick = { finish() }) {
Icon(
Expand All @@ -67,7 +67,7 @@ class SecondaryActivity : ComponentActivity() {
verticalArrangement = Arrangement.Center
) {
Text(
text = "Secondary Activity",
text = "Secondary Screen",
style = MaterialTheme.typography.headlineMedium
)

Expand Down
6 changes: 3 additions & 3 deletions examples/demo/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@
<!-- Send In-App Message -->
<string name="send_in_app_message">Send In-App Message</string>

<!-- Next Activity -->
<string name="next_activity">NEXT ACTIVITY</string>
<string name="secondary_activity">Secondary Activity</string>
<!-- Next Screen -->
<string name="next_activity">NEXT SCREEN</string>
<string name="secondary_activity">Secondary Screen</string>

<!-- Dialog -->
<string name="external_user_id">External User Id</string>
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
val kotlinVersion by extra("2.2.0")
val kotlinVersion by extra("1.9.25")
repositories {
google()
mavenCentral()
Expand Down
Loading