fix(compras): revocar el PRO tras un reembolso sin penalizar a quien pago
Verificacion silenciosa en segundo plano con queryPastPurchases, al abrir o volver a la app y al cargar Android Auto. Solo revoca tras dos respuestas validas de Play sin la compra separadas 12h; sin red o con error no toca nada. Reactiva el PRO automaticamente si Play confirma la compra.
This commit is contained in:
@@ -20,6 +20,7 @@ import 'emisoras_destacadas.dart';
|
||||
import 'musica_local_auto.dart';
|
||||
import 'navegacion_auto.dart';
|
||||
import 'servicio_audio_session.dart';
|
||||
import 'verificacion_licencia.dart' show CambioLicencia;
|
||||
|
||||
/// Estado de reproducción expuesto al UI.
|
||||
enum EstadoReproduccion {
|
||||
@@ -383,6 +384,36 @@ void invalidarArbolAuto() {
|
||||
_invalidarArbolAutoGlobal?.call();
|
||||
}
|
||||
|
||||
/// Silent license re-verification for the headless Android Auto engine,
|
||||
/// registered from `main.dart` (it owns the purchase port and the prefs).
|
||||
/// `null` until registered — [dispararVerificacionLicenciaAuto] is then a
|
||||
/// no-op.
|
||||
Future<CambioLicencia> Function()? _verificarLicenciaAutoGlobal;
|
||||
|
||||
/// Registers (or, with `null`, clears) the verification
|
||||
/// [dispararVerificacionLicenciaAuto] runs. Module-level like every other
|
||||
/// `registrar*` seam here, so tests need no real handler.
|
||||
void registrarVerificacionLicenciaAuto(
|
||||
Future<CambioLicencia> Function()? verificar,
|
||||
) {
|
||||
_verificarLicenciaAutoGlobal = verificar;
|
||||
}
|
||||
|
||||
/// Runs the registered license check and, if it changed the persisted flag
|
||||
/// in either direction, invalidates the cached car tree (local music is
|
||||
/// premium-gated). Never throws. The browse path calls it UNAWAITED so a
|
||||
/// head unit's browse answer is never delayed by a Play query.
|
||||
Future<void> dispararVerificacionLicenciaAuto() async {
|
||||
final verificar = _verificarLicenciaAutoGlobal;
|
||||
if (verificar == null) return;
|
||||
try {
|
||||
final cambio = await verificar();
|
||||
if (cambio != CambioLicencia.sinCambios) invalidarArbolAuto();
|
||||
} catch (e) {
|
||||
debugPrint('[PluriWave][licencia] verificacion Auto fallida $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a head unit has actually SUBSCRIBED to at least one browse id on
|
||||
/// the live handler (fix/android-auto-musica-local, item 4 — corrected).
|
||||
///
|
||||
@@ -3472,6 +3503,13 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
// [resolverLocalizacionesRespaldo], so this works on the engine
|
||||
// Android Auto starts without an Activity -- which is the only engine
|
||||
// a Play reviewer ever gets.
|
||||
// Silent license re-verification (refund revocation), on the root
|
||||
// only — every car connection asks for it — and fire-and-forget: the
|
||||
// browse answer below is served from the persisted flag right away,
|
||||
// and the check is throttled to at most once a day.
|
||||
if (parentMediaId == AudioService.browsableRootId) {
|
||||
unawaited(dispararVerificacionLicenciaAuto());
|
||||
}
|
||||
final etiquetas = etiquetasArbolAutoDesde(_textos);
|
||||
final constructor = ConstructorArbolAuto(etiquetas: etiquetas);
|
||||
// The "recent" root, resolved BEFORE the entitlement gate.
|
||||
|
||||
Reference in New Issue
Block a user