mirror of https://github.com/NekoX-Dev/NekoX.git
377 lines
14 KiB
Java
377 lines
14 KiB
Java
package org.telegram.messenger.voip;
|
|
|
|
import android.os.Build;
|
|
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
import org.telegram.messenger.ApplicationLoader;
|
|
import org.telegram.messenger.BuildVars;
|
|
import org.telegram.messenger.FileLog;
|
|
import org.webrtc.ContextUtils;
|
|
import org.webrtc.VideoSink;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
public final class Instance {
|
|
|
|
public static final List<String> AVAILABLE_VERSIONS = Build.VERSION.SDK_INT >= 18 ? Arrays.asList(/*"3.0.0", */"2.7.7", "2.4.4") : Arrays.asList("2.4.4");
|
|
|
|
public static final int AUDIO_STATE_MUTED = 0;
|
|
public static final int AUDIO_STATE_ACTIVE = 1;
|
|
|
|
public static final int VIDEO_STATE_INACTIVE = 0;
|
|
public static final int VIDEO_STATE_PAUSED = 1;
|
|
public static final int VIDEO_STATE_ACTIVE = 2;
|
|
|
|
//region Constants
|
|
public static final int NET_TYPE_UNKNOWN = 0;
|
|
public static final int NET_TYPE_GPRS = 1;
|
|
public static final int NET_TYPE_EDGE = 2;
|
|
public static final int NET_TYPE_3G = 3;
|
|
public static final int NET_TYPE_HSPA = 4;
|
|
public static final int NET_TYPE_LTE = 5;
|
|
public static final int NET_TYPE_WIFI = 6;
|
|
public static final int NET_TYPE_ETHERNET = 7;
|
|
public static final int NET_TYPE_OTHER_HIGH_SPEED = 8;
|
|
public static final int NET_TYPE_OTHER_LOW_SPEED = 9;
|
|
public static final int NET_TYPE_DIALUP = 10;
|
|
public static final int NET_TYPE_OTHER_MOBILE = 11;
|
|
public static final int ENDPOINT_TYPE_INET = 0;
|
|
public static final int ENDPOINT_TYPE_LAN = 1;
|
|
public static final int ENDPOINT_TYPE_UDP_RELAY = 2;
|
|
public static final int ENDPOINT_TYPE_TCP_RELAY = 3;
|
|
public static final int STATE_WAIT_INIT = 1;
|
|
public static final int STATE_WAIT_INIT_ACK = 2;
|
|
public static final int STATE_ESTABLISHED = 3;
|
|
public static final int STATE_FAILED = 4;
|
|
public static final int STATE_RECONNECTING = 5;
|
|
public static final int DATA_SAVING_NEVER = 0;
|
|
public static final int DATA_SAVING_MOBILE = 1;
|
|
public static final int DATA_SAVING_ALWAYS = 2;
|
|
public static final int DATA_SAVING_ROAMING = 3;
|
|
public static final int PEER_CAP_GROUP_CALLS = 1;
|
|
|
|
// Java-side Errors
|
|
public static final String ERROR_CONNECTION_SERVICE = "ERROR_CONNECTION_SERVICE";
|
|
public static final String ERROR_INSECURE_UPGRADE = "ERROR_INSECURE_UPGRADE";
|
|
public static final String ERROR_LOCALIZED = "ERROR_LOCALIZED";
|
|
public static final String ERROR_PRIVACY = "ERROR_PRIVACY";
|
|
public static final String ERROR_PEER_OUTDATED = "ERROR_PEER_OUTDATED";
|
|
|
|
// Native-side Errors
|
|
public static final String ERROR_UNKNOWN = "ERROR_UNKNOWN";
|
|
public static final String ERROR_INCOMPATIBLE = "ERROR_INCOMPATIBLE";
|
|
public static final String ERROR_TIMEOUT = "ERROR_TIMEOUT";
|
|
public static final String ERROR_AUDIO_IO = "ERROR_AUDIO_IO";
|
|
//endregion
|
|
|
|
private static ServerConfig globalServerConfig = new ServerConfig(new JSONObject());
|
|
private static int bufferSize;
|
|
|
|
private static NativeInstance instance;
|
|
|
|
private Instance() {
|
|
}
|
|
|
|
public static ServerConfig getGlobalServerConfig() {
|
|
return globalServerConfig;
|
|
}
|
|
|
|
public static void setGlobalServerConfig(String serverConfigJson) {
|
|
try {
|
|
globalServerConfig = new ServerConfig(new JSONObject(serverConfigJson));
|
|
if (instance != null) {
|
|
instance.setGlobalServerConfig(serverConfigJson);
|
|
}
|
|
} catch (JSONException e) {
|
|
if (BuildVars.LOGS_ENABLED) {
|
|
FileLog.e("failed to parse tgvoip server config", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void destroyInstance() {
|
|
instance = null;
|
|
}
|
|
|
|
public static NativeInstance makeInstance(String version, Config config, String persistentStateFilePath, Endpoint[] endpoints, Proxy proxy, int networkType, EncryptionKey encryptionKey, VideoSink remoteSink, long videoCapturer) {
|
|
if (!"2.4.4".equals(version)) {
|
|
ContextUtils.initialize(ApplicationLoader.applicationContext);
|
|
}
|
|
instance = NativeInstance.make(version, config, persistentStateFilePath, endpoints, proxy, networkType, encryptionKey, remoteSink, videoCapturer);
|
|
setGlobalServerConfig(globalServerConfig.jsonObject.toString());
|
|
setBufferSize(bufferSize);
|
|
return instance;
|
|
}
|
|
|
|
public static void setBufferSize(int size) {
|
|
bufferSize = size;
|
|
if (instance != null) {
|
|
instance.setBufferSize(size);
|
|
}
|
|
}
|
|
|
|
public static int getConnectionMaxLayer() {
|
|
return 92;
|
|
}
|
|
|
|
public static String getVersion() {
|
|
return instance != null ? instance.getVersion() : null;
|
|
}
|
|
|
|
private static void checkHasDelegate() {
|
|
if (instance == null) {
|
|
throw new IllegalStateException("tgvoip version is not set");
|
|
}
|
|
}
|
|
|
|
public interface OnStateUpdatedListener {
|
|
void onStateUpdated(int state);
|
|
}
|
|
|
|
public interface OnSignalBarsUpdatedListener {
|
|
void onSignalBarsUpdated(int signalBars);
|
|
}
|
|
|
|
public interface OnSignalingDataListener {
|
|
void onSignalingData(byte[] data);
|
|
}
|
|
|
|
public interface OnRemoteMediaStateUpdatedListener {
|
|
void onMediaStateUpdated(int audioState, int videoState);
|
|
}
|
|
|
|
public static final class Config {
|
|
|
|
public final double initializationTimeout;
|
|
public final double receiveTimeout;
|
|
public final int dataSaving;
|
|
public final boolean enableP2p;
|
|
public final boolean enableAec;
|
|
public final boolean enableNs;
|
|
public final boolean enableAgc;
|
|
public final boolean enableCallUpgrade;
|
|
public final String logPath;
|
|
public final String statsLogPath;
|
|
public final int maxApiLayer;
|
|
public final boolean enableSm;
|
|
|
|
public Config(double initializationTimeout, double receiveTimeout, int dataSaving, boolean enableP2p, boolean enableAec, boolean enableNs, boolean enableAgc, boolean enableCallUpgrade, boolean enableSm, String logPath, String statsLogPath, int maxApiLayer) {
|
|
this.initializationTimeout = initializationTimeout;
|
|
this.receiveTimeout = receiveTimeout;
|
|
this.dataSaving = dataSaving;
|
|
this.enableP2p = enableP2p;
|
|
this.enableAec = enableAec;
|
|
this.enableNs = enableNs;
|
|
this.enableAgc = enableAgc;
|
|
this.enableCallUpgrade = enableCallUpgrade;
|
|
this.logPath = logPath;
|
|
this.statsLogPath = statsLogPath;
|
|
this.maxApiLayer = maxApiLayer;
|
|
this.enableSm = enableSm;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Config{" +
|
|
"initializationTimeout=" + initializationTimeout +
|
|
", receiveTimeout=" + receiveTimeout +
|
|
", dataSaving=" + dataSaving +
|
|
", enableP2p=" + enableP2p +
|
|
", enableAec=" + enableAec +
|
|
", enableNs=" + enableNs +
|
|
", enableAgc=" + enableAgc +
|
|
", enableCallUpgrade=" + enableCallUpgrade +
|
|
", logPath='" + logPath + '\'' +
|
|
", statsLogPath='" + statsLogPath + '\'' +
|
|
", maxApiLayer=" + maxApiLayer +
|
|
", enableSm=" + enableSm +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class Endpoint {
|
|
|
|
public final boolean isRtc;
|
|
public final long id;
|
|
public final String ipv4;
|
|
public final String ipv6;
|
|
public final int port;
|
|
public final int type;
|
|
public final byte[] peerTag;
|
|
public final boolean turn;
|
|
public final boolean stun;
|
|
public final String username;
|
|
public final String password;
|
|
|
|
public Endpoint(boolean isRtc, long id, String ipv4, String ipv6, int port, int type, byte[] peerTag, boolean turn, boolean stun, String username, String password) {
|
|
this.isRtc = isRtc;
|
|
this.id = id;
|
|
this.ipv4 = ipv4;
|
|
this.ipv6 = ipv6;
|
|
this.port = port;
|
|
this.type = type;
|
|
this.peerTag = peerTag;
|
|
this.turn = turn;
|
|
this.stun = stun;
|
|
this.username = username;
|
|
this.password = password;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Endpoint{" +
|
|
"id=" + id +
|
|
", ipv4='" + ipv4 + '\'' +
|
|
", ipv6='" + ipv6 + '\'' +
|
|
", port=" + port +
|
|
", type=" + type +
|
|
", peerTag=" + Arrays.toString(peerTag) +
|
|
", turn=" + turn +
|
|
", stun=" + stun +
|
|
", username=" + username +
|
|
", password=" + password +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class Proxy {
|
|
|
|
public final String host;
|
|
public final int port;
|
|
public final String login;
|
|
public final String password;
|
|
|
|
public Proxy(String host, int port, String login, String password) {
|
|
this.host = host;
|
|
this.port = port;
|
|
this.login = login;
|
|
this.password = password;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Proxy{" +
|
|
"host='" + host + '\'' +
|
|
", port=" + port +
|
|
", login='" + login + '\'' +
|
|
", password='" + password + '\'' +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class EncryptionKey {
|
|
|
|
public final byte[] value;
|
|
public final boolean isOutgoing;
|
|
|
|
public EncryptionKey(byte[] value, boolean isOutgoing) {
|
|
this.value = value;
|
|
this.isOutgoing = isOutgoing;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "EncryptionKey{" +
|
|
"value=" + Arrays.toString(value) +
|
|
", isOutgoing=" + isOutgoing +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class FinalState {
|
|
|
|
public final byte[] persistentState;
|
|
public final String debugLog;
|
|
public final TrafficStats trafficStats;
|
|
public final boolean isRatingSuggested;
|
|
|
|
public FinalState(byte[] persistentState, String debugLog, TrafficStats trafficStats, boolean isRatingSuggested) {
|
|
this.persistentState = persistentState;
|
|
this.debugLog = debugLog;
|
|
this.trafficStats = trafficStats;
|
|
this.isRatingSuggested = isRatingSuggested;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "FinalState{" +
|
|
"persistentState=" + Arrays.toString(persistentState) +
|
|
", debugLog='" + debugLog + '\'' +
|
|
", trafficStats=" + trafficStats +
|
|
", isRatingSuggested=" + isRatingSuggested +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class TrafficStats {
|
|
|
|
public final long bytesSentWifi;
|
|
public final long bytesReceivedWifi;
|
|
public final long bytesSentMobile;
|
|
public final long bytesReceivedMobile;
|
|
|
|
public TrafficStats(long bytesSentWifi, long bytesReceivedWifi, long bytesSentMobile, long bytesReceivedMobile) {
|
|
this.bytesSentWifi = bytesSentWifi;
|
|
this.bytesReceivedWifi = bytesReceivedWifi;
|
|
this.bytesSentMobile = bytesSentMobile;
|
|
this.bytesReceivedMobile = bytesReceivedMobile;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "TrafficStats{" +
|
|
"bytesSentWifi=" + bytesSentWifi +
|
|
", bytesReceivedWifi=" + bytesReceivedWifi +
|
|
", bytesSentMobile=" + bytesSentMobile +
|
|
", bytesReceivedMobile=" + bytesReceivedMobile +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
public static final class ServerConfig {
|
|
|
|
public final boolean useSystemNs;
|
|
public final boolean useSystemAec;
|
|
public final boolean enableStunMarking;
|
|
public final double hangupUiTimeout;
|
|
|
|
public final boolean enable_vp8_encoder;
|
|
public final boolean enable_vp8_decoder;
|
|
public final boolean enable_vp9_encoder;
|
|
public final boolean enable_vp9_decoder;
|
|
public final boolean enable_h265_encoder;
|
|
public final boolean enable_h265_decoder;
|
|
public final boolean enable_h264_encoder;
|
|
public final boolean enable_h264_decoder;
|
|
|
|
private final JSONObject jsonObject;
|
|
|
|
private ServerConfig(JSONObject jsonObject) {
|
|
this.jsonObject = jsonObject;
|
|
this.useSystemNs = jsonObject.optBoolean("use_system_ns", true);
|
|
this.useSystemAec = jsonObject.optBoolean("use_system_aec", true);
|
|
this.enableStunMarking = jsonObject.optBoolean("voip_enable_stun_marking", false);
|
|
this.hangupUiTimeout = jsonObject.optDouble("hangup_ui_timeout", 5);
|
|
|
|
this.enable_vp8_encoder = jsonObject.optBoolean("enable_vp8_encoder", true);
|
|
this.enable_vp8_decoder = jsonObject.optBoolean("enable_vp8_decoder", true);
|
|
this.enable_vp9_encoder = jsonObject.optBoolean("enable_vp9_encoder", true);
|
|
this.enable_vp9_decoder = jsonObject.optBoolean("enable_vp9_decoder", true);
|
|
this.enable_h265_encoder = jsonObject.optBoolean("enable_h265_encoder", true);
|
|
this.enable_h265_decoder = jsonObject.optBoolean("enable_h265_decoder", true);
|
|
this.enable_h264_encoder = jsonObject.optBoolean("enable_h264_encoder", true);
|
|
this.enable_h264_decoder = jsonObject.optBoolean("enable_h264_decoder", true);
|
|
}
|
|
|
|
public String getString(String key) {
|
|
return getString(key, "");
|
|
}
|
|
|
|
public String getString(String key, String fallback) {
|
|
return jsonObject.optString(key, fallback);
|
|
}
|
|
}
|
|
}
|