Aller au contenu principal

Référence complète de l'API publique (package:tk_ota_push/tk_ota_push.dart)

Cette page documente l'intégralité des classes, énumérations, alias de types (typedef), constructeurs, méthodes, propriétés et exceptions exportés par lib/tk_ota_push.dart.

Point d'entrée de la bibliothèque​

import 'package:tk_ota_push/tk_ota_push.dart';

Exports de lib/tk_ota_push.dart :

  • package:shorebird_code_push/shorebird_code_push.dart (show UpdateStatus, UpdateTrack, Patch)
  • src/tk_ota_push_sdk.dart
  • src/models/ota_remote_config.dart
  • src/gatekeeper/remote_config_gatekeeper.dart
  • src/security/ota_security_shield.dart
  • src/environment/ota_environment.dart
  • src/assets/ota_asset_manager.dart

1. Orchestrateur principal (src/tk_ota_push_sdk.dart)​

Classe TkOtaPush (alias SaraOta, EntrepriseOta)​

Orchestrateur principal du SDK mobile au-dessus du moteur natif Rust ShorebirdUpdater.

Alias rétrocompatibles​

typedef SaraOta = TkOtaPush;
typedef EntrepriseOta = TkOtaPush;

Constructeur & Initialisation statique​

TkOtaPush({
ShorebirdUpdater? updater,
String appReleaseVersion = '',
bool enableGatekeeper = true,
bool requireWifiForSilentUpdate = false,
int minBatteryPercentageForSilentUpdate = 20,
OtaEnvironmentMonitor? environmentMonitor,
OtaBackgroundScheduler? backgroundScheduler,
OtaSecurityPolicy? securityPolicy,
OtaDeviceIntegrityInspector? deviceIntegrityInspector,
OtaRollbackTracker? rollbackTracker,
CriticalUpdateHandler? onCriticalUpdateRequired,
RollbackDetectedHandler? onRollbackDetected,
SecurityViolationHandler? onSecurityViolation,
})
static TkOtaPush init({
ShorebirdUpdater? updater,
required String appReleaseVersion,
bool enableGatekeeper = true,
bool requireWifiForSilentUpdate = false,
int minBatteryPercentageForSilentUpdate = 20,
OtaEnvironmentMonitor? environmentMonitor,
OtaBackgroundScheduler? backgroundScheduler,
OtaSecurityPolicy? securityPolicy,
OtaDeviceIntegrityInspector? deviceIntegrityInspector,
OtaRollbackTracker? rollbackTracker,
CriticalUpdateHandler? onCriticalUpdateRequired,
RollbackDetectedHandler? onRollbackDetected,
SecurityViolationHandler? onSecurityViolation,
})

Crée une instance configurée de TkOtaPush, l'assigne au singleton TkOtaPush.instance et la retourne.

Propriétés et Getters​

Propriété / GetterTypeDescription
static instanceTkOtaPushInstance partagée initialisée via TkOtaPush.init (ou instance par défaut si non initialisée).
appReleaseVersionStringVersion de base installée (ex: '1.0.0+3').
enableGatekeeperboolActive (true par défaut) ou désactive le filtrage RemoteConfigGatekeeper.
requireWifiForSilentUpdateboolSi true, diffère les mises à jour silencieuses lorsque l'appareil n'est pas en Wi-Fi/Ethernet.
minBatteryPercentageForSilentUpdateintSeuil minimal de batterie (défaut 20) requis hors charge pour une mise à jour silencieuse.
securityPolicyOtaSecurityPolicyPolitique active du bouclier de sécurité mobile.
onCriticalUpdateRequiredCriticalUpdateHandler?Callback invoqué lorsque remoteConfig.forceUpdate == true.
onRollbackDetectedRollbackDetectedHandler?Callback invoqué lorsqu'une régression de numéro de patch est détectée au démarrage.
onSecurityViolationSecurityViolationHandler?Callback invoqué lorsque securityVerdict.isTrusted == false.
trackUpdateTrackCanal OTA actuellement écouté (UpdateTrack.stable par défaut).
isAvailablebooltrue si le moteur natif Rust est présent et actif (build release compilé avec la toolchain Shorebird).

Méthodes de TkOtaPush​

enableQaMode() / disableQaMode()​
void enableQaMode()
void disableQaMode()

Bascule le canal écouté (track) sur UpdateTrack.staging (enableQaMode) ou revient sur UpdateTrack.stable (disableQaMode).

currentPatchNumber()​
Future<int?> currentPatchNumber()

Retourne le numéro du patch actuellement exécuté ((await _updater.readCurrentPatch())?.number), ou null si l'application tourne sur le binaire Store d'origine. Peut propager ReadPatchException si la lecture FFI échoue.

readClientId()​
Future<String?> readClientId({String? appSupportDirectoryPath})

Lit l'UUID v4 client_id persisté par le moteur Rust dans shorebird_updater/state.json (ou patches_state.json). Inspecte d'abord appSupportDirectoryPath s'il est fourni, puis détecte automatiquement les répertoires du bac à sable Android (files) et iOS (Library/Application Support, Documents). Retourne null si aucun fichier d'état n'est encore présent.

readShortSupportCode()​
Future<String?> readShortSupportCode({String? appSupportDirectoryPath})

Retourne le code court à 8 caractères préfixé par # (ex: '#6959347F') dérivé des 8 premiers caractères hexadécimaux (sans tirets, en majuscules) de readClientId(). Retourne null si clientId est absent.

readDeviceIdentity()​
Future<OtaDeviceIdentity?> readDeviceIdentity({String? appSupportDirectoryPath})

Retourne un objet OtaDeviceIdentity complet regroupant clientId, shortSupportCode, releaseVersion, track et currentPatchNumber, ou null si le clientId n'est pas encore initialisé.

checkForUpdate()​
Future<UpdateStatus> checkForUpdate()

Interroge directement le serveur OTA (POST /api/v1/patches/check) sur le canal track courant et retourne UpdateStatus.

update()​
Future<void> update()

Télécharge et installe le dernier patch disponible sur le canal track courant. Sera actif au prochain démarrage à froid. Peut lever UpdateException (de shorebird_code_push) en cas d'échec.

checkAndUpdate()​
Future<bool> checkAndUpdate()

Vérifie d'abord if (!isAvailable) return false;, puis appelle checkForUpdate(). Si le statut est UpdateStatus.outdated, appelle update() et retourne true ; sinon retourne false.

verifyStartupAndHandleRollback()​
Future<OtaRollbackEvent?> verifyStartupAndHandleRollback({
String? overrideAppReleaseVersion,
})

Compare le patch courant avec le dernier patch exécuté pour la version Release. Si un rollback a eu lieu (current < previous), invoque onRollbackDetected et retourne l'objet OtaRollbackEvent, sinon retourne null.

syncWithRemoteConfig()​
Future<OtaSyncOutcome> syncWithRemoteConfig(
OtaRemoteConfig remoteConfig, {
String? overrideAppReleaseVersion,
})

Exécute le cycle complet :

  1. verifyStartupAndHandleRollback (Étape 0a).
  2. Évaluation de securityPolicy via OtaDeviceIntegrityInspector.evaluatePolicy (Étape 0b).
  3. Évaluation des 3 conditions du RemoteConfigGatekeeper.
  4. Exécution de la politique critique (forceUpdate: true) ou silencieuse (forceUpdate: false) avec contrôle Wi-Fi/Batterie.
// Exemple d'utilisation
final outcome = await TkOtaPush.instance.syncWithRemoteConfig(
const OtaRemoteConfig(
targetReleaseVersion: '1.0.0+3',
patchAvailable: true,
latestPatchNumber: 2,
forceUpdate: false,
),
);

Classe OtaDeviceIdentity​

class OtaDeviceIdentity {
const OtaDeviceIdentity({
required this.clientId,
required this.shortSupportCode,
required this.releaseVersion,
required this.track,
this.currentPatchNumber,
});

final String clientId;
final String shortSupportCode;
final String releaseVersion;
final String track;
final int? currentPatchNumber;

Map<String, dynamic> toJson();
}

Énumération OtaUpdateExecutionMode​

enum OtaUpdateExecutionMode {
blockedByGatekeeper,
blockedBySecurityShield,
deferredToBackgroundTask,
silentBackgroundUpdate,
criticalForcedUpdate,
}

Classe OtaSyncOutcome​

class OtaSyncOutcome {
const OtaSyncOutcome({
required this.executionMode,
required this.networkCallPerformed,
required this.patchDownloaded,
required this.restartRequired,
this.gatekeeperEvaluation,
this.securityVerdict,
this.rollbackEvent,
this.message,
});

final OtaUpdateExecutionMode executionMode;
final bool networkCallPerformed;
final bool patchDownloaded;
final bool restartRequired;
final GatekeeperEvaluation? gatekeeperEvaluation;
final OtaSecurityVerdict? securityVerdict;
final OtaRollbackEvent? rollbackEvent;
final String? message;
}

Typedef CriticalUpdateHandler​

typedef CriticalUpdateHandler = Future<void> Function(
OtaRemoteConfig config,
Future<bool> Function() triggerImmediateDownload,
);

2. Modèles Remote Config & Gatekeeper (src/models/ota_remote_config.dart & src/gatekeeper/remote_config_gatekeeper.dart)​

Classe OtaRemoteConfig​

class OtaRemoteConfig {
const OtaRemoteConfig({
required this.targetReleaseVersion,
required this.patchAvailable,
required this.latestPatchNumber,
this.forceUpdate = false,
this.releaseNotes,
});

factory OtaRemoteConfig.fromJson(Map<String, dynamic> json);

final String targetReleaseVersion;
final bool patchAvailable;
final int latestPatchNumber;
final bool forceUpdate;
final String? releaseNotes;

Map<String, dynamic> toJson();
}

Énumération GatekeeperVerdict​

enum GatekeeperVerdict {
allowed,
skippedVersionMismatch,
skippedNoPatchAvailable,
skippedAlreadyUpToDate,
bypassedGatekeeperDisabled,
}

Classe GatekeeperEvaluation​

class GatekeeperEvaluation {
const GatekeeperEvaluation({
required this.verdict,
required this.shouldCallOtaServer,
required this.installedReleaseVersion,
required this.targetReleaseVersion,
required this.currentPatchNumber,
required this.latestPatchNumber,
required this.reason,
});

final GatekeeperVerdict verdict;
final bool shouldCallOtaServer;
final String installedReleaseVersion;
final String targetReleaseVersion;
final int currentPatchNumber;
final int latestPatchNumber;
final String reason;
}

Classe RemoteConfigGatekeeper​

class RemoteConfigGatekeeper {
const RemoteConfigGatekeeper();

GatekeeperEvaluation evaluate({
required String installedReleaseVersion,
required int? currentPatchNumber,
required OtaRemoteConfig remoteConfig,
});
}

3. Bouclier de sécurité & Rollback (src/security/ota_security_shield.dart)​

Classe OtaRollbackEvent & Typedef RollbackDetectedHandler​

typedef RollbackDetectedHandler = Future<void> Function(OtaRollbackEvent event);

class OtaRollbackEvent {
const OtaRollbackEvent({
required this.releaseVersion,
required this.previousPatchNumber,
required this.restoredPatchNumber,
required this.detectedAt,
});

final String releaseVersion;
final int previousPatchNumber;
final int restoredPatchNumber;
final DateTime detectedAt;


String toString();
}

Stockage et suivi de Rollback (OtaPatchStateStore, InMemoryOtaPatchStateStore, FileOtaPatchStateStore, OtaRollbackTracker)​

abstract class OtaPatchStateStore {
Future<int?> readLastExecutedPatch(String releaseVersion);
Future<void> writeLastExecutedPatch(String releaseVersion, int patchNumber);
}

class InMemoryOtaPatchStateStore implements OtaPatchStateStore {
InMemoryOtaPatchStateStore();

Future<int?> readLastExecutedPatch(String releaseVersion);

Future<void> writeLastExecutedPatch(String releaseVersion, int patchNumber);
}

class FileOtaPatchStateStore implements OtaPatchStateStore {
FileOtaPatchStateStore(this.stateFile);
final File stateFile;

Future<int?> readLastExecutedPatch(String releaseVersion);

Future<void> writeLastExecutedPatch(String releaseVersion, int patchNumber);
}

class OtaRollbackTracker {
OtaRollbackTracker({OtaPatchStateStore? store});

Future<OtaRollbackEvent?> evaluateAndRecord({
required String releaseVersion,
required int? currentPatchNumber,
});
}

Sécurité mobile (OtaSecurityViolationType, OtaSecurityVerdict, OtaSecurityPolicy)​

typedef SecurityViolationHandler = Future<void> Function(OtaSecurityVerdict verdict);

enum OtaSecurityViolationType {
apkSignatureMismatch,
deviceRootedOrJailbroken,
tlsCertificatePinningMismatch,
}

class OtaSecurityVerdict {
const OtaSecurityVerdict({
required this.isTrusted,
this.violationType,
this.reason,
this.observedApkSignatureSha256,
});

const OtaSecurityVerdict.trusted({this.observedApkSignatureSha256});

final bool isTrusted;
final OtaSecurityViolationType? violationType;
final String? reason;
final String? observedApkSignatureSha256;
}

class OtaSecurityPolicy {
const OtaSecurityPolicy({
this.expectedApkSignaturesSha256 = const {},
this.blockRootedOrJailbrokenDevices = false,
this.pinnedServerCertSha256Fingerprints = const {},
});

final Set<String> expectedApkSignaturesSha256;
final bool blockRootedOrJailbrokenDevices;
final Set<String> pinnedServerCertSha256Fingerprints;

static String normalizeSha256(String fingerprint);
}

Inspecteurs d'intégrité (OtaDeviceIntegrityInspector, DefaultOtaDeviceIntegrityInspector)​

abstract class OtaDeviceIntegrityInspector {
Future<String?> readInstalledApkSignatureSha256();
Future<bool> isDeviceRootedOrJailbroken();
Future<OtaSecurityVerdict> evaluatePolicy(OtaSecurityPolicy policy);
}

class DefaultOtaDeviceIntegrityInspector extends OtaDeviceIntegrityInspector {
DefaultOtaDeviceIntegrityInspector({
this.apkSignatureProvider,
List<String>? customSuspiciousPaths,
});

final Future<String?> Function()? apkSignatureProvider;


Future<String?> readInstalledApkSignatureSha256();

Future<bool> isDeviceRootedOrJailbroken();
}

Certificate Pinning TLS (OtaCertificatePinner, OtaPinnedHttpOverrides)​

class OtaCertificatePinner {
OtaCertificatePinner({
required Set<String> pinnedSha256Fingerprints,
this.enforcedHosts = const {},
});

final Set<String> enforcedHosts;

static String computeDerSha256Hex(List<int> derBytes);
bool verifyCertificateDer(List<int> derBytes, {String? host});
bool verifyX509Certificate(X509Certificate cert, {String? host});
}

class OtaPinnedHttpOverrides extends HttpOverrides {
OtaPinnedHttpOverrides(this.pinner);

final OtaCertificatePinner pinner;


HttpClient createHttpClient(SecurityContext? context);
}

4. Environnement & Planification (src/environment/ota_environment.dart)​

enum OtaConnectivityType {
wifi,
ethernet,
mobile,
none,
}

class OtaDeviceConditions {
const OtaDeviceConditions({
required this.connectivity,
this.batteryPercentage = 100,
this.isCharging = false,
});

final OtaConnectivityType connectivity;
final int batteryPercentage;
final bool isCharging;

bool get isUnmeteredWifi;
bool get isOnline;
}

abstract class OtaEnvironmentMonitor {
Future<OtaDeviceConditions> checkConditions();
}

class DefaultOtaEnvironmentMonitor implements OtaEnvironmentMonitor {
const DefaultOtaEnvironmentMonitor({
this.defaultConnectivity = OtaConnectivityType.wifi,
this.defaultBatteryPercentage = 100,
});

final OtaConnectivityType defaultConnectivity;
final int defaultBatteryPercentage;


Future<OtaDeviceConditions> checkConditions();
}

abstract class OtaBackgroundScheduler {
Future<void> scheduleSilentUpdateTask({
required String taskUniqueName,
required bool requireWifi,
required bool requireBatteryNotLow,
});
}

class InMemoryOtaBackgroundScheduler implements OtaBackgroundScheduler {
InMemoryOtaBackgroundScheduler();

final List<String> scheduledTasks = [];


Future<void> scheduleSilentUpdateTask({
required String taskUniqueName,
required bool requireWifi,
required bool requireBatteryNotLow,
});
}

5. Gestionnaire d'assets OTA (src/assets/ota_asset_manager.dart)​

class OtaAssetIntegrityException implements Exception {
OtaAssetIntegrityException({
required this.assetKey,
required this.expectedSha256,
required this.actualSha256,
});

final String assetKey;
final String expectedSha256;
final String actualSha256;


String toString();
}

class OtaRemoteAssetDescriptor {
const OtaRemoteAssetDescriptor({
required this.assetKey,
required this.downloadUrl,
required this.expectedSha256,
});

final String assetKey;
final String downloadUrl;
final String expectedSha256;
}

class OtaAssetManager {
OtaAssetManager({
required this.cacheDirectory,
http.Client? httpClient,
});

final Directory cacheDirectory;

File cachedFileFor(OtaRemoteAssetDescriptor descriptor);

/// Lève [HttpException] si le statut HTTP != 200.
/// Lève [OtaAssetIntegrityException] si le SHA-256 calculé != expectedSha256.
Future<File> getOrDownloadAsset(
OtaRemoteAssetDescriptor descriptor, {
Map<String, String>? headers,
});
}

6. Types ré-exportés depuis shorebird_code_push​

lib/tk_ota_push.dart ré-exporte directement UpdateStatus, UpdateTrack et Patch :

class Patch {
const Patch({required this.number});
final int number;
}

enum UpdateStatus {
upToDate,
outdated,
restartRequired,
unavailable,
}

extension type const UpdateTrack(String value) {
static const staging = UpdateTrack('staging');
static const beta = UpdateTrack('beta');
static const stable = UpdateTrack('stable');
String get name => value;
}