initializeServices static method
Initialize service bridges.
This is Phase 2 of 2-phase initialization:
- Setup HTTP transport/native config (if needed)
- Register platform-owned async callbacks and secure-storage caches
- Initialize C++ state/auth secure storage with resolved credentials
- Drive commons-owned deterministic Phase 2 orchestration
Call this AFTER Phase 1. Can be called in background.
apiKey API key for production/staging
baseURL Backend URL for production/staging
deviceId Device identifier
Implementation
static Future<SdkInitResult?> initializeServices({
String? apiKey,
String? baseURL,
String? deviceId,
String? buildToken,
bool forceRefreshAssignments = false,
bool flushTelemetry = true,
bool discoverDownloadedModels = true,
bool rescanLocalModels = true,
}) async {
if (!_isInitialized) {
throw StateError('Must call initialize() before initializeServices()');
}
if (_servicesInitialized) {
_logger.debug('Services already initialized, skipping');
return null;
}
_logger.debug('Starting Phase 2 services initialization');
// Step 1: HTTP transport — configure C++ HTTP layer BEFORE phase2 so that
// rac_sdk_init_phase2_proto's device-registration POST has a live transport.
// Mirrors Swift Step 1 in _performServicesInitialization(): setupHTTP runs
// before CppBridge.SdkInit.phase2() (RunAnywhere.swift:266-279 → :287).
if (!DartBridgeHTTP.instance.isConfigured) {
try {
await DartBridgeHTTP.instance.configure(
environment: _environment,
apiKey: apiKey,
baseURL: baseURL,
);
_logger.debug('HTTP transport configured');
} catch (_) {
_logger.warning('HTTP setup failed; SDK remains offline');
}
}
// Step 2: Register platform-owned async callbacks before commons Phase 2.
// Device registration itself is owned by rac_sdk_init_phase2_proto; this
// call only installs callbacks, SharedPreferences, and the cached device id.
await DartBridgeDevice.register(
environment: _environment,
baseURL: baseURL,
);
_logger.debug('Device callbacks wired for Phase 2');
// Platform services registration also drains the async secure-storage cache
// used by commons device/model discovery callbacks.
await DartBridgePlatform.registerServices();
_logger.debug('Platform services registered');
// Step 3: Install auth secure storage now that platform async caches are
// ready. Commons Phase 1 already owns rac_state_initialize with the
// resolved credentials/device ID.
await DartBridgeState.instance.initialize(
environment: _environment,
baseURL: baseURL,
);
_logger.debug('Auth secure storage initialized');
// Step 4: Drive the canonical Phase 2 step-list inside commons. HTTP and
// platform callbacks are configured, and model paths are set by
// RunAnywhere._runPhase2 before this call so commons can discover local
// downloads through the global registry.
// Soft failures (offline mode, missing creds) come back as
// success=true + warning; hard failures throw.
SdkInitResult? phase2Result;
try {
final result = DartBridgeSdkInit.phase2(
SdkInitPhase2Request(
buildToken: buildToken ?? DartBridgeDevConfig.buildToken ?? '',
forceRefreshAssignments: forceRefreshAssignments,
flushTelemetry: flushTelemetry,
discoverDownloadedModels: discoverDownloadedModels,
rescanLocalModels: rescanLocalModels,
),
);
phase2Result = result;
_logger.debug(
'SDK Phase 2 (proto) complete',
metadata: {
'httpConfigured': result.httpConfigured,
'deviceRegistered': result.deviceRegistered,
'linkedModelsCount': result.linkedModelsCount,
'discoveredOrphans': result.discoveredOrphans,
'hasCompletedHttpSetup': result.hasCompletedHttpSetup,
'durationMs': result.durationMs.toInt(),
'hasWarning': result.hasWarning(),
},
);
} catch (_) {
// Non-fatal: services init may still succeed via the per-bridge
// registrations below even when the C++ step-list reports an error.
_logger.warning('SDK Phase 2 proto failed');
}
// Flutter-only async bridge: commons Phase 2 owns device registration,
// but the Dart FFI device http_post callback can only capture the request.
// Drain the captured POST after the C ABI returns.
await DartBridgeDevice.flushPendingRegistrationPost();
_servicesInitialized = true;
_logger.info('Phase 2 services initialization complete');
return phase2Result;
}