fix(android): return NOT_AUTHORIZED when notify permission is lost

This commit is contained in:
Ayaan Zaidi
2026-03-01 20:28:32 +05:30
committed by Ayaan Zaidi
parent 0d672e43b9
commit 6f63fc288a
2 changed files with 37 additions and 1 deletions

View File

@@ -61,7 +61,7 @@ private class AndroidSystemNotificationPoster(
ContextCompat.checkSelfPermission(appContext, Manifest.permission.POST_NOTIFICATIONS) !=
PackageManager.PERMISSION_GRANTED
) {
return
throw SecurityException("notifications permission missing")
}
NotificationManagerCompat.from(appContext).notify((System.currentTimeMillis() and 0x7FFFFFFF).toInt(), notification)
}
@@ -127,6 +127,11 @@ class SystemHandler private constructor(
return try {
poster.post(params)
GatewaySession.InvokeResult.ok(null)
} catch (_: SecurityException) {
GatewaySession.InvokeResult.error(
code = "NOT_AUTHORIZED",
message = "NOT_AUTHORIZED: notifications",
)
} catch (err: Throwable) {
GatewaySession.InvokeResult.error(
code = "UNAVAILABLE",

View File

@@ -36,6 +36,26 @@ class SystemHandlerTest {
assertTrue(result.ok)
assertEquals(1, poster.posts)
}
@Test
fun handleSystemNotify_returnsUnauthorizedWhenPostFailsPermission() {
val handler = SystemHandler.forTesting(poster = ThrowingPoster(authorized = true, error = SecurityException("denied")))
val result = handler.handleSystemNotify("""{"title":"OpenClaw","body":"done"}""")
assertFalse(result.ok)
assertEquals("NOT_AUTHORIZED", result.error?.code)
}
@Test
fun handleSystemNotify_returnsUnavailableWhenPostFailsUnexpectedly() {
val handler = SystemHandler.forTesting(poster = ThrowingPoster(authorized = true, error = IllegalStateException("boom")))
val result = handler.handleSystemNotify("""{"title":"OpenClaw","body":"done"}""")
assertFalse(result.ok)
assertEquals("UNAVAILABLE", result.error?.code)
}
}
private class FakePoster(
@@ -50,3 +70,14 @@ private class FakePoster(
posts += 1
}
}
private class ThrowingPoster(
private val authorized: Boolean,
private val error: Throwable,
) : SystemNotificationPoster {
override fun isAuthorized(): Boolean = authorized
override fun post(request: SystemNotifyRequest) {
throw error
}
}