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, grantResults: IntArray,
) { ) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) 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 STATE_PATH = "/gametime/phone/projection"
const val PHONE_CAPABILITY = "gametime_phone_companion" const val PHONE_CAPABILITY = "gametime_phone_companion"
private const val SENSOR_PERMISSION_REQUEST = 4106 private const val SENSOR_PERMISSION_REQUEST = 4106
private const val SENSOR_PERMISSION_RETRY_DELAY_MS = 30000L
private const val READ_HEART_RATE_PERMISSION = private const val READ_HEART_RATE_PERMISSION =
"android.permission.health.READ_HEART_RATE" "android.permission.health.READ_HEART_RATE"
@ -51,7 +52,8 @@ object WatchBridgePlugin {
sensorSamplePath = SENSOR_SAMPLE_PATH, sensorSamplePath = SENSOR_SAMPLE_PATH,
onLocalSample = ::emitSensorSample, onLocalSample = ::emitSensorSample,
) )
private var sensorPermissionRequested = false private var sensorPermissionRequestInFlight = false
private var lastSensorPermissionRequestEpochMs = 0L
private var pendingSensorPermissionRequest = false private var pendingSensorPermissionRequest = false
fun register(flutterEngine: FlutterEngine, context: Context) { 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) { if (requestCode != SENSOR_PERMISSION_REQUEST) {
return return
} }
sensorPermissionRequestInFlight = false
val granted = appContext?.let(::hasRequiredSensorPermissions) == true || val granted = appContext?.let(::hasRequiredSensorPermissions) == true ||
grantResults.all { it == PackageManager.PERMISSION_GRANTED } grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (granted) { if (granted) {
@ -133,7 +140,10 @@ object WatchBridgePlugin {
Log.d(TAG, "sensor permissions granted") Log.d(TAG, "sensor permissions granted")
appContext?.let { heartRateCollector.onBodySensorsGranted(it) } appContext?.let { heartRateCollector.onBodySensorsGranted(it) }
} else { } 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") Log.d(TAG, "sensor permission request pending: activity unavailable")
return return
} }
if (sensorPermissionRequested) {
Log.d(TAG, "sensor permission request already attempted")
return
}
val permissions = requiredSensorPermissions() val permissions = requiredSensorPermissions()
.filter { activity.checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED } .filter { activity.checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED }
.toTypedArray() .toTypedArray()
@ -351,7 +357,27 @@ object WatchBridgePlugin {
appContext?.let { heartRateCollector.onBodySensorsGranted(it) } appContext?.let { heartRateCollector.onBodySensorsGranted(it) }
return 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()}") Log.d(TAG, "request sensor permissions=${permissions.joinToString()}")
activity.requestPermissions(permissions, SENSOR_PERMISSION_REQUEST) activity.requestPermissions(permissions, SENSOR_PERMISSION_REQUEST)
} }