智慧城市 v1.2.1版本的 MD5 值为:d4aeacb5153a2710d0b6882be5dd2b15
以下内容为反编译后的 ConnectionService.java 源代码,内容仅作参考
package io.rong.imlib;
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import io.rong.common.SystemUtils;
import io.rong.common.fwlog.FwLog;
import io.rong.common.rlog.RLog;
import io.rong.imlib.HeartBeatManager;
import io.rong.imlib.IRongCoreEnum;
import io.rong.imlib.IRongCoreListener;
import io.rong.imlib.NativeClient;
import io.rong.imlib.NativeObject;
import io.rong.imlib.common.DeviceUtils;
import io.rong.imlib.common.NetUtils;
import io.rong.imlib.common.SignatureUtils;
import io.rong.imlib.model.AndroidConfig;
import io.rong.imlib.navigation.NavigationCacheHelper;
import io.rong.imlib.navigation.NavigationClient;
import io.rong.imlib.navigation.NavigationObserver;
import io.rong.imlib.navigation.NetDetection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionService {
private static final int RECONNECT_INTERVAL = 1000;
private static final int RECONNECT_INTERVAL_MAX_LENGTH = 10;
private static final String TAG = "ConnectionService";
private String mAppKey;
private Executor mCallBackExecutor;
private NativeClient.IConnectResultCallback<String> mConnectCallback;
private ConnectStatusListener mConnectListener;
private ConnectionState mConnectionState;
private Context mContext;
private boolean mEnableReconnectKick;
private Handler mHandler;
private boolean mIsForeground;
private AtomicBoolean mIsReconnect;
private NativeObject mNativeObj;
private AtomicInteger mRcRetryCount;
private String[] mReconnectInterval;
private ReconnectRunnable mReconnectRunnable;
private ConcurrentHashMap<String, Integer> mTcpResultMap;
private volatile String mToken;
private ConnectionService() {
this.mContext = null;
this.mEnableReconnectKick = false;
this.mRcRetryCount = new AtomicInteger(0);
this.mReconnectInterval = new String[]{AndroidConfig.OPERATE, "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"};
HandlerThread handlerThread = new HandlerThread("IPC_RECONNECT_WORK");
handlerThread.start();
this.mHandler = new Handler(handlerThread.getLooper());
this.mCallBackExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
return new Thread(runnable, "IPC_CONNECT_CALLBACK");
}
});
this.mConnectionState = new ConnectionState();
}
public static ConnectionService getInstance() {
return SingleHolder.instance;
}
public void initService(Context context, NativeObject nativeObject, String str) {
int length;
this.mContext = context;
this.mNativeObj = nativeObject;
this.mAppKey = str;
ConnectStatusListener connectStatusListener = new ConnectStatusListener();
this.mConnectListener = connectStatusListener;
this.mNativeObj.SetConnectionStatusListener(connectStatusListener);
CMPStrategy.getInstance().setEnvironment(this.mContext);
this.mTcpResultMap = new ConcurrentHashMap<>();
try {
Resources resources = context.getResources();
String[] stringArray = resources.getStringArray(resources.getIdentifier("rc_reconnect_interval", "array", context.getPackageName()));
this.mReconnectInterval = stringArray;
length = stringArray.length;
RLog.i(TAG, "mReconnectInterval " + length);
} catch (Resources.NotFoundException unused) {
RLog.i(TAG, "Not found rc_reconnect_interval in rc_configuration.xml, use default config");
}
if (length != 0) {
String[] strArr = this.mReconnectInterval;
if (strArr[0] != null) {
if (length > 10) {
throw new IllegalArgumentException("The numbers of rc_reconnect_interval must less than 10");
}
for (String str2 : strArr) {
try {
Float.parseFloat(str2);
} catch (NumberFormatException unused2) {
throw new IllegalArgumentException("The value of the field must be digits");
}
}
setHeartBeatListener();
return;
}
}
throw new IllegalArgumentException("rc_reconnect_interval must have a value and the type of the field must be string-array");
}
private void setHeartBeatListener() {
HeartBeatManager.getInstance().setHeartBeatListener(new HeartBeatManager.HeartBeatListener() {
@Override
public void onPongReceiveFail() {
ConnectionService.this.disposeReconnectByErrorCode(IRongCoreEnum.CoreErrorCode.RC_PONG_RECV_FAIL.getValue(), -1);
}
});
}
public void setMainProgressConnectionStatusListener(NativeClient.ICodeListener iCodeListener) {
this.mConnectionState.setConnectionStatusListener(iCodeListener);
}
public void connect(final String str, final boolean z, final boolean z2, final NativeClient.IConnectResultCallback<String> iConnectResultCallback) {
resetReconnectCount();
this.mHandler.post(new Runnable() {
@Override
public void run() {
ConnectionService.this.connectServer(str, z, z2, iConnectResultCallback);
}
});
}
public void connectServer(final String str, final boolean z, final boolean z2, final NativeClient.IConnectResultCallback<String> iConnectResultCallback) {
if (z) {
if (!canReconnect()) {
RLog.i(TAG, "[connect] can't connect status " + this.mConnectionState.getCurrentStatus());
return;
}
} else {
this.mToken = str;
}
if (TextUtils.isEmpty(str)) {
RLog.e(TAG, "connectServer token is null");
if (iConnectResultCallback != null) {
iConnectResultCallback.onError(IRongCoreEnum.CoreErrorCode.PARAMETER_ERROR.getValue());
return;
}
return;
}
this.mConnectionState.connecting();
stopRetry();
NavigationClient.getInstance().addObserver(new NavigationObserver() {
@Override
public void onSuccess(String str2) {
RLog.d(ConnectionService.TAG, "[connect] get cmp success");
boolean privateCloudConfig = NavigationCacheHelper.getPrivateCloudConfig(ConnectionService.this.mContext);
FwLog.write(3, 1, "L-Env-S", "private", Boolean.valueOf(privateCloudConfig));
ConnectionService.this.mNativeObj.SetEnvironment(privateCloudConfig);
ConnectionService.this.internalConnect(str, str2, z, z2, iConnectResultCallback);
}
@Override
public void onError(String str2, int i) {
RLog.e(ConnectionService.TAG, "[connect] get cmp error, errorCode = " + i);
if (IRongCoreEnum.CoreErrorCode.RC_CONN_USER_OR_PASSWD_ERROR.getValue() != i && IRongCoreEnum.CoreErrorCode.RC_ENVIRONMENT_ERROR.getValue() != i) {
boolean privateCloudConfig = NavigationCacheHelper.getPrivateCloudConfig(ConnectionService.this.mContext);
List<String> cmpList = CMPStrategy.getInstance().getCmpList();
if (cmpList != null && !cmpList.isEmpty()) {
FwLog.write(3, 1, "L-Env-S", "private:", Boolean.valueOf(privateCloudConfig));
ConnectionService.this.mNativeObj.SetEnvironment(privateCloudConfig);
ConnectionService.this.internalConnect(str, str2, z, z2, iConnectResultCallback);
} else {
ConnectionService.this.disposeReconnectByErrorCode(i, -1);
}
if (i == 30008) {
FwLog.write(1, 1, "P-rtcon-E", "code|method|nativeCode|sessionId|seq_id", Integer.valueOf(i), "navi", 0, 0, AndroidConfig.OPERATE);
return;
}
return;
}
ConnectionService.this.disposeReconnectByErrorCode(i, -1);
iConnectResultCallback.onError(i);
}
});
NavigationClient.getInstance().getCMPServerString(this.mContext, this.mAppKey, str);
}
public void internalConnect(String str, String str2, final boolean z, boolean z2, final NativeClient.IConnectResultCallback<String> iConnectResultCallback) {
FwLog.write(3, 1, z ? "L-reconnect-T" : "L-connect-T", "sequences", Integer.valueOf(this.mRcRetryCount.get()));
this.mToken = str;
tryConnect(str, str2, z, z2, new NativeClient.IConnectResultCallback<String>() {
@Override
public void onSuccess(String str3) {
FwLog.write(3, 1, z ? "L-reconnect-R" : "L-connect-R", "code|sequences", 0, Integer.valueOf(ConnectionService.this.mRcRetryCount.get()));
NativeClient.IConnectResultCallback iConnectResultCallback2 = iConnectResultCallback;
if (iConnectResultCallback2 != null) {
iConnectResultCallback2.onSuccess(str3);
}
}
@Override
public void onError(int i) {
FwLog.write(2, 1, z ? "L-reconnect-R" : "L-connect-R", "code|network|sequences", Integer.valueOf(i), DeviceUtils.getNetworkType(ConnectionService.this.mContext), Integer.valueOf(ConnectionService.this.mRcRetryCount.get()));
NativeClient.IConnectResultCallback iConnectResultCallback2 = iConnectResultCallback;
if (iConnectResultCallback2 != null) {
iConnectResultCallback2.onError(i);
}
}
@Override
public void OnDatabaseOpened(int i) {
NativeClient.IConnectResultCallback iConnectResultCallback2 = iConnectResultCallback;
if (iConnectResultCallback2 != null) {
iConnectResultCallback2.OnDatabaseOpened(i);
}
}
});
}
private void tryConnect(String str, String str2, boolean z, boolean z2, NativeClient.IConnectResultCallback<String> iConnectResultCallback) {
boolean z3;
String str3;
int Connect;
ConnectStatusListener connectStatusListener;
TelephonyManager telephonyManager;
this.mIsForeground = z2;
this.mConnectCallback = iConnectResultCallback;
this.mTcpResultMap.clear();
String str4 = str2 == null ? "" : str2;
List<String> cmpList = CMPStrategy.getInstance().getCmpList();
List<URL> legalCmpList = getLegalCmpList(cmpList);
if (legalCmpList == null || legalCmpList.size() <= 0) {
CMPStrategy.getInstance().clearCache(this.mContext);
this.mConnectListener.OnRmtpComplete(IRongCoreEnum.CoreErrorCode.RC_NODE_NOT_FOUND.getValue(), "", 0, (short) 0, "");
return;
}
NativeObject.ConnectionEntry[] connectionEntries = getConnectionEntries(legalCmpList);
NativeClient.getInstance().setCurrentUserId(str4);
boolean isMPOpened = NavigationClient.getInstance().isMPOpened(this.mContext);
boolean isUSOpened = NavigationClient.getInstance().isUSOpened(this.mContext);
boolean isGROpened = NavigationClient.getInstance().isGROpened(this.mContext);
boolean isKvStorageEnabled = NavigationCacheHelper.isKvStorageEnabled(this.mContext);
String primeP = NavigationClient.getInstance().getPrimeP(this.mContext);
String primeG = NavigationClient.getInstance().getPrimeG(this.mContext);
String keyE = NavigationClient.getInstance().getKeyE(this.mContext);
String keyN = NavigationClient.getInstance().getKeyN(this.mContext);
String site = NavigationClient.getInstance().getSite(this.mContext);
long randomR = NavigationClient.getInstance().getRandomR(this.mContext);
int algorithm = NavigationClient.getInstance().getAlgorithm(this.mContext);
boolean isRepairMsgEnabled = NavigationClient.getInstance().isRepairMsgEnabled(this.mContext);
try {
z3 = isRepairMsgEnabled;
try {
telephonyManager = (TelephonyManager) this.mContext.getSystemService("phone");
} catch (SecurityException e) {
e = e;
RLog.e(TAG, "tryConnect SecurityException", e);
str3 = "";
String networkType = DeviceUtils.getNetworkType(this.mContext);
RLog.d(TAG, "[connect] device info: " + Build.MANUFACTURER + ", " + Build.MODEL + ", " + Build.VERSION.SDK_INT + ", 5.1.3.5, " + networkType + ", " + str3);
StringBuilder sb = new StringBuilder();
sb.append("[connect] tryConnect::cmp:");
sb.append(SystemUtils.listToString(cmpList));
sb.append(", userId : ");
sb.append(str4);
RLog.d(TAG, sb.toString());
boolean z4 = true;
FwLog.write(3, 1, "P-connect-T", "strategy|cached|use", "parallel", SystemUtils.listToString(cmpList), SystemUtils.listToString(cmpList));
if (this.mEnableReconnectKick) {
}
if (isGROpened) {
}
String clientIp = NavigationCacheHelper.getClientIp(this.mContext);
if (!NetUtils.isLegalServer(clientIp)) {
}
boolean openTls = NavigationCacheHelper.getOpenTls(this.mContext);
boolean openAnti = NavigationCacheHelper.getOpenAnti(this.mContext);
NativeObject.UserProfile userProfile = new NativeObject.UserProfile();
userProfile.setIpv6Preferred(false);
userProfile.setPublicService(isMPOpened);
userProfile.setPushSetting(isUSOpened);
userProfile.setSdkReconnect(z4);
userProfile.setGroupMessageLimit(r0);
userProfile.setClientIp(r3);
userProfile.setKvStorageOpened(isKvStorageEnabled);
userProfile.setIdentification(SignatureUtils.getAppSignatureSHA1(this.mContext));
userProfile.setPrimeP(primeP);
userProfile.setPrimeG(primeG);
userProfile.setKeyE(keyE);
userProfile.setKeyN(keyN);
userProfile.setSite(site);
userProfile.setRandomR(randomR);
userProfile.setAlgorithm(algorithm);
userProfile.setTlsEnabled(openTls);
userProfile.setMsgShortagesEnabled(z3);
userProfile.setAntiEnabled(openAnti);
Connect = this.mNativeObj.Connect(NavigationClient.getInstance().getTokenExceptNavi(str), connectionEntries, str4, userProfile);
if (Connect == 0) {
}
}
} catch (SecurityException e2) {
e = e2;
z3 = isRepairMsgEnabled;
}
if (telephonyManager != null) {
str3 = telephonyManager.getNetworkOperator();
String networkType2 = DeviceUtils.getNetworkType(this.mContext);
RLog.d(TAG, "[connect] device info: " + Build.MANUFACTURER + ", " + Build.MODEL + ", " + Build.VERSION.SDK_INT + ", 5.1.3.5, " + networkType2 + ", " + str3);
StringBuilder sb2 = new StringBuilder();
sb2.append("[connect] tryConnect::cmp:");
sb2.append(SystemUtils.listToString(cmpList));
sb2.append(", userId : ");
sb2.append(str4);
RLog.d(TAG, sb2.toString());
boolean z42 = true;
FwLog.write(3, 1, "P-connect-T", "strategy|cached|use", "parallel", SystemUtils.listToString(cmpList), SystemUtils.listToString(cmpList));
z42 = (this.mEnableReconnectKick || !z) ? false : false;
int groupMessageLimit = isGROpened ? NavigationClient.getInstance().getGroupMessageLimit(this.mContext) : 0;
String clientIp2 = NavigationCacheHelper.getClientIp(this.mContext);
String str5 = !NetUtils.isLegalServer(clientIp2) ? "" : clientIp2;
boolean openTls2 = NavigationCacheHelper.getOpenTls(this.mContext);
boolean openAnti2 = NavigationCacheHelper.getOpenAnti(this.mContext);
NativeObject.UserProfile userProfile2 = new NativeObject.UserProfile();
userProfile2.setIpv6Preferred(false);
userProfile2.setPublicService(isMPOpened);
userProfile2.setPushSetting(isUSOpened);
userProfile2.setSdkReconnect(z42);
userProfile2.setGroupMessageLimit(groupMessageLimit);
userProfile2.setClientIp(str5);
userProfile2.setKvStorageOpened(isKvStorageEnabled);
userProfile2.setIdentification(SignatureUtils.getAppSignatureSHA1(this.mContext));
userProfile2.setPrimeP(primeP);
userProfile2.setPrimeG(primeG);
userProfile2.setKeyE(keyE);
userProfile2.setKeyN(keyN);
userProfile2.setSite(site);
userProfile2.setRandomR(randomR);
userProfile2.setAlgorithm(algorithm);
userProfile2.setTlsEnabled(openTls2);
userProfile2.setMsgShortagesEnabled(z3);
userProfile2.setAntiEnabled(openAnti2);
Connect = this.mNativeObj.Connect(NavigationClient.getInstance().getTokenExceptNavi(str), connectionEntries, str4, userProfile2);
if (Connect == 0 || (connectStatusListener = this.mConnectListener) == null) {
}
connectStatusListener.OnRmtpComplete(Connect, "", -1, (short) 0, "");
return;
}
str3 = "";
String networkType22 = DeviceUtils.getNetworkType(this.mContext);
RLog.d(TAG, "[connect] device info: " + Build.MANUFACTURER + ", " + Build.MODEL + ", " + Build.VERSION.SDK_INT + ", 5.1.3.5, " + networkType22 + ", " + str3);
StringBuilder sb22 = new StringBuilder();
sb22.append("[connect] tryConnect::cmp:");
sb22.append(SystemUtils.listToString(cmpList));
sb22.append(", userId : ");
sb22.append(str4);
RLog.d(TAG, sb22.toString());
boolean z422 = true;
FwLog.write(3, 1, "P-connect-T", "strategy|cached|use", "parallel", SystemUtils.listToString(cmpList), SystemUtils.listToString(cmpList));
if (this.mEnableReconnectKick) {
}
if (isGROpened) {
}
String clientIp22 = NavigationCacheHelper.getClientIp(this.mContext);
if (!NetUtils.isLegalServer(clientIp22)) {
}
boolean openTls22 = NavigationCacheHelper.getOpenTls(this.mContext);
boolean openAnti22 = NavigationCacheHelper.getOpenAnti(this.mContext);
NativeObject.UserProfile userProfile22 = new NativeObject.UserProfile();
userProfile22.setIpv6Preferred(false);
userProfile22.setPublicService(isMPOpened);
userProfile22.setPushSetting(isUSOpened);
userProfile22.setSdkReconnect(z422);
userProfile22.setGroupMessageLimit(groupMessageLimit);
userProfile22.setClientIp(str5);
userProfile22.setKvStorageOpened(isKvStorageEnabled);
userProfile22.setIdentification(SignatureUtils.getAppSignatureSHA1(this.mContext));
userProfile22.setPrimeP(primeP);
userProfile22.setPrimeG(primeG);
userProfile22.setKeyE(keyE);
userProfile22.setKeyN(keyN);
userProfile22.setSite(site);
userProfile22.setRandomR(randomR);
userProfile22.setAlgorithm(algorithm);
userProfile22.setTlsEnabled(openTls22);
userProfile22.setMsgShortagesEnabled(z3);
userProfile22.setAntiEnabled(openAnti22);
Connect = this.mNativeObj.Connect(NavigationClient.getInstance().getTokenExceptNavi(str), connectionEntries, str4, userProfile22);
if (Connect == 0) {
}
}
public void OnProtocolRmtpComplete(int i, String str, int i2, short s, String str2) {
RLog.d(TAG, "[connect] operationComplete status:" + i + ", logInfo:" + str2);
if (i == 0) {
FwLog.write(3, 1, "P-connect-R", "status_code|user_id|native_code|duration|network", Integer.valueOf(i), str, Integer.valueOf(i2), Short.valueOf(s), DeviceUtils.getNetworkType(this.mContext));
resetReconnectCount();
stopRetry();
this.mConnectionState.onEvent(i);
NativeClient.getInstance().setCurrentUserId(str);
NavigationCacheHelper.saveUserId(this.mContext, str);
responseConnectSuccessBlock(str);
CMPStrategy.getInstance().onConnected();
} else {
Object[] objArr = new Object[6];
objArr[0] = Integer.valueOf(i);
objArr[1] = str;
objArr[2] = Integer.valueOf(i2);
objArr[3] = Short.valueOf(s);
objArr[4] = DeviceUtils.getNetworkType(this.mContext);
objArr[5] = this.mIsForeground ? "false" : "true";
FwLog.write(1, 1, "P-connect-R", "status_code|user_id|native_code|duration|network|bg", objArr);
if (i2 == IRongCoreEnum.ConnectionErrorCode.RC_CONN_TOKEN_INCORRECT.getValue()) {
RLog.e(TAG, "Connect failed due to Token is incorrect,Please check whether the token is expired or whether the token is consistent with AppKey. AppKey=" + this.mAppKey + ",Token=" + this.mToken);
} else if (i2 == IRongCoreEnum.CoreErrorCode.RC_CONN_REDIRECTED.getValue()) {
RLog.e(TAG, "Connect redirectedAppKey=" + this.mAppKey + ",Token=" + this.mToken);
this.mIsReconnect = new AtomicBoolean(false);
}
this.mConnectionState.onEvent(i);
if (!this.mConnectionState.getCurrentStatus().equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.SUSPEND)) {
responseConnectErrorBlock(i);
}
disposeReconnectByErrorCode(i, i2);
}
boolean isFetching = NavigationClient.getInstance().isFetching();
if (NavigationClient.getInstance().isNaviCacheValid(this.mContext, this.mAppKey, this.mToken) || isFetching || needClearNavi(i) || TextUtils.isEmpty(this.mToken)) {
return;
}
NavigationClient.getInstance().requestNavi(this.mAppKey, this.mToken, false);
}
public void OnProtocolRmtpDisconnected(int i, int i2, String str) {
RLog.i(TAG, "ExceptionListener onError. errorCode: " + i);
disposeReconnectByErrorCode(i, i2);
}
public void OnProtocolTcpComplete(NativeObject.ConnectionEntry connectionEntry) {
int i;
RLog.e(TAG, "connectionCollection onComplete:" + connectionEntry.getHost() + " " + connectionEntry.getPort() + " " + connectionEntry.getError() + " " + connectionEntry.getDuration());
if (connectionEntry.getError() == 0) {
CMPStrategy.getInstance().setMainCMP(connectionEntry.getHost() + ":" + connectionEntry.getPort());
} else if (connectionEntry.getError() != -1 && connectionEntry.getError() != 115) {
i = 2;
FwLog.write(i, 1, "P-connect_entry-S", "code|cmp|duration", Integer.valueOf(connectionEntry.getError()), connectionEntry.getHost() + ":" + connectionEntry.getPort(), Integer.valueOf(connectionEntry.getDuration()));
detectNaviIfNeed(connectionEntry.getHost(), connectionEntry.getPort(), connectionEntry.getError());
}
i = 3;
FwLog.write(i, 1, "P-connect_entry-S", "code|cmp|duration", Integer.valueOf(connectionEntry.getError()), connectionEntry.getHost() + ":" + connectionEntry.getPort(), Integer.valueOf(connectionEntry.getDuration()));
detectNaviIfNeed(connectionEntry.getHost(), connectionEntry.getPort(), connectionEntry.getError());
}
public void OnProtocolDBOpened(int i) {
responseDBOpenBlock(i);
}
public void OnProtocolPongReceived() {
RLog.i(TAG, "ConnectionStatusListener OnPongReceived.");
}
private void responseConnectSuccessBlock(String str) {
NativeClient.IConnectResultCallback<String> iConnectResultCallback = this.mConnectCallback;
if (iConnectResultCallback != null) {
iConnectResultCallback.onSuccess(str);
}
}
public void responseConnectErrorBlock(int i) {
NativeClient.IConnectResultCallback<String> iConnectResultCallback = this.mConnectCallback;
if (iConnectResultCallback != null) {
iConnectResultCallback.onError(i);
}
}
private void responseDBOpenBlock(int i) {
RLog.d(TAG, "onDatabaseOpened.");
NativeClient.IConnectResultCallback<String> iConnectResultCallback = this.mConnectCallback;
if (iConnectResultCallback != null) {
iConnectResultCallback.OnDatabaseOpened(i);
}
}
boolean disposeReconnectByErrorCode(int i, int i2) {
FwLog.write(4, 1, "P-connect-S", "status_code|native_code", Integer.valueOf(i), Integer.valueOf(i2));
this.mConnectionState.onEvent(i);
IRongCoreListener.ConnectionStatusListener.ConnectionStatus currentStatus = this.mConnectionState.getCurrentStatus();
if (currentStatus.equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.CONNECTED)) {
stopRetry();
return false;
} else if (currentStatus.equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.SUSPEND)) {
handleSuspend(i);
return true;
} else {
RLog.d(TAG, "disposeReconnectByErrorCode cannot reconnect : status = " + this.mConnectionState.getCurrentStatus());
if (currentStatus.equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.TIMEOUT)) {
disconnect(true, false);
}
stopRetry();
return false;
}
}
private void handleSuspend(int i) {
if (i == IRongCoreEnum.CoreErrorCode.RC_CONNECTION_RESET_BY_PEER.getValue() || i == IRongCoreEnum.CoreErrorCode.RC_CONN_ACK_TIMEOUT.getValue()) {
CMPStrategy.getInstance().updateCmpList();
} else if (i == IRongCoreEnum.CoreErrorCode.RC_PONG_RECV_FAIL.getValue() && isNetworkAvailable()) {
CMPStrategy.getInstance().updateCmpList();
} else if (needClearNavi(i)) {
CMPStrategy.getInstance().clearCache(this.mContext);
}
retry();
}
private boolean needClearNavi(int i) {
return i == IRongCoreEnum.CoreErrorCode.RC_CONN_REDIRECTED.getValue() || i == IRongCoreEnum.CoreErrorCode.PARAMETER_ERROR.getValue() || i == IRongCoreEnum.CoreErrorCode.RC_CONN_REFUSED.getValue() || i == IRongCoreEnum.CoreErrorCode.RC_CONN_ENCRYPT_AUTH_FAILURE.getValue();
}
private void retry() {
float parseFloat;
if (canReconnect()) {
int length = this.mReconnectInterval.length - 1;
if (this.mRcRetryCount.get() >= 0 && this.mRcRetryCount.get() <= length) {
parseFloat = Float.parseFloat(this.mReconnectInterval[this.mRcRetryCount.get()]);
} else {
parseFloat = Float.parseFloat(this.mReconnectInterval[length]);
}
int i = (int) (parseFloat * 1000.0f);
RLog.d(TAG, "onStatusChange, Will reconnect after " + i);
FwLog.write(4, 1, "L-reconnect-S", "retry_after", Integer.valueOf(i));
ReconnectRunnable reconnectRunnable = new ReconnectRunnable();
this.mReconnectRunnable = reconnectRunnable;
this.mHandler.postDelayed(reconnectRunnable, i);
incrementCount();
}
}
private void incrementCount() {
this.mRcRetryCount.incrementAndGet();
}
private void stopRetry() {
ReconnectRunnable reconnectRunnable = this.mReconnectRunnable;
if (reconnectRunnable != null) {
this.mHandler.removeCallbacks(reconnectRunnable);
this.mReconnectRunnable = null;
}
}
private boolean canReconnect() {
if (this.mConnectionState.isTerminate()) {
RLog.e(TAG, "globalConnectionState can not reconnect");
this.mToken = null;
stopRetry();
return false;
} else if (this.mConnectionState.getCurrentStatus().equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.CONNECTED)) {
RLog.i(TAG, "already connected. ignore this connect event.");
return false;
} else if (this.mToken == null) {
RLog.e(TAG, "mToken is cleared for terminal reconnect reason");
return false;
} else if (isNetworkAvailable()) {
return true;
} else {
resetReconnectCount();
this.mConnectionState.networkUnavailable();
return false;
}
}
public void setReconnectKickEnable(boolean z) {
this.mEnableReconnectKick = z;
}
public void disconnect(boolean z, boolean z2) {
resetReconnectCount();
stopRetry();
if (this.mNativeObj == null) {
throw new RuntimeException("NativeClient has not been initialized yet!");
}
RLog.d(TAG, "[connect] disconnect:" + z);
this.mConnectionState.signUp();
this.mToken = null;
this.mNativeObj.Disconnect(z ? 2 : 4, z2);
HeartBeatManager.getInstance().removeHeartbeatFromAM(this.mContext);
HeartBeatManager.getInstance().resetQueue();
}
private boolean isNetworkAvailable() {
NetworkInfo activeNetworkInfo = ((ConnectivityManager) this.mContext.getSystemService("connectivity")).getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isAvailable();
}
void resetReconnectCount() {
RLog.i(TAG, "reset reconnectCount");
this.mRcRetryCount.set(0);
}
private NativeObject.ConnectionEntry[] getConnectionEntries(List<URL> list) {
ArrayList arrayList = new ArrayList();
if (list == null || list.size() <= 0) {
return (NativeObject.ConnectionEntry[]) arrayList.toArray(new NativeObject.ConnectionEntry[0]);
}
for (URL url : list) {
NativeObject.ConnectionEntry connectionEntry = new NativeObject.ConnectionEntry();
connectionEntry.setHost(url.getHost().replace("[", "").replace("]", ""));
connectionEntry.setPort(url.getPort());
arrayList.add(connectionEntry);
}
return (NativeObject.ConnectionEntry[]) arrayList.toArray(new NativeObject.ConnectionEntry[list.size()]);
}
private List<URL> getLegalCmpList(List<String> list) {
ArrayList arrayList = new ArrayList();
for (String str : new ArrayList(list)) {
URL legalServer = NetUtils.getLegalServer(str, true);
if (legalServer != null) {
arrayList.add(legalServer);
} else {
FwLog.write(1, 1, "L-check_cmp-S", "cmp", str);
}
}
return arrayList;
}
public void setIpcConnectTimeOut() {
this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
if (ConnectionService.this.mConnectionState.getCurrentStatus().equals(IRongCoreListener.ConnectionStatusListener.ConnectionStatus.CONNECTED)) {
return;
}
RLog.e(ConnectionService.TAG, "IM reconnect timeout, the connection will not continue");
ConnectionService.this.disposeReconnectByErrorCode(IRongCoreEnum.CoreErrorCode.RC_CONNECT_TIMEOUT.getValue(), -1);
ConnectionService.this.responseConnectErrorBlock(IRongCoreEnum.CoreErrorCode.RC_CONNECT_TIMEOUT.getValue());
}
});
}
public void initIPCEnviroment(String str, int i) {
RLog.i(TAG, "initConnectToken " + str);
this.mToken = str;
this.mConnectionState.initConnectStatus(i);
}
public ConnectionState getConnectionState() {
return this.mConnectionState;
}
public IRongCoreListener.ConnectionStatusListener.ConnectionStatus getCurrentConnectStatus() {
return getConnectionState().getCurrentStatus();
}
private void detectNaviIfNeed(String str, int i, int i2) {
boolean z;
if (IRongCoreEnum.CoreErrorCode.RC_CONN_ID_REJECT.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_CONN_USER_OR_PASSWD_ERROR.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_CONN_NOT_AUTHRORIZED.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_CONN_APP_BLOCKED_OR_DELETED.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_CONN_USER_BLOCKED.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_DISCONN_KICK.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_CONN_OTHER_DEVICE_LOGIN.getValue() == i2 || IRongCoreEnum.CoreErrorCode.BIZ_ERROR_CLIENT_NOT_INIT.getValue() == i2 || IRongCoreEnum.CoreErrorCode.PARAMETER_ERROR.getValue() == i2 || IRongCoreEnum.CoreErrorCode.RC_ENVIRONMENT_ERROR.getValue() == i2) {
return;
}
ConcurrentHashMap<String, Integer> concurrentHashMap = this.mTcpResultMap;
concurrentHashMap.put(str + ":" + i, new Integer(i2));
if (this.mTcpResultMap.size() >= getLegalCmpList(CMPStrategy.getInstance().getCmpList()).size()) {
Iterator<String> it = this.mTcpResultMap.keySet().iterator();
while (true) {
if (!it.hasNext()) {
z = false;
break;
}
Integer num = this.mTcpResultMap.get(it.next());
if (num != null && num.intValue() == 0) {
z = true;
break;
}
}
if (!z) {
NetDetection.detectNavi(this.mContext, false, new NetDetection.DetectionCallback() {
@Override
public void onError() {
}
@Override
public void onSuccess(String str2, String str3, String str4) {
FwLog.write(1, 1, FwLog.LogTag.L_DETECT_CMP_S.getTag(), "navi|ip|net", str2, str3, str4);
}
});
}
this.mTcpResultMap.clear();
}
}
private static class SingleHolder {
static ConnectionService instance = new ConnectionService();
private SingleHolder() {
}
}
public class ConnectStatusListener implements NativeObject.ConnectionStatusListener {
private ConnectStatusListener() {
}
@Override
public void OnTcpComplete(final NativeObject.ConnectionEntry connectionEntry) {
ConnectionService.this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
ConnectionService.this.OnProtocolTcpComplete(connectionEntry);
}
});
}
@Override
public void OnRmtpComplete(final int i, final String str, final int i2, final short s, final String str2) {
ConnectionService.this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
ConnectionService.this.OnProtocolRmtpComplete(i, str, i2, s, str2);
}
});
}
@Override
public void OnRmtpDisconnected(final int i, final int i2, final String str) {
ConnectionService.this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
ConnectionService.this.OnProtocolRmtpDisconnected(i, i2, str);
}
});
}
@Override
public void OnPongReceived() {
ConnectionService.this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
ConnectionService.this.OnProtocolPongReceived();
HeartBeatManager.getInstance().dequeue();
}
});
}
@Override
public void OnDatabaseOpened(final int i) {
ConnectionService.this.mCallBackExecutor.execute(new Runnable() {
@Override
public void run() {
ConnectionService.this.OnProtocolDBOpened(i);
}
});
}
}
public class ReconnectRunnable implements Runnable {
ReconnectRunnable() {
RLog.d(ConnectionService.TAG, "ReconnectRunnable");
}
@Override
public void run() {
RLog.d(ConnectionService.TAG, "ReconnectRunnable, count = " + ConnectionService.this.mRcRetryCount.get());
String str = ConnectionService.this.mToken;
if (!TextUtils.isEmpty(str)) {
boolean z = ConnectionService.this.mIsReconnect == null || ConnectionService.this.mIsReconnect.get();
ConnectionService.this.mIsReconnect = null;
ConnectionService connectionService = ConnectionService.this;
connectionService.connectServer(str, z, true, connectionService.mConnectCallback);
}
ConnectionService.this.mReconnectRunnable = null;
}
}
}