Document ringback and notification playback ownership contracts

This commit is contained in:
evgeny committed 2026-10-28 14:43:27 +01:00
1 parent 776345997f
commit 6a82192b02
1 file changed
+31
+31
View File
@@ -293,6 +293,34 @@ Ringtone/MediaPlayer/Vibrator остаются до успешного stop/rele
очистки нет. Логи `Ringtone` показывают идентификатор ресурса, причину отказа,
успешное освобождение и оставшиеся sound/focus/vibration после запроса stop.
`CallRingback` на main владеет одним зацикленным MediaPlayer с профилем MEDIA:
connecting и ringing выбирают разные ресурсы. Повтор активной фазы сохраняет
плеер. Смена фазы, stop, error и неожиданный completion сначала запрещают
callbacks, затем запрашивают release. При исключении ссылка и прежний resource ID
остаются для следующего stop/start. Пока release не подтверждён, новая фаза
пропускается с WARN; запоздалые callbacks не повторяют очистку и не трогают
замену. После восстановления start может заново запустить ту же фазу.
Пропущенный start автоматически не воспроизводится; таймера повторов нет.
`NotificationSound` на main запускает отдельный однократный плеер с профилем
уведомлений; сигналы разных сообщений могут перекрываться. Объект приложения
сильно удерживает каждый плеер от получения из create до успешного release,
включая настройку listeners и проигрывание: это предотвращает преждевременное
завершение звука сборщиком мусора, описанное в
[контракте MediaPlayer](https://developer.android.com/reference/android/media/MediaPlayer).
ID звука — канал либо `dm:<ID>`; enabled/mutedChannels — снимки настроек для
новых сигналов. Смена настроек не останавливает уже играющие сигналы.
Completion/error/ошибка настройки или запуска запрашивает release своего
плеера. Исключение сохраняет владельца с признаком незавершённой очистки;
следующий callback либо play повторяет попытку. В начале play повторяются
только такие release, включая случаи disabled/mute и последующий отказ create.
Неудача одного плеера не мешает очистить остальные или запустить новый сигнал;
ещё играющие плееры остаются нетронутыми. После успешного release владелец
удаляется, поздние callbacks игнорируются. Автоматического таймера очистки нет.
Логи Ringback/Sound отмечают успех только после возврата release без исключения;
при отказе показывают ресурс/канал, идентификатор плеера и причину попытки.
`BatteryOptimizationPermission` читает power allowlist Android для текущего пакета:
true/false — ответ ОС, null — ошибка чтения сервиса/статуса с ERROR-диагностикой.
Флаг в DataStore не сохраняется и результат не кэшируется. Это исключение
@@ -370,6 +398,9 @@ notify/cancel и отмены PendingIntent, stop/release проигрывате
audio focus, импульса/cancel вибрации и постановки таймера. Проверяются независимая
повторная очистка, замена вызова и устаревшие callbacks. Эти модели не проверяют
поведение системных служб/OEM на устройстве.
Для CallRingback/NotificationSound проверяются также запрет смены фазы при
неосвобождённом loop, независимость перекрывающихся сигналов, очистка без
установленных callbacks и повтор release при выключенном звуке/ошибке create.
На Linux `:app:testDebugUnitTest` также запускает 25 fault-сценариев настоящего
JNI logger через `:app:testJniLog`; окружение и границы модели: `tests/jni_log/README.md`.
Проверки native bridge/standby доступны в `tests/Makefile.am`;