feat(watch): renforce la vibration de fin de chrono et consolide la remontee des donnees stats montre

Cote montre pour #180 (vibration timerFinished plus longue et plus forte) et #179 (contrat/collecte des donnees stats vers le telephone).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 14:55:52 +02:00
parent 36691643d7
commit b4503d6b5f
8 changed files with 170 additions and 29 deletions

View File

@ -170,8 +170,7 @@ object WatchBridgePlugin {
return
}
sensorPermissionRequestInFlight = false
val granted = appContext?.let(::hasRequiredSensorPermissions) == true ||
grantResults.all { it == PackageManager.PERMISSION_GRANTED }
val granted = appContext?.let(::hasRequiredRuntimePermissions) == true
if (granted) {
pendingSensorPermissionRequest = false
Log.d(TAG, "sensor permissions granted")
@ -187,6 +186,7 @@ object WatchBridgePlugin {
grantResults.getOrNull(index) != PackageManager.PERMISSION_GRANTED
}
Log.w(TAG, "sensor permissions denied=${denied.joinToString()}")
emitSensorPermissionRequired()
}
}
@ -458,12 +458,12 @@ object WatchBridgePlugin {
@Suppress("DEPRECATION")
context.getSystemService(Vibrator::class.java)
} ?: return
val timings = longArrayOf(0L, 180L, 120L, 260L)
val timings = longArrayOf(0L, 320L, 90L, 420L, 90L, 520L)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(
VibrationEffect.createWaveform(
timings,
intArrayOf(0, 255, 0, 255),
intArrayOf(0, 255, 0, 255, 0, 255),
-1,
),
)
@ -492,6 +492,7 @@ object WatchBridgePlugin {
executionContext = telemetryContext(projection),
)
pendingSensorPermissionRequest = true
emitSensorPermissionRequired()
requestSensorPermissionsOnce()
return
}
@ -603,6 +604,29 @@ object WatchBridgePlugin {
val index = (value as? Number)?.toInt() ?: return null
return if (index > 0) index - 1 else null
}
private fun emitSensorPermissionRequired() {
val projection = lastSensorProjection ?: lastActiveProjection ?: return
val sessionId = projection["deviceSessionId"] as? String ?: return
if (sessionId.isBlank()) {
return
}
emitSensorSample(
mapOf(
"schemaVersion" to 4,
"sampleId" to "$sessionId-permission-${System.currentTimeMillis()}",
"sessionId" to sessionId,
"capturedAtEpochMs" to System.currentTimeMillis(),
"recordedAtEpochMs" to System.currentTimeMillis(),
"programIndex" to projection["programIndex"],
"exerciseIndex" to projection["exerciseIndex"],
"setIndex" to projection["setIndex"],
"passageIndex" to zeroBasedNullableIndex(projection["passageIndex"]),
"stepIndex" to zeroBasedNullableIndex(projection["stepIndex"]),
"sensorCollectionStatus" to "authorizationRequired",
),
)
}
}
private fun JSONObject.toMap(): Map<String, Any?> {

View File

@ -445,6 +445,8 @@ internal class WatchHeartRateCollector(
sampleSequence = 0
executionContext = emptyMap()
shouldAggregate = false
exerciseMetricsStarted = false
exerciseMetricsStartInFlight = false
exerciseHeartRateSupported = false
exerciseHeartRateObserved = false
}