Aller au contenu principal

Remote Config Gatekeeper en 3 étapes

Dans une implémentation OTA classique (auto_update: true), chaque ouverture de l'application mobile déclenche une requête HTTP POST /api/v1/patches/check vers le serveur OTA. Sur une flotte de plusieurs millions de terminaux, cela représente des millions d'appels quotidiens alors même qu'aucun nouveau patch n'a été publié, consommant inutilement la bande passante serveur et les données mobiles des utilisateurs.

Le RemoteConfigGatekeeper (lib/src/gatekeeper/remote_config_gatekeeper.dart) résout ce problème en évaluant localement en mémoire 3 conditions cumulatives à partir d'un payload JSON léger (issu de votre chargement de configuration habituel au démarrage : Firebase Remote Config, appel d'initialisation API métier, etc.).

Architecture et flux de décision​

Séquence d'évaluation du Gatekeeper
  1. Vérification au démarrage : Contrôle de l'état de santé du dernier lancement et gestion d'éventuels rollbacks.
  2. Contrôle de conformité : Évaluation des politiques de sécurité locales sur le terminal.
  3. Requête de mise à jour : Interrogation du serveur TkushPatch avec les métadonnées d'environnement.
  4. Téléchargement et application : Récupération du correctif signé si toutes les conditions sont remplies.

Les 3 conditions cumulatives​

La méthode RemoteConfigGatekeeper.evaluate(...) vérifie dans l'ordre strict suivant :

  1. Condition 1 — Correspondance de la Version Release (targetReleaseVersion) :

    • Compare installedReleaseVersion.trim() avec remoteConfig.targetReleaseVersion.trim().
    • Si l'une des deux chaînes est vide ou si installed != target, le Gatekeeper retourne immédiatement GatekeeperVerdict.skippedVersionMismatch (shouldCallOtaServer: false).
    • Utilité : un utilisateur qui exécute encore la version 1.0.0+2 (ou qui vient d'installer la 1.0.0+4) n'interrogera jamais le serveur pour un patch destiné uniquement à la 1.0.0+3.
  2. Condition 2 — Interrupteur de disponibilité (patchAvailable) :

    • Vérifie que remoteConfig.patchAvailable == true.
    • Si false, retourne GatekeeperVerdict.skippedNoPatchAvailable (shouldCallOtaServer: false).
    • Utilité : permet de couper instantanément toute interrogation du serveur OTA en un clic depuis votre Remote Config sans redéployer quoi que ce soit.
  3. Condition 3 — Monotonie stricte du numéro de patch (latestPatchNumber) :

    • Lit le patch actuellement exécuté par le moteur Rust (currentPatchNumber ?? 0) et le compare à remoteConfig.latestPatchNumber.
    • Si currentPatch >= latestPatch, retourne GatekeeperVerdict.skippedAlreadyUpToDate (shouldCallOtaServer: false).
    • Si currentPatch < latestPatch, les 3 conditions sont réunies : retourne GatekeeperVerdict.allowed (shouldCallOtaServer: true).

Le modèle OtaRemoteConfig​

La classe OtaRemoteConfig (lib/src/models/ota_remote_config.dart) supporte à la fois le format snake_case et le format camelCase lors de la désérialisation via OtaRemoteConfig.fromJson(Map<String, dynamic> json) :

Propriété DartClés JSON acceptées par fromJsonTypeDéfautRôle
targetReleaseVersiontarget_release_version, targetReleaseVersionString''Version complète ciblée (x.y.z+build).
patchAvailablepatch_available, patchAvailableboolfalseActive ou coupe la recherche de patch pour cette version.
latestPatchNumberlatest_patch_number, latestPatchNumberint0Numéro du dernier patch publié (int, num ou String numérique convertie).
forceUpdateforce_update, forceUpdate, force_critical_updateboolfalsefalse = téléchargement silencieux ; true = mise à jour critique bloquante.
releaseNotesrelease_notes, releaseNotesString?nullMessage descriptif transmis à onCriticalUpdateRequired.

Exemples de payloads JSON serveur / Remote Config​

Scénario A : Aucun patch publié pour la Release courante (0 appel réseau)​

{
"target_release_version": "1.0.0+3",
"patch_available": false,
"latest_patch_number": 0,
"force_update": false
}

Scénario B : Mise à jour silencieuse en arrière-plan (Patch #2 disponible)​

{
"target_release_version": "1.0.0+3",
"patch_available": true,
"latest_patch_number": 2,
"force_update": false,
"release_notes": "Optimisation du chargement de l'historique des transactions."
}

Scénario C : Mise à jour critique forcée avec modale bloquante​

{
"target_release_version": "1.0.0+3",
"patch_available": true,
"latest_patch_number": 3,
"force_update": true,
"release_notes": "Mise à jour de sécurité requise pour valider vos opérations."
}

Matrice complète des verdicts (GatekeeperVerdict) et modes d'exécution (OtaUpdateExecutionMode)​

État de l'appareilPayload OtaRemoteConfigGatekeeperVerdictOtaUpdateExecutionModenetworkCallPerformedrestartRequired
Certificat APK invalide ou Root détecté(Quelconque)null (arrêté avant)blockedBySecurityShieldfalsefalse
Version 1.0.0+2, Patch nulltarget: "1.0.0+3", available: true, latest: 1skippedVersionMismatchblockedByGatekeeperfalsefalse
Version 1.0.0+3, Patch nulltarget: "1.0.0+3", available: false, latest: 1skippedNoPatchAvailableblockedByGatekeeperfalsefalse
Version 1.0.0+3, Patch #2target: "1.0.0+3", available: true, latest: 2skippedAlreadyUpToDateblockedByGatekeeperfalsefalse
Version 1.0.0+3, Patch #1, en 4G (requireWifi: true)target: "1.0.0+3", available: true, latest: 2, force: falsealloweddeferredToBackgroundTaskfalsefalse
Version 1.0.0+3, Patch #1, Wi-Fi & Batterie OKtarget: "1.0.0+3", available: true, latest: 2, force: falseallowedsilentBackgroundUpdatetruefalse
Version 1.0.0+3, Patch #1, même en 4Gtarget: "1.0.0+3", available: true, latest: 2, force: trueallowedcriticalForcedUpdatetruetrue (si téléchargé)
enableGatekeeper: falseforce: false (Wi-Fi/Batterie OK)bypassedGatekeeperDisabledsilentBackgroundUpdatetruefalse
Priorité du mode critique sur les contraintes d'environnement

Lorsque forceUpdate: true, le SDK ignore la restriction requireWifiForSilentUpdate et le seuil de batterie minBatteryPercentageForSilentUpdate afin que le correctif critique puisse être téléchargé immédiatement, même sur réseau mobile 3G/4G.