Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ class LanternApp : Application() {
try {
val outboundSocks = systemProp("debug.lantern.outbound_socks").trim()
val tz = systemProp("debug.lantern.tz").trim()
if (outboundSocks.isEmpty() && tz.isEmpty()) return
val forceMeekOnly = systemProp("debug.lantern.force_meek_only").trim()
if (outboundSocks.isEmpty() && tz.isEmpty() && forceMeekOnly.isEmpty()) return

Mobile.setQAEnvOverrides(outboundSocks, tz)
Log.i(TAG, "QA env overrides applied: outbound_socks=$outboundSocks tz=$tz")
Mobile.setQAEnvOverrides(outboundSocks, tz, forceMeekOnly)
Log.i(TAG, "QA env overrides applied: outbound_socks=$outboundSocks tz=$tz force_meek_only=$forceMeekOnly")
} catch (e: Throwable) {
Log.e(TAG, "Failed to apply QA env overrides", e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class LanternVpnService :
logLevel = "trace"
deviceid = DeviceUtil.deviceId()
locale = DeviceUtil.getLanguageCode(this@LanternVpnService)
mcc = DeviceUtil.networkMcc(this@LanternVpnService)
telemetryConsent = isTelemetryEnabled()
env = getRadianceEnv()
platform = this@LanternVpnService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import org.getlantern.lantern.BuildConfig
import org.getlantern.lantern.LanternApp

Expand Down Expand Up @@ -41,6 +42,24 @@ object DeviceUtil {
return String.format("Android-%s", Build.VERSION.RELEASE)
}

// networkMcc returns the 3-digit Mobile Country Code of the cell
// tower the device is currently camped on. Empty string when
// unavailable (WiFi-only device, no signal, no telephony service).
// No runtime permission is required; networkOperator reflects the
// tower we're registered with regardless of which SIM is inserted.
fun networkMcc(context: Context): String {
return try {
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
?: return ""
if (tm.phoneType == TelephonyManager.PHONE_TYPE_NONE) return ""
val op = tm.networkOperator ?: ""
if (op.length >= 3) op.substring(0, 3) else ""
} catch (e: Exception) {
AppLogger.w("DeviceUtil", "Failed to read network MCC: ${e.message}")
""
}
}

fun model(): String {
return Build.MODEL ?: ""
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ replace github.com/quic-go/qpack => github.com/quic-go/qpack v0.5.1
require (
github.com/alecthomas/assert/v2 v2.3.0
github.com/getlantern/lantern-server-provisioner v0.0.0-20251031121934-8ea031fccfa9
github.com/getlantern/radiance v0.0.0-20260521164929-568c5ece4bcc
github.com/getlantern/radiance v0.0.0-20260524155314-e2c2e029a0f7
github.com/sagernet/sing-box v1.12.22
golang.org/x/mobile v0.0.0-20250711185624-d5bb5ecc55c0
golang.org/x/sys v0.41.0
Expand Down Expand Up @@ -172,7 +172,7 @@ require (
github.com/getlantern/domainfront v0.0.0-20260419161617-0bff0b2169f4 // indirect
github.com/getlantern/keepcurrent v0.0.0-20260422161259-54a4d9a93694 // indirect
github.com/getlantern/kindling v0.0.0-20260516120759-a9712f95df03 // indirect
github.com/getlantern/lantern-box v0.0.82 // indirect
github.com/getlantern/lantern-box v0.0.83-0.20260524155143-c467035b6497 // indirect
github.com/getlantern/lantern-water v0.0.0-20260317143726-e0ee64a11d90 // indirect
github.com/getlantern/osversion v0.0.0-20240418205916-2e84a4a4e175 // indirect
github.com/getlantern/pluriconfig v0.0.0-20251126214241-8cc8bc561535 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ github.com/getlantern/keepcurrent v0.0.0-20260422161259-54a4d9a93694 h1:iLWm6S/4
github.com/getlantern/keepcurrent v0.0.0-20260422161259-54a4d9a93694/go.mod h1:ag5g9aWUw2FJcX5RVRpJ9EBQBy5yJuy2WXDouIn/m4w=
github.com/getlantern/kindling v0.0.0-20260516120759-a9712f95df03 h1:dUTN7mnTTBcSvsURNs1rTlyKrD1uXUEPqxEZDfl+hb4=
github.com/getlantern/kindling v0.0.0-20260516120759-a9712f95df03/go.mod h1:TGTxpoNVwc8Be4qkBNtf5oj2psJaEIZEq47GOPS7zkA=
github.com/getlantern/lantern-box v0.0.82 h1:hCXqpCxLOQNxYtQZQDYVh3aj3t8NqSBqJjCn2mIBtK0=
github.com/getlantern/lantern-box v0.0.82/go.mod h1:wJhPQKdnwD6qW/ghAfzsrj/IfHZbvFSAfr52+Tu6dbw=
github.com/getlantern/lantern-box v0.0.83-0.20260524155143-c467035b6497 h1:yXtbk9i03UD7/S5NYoMjKqE+LfuzPs/t0S3SDTesr6Q=
github.com/getlantern/lantern-box v0.0.83-0.20260524155143-c467035b6497/go.mod h1:wJhPQKdnwD6qW/ghAfzsrj/IfHZbvFSAfr52+Tu6dbw=
github.com/getlantern/lantern-server-provisioner v0.0.0-20251031121934-8ea031fccfa9 h1:6seyD2f9tz2am0YQd/Qn+q7LFiiQgnmxgwWFnVceGZw=
github.com/getlantern/lantern-server-provisioner v0.0.0-20251031121934-8ea031fccfa9/go.mod h1:s0VKrlJf/z+M0U8IKHFL2hfuflocRw3SINmMacrTlMA=
github.com/getlantern/lantern-water v0.0.0-20260317143726-e0ee64a11d90 h1:P9JX1yAu2uq3b5YiT0sLtHkTrkZuttV8gPZh81nUuag=
Expand All @@ -261,8 +261,8 @@ github.com/getlantern/pluriconfig v0.0.0-20251126214241-8cc8bc561535 h1:rtDmW8YL
github.com/getlantern/pluriconfig v0.0.0-20251126214241-8cc8bc561535/go.mod h1:WKJEdjMOD4IuTRYwjQHjT4bmqDl5J82RShMLxPAvi0Q=
github.com/getlantern/publicip v0.0.0-20260328175246-2c460fe80c6b h1:gMYJzEhLrmIqQ+JnjiYNm+UyUDalK3WUmVyecFwmV5g=
github.com/getlantern/publicip v0.0.0-20260328175246-2c460fe80c6b/go.mod h1:NpfXdK4ldEKkjQ4P1R+DBF4ua5VFOlxmgHROTnYrApg=
github.com/getlantern/radiance v0.0.0-20260521164929-568c5ece4bcc h1:dHSMAgafZhDmEsx8uAZDnWQA/w6C9Odm3zPKgzQeW9U=
github.com/getlantern/radiance v0.0.0-20260521164929-568c5ece4bcc/go.mod h1:sX6xqbFpHlPXcRF+26iNhKbD+1h9IKcFTesWEDIaMjY=
github.com/getlantern/radiance v0.0.0-20260524155314-e2c2e029a0f7 h1:+uacxj2L28bm26gGEc5dSL5DQTU37gVQgYRI2KCUTTs=
github.com/getlantern/radiance v0.0.0-20260524155314-e2c2e029a0f7/go.mod h1:zvt5D0njMmI0N5tqLkDO5YkEjNnoKgxJqrf1xunUsfw=
github.com/getlantern/samizdat v0.0.3-0.20260327203406-ef7323341974 h1:k+/qNo5YNO+8M8LVUp6G5Evm1OQdEs3Z4ye8top4AhI=
github.com/getlantern/samizdat v0.0.3-0.20260327203406-ef7323341974/go.mod h1:uEeykQSW2/6rTjfPlj3MTTo59poSHXfAHTGgzYDkbr0=
github.com/getlantern/semconv v0.0.0-20260327040646-21845dda05cb h1:c5YM7b3a4r2J8Eh89KkI6M/iTFe6Bi+b8AJlfkKdFq4=
Expand Down
1 change: 1 addition & 0 deletions lantern-core/init_mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func createClient(ctx context.Context, opts *utils.Opts) (*ipc.Client, error) {
DeviceID: opts.Deviceid,
LogLevel: opts.LogLevel,
Locale: opts.Locale,
MCC: opts.Mcc,
TelemetryConsent: opts.TelemetryConsent,
}
return ipc.NewClient(ctx, backendOpts)
Expand Down
9 changes: 8 additions & 1 deletion lantern-core/mobile/mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func getClient() (*ipc.Client, error) {
}

// SetQAEnvOverrides applies QA-only environment overrides before Radiance starts.
func SetQAEnvOverrides(outboundSocks, tz string) error {
func SetQAEnvOverrides(outboundSocks, tz, forceMeekOnly string) error {
if outboundSocks != "" {
if err := os.Setenv("RADIANCE_OUTBOUND_SOCKS_ADDRESS", outboundSocks); err != nil {
return fmt.Errorf("set RADIANCE_OUTBOUND_SOCKS_ADDRESS: %w", err)
Expand All @@ -103,6 +103,12 @@ func SetQAEnvOverrides(outboundSocks, tz string) error {
}
slog.Info("QA env override set", "name", "TZ", "value", tz)
}
if forceMeekOnly != "" {
if err := os.Setenv("RADIANCE_FORCE_MEEK_ONLY", forceMeekOnly); err != nil {
return fmt.Errorf("set RADIANCE_FORCE_MEEK_ONLY: %w", err)
}
slog.Info("QA env override set", "name", "RADIANCE_FORCE_MEEK_ONLY", "value", forceMeekOnly)
}
return nil
}

Expand Down Expand Up @@ -294,6 +300,7 @@ func StartIPCServer(platform utils.PlatformInterface, opts *utils.Opts) error {
Locale: opts.Locale,
LogLevel: opts.LogLevel,
DeviceID: opts.Deviceid,
MCC: opts.Mcc,
TelemetryConsent: opts.TelemetryConsent,
PlatformInterface: platform,
}
Expand Down
6 changes: 6 additions & 0 deletions lantern-core/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ type Opts struct {
LogLevel string
Locale string
Env string
// Mcc is the network Mobile Country Code, read by the host from
// the cellular stack (Android: first 3 chars of
// TelephonyManager.getNetworkOperator()). Empty on WiFi-only,
// no cellular signal, or platforms that don't expose it. Used
// by radiance to gate activation of the heavier meek transport.
Mcc string
TelemetryConsent bool
Platform PlatformInterface
}
Expand Down
Loading