Skip to content

Commit 441c409

Browse files
nan-liclaude
andcommitted
nit(style): fix spotless formatting and core detekt issues
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0a3d18e commit 441c409

8 files changed

Lines changed: 51 additions & 30 deletions

File tree

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/backend/impl/FeatureFlagsBackendService.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.onesignal.core.internal.backend.impl
33
import com.onesignal.common.OneSignalUtils
44
import com.onesignal.core.internal.backend.IFeatureFlagsBackendService
55
import com.onesignal.core.internal.backend.RemoteFeatureFlagsFetchOutcome
6+
import com.onesignal.core.internal.http.HttpResponse
67
import com.onesignal.core.internal.http.IHttpClient
78
import com.onesignal.debug.LogLevel
89
import com.onesignal.debug.internal.logging.Logging
@@ -43,8 +44,11 @@ internal class FeatureFlagsBackendService(
4344
platform = TURBINE_FEATURES_PLATFORM_ANDROID,
4445
sdkVersion = sdkVersion,
4546
)
47+
return mapResponseToOutcome(http.get(path, null))
48+
}
4649

47-
val response = http.get(path, null)
50+
@Suppress("ReturnCount")
51+
private fun mapResponseToOutcome(response: HttpResponse): RemoteFeatureFlagsFetchOutcome {
4852
val body = response.payload
4953
if (!response.isSuccess) {
5054
val msg =
@@ -56,12 +60,9 @@ internal class FeatureFlagsBackendService(
5660
return RemoteFeatureFlagsFetchOutcome.Unavailable
5761
}
5862
if (body.isNullOrBlank()) {
59-
Logging.warn(
60-
"FeatureFlagsBackendService: empty body for success status=${response.statusCode}",
61-
)
63+
Logging.warn("FeatureFlagsBackendService: empty body for success status=${response.statusCode}")
6264
return RemoteFeatureFlagsFetchOutcome.Unavailable
6365
}
64-
6566
val parsed = FeatureFlagsJsonParser.parseSuccessful(body)
6667
return if (parsed != null) {
6768
RemoteFeatureFlagsFetchOutcome.Success(parsed)

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/backend/impl/FeatureFlagsJsonParser.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ internal object FeatureFlagsJsonParser {
5959
}
6060
}
6161

62+
@Suppress("ReturnCount")
6263
private fun parseRootStrict(root: JsonObject): RemoteFeatureFlagsResult? {
6364
val featuresEl = root[FEATURES_PROPERTY] ?: return null
6465
val featuresArray = featuresEl as? JsonArray ?: return null
@@ -88,6 +89,7 @@ internal object FeatureFlagsJsonParser {
8889
return RemoteFeatureFlagsResult(keys, metaOut)
8990
}
9091

92+
@Suppress("ReturnCount")
9193
private fun findSiblingJsonObject(
9294
root: JsonObject,
9395
rawKeyFromFeaturesArray: String,
@@ -127,6 +129,7 @@ internal object FeatureFlagsJsonParser {
127129
* Decodes [ConfigModel.sdkRemoteFeatureFlagMetadata] (a JSON object of flag id → object) into a map.
128130
* Non-object values are skipped so each entry stays a [JsonObject] for nested decoding (e.g. with `Json.decodeFromJsonElement`).
129131
*/
132+
@Suppress("ReturnCount")
130133
fun parseStoredMetadataMap(raw: String?): Map<String, JsonObject> {
131134
if (raw.isNullOrBlank()) {
132135
return emptyMap()

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/backend/impl/TurbineSdkFeatureFlagsPath.kt

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,36 @@ internal object TurbineSdkFeatureFlagsPath {
3434
*/
3535
internal fun percentEncodePathSegmentUtf8(segment: String): String {
3636
val bytes = segment.encodeToByteArray()
37-
return buildString(bytes.size * 3) {
37+
return buildString(bytes.size * PERCENT_ENCODED_MAX_CHARS_PER_BYTE) {
3838
for (b in bytes) {
39-
val u = b.toInt() and 0xff
39+
val u = b.toInt() and BYTE_MASK
4040
if (isUnreservedByte(u)) {
4141
append(u.toChar())
4242
} else {
4343
append('%')
44-
append(HEX_DIGITS[u shr 4])
45-
append(HEX_DIGITS[u and 15])
44+
append(HEX_DIGITS[u shr NIBBLE_BITS])
45+
append(HEX_DIGITS[u and LOW_NIBBLE_MASK])
4646
}
4747
}
4848
}
4949
}
5050

51-
private fun isUnreservedByte(u: Int): Boolean =
52-
u in 0x41..0x5A ||
53-
u in 0x61..0x7A ||
54-
u in 0x30..0x39 ||
55-
u == 0x2D ||
56-
u == 0x2E ||
57-
u == 0x5F ||
58-
u == 0x7E
51+
private fun isUnreservedByte(u: Int): Boolean {
52+
val c = u.toChar()
53+
return c in 'A'..'Z' ||
54+
c in 'a'..'z' ||
55+
c in '0'..'9' ||
56+
c == '-' ||
57+
c == '.' ||
58+
c == '_' ||
59+
c == '~'
60+
}
5961

6062
private const val HEX_DIGITS = "0123456789ABCDEF"
63+
private const val BYTE_MASK = 0xFF
64+
private const val NIBBLE_BITS = 4
65+
private const val LOW_NIBBLE_MASK = 0x0F
66+
67+
// Worst-case characters per byte when percent-encoding: "%HH".
68+
private const val PERCENT_ENCODED_MAX_CHARS_PER_BYTE = 3
6169
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/config/impl/FeatureFlagsRefreshService.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,27 @@ internal class FeatureFlagsRefreshService(
9090
}
9191
val appId = configModelStore.model.appId
9292
if (appId.isNotEmpty()) {
93-
try {
94-
fetchAndApply(appId)
95-
} catch (e: CancellationException) {
96-
throw e
97-
} catch (e: Exception) {
98-
Logging.warn("FeatureFlagsRefreshService: fetch failed", e)
99-
}
93+
runFetchAndApplySafely(appId)
10094
}
10195
delay(REFRESH_INTERVAL_MS)
10296
}
10397
}
10498
}
10599
}
106100

101+
// Broad catch: the polling loop must not die on any per-iteration failure (HTTP, parsing,
102+
// etc.). CancellationException is rethrown so structured concurrency still works.
103+
@Suppress("TooGenericExceptionCaught")
104+
private suspend fun runFetchAndApplySafely(appId: String) {
105+
try {
106+
fetchAndApply(appId)
107+
} catch (e: CancellationException) {
108+
throw e
109+
} catch (e: Exception) {
110+
Logging.warn("FeatureFlagsRefreshService: fetch failed", e)
111+
}
112+
}
113+
107114
private suspend fun fetchAndApply(appId: String) {
108115
val result =
109116
when (val outcome = featureFlagsBackend.fetchRemoteFeatureFlags(appId)) {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/features/FeatureManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ internal class FeatureManager(
9090
(
9191
model.sdkRemoteFeatureFlags.map { canonicalizeFeatureKey(it) } +
9292
localFeatureOverrides.map { canonicalizeFeatureKey(it) }
93-
).toSet()
93+
).toSet()
9494
if (localFeatureOverrides.isNotEmpty()) {
9595
Logging.warn(
9696
"OneSignal: Local feature override enabled for testing only: $localFeatureOverrides",

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/impl/PreferencesService.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,13 @@ internal class PreferencesService(
241241
}
242242

243243
@Synchronized
244+
@Suppress("TooGenericExceptionCaught", "SwallowedException")
244245
private fun getSharedPrefsByName(store: String): SharedPreferences? {
245246
return try {
246247
_applicationService.appContext.getSharedPreferences(store, Context.MODE_PRIVATE)
247248
} catch (t: Throwable) {
248-
// App context may not be ready yet during early startup.
249+
// App context may not be ready yet during early startup. Any access failure here is
250+
// recoverable — callers tolerate null and retry on the next tick.
249251
null
250252
}
251253
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ internal class OneSignalImp(
381381
suspendifyOnIO { loginHelper.login(externalId, jwtBearerToken) }
382382
} else {
383383
if (!isInitialized) {
384-
throw IllegalStateException("Must call 'initWithContext' before 'login'")
384+
error("Must call 'initWithContext' before 'login'")
385385
}
386386
Thread {
387387
runBlocking(runtimeIoDispatcher) {
@@ -399,7 +399,7 @@ internal class OneSignalImp(
399399
suspendifyOnIO { logoutHelper.logout() }
400400
} else {
401401
if (!isInitialized) {
402-
throw IllegalStateException("Must call 'initWithContext' before 'logout'")
402+
error("Must call 'initWithContext' before 'logout'")
403403
}
404404
Thread {
405405
runBlocking(runtimeIoDispatcher) {
@@ -520,7 +520,7 @@ internal class OneSignalImp(
520520
if (isInitialized) {
521521
getter()
522522
} else {
523-
throw IllegalStateException("Must call 'initWithContext' before use")
523+
error("Must call 'initWithContext' before use")
524524
}
525525
}
526526
}

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/features/FeatureManagerTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import com.onesignal.core.internal.config.ConfigModelStore
77
import io.kotest.core.spec.style.FunSpec
88
import io.kotest.matchers.shouldBe
99
import io.mockk.every
10-
import kotlinx.serialization.json.jsonPrimitive
1110
import io.mockk.just
1211
import io.mockk.mockk
1312
import io.mockk.runs
13+
import kotlinx.serialization.json.jsonPrimitive
1414

1515
class FeatureManagerTests : FunSpec({
1616
beforeEach {

0 commit comments

Comments
 (0)