merge(develop): déverrouille les demandes de permissions capteurs montre

Intègre le correctif de throttling des demandes de permissions
READ_HEART_RATE / ACTIVITY_RECOGNITION côté montre, qui restaient
bloquées à granted=false après une première tentative. QA verte.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 13:17:16 +02:00
2 changed files with 35 additions and 9 deletions

View File

@ -35,6 +35,6 @@ class MainActivity :
grantResults: IntArray,
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
WatchBridgePlugin.handlePermissionResult(requestCode, grantResults)
WatchBridgePlugin.handlePermissionResult(requestCode, permissions, grantResults)
}
}

View File

@ -35,6 +35,7 @@ object WatchBridgePlugin {
const val STATE_PATH = "/gametime/phone/projection"
const val PHONE_CAPABILITY = "gametime_phone_companion"
private const val SENSOR_PERMISSION_REQUEST = 4106
private const val SENSOR_PERMISSION_RETRY_DELAY_MS = 30000L
private const val READ_HEART_RATE_PERMISSION =
"android.permission.health.READ_HEART_RATE"
@ -51,7 +52,8 @@ object WatchBridgePlugin {
sensorSamplePath = SENSOR_SAMPLE_PATH,
onLocalSample = ::emitSensorSample,
)
private var sensorPermissionRequested = false
private var sensorPermissionRequestInFlight = false
private var lastSensorPermissionRequestEpochMs = 0L
private var pendingSensorPermissionRequest = false
fun register(flutterEngine: FlutterEngine, context: Context) {
@ -122,10 +124,15 @@ object WatchBridgePlugin {
}
}
fun handlePermissionResult(requestCode: Int, grantResults: IntArray) {
fun handlePermissionResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray,
) {
if (requestCode != SENSOR_PERMISSION_REQUEST) {
return
}
sensorPermissionRequestInFlight = false
val granted = appContext?.let(::hasRequiredSensorPermissions) == true ||
grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (granted) {
@ -133,7 +140,10 @@ object WatchBridgePlugin {
Log.d(TAG, "sensor permissions granted")
appContext?.let { heartRateCollector.onBodySensorsGranted(it) }
} else {
Log.w(TAG, "sensor permissions denied")
val denied = permissions.filterIndexed { index, _ ->
grantResults.getOrNull(index) != PackageManager.PERMISSION_GRANTED
}
Log.w(TAG, "sensor permissions denied=${denied.joinToString()}")
}
}
@ -339,10 +349,6 @@ object WatchBridgePlugin {
Log.d(TAG, "sensor permission request pending: activity unavailable")
return
}
if (sensorPermissionRequested) {
Log.d(TAG, "sensor permission request already attempted")
return
}
val permissions = requiredSensorPermissions()
.filter { activity.checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED }
.toTypedArray()
@ -351,7 +357,27 @@ object WatchBridgePlugin {
appContext?.let { heartRateCollector.onBodySensorsGranted(it) }
return
}
sensorPermissionRequested = true
val now = System.currentTimeMillis()
if (sensorPermissionRequestInFlight &&
now - lastSensorPermissionRequestEpochMs < SENSOR_PERMISSION_RETRY_DELAY_MS
) {
Log.d(
TAG,
"sensor permission request in flight missing=${permissions.joinToString()}",
)
return
}
if (!sensorPermissionRequestInFlight &&
now - lastSensorPermissionRequestEpochMs < SENSOR_PERMISSION_RETRY_DELAY_MS
) {
Log.d(
TAG,
"sensor permission request throttled missing=${permissions.joinToString()}",
)
return
}
sensorPermissionRequestInFlight = true
lastSensorPermissionRequestEpochMs = now
Log.d(TAG, "request sensor permissions=${permissions.joinToString()}")
activity.requestPermissions(permissions, SENSOR_PERMISSION_REQUEST)
}