From 5795e58586fbdd206b49d87fa3f031dcc5c1bcd7 Mon Sep 17 00:00:00 2001 From: Alexander Anisimov Date: Wed, 6 May 2026 22:07:59 +0300 Subject: [PATCH 1/2] fix mobile conection check --- mobile/mobile.go | 100 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/mobile/mobile.go b/mobile/mobile.go index 5a74367..f37750c 100644 --- a/mobile/mobile.go +++ b/mobile/mobile.go @@ -54,6 +54,7 @@ var ( mu sync.Mutex defaults mobileConfig defaultsSet sync.Once + registerSet sync.Once cancel context.CancelFunc done chan struct{} ready chan struct{} @@ -169,6 +170,96 @@ func StartWithTransport( return startWithConfig(carrierName, transportName, roomID, clientID, keyHex, socksPort, socksUser, socksPass, cfg) } +// Check starts an isolated short-lived client and returns elapsed milliseconds once ready. +// It does not use the singleton Start/Stop runtime, so callers may run checks in parallel. +func Check( + carrierName, transportName, roomID, clientID, keyHex string, + socksPort int, + timeoutMillis int, + vp8FPS int, + vp8BatchSize int, +) (int64, error) { + registerDefaults() + carrierName = normalizeCarrier(carrierName) + transportName = normalizeTransport(transportName) + + switch { + case carrierName == "": + return 0, errCarrierRequired + case roomID == "" && carrierName != "jazz": + return 0, errRoomIDRequired + case clientID == "": + return 0, errClientIDRequired + case keyHex == "": + return 0, errKeyHexRequired + } + + if timeoutMillis <= 0 { + timeoutMillis = 8000 + } + + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + + readyCh := make(chan struct{}) + doneCh := make(chan error, 1) + var readyOnce sync.Once + startedAt := time.Now() + + go func() { + doneCh <- client.RunWithReady( + ctx, + defaultLink, + transportName, + carrierName, + buildRoomURL(carrierName, roomID), + keyHex, + clientID, + fmt.Sprintf("127.0.0.1:%d", socksPort), + defaultDNSServer, + "", + "", + func() { + readyOnce.Do(func() { + close(readyCh) + }) + }, + 0, + 0, + 0, + "", + "", + 0, + "", + "", + 0, + 0, + clamp(vp8FPS, 1, 120), + clamp(vp8BatchSize, 1, 64), + ) + }() + + timer := time.NewTimer(time.Duration(timeoutMillis) * time.Millisecond) + defer timer.Stop() + + select { + case <-readyCh: + elapsed := time.Since(startedAt).Milliseconds() + cancelFunc() + waitForCheckDone(doneCh) + return elapsed, nil + case err := <-doneCh: + if err != nil { + return 0, err + } + return 0, errStoppedBeforeReady + case <-timer.C: + cancelFunc() + waitForCheckDone(doneCh) + return 0, errStartTimedOut + } +} + func startWithConfig( carrierName, transportName, roomID, clientID, keyHex string, socksPort int, @@ -330,7 +421,14 @@ func IsRunning() bool { } func registerDefaults() { - session.RegisterDefaults() + registerSet.Do(session.RegisterDefaults) +} + +func waitForCheckDone(doneCh <-chan error) { + select { + case <-doneCh: + case <-time.After(2 * time.Second): + } } func ensureDefaultConfigLocked() { From cd0a2fce46088476c7b91dec1280a060a301e59a Mon Sep 17 00:00:00 2001 From: Alexander Anisimov Date: Wed, 6 May 2026 22:24:49 +0300 Subject: [PATCH 2/2] fix: satisfy mobile lint checks --- mobile/mobile.go | 58 +++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/mobile/mobile.go b/mobile/mobile.go index f37750c..d4aa958 100644 --- a/mobile/mobile.go +++ b/mobile/mobile.go @@ -47,6 +47,7 @@ const ( dataTransport = "datachannel" defaultDNSServer = "1.1.1.1:53" carrierWBStream = "wbstream" + carrierJazz = "jazz" ) //nolint:gochecknoglobals // Mobile bindings expose a singleton runtime controlled by the embedding app. @@ -124,8 +125,8 @@ func SetVP8Options(fps, batchSize int) { mu.Lock() defer mu.Unlock() ensureDefaultConfigLocked() - defaults.vp8FPS = clamp(fps, 1, 120) - defaults.vp8BatchSize = clamp(batchSize, 1, 64) + defaults.vp8FPS = clamp(fps, 120) + defaults.vp8BatchSize = clamp(batchSize, 64) } // SetDebug enables or disables verbose logging. @@ -182,16 +183,8 @@ func Check( registerDefaults() carrierName = normalizeCarrier(carrierName) transportName = normalizeTransport(transportName) - - switch { - case carrierName == "": - return 0, errCarrierRequired - case roomID == "" && carrierName != "jazz": - return 0, errRoomIDRequired - case clientID == "": - return 0, errClientIDRequired - case keyHex == "": - return 0, errKeyHexRequired + if err := validateStartArgs(carrierName, roomID, clientID, keyHex); err != nil { + return 0, err } if timeoutMillis <= 0 { @@ -234,8 +227,8 @@ func Check( "", 0, 0, - clamp(vp8FPS, 1, 120), - clamp(vp8BatchSize, 1, 64), + clamp(vp8FPS, 120), + clamp(vp8BatchSize, 64), ) }() @@ -275,17 +268,11 @@ func startWithConfig( cfg.transport = normalizeTransport(transportName) } - switch { - case cancel != nil: + if cancel != nil { return errAlreadyRunning - case carrierName == "": - return errCarrierRequired - case roomID == "" && carrierName != "jazz": - return errRoomIDRequired - case clientID == "": - return errClientIDRequired - case keyHex == "": - return errKeyHexRequired + } + if err := validateStartArgs(carrierName, roomID, clientID, keyHex); err != nil { + return err } roomURL := buildRoomURL(carrierName, roomID) @@ -461,11 +448,26 @@ func normalizeCarrier(carrierName string) string { return carrierName } +func validateStartArgs(carrierName, roomID, clientID, keyHex string) error { + switch { + case carrierName == "": + return errCarrierRequired + case roomID == "" && carrierName != carrierJazz: + return errRoomIDRequired + case clientID == "": + return errClientIDRequired + case keyHex == "": + return errKeyHexRequired + default: + return nil + } +} + func buildRoomURL(carrierName, roomID string) string { switch carrierName { case "telemost": return "https://telemost.yandex.ru/j/" + roomID - case "jazz": + case carrierJazz: if roomID == "" { return "any" } @@ -477,9 +479,9 @@ func buildRoomURL(carrierName, roomID string) string { } } -func clamp(value, minValue, maxValue int) int { - if value < minValue { - return minValue +func clamp(value, maxValue int) int { + if value < 1 { + return 1 } if value > maxValue { return maxValue