Ostrich VPN v1.19.0222版本的 MD5 值为:1b442e5f3dd93fd660d88d6f4b94ace3
以下内容为反编译后的 VpnControlService.java 源代码,内容仅作参考
package com.best.free.vpn.proxy.connect;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.VpnService;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import androidx.core.app.NotificationCompat;
import com.best.free.vpn.proxy.connect.VpnControlService;
import com.best.free.vpn.proxy.connect.bean.Dns;
import com.best.free.vpn.proxy.connect.bean.V2rayConfig;
import com.best.free.vpn.proxy.util.LogKt;
import com.beust.klaxon.JsonObject;
import com.beust.klaxon.Klaxon;
import com.google.android.gms.common.Scopes;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
import kotlin.Metadata;
import kotlin.Unit;
import kotlin.concurrent.ThreadsKt;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.Reflection;
import kotlin.text.Charsets;
import kotlin.text.StringsKt;
import org.greenrobot.eventbus.EventBus;
import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.logic.CharonVpnService;
import org.strongswan.android.logic.Ikev2Callback;
import org.strongswan.android.logic.VpnStateService;
import protocol.openvpn.lib.OVErrorCode;
import protocol.openvpn.lib.OpenVpnCallback;
import protocol.openvpn.lib.OpenVpnClient;
import tun2socks.PacketFlow;
import tun2socks.Tun2socks;
@Metadata(d1 = {"\u0000\u0091\u0001\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u000b\n\u0000\n\u0002\b\u0003\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010 \n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0007\n\u0002\u0018\u0002\n\u0002\b\n*\u0001\u0019\u0018\u00002\u00020\u0001:\u0003<=>B\u0005¢\u0006\u0002\u0010\u0002J(\u0010\u001b\u001a\u00020\u001c2\u0006\u0010\u001d\u001a\u00020\u001e2\u0006\u0010\u001f\u001a\u00020\u00172\u000e\u0010 \u001a\n\u0012\u0004\u0012\u00020\u0004\u0018\u00010!H\u0002J\u0010\u0010\"\u001a\u00020\u001c2\u0006\u0010#\u001a\u00020$H\u0002J\u0010\u0010%\u001a\u00020\u001c2\u0006\u0010#\u001a\u00020&H\u0002J\n\u0010'\u001a\u00060(R\u00020\u0001J\b\u0010)\u001a\u00020\u001cH\u0002J\u0014\u0010*\u001a\u0004\u0018\u00010+2\b\u0010,\u001a\u0004\u0018\u00010-H\u0016J\b\u0010.\u001a\u00020\u001cH\u0016J\b\u0010/\u001a\u00020\u001cH\u0016J\b\u00100\u001a\u00020\u001cH\u0016J\b\u00101\u001a\u00020\u001cH\u0002J\u0010\u00102\u001a\u00020\u001c2\u0006\u00103\u001a\u00020\u0004H\u0002J\u0014\u00104\u001a\u00020\u001c2\f\u0010#\u001a\b\u0012\u0002\b\u0003\u0018\u000105J(\u00106\u001a\u00020\u001c2\u0006\u00107\u001a\u00020\u00042\u000e\u00108\u001a\n\u0012\u0004\u0012\u00020\u0004\u0018\u00010!2\u0006\u0010\u001f\u001a\u00020\u0017H\u0002J\u0006\u00109\u001a\u00020\u001cJ\b\u0010:\u001a\u00020\u001cH\u0002J\b\u0010;\u001a\u00020\u001cH\u0002R\u0016\u0010\u0003\u001a\n \u0005*\u0004\u0018\u00010\u00040\u0004X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u0006\u001a\u00020\u0007X\u0082.¢\u0006\u0002\n\u0000R\u0012\u0010\b\u001a\u00060\tR\u00020\u0000X\u0082\u0004¢\u0006\u0002\n\u0000R\u0016\u0010\n\u001a\n \u0005*\u0004\u0018\u00010\u000b0\u000bX\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\f\u001a\u0004\u0018\u00010\rX\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u000e\u001a\u0004\u0018\u00010\u000fX\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u0010\u001a\u0004\u0018\u00010\u0011X\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u0012\u001a\u0004\u0018\u00010\u0013X\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u0014\u001a\u0004\u0018\u00010\u0015X\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\u0016\u001a\u00020\u0017X\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u0018\u001a\u00020\u0019X\u0082\u0004¢\u0006\u0004\n\u0002\u0010\u001a¨\u0006?"}, d2 = {"Lcom/best/free/vpn/proxy/connect/VpnControlService;", "Landroid/net/VpnService;", "()V", "TAG", "", "kotlin.jvm.PlatformType", "bgThread", "Ljava/lang/Thread;", "binder", "Lcom/best/free/vpn/proxy/connect/VpnControlService$LocalBinder;", "buffer", "Ljava/nio/ByteBuffer;", "ikev2Service", "Lorg/strongswan/android/logic/CharonVpnService;", "inputStream", "Ljava/io/FileInputStream;", "openVpnClient", "Lprotocol/openvpn/lib/OpenVpnClient;", "outputStream", "Ljava/io/FileOutputStream;", "pfd", "Landroid/os/ParcelFileDescriptor;", "running", "", "v2rayBroadcastReceiver", "com/best/free/vpn/proxy/connect/VpnControlService$v2rayBroadcastReceiver$1", "Lcom/best/free/vpn/proxy/connect/VpnControlService$v2rayBroadcastReceiver$1;", "connectIkev2", "", Scopes.PROFILE, "Lorg/strongswan/android/data/VpnProfile;", "proxySelf", "ignoreApp", "", "connectOpenVpn", "config", "Lcom/best/free/vpn/proxy/connect/OVProfileConfig;", "connectV2rayVpn", "Lcom/best/free/vpn/proxy/connect/V2rayProfileConfig;", "createBuilder", "Landroid/net/VpnService$Builder;", "handlePackets", "onBind", "Landroid/os/IBinder;", "intent", "Landroid/content/Intent;", "onCreate", "onDestroy", "onRevoke", "registerV2rayReceivers", "safeRegisterReceiver", "name", "start", "Lcom/best/free/vpn/proxy/connect/ProfileConfig;", "startV2ray", "configString", "ignoreApps", "stopConnection", "stopV2ray", "tearDownActiveConnection", "Flow", "LocalBinder", "Service", "vpnkt-v1.19.0(222)_release"}, k = 1, mv = {1, 9, 0}, xi = 48)
public final class VpnControlService extends VpnService {
private Thread bgThread;
private CharonVpnService ikev2Service;
private FileInputStream inputStream;
private OpenVpnClient openVpnClient;
private FileOutputStream outputStream;
private ParcelFileDescriptor pfd;
private volatile boolean running;
private final LocalBinder binder = new LocalBinder();
private final String TAG = getClass().getSimpleName();
private final VpnControlService$v2rayBroadcastReceiver$1 v2rayBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context contxt, Intent intent) {
String action = intent != null ? intent.getAction() : null;
if (action != null) {
switch (action.hashCode()) {
case -1005573711:
if (action.equals("stop_v2ray")) {
VpnControlService.this.stopV2ray();
EventBus.getDefault().post(new ConnectEvent(4L));
return;
}
return;
case -230906038:
if (!action.equals("v2ray_start_err_config")) {
return;
}
break;
case 831577399:
if (!action.equals("v2ray_start_err")) {
return;
}
break;
case 2123768176:
if (action.equals("v2ray_started")) {
EventBus.getDefault().post(new ConnectEvent(1L));
return;
}
return;
default:
return;
}
EventBus.getDefault().post(new ConnectEvent(3L));
VpnControlService.this.stopV2ray();
}
}
};
private ByteBuffer buffer = ByteBuffer.allocate(1501);
@Metadata(d1 = {"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0003\b\u0086\u0004\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002R\u0011\u0010\u0003\u001a\u00020\u00048F¢\u0006\u0006\u001a\u0004\b\u0005\u0010\u0006¨\u0006\u0007"}, d2 = {"Lcom/best/free/vpn/proxy/connect/VpnControlService$LocalBinder;", "Landroid/os/Binder;", "(Lcom/best/free/vpn/proxy/connect/VpnControlService;)V", NotificationCompat.CATEGORY_SERVICE, "Lcom/best/free/vpn/proxy/connect/VpnControlService;", "getService", "()Lcom/best/free/vpn/proxy/connect/VpnControlService;", "vpnkt-v1.19.0(222)_release"}, k = 1, mv = {1, 9, 0}, xi = 48)
public final class LocalBinder extends Binder {
public final VpnControlService getThis$0() {
return VpnControlService.this;
}
public LocalBinder() {
}
}
@Override
public IBinder onBind(Intent intent) {
return this.binder;
}
@Override
public void onCreate() {
super.onCreate();
registerV2rayReceivers();
}
@Override
public void onDestroy() {
super.onDestroy();
tearDownActiveConnection();
EventBus.getDefault().post(new ConnectEvent(4L));
try {
unregisterReceiver(this.v2rayBroadcastReceiver);
} catch (Exception unused) {
LogKt.logD("already unRegister");
}
}
private final void registerV2rayReceivers() {
safeRegisterReceiver("stop_v2ray");
safeRegisterReceiver("v2ray_stopped");
safeRegisterReceiver("v2ray_started");
safeRegisterReceiver("v2ray_start_err");
safeRegisterReceiver("v2ray_start_err_config");
}
private final void safeRegisterReceiver(String name) {
try {
if (Build.VERSION.SDK_INT > 33) {
registerReceiver(this.v2rayBroadcastReceiver, new IntentFilter(name), 2);
} else {
registerReceiver(this.v2rayBroadcastReceiver, new IntentFilter(name));
}
} catch (Exception unused) {
LogKt.logD("already registered " + name);
}
}
@Override
public void onRevoke() {
super.onRevoke();
tearDownActiveConnection();
EventBus.getDefault().post(4L);
}
public final void start(ProfileConfig<?> config) {
if (config instanceof Ikev2StartConfig) {
Ikev2StartConfig ikev2StartConfig = (Ikev2StartConfig) config;
connectIkev2(ikev2StartConfig.getConfig().getConfig(), ikev2StartConfig.getConfig().getProxySelf(), ikev2StartConfig.getConfig().getIgnoreApp());
} else if (config instanceof OVStartConfig) {
connectOpenVpn(((OVStartConfig) config).getConfig());
} else if (config instanceof V2rayStartConfig) {
connectV2rayVpn(((V2rayStartConfig) config).getConfig());
}
}
private final void connectOpenVpn(OVProfileConfig config) {
tearDownActiveConnection();
if (this.openVpnClient == null) {
this.openVpnClient = new OpenVpnClient(this);
}
OpenVpnClient openVpnClient = this.openVpnClient;
Intrinsics.checkNotNull(openVpnClient);
openVpnClient.start(config, new OpenVpnCallback() {
@Override
public void onSuccess() {
new OpenVpnConfigHelper().clearConfigFiles();
EventBus.getDefault().post(new ConnectEvent(1L));
}
@Override
public void onFailed(OVErrorCode errorCode) {
Intrinsics.checkNotNullParameter(errorCode, "errorCode");
new OpenVpnConfigHelper().clearConfigFiles();
VpnControlService.this.tearDownActiveConnection();
EventBus eventBus = EventBus.getDefault();
ConnectEvent connectEvent = new ConnectEvent(3L);
connectEvent.setErrorMsg(errorCode.toString());
eventBus.post(connectEvent);
}
});
}
private final void connectIkev2(VpnProfile profile, boolean proxySelf, List<String> ignoreApp) {
String TAG = this.TAG;
Intrinsics.checkNotNullExpressionValue(TAG, "TAG");
LogKt.logD(TAG, "ikev2 开始连接");
EventBus.getDefault().post(new ConnectEvent(2L));
if (this.ikev2Service == null) {
this.ikev2Service = new CharonVpnService(this);
}
CharonVpnService charonVpnService = this.ikev2Service;
if (charonVpnService != null) {
charonVpnService.start(profile, proxySelf, ignoreApp, new Ikev2Callback() {
@Override
public void onSuccess() {
String str;
str = VpnControlService.this.TAG;
Intrinsics.checkNotNullExpressionValue(str, "access$getTAG$p(...)");
LogKt.logD(str, "ikev2 连接成功");
EventBus.getDefault().post(new ConnectEvent(1L));
}
@Override
public void onFailed(VpnStateService.ErrorState state) {
String str;
str = VpnControlService.this.TAG;
Intrinsics.checkNotNullExpressionValue(str, "access$getTAG$p(...)");
LogKt.logD(str, "ikev2 连接失败:--》 " + state);
EventBus eventBus = EventBus.getDefault();
ConnectEvent connectEvent = new ConnectEvent(3L);
connectEvent.setErrorMsg(String.valueOf(state));
eventBus.post(connectEvent);
}
});
}
}
public final void stopConnection() {
tearDownActiveConnection();
EventBus.getDefault().post(new ConnectEvent(4L));
}
public final void tearDownActiveConnection() {
OpenVpnClient openVpnClient = this.openVpnClient;
if (openVpnClient != null) {
openVpnClient.stop();
}
CharonVpnService charonVpnService = this.ikev2Service;
if (charonVpnService != null) {
charonVpnService.destroy();
}
this.ikev2Service = null;
sendBroadcast(new Intent("stop_v2ray"));
}
public final VpnService.Builder createBuilder() {
return new VpnService.Builder(this);
}
private final void connectV2rayVpn(V2rayProfileConfig config) {
EventBus.getDefault().post(new ConnectEvent(2L));
startV2ray(config.getVmessConfig(), config.getIgnoreApp(), config.getProxySelf());
}
public final void stopV2ray() {
try {
Tun2socks.stopV2Ray();
} catch (Error e) {
e.printStackTrace();
}
ParcelFileDescriptor parcelFileDescriptor = this.pfd;
if (parcelFileDescriptor != null) {
parcelFileDescriptor.close();
}
this.pfd = null;
this.inputStream = null;
this.outputStream = null;
this.running = false;
}
@Metadata(d1 = {"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0012\n\u0000\u0018\u00002\u00020\u0001B\u000f\u0012\b\u0010\u0002\u001a\u0004\u0018\u00010\u0003¢\u0006\u0002\u0010\u0004J\u0012\u0010\u0006\u001a\u00020\u00072\b\u0010\b\u001a\u0004\u0018\u00010\tH\u0016R\u0010\u0010\u0005\u001a\u0004\u0018\u00010\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\n"}, d2 = {"Lcom/best/free/vpn/proxy/connect/VpnControlService$Flow;", "Ltun2socks/PacketFlow;", "stream", "Ljava/io/FileOutputStream;", "(Ljava/io/FileOutputStream;)V", "flowOutputStream", "writePacket", "", "pkt", "", "vpnkt-v1.19.0(222)_release"}, k = 1, mv = {1, 9, 0}, xi = 48)
public static final class Flow implements PacketFlow {
private final FileOutputStream flowOutputStream;
public Flow(FileOutputStream fileOutputStream) {
this.flowOutputStream = fileOutputStream;
}
@Override
public void writePacket(byte[] pkt) {
FileOutputStream fileOutputStream = this.flowOutputStream;
if (fileOutputStream != null) {
fileOutputStream.write(pkt);
}
}
}
@Metadata(d1 = {"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u000b\n\u0000\n\u0002\u0010\t\n\u0000\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0010\u0010\u0006\u001a\u00020\u00072\u0006\u0010\b\u001a\u00020\tH\u0016R\u000e\u0010\u0005\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\n"}, d2 = {"Lcom/best/free/vpn/proxy/connect/VpnControlService$Service;", "Ltun2socks/VpnService;", NotificationCompat.CATEGORY_SERVICE, "Landroid/net/VpnService;", "(Landroid/net/VpnService;)V", "vpnService", "protect", "", "fd", "", "vpnkt-v1.19.0(222)_release"}, k = 1, mv = {1, 9, 0}, xi = 48)
public static final class Service implements tun2socks.VpnService {
private final VpnService vpnService;
public Service(VpnService service) {
Intrinsics.checkNotNullParameter(service, "service");
this.vpnService = service;
}
@Override
public boolean protect(long fd) {
return this.vpnService.protect((int) fd);
}
}
public final void handlePackets() {
Integer valueOf;
while (this.running) {
try {
FileInputStream fileInputStream = this.inputStream;
valueOf = fileInputStream != null ? Integer.valueOf(fileInputStream.read(this.buffer.array())) : null;
} catch (Exception unused) {
System.out.println((Object) "failed to read bytes from TUN fd");
}
if (valueOf == null) {
return;
}
valueOf.intValue();
if (valueOf.intValue() > 0) {
this.buffer.limit(valueOf.intValue());
Tun2socks.inputPacket(this.buffer.array());
this.buffer.clear();
}
}
}
private final void startV2ray(final String configString, final List<String> ignoreApps, final boolean proxySelf) {
Thread thread;
thread = ThreadsKt.thread((r12 & 1) != 0 ? true : true, (r12 & 2) != 0 ? false : false, (r12 & 4) != 0 ? null : null, (r12 & 8) != 0 ? null : null, (r12 & 16) != 0 ? -1 : 0, new Function0<Unit>() {
{
super(0);
}
@Override
public Unit invoke() {
invoke2();
return Unit.INSTANCE;
}
public final void invoke2() {
ParcelFileDescriptor parcelFileDescriptor;
ParcelFileDescriptor parcelFileDescriptor2;
ParcelFileDescriptor parcelFileDescriptor3;
ParcelFileDescriptor parcelFileDescriptor4;
FileOutputStream fileOutputStream;
String str;
try {
Klaxon klaxon = new Klaxon();
V2rayConfig v2rayConfig = (V2rayConfig) klaxon.fromJsonObject((JsonObject) Klaxon.parser$default(klaxon, Reflection.getOrCreateKotlinClass(V2rayConfig.class), null, false, 6, null).parse(new StringReader(configString)), V2rayConfig.class, Reflection.getOrCreateKotlinClass(V2rayConfig.class));
if (v2rayConfig != null) {
Dns dns = v2rayConfig.getDns();
if ((dns != null ? dns.getServers() : null) == null || v2rayConfig.getDns().getServers().isEmpty()) {
System.out.println((Object) "must configure dns servers since v2ray will use localhost if there isn't any dns servers");
this.sendBroadcast(new Intent("v2ray_start_err_config"));
return;
}
List<Object> servers = v2rayConfig.getDns().getServers();
VpnControlService vpnControlService = this;
for (Object obj : servers) {
String str2 = obj instanceof String ? (String) obj : null;
if (str2 != null && Intrinsics.areEqual(str2, "localhost")) {
System.out.println((Object) "using local dns resolver is not allowed since it will cause infinite loop");
vpnControlService.sendBroadcast(new Intent("v2ray_start_err_config"));
return;
}
}
VpnService.Builder addRoute = new VpnService.Builder(this).setSession("Ostrich").setMtu(1500).addAddress("10.233.233.233", 30).addDnsServer("8.8.8.8").addRoute("0.0.0.0", 0);
Intrinsics.checkNotNullExpressionValue(addRoute, "addRoute(...)");
List<String> list = ignoreApps;
if (list != null) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
addRoute.addDisallowedApplication(it.next());
}
}
if (!proxySelf) {
str = this.TAG;
Intrinsics.checkNotNullExpressionValue(str, "access$getTAG$p(...)");
LogKt.logI(str, "NOT proxySelf: " + this.getApplication().getPackageName());
addRoute.addDisallowedApplication(this.getApplication().getPackageName());
}
this.pfd = addRoute.establish();
parcelFileDescriptor = this.pfd;
if (parcelFileDescriptor != null) {
parcelFileDescriptor2 = this.pfd;
Intrinsics.checkNotNull(parcelFileDescriptor2);
if (Tun2socks.setNonblock(parcelFileDescriptor2.getFd(), false)) {
VpnControlService vpnControlService2 = this;
parcelFileDescriptor3 = this.pfd;
Intrinsics.checkNotNull(parcelFileDescriptor3);
vpnControlService2.inputStream = new FileInputStream(parcelFileDescriptor3.getFileDescriptor());
VpnControlService vpnControlService3 = this;
parcelFileDescriptor4 = this.pfd;
Intrinsics.checkNotNull(parcelFileDescriptor4);
vpnControlService3.outputStream = new FileOutputStream(parcelFileDescriptor4.getFileDescriptor());
fileOutputStream = this.outputStream;
VpnControlService.Flow flow = new VpnControlService.Flow(fileOutputStream);
VpnControlService.Service service = new VpnControlService.Service(this);
String obj2 = StringsKt.trim((CharSequence) "http,tls").toString();
Tun2socks.setLocalDNS("8.8.8.8:53");
VpnControlService.Flow flow2 = flow;
VpnControlService.Service service2 = service;
byte[] bytes = configString.getBytes(Charsets.UTF_8);
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)");
if (((int) Tun2socks.startV2Ray(flow2, service2, null, bytes, "tun2socks", obj2, this.getFilesDir().getAbsolutePath())) != 0) {
this.sendBroadcast(new Intent("v2ray_start_err"));
return;
}
this.sendBroadcast(new Intent("v2ray_started"));
this.running = true;
this.handlePackets();
return;
}
}
System.out.println((Object) "failed to put tunFd in blocking mode");
this.sendBroadcast(new Intent("v2ray_start_err"));
return;
}
System.out.println((Object) "parsing v2ray config is null");
this.sendBroadcast(new Intent("v2ray_start_err_config"));
} catch (Exception unused) {
this.sendBroadcast(new Intent("v2ray_start_err_config"));
}
}
});
this.bgThread = thread;
}
}