From f16a07cc6c73229ecbde31e2a7d79ff326212e9e Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Sun, 29 Mar 2026 16:48:45 +0800 Subject: [PATCH] Batch 5: remove silent desktop gateway fallback --- ...p_controller_desktop_settings_runtime.dart | 1 - lib/runtime/gateway_runtime_core.dart | 7 ++- test/runtime/gateway_runtime_suite.dart | 43 ++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/app/app_controller_desktop_settings_runtime.dart b/lib/app/app_controller_desktop_settings_runtime.dart index cb0de2a8..6804328a 100644 --- a/lib/app/app_controller_desktop_settings_runtime.dart +++ b/lib/app/app_controller_desktop_settings_runtime.dart @@ -301,7 +301,6 @@ extension AppControllerDesktopSettingsRuntime on AppController { final runtime = GatewayRuntime( store: temporaryStore, identityStore: DeviceIdentityStore(temporaryStore), - sessionClient: GoGatewayRuntimeDesktopClient(), ); await runtime.initialize(); try { diff --git a/lib/runtime/gateway_runtime_core.dart b/lib/runtime/gateway_runtime_core.dart index 0d7dab14..728e9f4b 100644 --- a/lib/runtime/gateway_runtime_core.dart +++ b/lib/runtime/gateway_runtime_core.dart @@ -26,10 +26,13 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { required SecureConfigStore store, required DeviceIdentityStore identityStore, GatewayRuntimeSessionClient? sessionClient, + bool allowDirectSocketFallbackOnSessionClientFailure = false, String runtimeId = '', }) : storeInternal = store, identityStoreInternal = identityStore, sessionClientInternal = sessionClient, + allowDirectSocketFallbackOnSessionClientFailureInternal = + allowDirectSocketFallbackOnSessionClientFailure, runtimeIdInternal = runtimeId.trim().isNotEmpty ? runtimeId.trim() : randomIdInternal(); @@ -37,6 +40,7 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { final SecureConfigStore storeInternal; final DeviceIdentityStore identityStoreInternal; final GatewayRuntimeSessionClient? sessionClientInternal; + final bool allowDirectSocketFallbackOnSessionClientFailureInternal; final String runtimeIdInternal; final StreamController eventsInternal = StreamController.broadcast(); @@ -292,7 +296,8 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { notifyListeners(); return; } on GatewayRuntimeException catch (error) { - if (_shouldFallbackToDirectRuntimeInternal(error)) { + if (allowDirectSocketFallbackOnSessionClientFailureInternal && + _shouldFallbackToDirectRuntimeInternal(error)) { appendLogInternal( this, 'warn', diff --git a/test/runtime/gateway_runtime_suite.dart b/test/runtime/gateway_runtime_suite.dart index 24ab311f..41f144b5 100644 --- a/test/runtime/gateway_runtime_suite.dart +++ b/test/runtime/gateway_runtime_suite.dart @@ -225,7 +225,7 @@ void main() { ); test( - 'GatewayRuntime falls back to direct websocket when go-core bridge is unavailable', + 'GatewayRuntime does not silently fall back to direct websocket when go-core bridge is unavailable', () async { SharedPreferences.setMockInitialValues({}); final store = createIsolatedTestStore(); @@ -243,6 +243,47 @@ void main() { addTearDown(runtime.dispose); addTearDown(server.close); + await runtime.initialize(); + await expectLater( + () => runtime.connectProfile( + GatewayConnectionProfile.defaults().copyWith( + mode: RuntimeConnectionMode.local, + host: '127.0.0.1', + port: server.port, + tls: false, + useSetupCode: false, + ), + authTokenOverride: 'shared-token-from-form', + ), + throwsA(isA()), + ); + + expect(server.connectAuth, isNull); + expect(runtime.snapshot.status, RuntimeConnectionStatus.error); + expect(runtime.snapshot.lastErrorCode, 'GO_GATEWAY_RUNTIME_ENDPOINT_MISSING'); + }, + ); + + test( + 'GatewayRuntime can explicitly fall back to direct websocket when enabled', + () async { + SharedPreferences.setMockInitialValues({}); + final store = createIsolatedTestStore(); + final runtime = GatewayRuntime( + store: store, + identityStore: DeviceIdentityStore(store), + sessionClient: _FakeGatewayRuntimeSessionClient( + connectError: GatewayRuntimeException( + 'go bridge unavailable', + code: 'GO_GATEWAY_RUNTIME_ENDPOINT_MISSING', + ), + ), + allowDirectSocketFallbackOnSessionClientFailure: true, + ); + final server = await FakeGatewayRuntimeServerInternal.start(); + addTearDown(runtime.dispose); + addTearDown(server.close); + await runtime.initialize(); await runtime.connectProfile( GatewayConnectionProfile.defaults().copyWith(