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.dartsrc/models/ota_remote_config.dartsrc/gatekeeper/remote_config_gatekeeper.dartsrc/security/ota_security_shield.dartsrc/environment/ota_environment.dartsrc/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é / Getter | Type | Description |
|---|---|---|
static instance | TkOtaPush | Instance partagée initialisée via TkOtaPush.init (ou instance par défaut si non initialisée). |
appReleaseVersion | String | Version de base installée (ex: '1.0.0+3'). |
enableGatekeeper | bool | Active (true par défaut) ou désactive le filtrage RemoteConfigGatekeeper. |
requireWifiForSilentUpdate | bool | Si true, diffère les mises à jour silencieuses lorsque l'appareil n'est pas en Wi-Fi/Ethernet. |
minBatteryPercentageForSilentUpdate | int | Seuil minimal de batterie (défaut 20) requis hors charge pour une mise à jour silencieuse. |
securityPolicy | OtaSecurityPolicy | Politique active du bouclier de sécurité mobile. |
onCriticalUpdateRequired | CriticalUpdateHandler? | Callback invoqué lorsque remoteConfig.forceUpdate == true. |
onRollbackDetected | RollbackDetectedHandler? | Callback invoqué lorsqu'une régression de numéro de patch est détectée au démarrage. |
onSecurityViolation | SecurityViolationHandler? | Callback invoqué lorsque securityVerdict.isTrusted == false. |
track | UpdateTrack | Canal OTA actuellement écouté (UpdateTrack.stable par défaut). |
isAvailable | bool | true 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 :
verifyStartupAndHandleRollback(Étape 0a).- Évaluation de
securityPolicyviaOtaDeviceIntegrityInspector.evaluatePolicy(Étape 0b). - Évaluation des 3 conditions du
RemoteConfigGatekeeper. - 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;
}