2015-09-24 22:52:02 +02:00
package org.telegram.tgnet ;
import android.annotation.SuppressLint ;
2017-07-08 18:32:04 +02:00
import android.app.Activity ;
import android.content.SharedPreferences ;
2017-12-08 18:35:59 +01:00
import android.content.pm.PackageInfo ;
2017-07-08 18:32:04 +02:00
import android.os.AsyncTask ;
2015-09-24 22:52:02 +02:00
import android.os.Build ;
2018-07-30 04:07:02 +02:00
import android.os.SystemClock ;
2017-07-08 18:32:04 +02:00
import android.text.TextUtils ;
import android.util.Base64 ;
2015-09-24 22:52:02 +02:00
2018-07-30 04:07:02 +02:00
import com.google.firebase.remoteconfig.FirebaseRemoteConfig ;
2017-07-08 18:32:04 +02:00
import org.json.JSONArray ;
import org.json.JSONObject ;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.AccountInstance ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.AndroidUtilities ;
2022-06-21 04:51:00 +02:00
import org.telegram.messenger.ApplicationLoader ;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.BaseController ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.BuildVars ;
2019-12-31 14:08:08 +01:00
import org.telegram.messenger.EmuDetector ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.FileLog ;
2018-07-30 04:07:02 +02:00
import org.telegram.messenger.KeepAliveJob ;
2017-12-08 18:35:59 +01:00
import org.telegram.messenger.LocaleController ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.MessagesController ;
import org.telegram.messenger.NotificationCenter ;
2022-08-12 17:23:51 +02:00
import org.telegram.messenger.PushListenerController ;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.SharedConfig ;
2017-03-31 01:58:05 +02:00
import org.telegram.messenger.StatsController ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.UserConfig ;
import org.telegram.messenger.Utilities ;
2017-07-08 18:32:04 +02:00
import java.io.ByteArrayOutputStream ;
2018-07-30 04:07:02 +02:00
import java.io.File ;
2017-07-08 18:32:04 +02:00
import java.io.InputStream ;
2015-09-24 22:52:02 +02:00
import java.net.Inet4Address ;
import java.net.Inet6Address ;
import java.net.InetAddress ;
import java.net.InterfaceAddress ;
import java.net.NetworkInterface ;
2023-02-25 09:01:39 +01:00
import java.net.SocketTimeoutException ;
2017-07-08 18:32:04 +02:00
import java.net.URL ;
import java.net.URLConnection ;
import java.util.ArrayList ;
import java.util.Collections ;
2015-09-24 22:52:02 +02:00
import java.util.Enumeration ;
2019-06-04 12:14:50 +02:00
import java.util.HashMap ;
2015-09-24 22:52:02 +02:00
import java.util.List ;
2022-09-16 20:48:21 +02:00
import java.util.Objects ;
2020-04-24 11:21:58 +02:00
import java.util.TimeZone ;
2019-07-18 15:01:39 +02:00
import java.util.concurrent.BlockingQueue ;
import java.util.concurrent.Executor ;
import java.util.concurrent.LinkedBlockingQueue ;
import java.util.concurrent.ThreadFactory ;
import java.util.concurrent.ThreadPoolExecutor ;
import java.util.concurrent.TimeUnit ;
2015-11-26 22:04:02 +01:00
import java.util.concurrent.atomic.AtomicInteger ;
2015-09-24 22:52:02 +02:00
2023-02-25 09:01:39 +01:00
import javax.net.ssl.SSLException ;
2019-07-18 15:01:39 +02:00
public class ConnectionsManager extends BaseController {
2015-09-24 22:52:02 +02:00
public final static int ConnectionTypeGeneric = 1 ;
public final static int ConnectionTypeDownload = 2 ;
public final static int ConnectionTypeUpload = 4 ;
public final static int ConnectionTypePush = 8 ;
public final static int ConnectionTypeDownload2 = ConnectionTypeDownload | ( 1 < < 16 ) ;
2017-03-31 01:58:05 +02:00
public final static int FileTypePhoto = 0x01000000 ;
public final static int FileTypeVideo = 0x02000000 ;
public final static int FileTypeAudio = 0x03000000 ;
public final static int FileTypeFile = 0x04000000 ;
2015-09-24 22:52:02 +02:00
public final static int RequestFlagEnableUnauthorized = 1 ;
public final static int RequestFlagFailOnServerErrors = 2 ;
public final static int RequestFlagCanCompress = 4 ;
public final static int RequestFlagWithoutLogin = 8 ;
public final static int RequestFlagTryDifferentDc = 16 ;
public final static int RequestFlagForceDownload = 32 ;
public final static int RequestFlagInvokeAfter = 64 ;
public final static int RequestFlagNeedQuickAck = 128 ;
2022-11-05 13:34:47 +01:00
public final static int RequestFlagDoNotWaitFloodWait = 1024 ;
2015-09-24 22:52:02 +02:00
public final static int ConnectionStateConnecting = 1 ;
public final static int ConnectionStateWaitingForNetwork = 2 ;
public final static int ConnectionStateConnected = 3 ;
2017-07-08 18:32:04 +02:00
public final static int ConnectionStateConnectingToProxy = 4 ;
public final static int ConnectionStateUpdating = 5 ;
2021-02-24 02:02:54 +01:00
public final static byte USE_IPV4_ONLY = 0 ;
public final static byte USE_IPV6_ONLY = 1 ;
public final static byte USE_IPV4_IPV6_RANDOM = 2 ;
2017-07-08 18:32:04 +02:00
private static long lastDnsRequestTime ;
2015-09-24 22:52:02 +02:00
public final static int DEFAULT_DATACENTER_ID = Integer . MAX_VALUE ;
private long lastPauseTime = System . currentTimeMillis ( ) ;
private boolean appPaused = true ;
2017-03-31 01:58:05 +02:00
private boolean isUpdating ;
2018-07-30 04:07:02 +02:00
private int connectionState ;
2015-11-26 22:04:02 +01:00
private AtomicInteger lastRequestToken = new AtomicInteger ( 1 ) ;
2017-03-31 01:58:05 +02:00
private int appResumeCount ;
2015-09-24 22:52:02 +02:00
2017-07-08 18:32:04 +02:00
private static AsyncTask currentTask ;
2019-06-04 12:14:50 +02:00
private static HashMap < String , ResolveHostByNameTask > resolvingHostnameTasks = new HashMap < > ( ) ;
2019-07-18 15:01:39 +02:00
public static final Executor DNS_THREAD_POOL_EXECUTOR ;
public static final int CPU_COUNT = Runtime . getRuntime ( ) . availableProcessors ( ) ;
private static final int CORE_POOL_SIZE = Math . max ( 2 , Math . min ( CPU_COUNT - 1 , 4 ) ) ;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1 ;
private static final int KEEP_ALIVE_SECONDS = 30 ;
private static final BlockingQueue < Runnable > sPoolWorkQueue = new LinkedBlockingQueue < > ( 128 ) ;
private static final ThreadFactory sThreadFactory = new ThreadFactory ( ) {
private final AtomicInteger mCount = new AtomicInteger ( 1 ) ;
public Thread newThread ( Runnable r ) {
return new Thread ( r , " DnsAsyncTask # " + mCount . getAndIncrement ( ) ) ;
}
} ;
2022-06-21 04:51:00 +02:00
private boolean forceTryIpV6 ;
2019-07-18 15:01:39 +02:00
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor ( CORE_POOL_SIZE , MAXIMUM_POOL_SIZE , KEEP_ALIVE_SECONDS , TimeUnit . SECONDS , sPoolWorkQueue , sThreadFactory ) ;
threadPoolExecutor . allowCoreThreadTimeOut ( true ) ;
DNS_THREAD_POOL_EXECUTOR = threadPoolExecutor ;
}
2022-06-21 04:51:00 +02:00
public void setForceTryIpV6 ( boolean forceTryIpV6 ) {
if ( this . forceTryIpV6 ! = forceTryIpV6 ) {
this . forceTryIpV6 = forceTryIpV6 ;
checkConnection ( ) ;
}
}
2018-07-30 04:07:02 +02:00
private static class ResolvedDomain {
2019-02-08 03:30:32 +01:00
public ArrayList < String > addresses ;
2018-07-30 04:07:02 +02:00
long ttl ;
2019-02-08 03:30:32 +01:00
public ResolvedDomain ( ArrayList < String > a , long t ) {
addresses = a ;
2018-07-30 04:07:02 +02:00
ttl = t ;
}
2019-02-08 03:30:32 +01:00
public String getAddress ( ) {
return addresses . get ( Utilities . random . nextInt ( addresses . size ( ) ) ) ;
}
2018-07-30 04:07:02 +02:00
}
2019-07-18 15:01:39 +02:00
private static HashMap < String , ResolvedDomain > dnsCache = new HashMap < > ( ) ;
2015-09-24 22:52:02 +02:00
2018-07-30 04:07:02 +02:00
private static int lastClassGuid = 1 ;
2019-07-18 15:01:39 +02:00
2022-06-21 04:51:00 +02:00
private static final ConnectionsManager [ ] Instance = new ConnectionsManager [ UserConfig . MAX_ACCOUNT_COUNT ] ;
2018-07-30 04:07:02 +02:00
public static ConnectionsManager getInstance ( int num ) {
ConnectionsManager localInstance = Instance [ num ] ;
2015-09-24 22:52:02 +02:00
if ( localInstance = = null ) {
synchronized ( ConnectionsManager . class ) {
2018-07-30 04:07:02 +02:00
localInstance = Instance [ num ] ;
2015-09-24 22:52:02 +02:00
if ( localInstance = = null ) {
2018-07-30 04:07:02 +02:00
Instance [ num ] = localInstance = new ConnectionsManager ( num ) ;
2015-09-24 22:52:02 +02:00
}
}
}
return localInstance ;
}
2018-07-30 04:07:02 +02:00
public ConnectionsManager ( int instance ) {
2019-07-18 15:01:39 +02:00
super ( instance ) ;
2018-07-30 04:07:02 +02:00
connectionState = native_getConnectionState ( currentAccount ) ;
2017-12-08 18:35:59 +01:00
String deviceModel ;
String systemLangCode ;
String langCode ;
String appVersion ;
String systemVersion ;
2018-07-30 04:07:02 +02:00
File config = ApplicationLoader . getFilesDirFixed ( ) ;
if ( instance ! = 0 ) {
config = new File ( config , " account " + instance ) ;
config . mkdirs ( ) ;
}
String configPath = config . toString ( ) ;
2019-12-31 14:08:08 +01:00
boolean enablePushConnection = isPushConnectionEnabled ( ) ;
2017-12-08 18:35:59 +01:00
try {
2018-07-30 04:07:02 +02:00
systemLangCode = LocaleController . getSystemLocaleStringIso639 ( ) . toLowerCase ( ) ;
langCode = LocaleController . getLocaleStringIso639 ( ) . toLowerCase ( ) ;
2017-12-08 18:35:59 +01:00
deviceModel = Build . MANUFACTURER + Build . MODEL ;
PackageInfo pInfo = ApplicationLoader . applicationContext . getPackageManager ( ) . getPackageInfo ( ApplicationLoader . applicationContext . getPackageName ( ) , 0 ) ;
appVersion = pInfo . versionName + " ( " + pInfo . versionCode + " ) " ;
2020-03-30 14:00:09 +02:00
if ( BuildVars . DEBUG_PRIVATE_VERSION ) {
appVersion + = " pbeta " ;
} else if ( BuildVars . DEBUG_VERSION ) {
appVersion + = " beta " ;
}
2017-12-08 18:35:59 +01:00
systemVersion = " SDK " + Build . VERSION . SDK_INT ;
} catch ( Exception e ) {
systemLangCode = " en " ;
langCode = " " ;
deviceModel = " Android unknown " ;
appVersion = " App version unknown " ;
systemVersion = " SDK " + Build . VERSION . SDK_INT ;
}
if ( systemLangCode . trim ( ) . length ( ) = = 0 ) {
2018-07-30 04:07:02 +02:00
systemLangCode = " en " ;
2017-12-08 18:35:59 +01:00
}
if ( deviceModel . trim ( ) . length ( ) = = 0 ) {
deviceModel = " Android unknown " ;
}
if ( appVersion . trim ( ) . length ( ) = = 0 ) {
appVersion = " App version unknown " ;
}
if ( systemVersion . trim ( ) . length ( ) = = 0 ) {
systemVersion = " SDK Unknown " ;
}
2019-07-18 15:01:39 +02:00
getUserConfig ( ) . loadConfig ( ) ;
2021-08-31 21:06:39 +02:00
String pushString = getRegId ( ) ;
2019-12-31 14:08:08 +01:00
String fingerprint = AndroidUtilities . getCertificateSHA256Fingerprint ( ) ;
2020-04-24 11:21:58 +02:00
int timezoneOffset = ( TimeZone . getDefault ( ) . getRawOffset ( ) + TimeZone . getDefault ( ) . getDSTSavings ( ) ) / 1000 ;
2022-06-21 04:51:00 +02:00
SharedPreferences mainPreferences ;
if ( currentAccount = = 0 ) {
mainPreferences = ApplicationLoader . applicationContext . getSharedPreferences ( " mainconfig " , Activity . MODE_PRIVATE ) ;
} else {
mainPreferences = ApplicationLoader . applicationContext . getSharedPreferences ( " mainconfig " + currentAccount , Activity . MODE_PRIVATE ) ;
}
forceTryIpV6 = mainPreferences . getBoolean ( " forceTryIpV6 " , false ) ;
2020-04-24 11:21:58 +02:00
init ( BuildVars . BUILD_VERSION , TLRPC . LAYER , BuildVars . APP_ID , deviceModel , systemVersion , appVersion , langCode , systemLangCode , configPath , FileLog . getNetworkLogPath ( ) , pushString , fingerprint , timezoneOffset , getUserConfig ( ) . getClientUserId ( ) , enablePushConnection ) ;
2019-12-31 14:08:08 +01:00
}
2021-08-31 21:06:39 +02:00
private String getRegId ( ) {
String pushString = SharedConfig . pushString ;
2022-08-12 17:23:51 +02:00
if ( ! TextUtils . isEmpty ( pushString ) & & SharedConfig . pushType = = PushListenerController . PUSH_TYPE_HUAWEI ) {
pushString = " huawei:// " + pushString ;
}
2021-08-31 21:06:39 +02:00
if ( TextUtils . isEmpty ( pushString ) & & ! TextUtils . isEmpty ( SharedConfig . pushStringStatus ) ) {
pushString = SharedConfig . pushStringStatus ;
}
if ( TextUtils . isEmpty ( pushString ) ) {
2022-08-12 17:23:51 +02:00
String tag = SharedConfig . pushType = = PushListenerController . PUSH_TYPE_FIREBASE ? " FIREBASE " : " HUAWEI " ;
pushString = SharedConfig . pushStringStatus = " __ " + tag + " _GENERATING_SINCE_ " + getCurrentTime ( ) + " __ " ;
2021-08-31 21:06:39 +02:00
}
return pushString ;
}
2019-12-31 14:08:08 +01:00
public boolean isPushConnectionEnabled ( ) {
SharedPreferences preferences = MessagesController . getGlobalNotificationsSettings ( ) ;
if ( preferences . contains ( " pushConnection " ) ) {
return preferences . getBoolean ( " pushConnection " , true ) ;
} else {
return MessagesController . getMainSettings ( UserConfig . selectedAccount ) . getBoolean ( " backgroundConnection " , false ) ;
}
2015-09-24 22:52:02 +02:00
}
public long getCurrentTimeMillis ( ) {
2018-07-30 04:07:02 +02:00
return native_getCurrentTimeMillis ( currentAccount ) ;
2015-09-24 22:52:02 +02:00
}
public int getCurrentTime ( ) {
2018-07-30 04:07:02 +02:00
return native_getCurrentTime ( currentAccount ) ;
2015-09-24 22:52:02 +02:00
}
2020-10-30 11:26:29 +01:00
public int getCurrentDatacenterId ( ) {
return native_getCurrentDatacenterId ( currentAccount ) ;
}
2015-09-24 22:52:02 +02:00
public int getTimeDifference ( ) {
2018-07-30 04:07:02 +02:00
return native_getTimeDifference ( currentAccount ) ;
2015-09-24 22:52:02 +02:00
}
public int sendRequest ( TLObject object , RequestDelegate completionBlock ) {
return sendRequest ( object , completionBlock , null , 0 ) ;
}
public int sendRequest ( TLObject object , RequestDelegate completionBlock , int flags ) {
2021-03-19 11:25:58 +01:00
return sendRequest ( object , completionBlock , null , null , null , flags , DEFAULT_DATACENTER_ID , ConnectionTypeGeneric , true ) ;
2015-09-24 22:52:02 +02:00
}
public int sendRequest ( TLObject object , RequestDelegate completionBlock , int flags , int connetionType ) {
2021-03-19 11:25:58 +01:00
return sendRequest ( object , completionBlock , null , null , null , flags , DEFAULT_DATACENTER_ID , connetionType , true ) ;
}
public int sendRequest ( TLObject object , RequestDelegateTimestamp completionBlock , int flags , int connetionType , int datacenterId ) {
return sendRequest ( object , null , completionBlock , null , null , flags , datacenterId , connetionType , true ) ;
2015-09-24 22:52:02 +02:00
}
public int sendRequest ( TLObject object , RequestDelegate completionBlock , QuickAckDelegate quickAckBlock , int flags ) {
2021-03-19 11:25:58 +01:00
return sendRequest ( object , completionBlock , null , quickAckBlock , null , flags , DEFAULT_DATACENTER_ID , ConnectionTypeGeneric , true ) ;
2015-09-24 22:52:02 +02:00
}
2017-07-08 18:32:04 +02:00
public int sendRequest ( final TLObject object , final RequestDelegate onComplete , final QuickAckDelegate onQuickAck , final WriteToSocketDelegate onWriteToSocket , final int flags , final int datacenterId , final int connetionType , final boolean immediate ) {
2021-03-19 11:25:58 +01:00
return sendRequest ( object , onComplete , null , onQuickAck , onWriteToSocket , flags , datacenterId , connetionType , immediate ) ;
}
2023-02-25 09:01:39 +01:00
public int sendRequestSync ( final TLObject object , final RequestDelegate onComplete , final QuickAckDelegate onQuickAck , final WriteToSocketDelegate onWriteToSocket , final int flags , final int datacenterId , final int connetionType , final boolean immediate ) {
final int requestToken = lastRequestToken . getAndIncrement ( ) ;
sendRequestInternal ( object , onComplete , null , onQuickAck , onWriteToSocket , flags , datacenterId , connetionType , immediate , requestToken ) ;
return requestToken ;
}
2021-03-19 11:25:58 +01:00
public int sendRequest ( final TLObject object , final RequestDelegate onComplete , final RequestDelegateTimestamp onCompleteTimestamp , final QuickAckDelegate onQuickAck , final WriteToSocketDelegate onWriteToSocket , final int flags , final int datacenterId , final int connetionType , final boolean immediate ) {
2015-11-26 22:04:02 +01:00
final int requestToken = lastRequestToken . getAndIncrement ( ) ;
2019-01-23 18:03:33 +01:00
Utilities . stageQueue . postRunnable ( ( ) - > {
2023-02-25 09:01:39 +01:00
sendRequestInternal ( object , onComplete , onCompleteTimestamp , onQuickAck , onWriteToSocket , flags , datacenterId , connetionType , immediate , requestToken ) ;
} ) ;
return requestToken ;
}
2016-03-06 02:49:31 +01:00
2023-02-25 09:01:39 +01:00
private void sendRequestInternal ( TLObject object , RequestDelegate onComplete , RequestDelegateTimestamp onCompleteTimestamp , QuickAckDelegate onQuickAck , WriteToSocketDelegate onWriteToSocket , int flags , int datacenterId , int connetionType , boolean immediate , int requestToken ) {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " send request " + object + " with token = " + requestToken ) ;
}
try {
NativeByteBuffer buffer = new NativeByteBuffer ( object . getObjectSize ( ) ) ;
object . serializeToStream ( buffer ) ;
object . freeResources ( ) ;
long startRequestTime = 0 ;
if ( BuildVars . DEBUG_PRIVATE_VERSION & & BuildVars . LOGS_ENABLED ) {
startRequestTime = System . currentTimeMillis ( ) ;
}
long finalStartRequestTime = startRequestTime ;
native_sendRequest ( currentAccount , buffer . address , ( response , errorCode , errorText , networkType , timestamp , requestMsgId ) - > {
try {
TLObject resp = null ;
TLRPC . TL_error error = null ;
if ( response ! = 0 ) {
NativeByteBuffer buff = NativeByteBuffer . wrap ( response ) ;
buff . reused = true ;
try {
resp = object . deserializeResponse ( buff , buff . readInt32 ( true ) , true ) ;
} catch ( Exception e2 ) {
if ( BuildVars . DEBUG_PRIVATE_VERSION ) {
throw e2 ;
2022-09-16 20:48:21 +02:00
}
2023-02-25 09:01:39 +01:00
FileLog . fatal ( e2 ) ;
2022-09-16 20:48:21 +02:00
return ;
}
2023-02-25 09:01:39 +01:00
} else if ( errorText ! = null ) {
error = new TLRPC . TL_error ( ) ;
error . code = errorCode ;
error . text = errorText ;
if ( BuildVars . LOGS_ENABLED ) {
FileLog . e ( object + " got error " + error . code + " " + error . text ) ;
2019-01-23 18:03:33 +01:00
}
2023-02-25 09:01:39 +01:00
}
if ( BuildVars . DEBUG_PRIVATE_VERSION & & ! getUserConfig ( ) . isClientActivated ( ) & & error ! = null & & error . code = = 400 & & Objects . equals ( error . text , " CONNECTION_NOT_INITED " ) ) {
2019-01-23 18:03:33 +01:00
if ( BuildVars . LOGS_ENABLED ) {
2023-02-25 09:01:39 +01:00
FileLog . d ( " Cleanup keys for " + currentAccount + " because of CONNECTION_NOT_INITED " ) ;
2019-01-23 18:03:33 +01:00
}
2023-02-25 09:01:39 +01:00
cleanup ( true ) ;
sendRequest ( object , onComplete , onCompleteTimestamp , onQuickAck , onWriteToSocket , flags , datacenterId , connetionType , immediate ) ;
return ;
2019-01-23 18:03:33 +01:00
}
2023-02-25 09:01:39 +01:00
if ( resp ! = null ) {
resp . networkType = networkType ;
}
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " java received " + resp + " error = " + error ) ;
}
FileLog . dumpResponseAndRequest ( object , resp , error , requestMsgId , finalStartRequestTime , requestToken ) ;
final TLObject finalResponse = resp ;
final TLRPC . TL_error finalError = error ;
Utilities . stageQueue . postRunnable ( ( ) - > {
if ( onComplete ! = null ) {
onComplete . run ( finalResponse , finalError ) ;
} else if ( onCompleteTimestamp ! = null ) {
onCompleteTimestamp . run ( finalResponse , finalError , timestamp ) ;
}
if ( finalResponse ! = null ) {
finalResponse . freeResources ( ) ;
}
} ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
} , onQuickAck , onWriteToSocket , flags , datacenterId , connetionType , immediate , requestToken ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
2015-09-24 22:52:02 +02:00
}
public void cancelRequest ( int token , boolean notifyServer ) {
2023-02-25 09:01:39 +01:00
Utilities . stageQueue . postRunnable ( ( ) - > {
native_cancelRequest ( currentAccount , token , notifyServer ) ;
} ) ;
2015-09-24 22:52:02 +02:00
}
2018-07-30 04:07:02 +02:00
public void cleanup ( boolean resetKeys ) {
native_cleanUp ( currentAccount , resetKeys ) ;
2015-09-24 22:52:02 +02:00
}
public void cancelRequestsForGuid ( int guid ) {
2023-02-25 09:01:39 +01:00
Utilities . stageQueue . postRunnable ( ( ) - > {
native_cancelRequestsForGuid ( currentAccount , guid ) ;
} ) ;
2015-09-24 22:52:02 +02:00
}
public void bindRequestToGuid ( int requestToken , int guid ) {
2018-07-30 04:07:02 +02:00
native_bindRequestToGuid ( currentAccount , requestToken , guid ) ;
2015-09-24 22:52:02 +02:00
}
public void applyDatacenterAddress ( int datacenterId , String ipAddress , int port ) {
2018-07-30 04:07:02 +02:00
native_applyDatacenterAddress ( currentAccount , datacenterId , ipAddress , port ) ;
2015-09-24 22:52:02 +02:00
}
public int getConnectionState ( ) {
if ( connectionState = = ConnectionStateConnected & & isUpdating ) {
return ConnectionStateUpdating ;
}
return connectionState ;
}
2021-09-20 07:54:41 +02:00
public void setUserId ( long id ) {
2018-07-30 04:07:02 +02:00
native_setUserId ( currentAccount , id ) ;
2015-09-24 22:52:02 +02:00
}
2019-01-23 18:03:33 +01:00
public void checkConnection ( ) {
2023-03-24 12:38:14 +01:00
byte selectedStrategy = getIpStrategy ( ) ;
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " selected ip strategy " + selectedStrategy ) ;
}
native_setIpStrategy ( currentAccount , selectedStrategy ) ;
2019-01-23 18:03:33 +01:00
native_setNetworkAvailable ( currentAccount , ApplicationLoader . isNetworkOnline ( ) , ApplicationLoader . getCurrentNetworkType ( ) , ApplicationLoader . isConnectionSlow ( ) ) ;
2015-09-24 22:52:02 +02:00
}
2016-04-22 15:49:00 +02:00
public void setPushConnectionEnabled ( boolean value ) {
2018-07-30 04:07:02 +02:00
native_setPushConnectionEnabled ( currentAccount , value ) ;
2016-04-22 15:49:00 +02:00
}
2021-09-20 07:54:41 +02:00
public void init ( int version , int layer , int apiId , String deviceModel , String systemVersion , String appVersion , String langCode , String systemLangCode , String configPath , String logPath , String regId , String cFingerprint , int timezoneOffset , long userId , boolean enablePushConnection ) {
2017-07-08 18:32:04 +02:00
SharedPreferences preferences = ApplicationLoader . applicationContext . getSharedPreferences ( " mainconfig " , Activity . MODE_PRIVATE ) ;
String proxyAddress = preferences . getString ( " proxy_ip " , " " ) ;
String proxyUsername = preferences . getString ( " proxy_user " , " " ) ;
String proxyPassword = preferences . getString ( " proxy_pass " , " " ) ;
2018-07-30 04:07:02 +02:00
String proxySecret = preferences . getString ( " proxy_secret " , " " ) ;
2017-07-08 18:32:04 +02:00
int proxyPort = preferences . getInt ( " proxy_port " , 1080 ) ;
2021-09-20 07:54:41 +02:00
2017-07-08 18:32:04 +02:00
if ( preferences . getBoolean ( " proxy_enabled " , false ) & & ! TextUtils . isEmpty ( proxyAddress ) ) {
2018-07-30 04:07:02 +02:00
native_setProxySettings ( currentAccount , proxyAddress , proxyPort , proxyUsername , proxyPassword , proxySecret ) ;
2017-07-08 18:32:04 +02:00
}
2020-07-26 10:03:38 +02:00
String installer = " " ;
try {
installer = ApplicationLoader . applicationContext . getPackageManager ( ) . getInstallerPackageName ( ApplicationLoader . applicationContext . getPackageName ( ) ) ;
} catch ( Throwable ignore ) {
2017-07-08 18:32:04 +02:00
2020-07-26 10:03:38 +02:00
}
if ( installer = = null ) {
installer = " " ;
}
2021-04-14 03:44:46 +02:00
String packageId = " " ;
try {
packageId = ApplicationLoader . applicationContext . getPackageName ( ) ;
} catch ( Throwable ignore ) {
}
if ( packageId = = null ) {
packageId = " " ;
}
2020-07-26 10:03:38 +02:00
2023-02-18 22:24:25 +01:00
native_init ( currentAccount , version , layer , apiId , deviceModel , systemVersion , appVersion , langCode , systemLangCode , configPath , logPath , regId , cFingerprint , installer , packageId , timezoneOffset , userId , enablePushConnection , ApplicationLoader . isNetworkOnline ( ) , ApplicationLoader . getCurrentNetworkType ( ) , SharedConfig . measureDevicePerformanceClass ( ) ) ;
2015-09-24 22:52:02 +02:00
checkConnection ( ) ;
}
2018-07-30 04:07:02 +02:00
public static void setLangCode ( String langCode ) {
langCode = langCode . replace ( '_' , '-' ) . toLowerCase ( ) ;
for ( int a = 0 ; a < UserConfig . MAX_ACCOUNT_COUNT ; a + + ) {
native_setLangCode ( a , langCode ) ;
}
2017-07-08 18:32:04 +02:00
}
2022-08-12 17:23:51 +02:00
public static void setRegId ( String regId , @PushListenerController.PushType int type , String status ) {
2019-07-18 15:01:39 +02:00
String pushString = regId ;
2022-08-12 17:23:51 +02:00
if ( ! TextUtils . isEmpty ( pushString ) & & type = = PushListenerController . PUSH_TYPE_HUAWEI ) {
pushString = " huawei:// " + pushString ;
}
2019-07-18 15:01:39 +02:00
if ( TextUtils . isEmpty ( pushString ) & & ! TextUtils . isEmpty ( status ) ) {
pushString = status ;
}
2021-08-31 21:06:39 +02:00
if ( TextUtils . isEmpty ( pushString ) ) {
2022-08-12 17:23:51 +02:00
String tag = type = = PushListenerController . PUSH_TYPE_FIREBASE ? " FIREBASE " : " HUAWEI " ;
pushString = SharedConfig . pushStringStatus = " __ " + tag + " _GENERATING_SINCE_ " + getInstance ( 0 ) . getCurrentTime ( ) + " __ " ;
2021-08-31 21:06:39 +02:00
}
2019-07-18 15:01:39 +02:00
for ( int a = 0 ; a < UserConfig . MAX_ACCOUNT_COUNT ; a + + ) {
native_setRegId ( a , pushString ) ;
}
}
2019-01-23 18:03:33 +01:00
public static void setSystemLangCode ( String langCode ) {
langCode = langCode . replace ( '_' , '-' ) . toLowerCase ( ) ;
for ( int a = 0 ; a < UserConfig . MAX_ACCOUNT_COUNT ; a + + ) {
native_setSystemLangCode ( a , langCode ) ;
}
}
2021-07-30 16:49:55 +02:00
public void switchBackend ( boolean restart ) {
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController . getGlobalMainSettings ( ) ;
2017-12-08 18:35:59 +01:00
preferences . edit ( ) . remove ( " language_showed2 " ) . commit ( ) ;
2021-07-30 16:49:55 +02:00
native_switchBackend ( currentAccount , restart ) ;
}
public boolean isTestBackend ( ) {
return native_isTestBackend ( currentAccount ) ! = 0 ;
2015-09-24 22:52:02 +02:00
}
public void resumeNetworkMaybe ( ) {
2018-07-30 04:07:02 +02:00
native_resumeNetwork ( currentAccount , true ) ;
2015-09-24 22:52:02 +02:00
}
public void updateDcSettings ( ) {
2018-07-30 04:07:02 +02:00
native_updateDcSettings ( currentAccount ) ;
2015-09-24 22:52:02 +02:00
}
public long getPauseTime ( ) {
return lastPauseTime ;
}
2018-07-30 04:07:02 +02:00
public long checkProxy ( String address , int port , String username , String password , String secret , RequestTimeDelegate requestTimeDelegate ) {
if ( TextUtils . isEmpty ( address ) ) {
return 0 ;
}
if ( address = = null ) {
address = " " ;
}
if ( username = = null ) {
username = " " ;
}
if ( password = = null ) {
password = " " ;
}
if ( secret = = null ) {
secret = " " ;
}
return native_checkProxy ( currentAccount , address , port , username , password , secret , requestTimeDelegate ) ;
}
2015-09-24 22:52:02 +02:00
public void setAppPaused ( final boolean value , final boolean byScreenState ) {
if ( ! byScreenState ) {
appPaused = value ;
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " app paused = " + value ) ;
}
2017-03-31 01:58:05 +02:00
if ( value ) {
appResumeCount - - ;
} else {
appResumeCount + + ;
}
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " app resume count " + appResumeCount ) ;
}
2017-03-31 01:58:05 +02:00
if ( appResumeCount < 0 ) {
appResumeCount = 0 ;
}
2015-09-24 22:52:02 +02:00
}
2017-03-31 01:58:05 +02:00
if ( appResumeCount = = 0 ) {
2015-09-24 22:52:02 +02:00
if ( lastPauseTime = = 0 ) {
lastPauseTime = System . currentTimeMillis ( ) ;
}
2018-07-30 04:07:02 +02:00
native_pauseNetwork ( currentAccount ) ;
2015-09-24 22:52:02 +02:00
} else {
if ( appPaused ) {
return ;
}
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " reset app pause time " ) ;
}
2015-09-24 22:52:02 +02:00
if ( lastPauseTime ! = 0 & & System . currentTimeMillis ( ) - lastPauseTime > 5000 ) {
2019-07-18 15:01:39 +02:00
getContactsController ( ) . checkContacts ( ) ;
2015-09-24 22:52:02 +02:00
}
lastPauseTime = 0 ;
2018-07-30 04:07:02 +02:00
native_resumeNetwork ( currentAccount , false ) ;
2015-09-24 22:52:02 +02:00
}
}
2022-11-06 02:16:18 +01:00
public static void onUnparsedMessageReceived ( long address , final int currentAccount , long messageId ) {
2015-09-24 22:52:02 +02:00
try {
NativeByteBuffer buff = NativeByteBuffer . wrap ( address ) ;
2016-05-25 23:49:47 +02:00
buff . reused = true ;
2019-01-23 18:03:33 +01:00
int constructor = buff . readInt32 ( true ) ;
final TLObject message = TLClassStore . Instance ( ) . TLdeserialize ( buff , constructor , true ) ;
2022-11-06 02:16:18 +01:00
FileLog . dumpUnparsedMessage ( message , messageId ) ;
2015-09-24 22:52:02 +02:00
if ( message instanceof TLRPC . Updates ) {
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " java received " + message ) ;
}
KeepAliveJob . finishJob ( ) ;
2019-07-18 15:01:39 +02:00
Utilities . stageQueue . postRunnable ( ( ) - > AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . processUpdates ( ( TLRPC . Updates ) message , false ) ) ;
2019-01-23 18:03:33 +01:00
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( String . format ( " java received unknown constructor 0x%x " , constructor ) ) ;
}
2015-09-24 22:52:02 +02:00
}
} catch ( Exception e ) {
2017-03-31 01:58:05 +02:00
FileLog . e ( e ) ;
2015-09-24 22:52:02 +02:00
}
}
2018-07-30 04:07:02 +02:00
public static void onUpdate ( final int currentAccount ) {
2019-07-18 15:01:39 +02:00
Utilities . stageQueue . postRunnable ( ( ) - > AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . updateTimerProc ( ) ) ;
2015-09-24 22:52:02 +02:00
}
2018-07-30 04:07:02 +02:00
public static void onSessionCreated ( final int currentAccount ) {
2019-07-18 15:01:39 +02:00
Utilities . stageQueue . postRunnable ( ( ) - > AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . getDifference ( ) ) ;
2015-09-24 22:52:02 +02:00
}
2018-07-30 04:07:02 +02:00
public static void onConnectionStateChanged ( final int state , final int currentAccount ) {
2019-01-23 18:03:33 +01:00
AndroidUtilities . runOnUIThread ( ( ) - > {
getInstance ( currentAccount ) . connectionState = state ;
2019-07-18 15:01:39 +02:00
AccountInstance . getInstance ( currentAccount ) . getNotificationCenter ( ) . postNotificationName ( NotificationCenter . didUpdateConnectionState ) ;
2015-09-24 22:52:02 +02:00
} ) ;
}
2018-07-30 04:07:02 +02:00
public static void onLogout ( final int currentAccount ) {
2019-01-23 18:03:33 +01:00
AndroidUtilities . runOnUIThread ( ( ) - > {
2019-07-18 15:01:39 +02:00
AccountInstance accountInstance = AccountInstance . getInstance ( currentAccount ) ;
if ( accountInstance . getUserConfig ( ) . getClientUserId ( ) ! = 0 ) {
accountInstance . getUserConfig ( ) . clearConfig ( ) ;
accountInstance . getMessagesController ( ) . performLogout ( 0 ) ;
2015-09-24 22:52:02 +02:00
}
} ) ;
}
2019-02-08 03:30:32 +01:00
public static int getInitFlags ( ) {
2020-01-23 13:58:50 +01:00
int flags = 0 ;
2019-12-31 14:08:08 +01:00
EmuDetector detector = EmuDetector . with ( ApplicationLoader . applicationContext ) ;
if ( detector . detect ( ) ) {
2020-10-30 11:26:29 +01:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " detected emu " ) ;
}
2020-01-23 13:58:50 +01:00
flags | = 1024 ;
}
return flags ;
2018-07-30 04:07:02 +02:00
}
public static void onBytesSent ( int amount , int networkType , final int currentAccount ) {
2017-03-31 01:58:05 +02:00
try {
2019-07-18 15:01:39 +02:00
AccountInstance . getInstance ( currentAccount ) . getStatsController ( ) . incrementSentBytesCount ( networkType , StatsController . TYPE_TOTAL , amount ) ;
2017-03-31 01:58:05 +02:00
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
}
2018-07-30 04:07:02 +02:00
public static void onRequestNewServerIpAndPort ( final int second , final int currentAccount ) {
2020-07-26 10:03:38 +02:00
Utilities . globalQueue . postRunnable ( ( ) - > {
boolean networkOnline = ApplicationLoader . isNetworkOnline ( ) ;
Utilities . stageQueue . postRunnable ( ( ) - > {
if ( currentTask ! = null | | second = = 0 & & Math . abs ( lastDnsRequestTime - System . currentTimeMillis ( ) ) < 10000 | | ! networkOnline ) {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " don't start task, current task = " + currentTask + " next task = " + second + " time diff = " + Math . abs ( lastDnsRequestTime - System . currentTimeMillis ( ) ) + " network = " + ApplicationLoader . isNetworkOnline ( ) ) ;
}
return ;
2018-07-30 04:07:02 +02:00
}
2020-07-26 10:03:38 +02:00
lastDnsRequestTime = System . currentTimeMillis ( ) ;
if ( second = = 3 ) {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " start mozilla txt task " ) ;
}
MozillaDnsLoadTask task = new MozillaDnsLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
} else if ( second = = 2 ) {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " start google txt task " ) ;
}
GoogleDnsLoadTask task = new GoogleDnsLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
} else if ( second = = 1 ) {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " start dns txt task " ) ;
}
DnsTxtLoadTask task = new DnsTxtLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " start firebase task " ) ;
}
FirebaseTask task = new FirebaseTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
2019-01-23 18:03:33 +01:00
}
2020-07-26 10:03:38 +02:00
} ) ;
2018-07-30 04:07:02 +02:00
} ) ;
}
public static void onProxyError ( ) {
2019-01-23 18:03:33 +01:00
AndroidUtilities . runOnUIThread ( ( ) - > NotificationCenter . getGlobalInstance ( ) . postNotificationName ( NotificationCenter . needShowAlert , 3 ) ) ;
2018-07-30 04:07:02 +02:00
}
2019-05-14 14:08:05 +02:00
public static void getHostByName ( String hostName , long address ) {
2019-07-18 15:01:39 +02:00
AndroidUtilities . runOnUIThread ( ( ) - > {
ResolvedDomain resolvedDomain = dnsCache . get ( hostName ) ;
if ( resolvedDomain ! = null & & SystemClock . elapsedRealtime ( ) - resolvedDomain . ttl < 5 * 60 * 1000 ) {
native_onHostNameResolved ( hostName , address , resolvedDomain . getAddress ( ) ) ;
} else {
ResolveHostByNameTask task = resolvingHostnameTasks . get ( hostName ) ;
if ( task = = null ) {
task = new ResolveHostByNameTask ( hostName ) ;
try {
task . executeOnExecutor ( DNS_THREAD_POOL_EXECUTOR , null , null , null ) ;
} catch ( Throwable e ) {
FileLog . e ( e ) ;
native_onHostNameResolved ( hostName , address , " " ) ;
return ;
}
resolvingHostnameTasks . put ( hostName , task ) ;
}
task . addAddress ( address ) ;
2019-06-04 12:14:50 +02:00
}
2019-07-18 15:01:39 +02:00
} ) ;
2017-07-08 18:32:04 +02:00
}
2018-07-30 04:07:02 +02:00
public static void onBytesReceived ( int amount , int networkType , final int currentAccount ) {
2017-03-31 01:58:05 +02:00
try {
2018-07-30 04:07:02 +02:00
StatsController . getInstance ( currentAccount ) . incrementReceivedBytesCount ( networkType , StatsController . TYPE_TOTAL , amount ) ;
2017-03-31 01:58:05 +02:00
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
}
2018-07-30 04:07:02 +02:00
public static void onUpdateConfig ( long address , final int currentAccount ) {
2015-09-24 22:52:02 +02:00
try {
NativeByteBuffer buff = NativeByteBuffer . wrap ( address ) ;
2016-05-25 23:49:47 +02:00
buff . reused = true ;
2015-09-24 22:52:02 +02:00
final TLRPC . TL_config message = TLRPC . TL_config . TLdeserialize ( buff , buff . readInt32 ( true ) , true ) ;
if ( message ! = null ) {
2019-07-18 15:01:39 +02:00
Utilities . stageQueue . postRunnable ( ( ) - > AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . updateConfig ( message ) ) ;
2015-09-24 22:52:02 +02:00
}
} catch ( Exception e ) {
2017-03-31 01:58:05 +02:00
FileLog . e ( e ) ;
2015-09-24 22:52:02 +02:00
}
}
2018-07-30 04:07:02 +02:00
public static void onInternalPushReceived ( final int currentAccount ) {
KeepAliveJob . startJob ( ) ;
}
public static void setProxySettings ( boolean enabled , String address , int port , String username , String password , String secret ) {
if ( address = = null ) {
address = " " ;
}
if ( username = = null ) {
username = " " ;
}
if ( password = = null ) {
password = " " ;
}
if ( secret = = null ) {
secret = " " ;
}
2021-09-20 07:54:41 +02:00
2018-07-30 04:07:02 +02:00
for ( int a = 0 ; a < UserConfig . MAX_ACCOUNT_COUNT ; a + + ) {
if ( enabled & & ! TextUtils . isEmpty ( address ) ) {
native_setProxySettings ( a , address , port , username , password , secret ) ;
} else {
native_setProxySettings ( a , " " , 1080 , " " , " " , " " ) ;
2015-09-24 22:52:02 +02:00
}
2019-07-18 15:01:39 +02:00
AccountInstance accountInstance = AccountInstance . getInstance ( a ) ;
if ( accountInstance . getUserConfig ( ) . isClientActivated ( ) ) {
2020-04-30 21:07:00 +02:00
accountInstance . getMessagesController ( ) . checkPromoInfo ( true ) ;
2018-07-30 04:07:02 +02:00
}
}
2015-09-24 22:52:02 +02:00
}
2021-07-30 16:49:55 +02:00
public static native void native_switchBackend ( int currentAccount , boolean restart ) ;
2018-07-30 04:07:02 +02:00
public static native int native_isTestBackend ( int currentAccount ) ;
public static native void native_pauseNetwork ( int currentAccount ) ;
2021-02-24 02:02:54 +01:00
public static native void native_setIpStrategy ( int currentAccount , byte value ) ;
2018-07-30 04:07:02 +02:00
public static native void native_updateDcSettings ( int currentAccount ) ;
public static native void native_setNetworkAvailable ( int currentAccount , boolean value , int networkType , boolean slow ) ;
public static native void native_resumeNetwork ( int currentAccount , boolean partial ) ;
public static native long native_getCurrentTimeMillis ( int currentAccount ) ;
public static native int native_getCurrentTime ( int currentAccount ) ;
2020-10-30 11:26:29 +01:00
public static native int native_getCurrentDatacenterId ( int currentAccount ) ;
2018-07-30 04:07:02 +02:00
public static native int native_getTimeDifference ( int currentAccount ) ;
public static native void native_sendRequest ( int currentAccount , long object , RequestDelegateInternal onComplete , QuickAckDelegate onQuickAck , WriteToSocketDelegate onWriteToSocket , int flags , int datacenterId , int connetionType , boolean immediate , int requestToken ) ;
public static native void native_cancelRequest ( int currentAccount , int token , boolean notifyServer ) ;
public static native void native_cleanUp ( int currentAccount , boolean resetKeys ) ;
public static native void native_cancelRequestsForGuid ( int currentAccount , int guid ) ;
public static native void native_bindRequestToGuid ( int currentAccount , int requestToken , int guid ) ;
public static native void native_applyDatacenterAddress ( int currentAccount , int datacenterId , String ipAddress , int port ) ;
public static native int native_getConnectionState ( int currentAccount ) ;
2021-09-20 07:54:41 +02:00
public static native void native_setUserId ( int currentAccount , long id ) ;
2023-02-18 22:24:25 +01:00
public static native void native_init ( int currentAccount , int version , int layer , int apiId , String deviceModel , String systemVersion , String appVersion , String langCode , String systemLangCode , String configPath , String logPath , String regId , String cFingerprint , String installer , String packageId , int timezoneOffset , long userId , boolean enablePushConnection , boolean hasNetwork , int networkType , int performanceClass ) ;
2018-07-30 04:07:02 +02:00
public static native void native_setProxySettings ( int currentAccount , String address , int port , String username , String password , String secret ) ;
public static native void native_setLangCode ( int currentAccount , String langCode ) ;
2019-07-18 15:01:39 +02:00
public static native void native_setRegId ( int currentAccount , String regId ) ;
2019-01-23 18:03:33 +01:00
public static native void native_setSystemLangCode ( int currentAccount , String langCode ) ;
public static native void native_seSystemLangCode ( int currentAccount , String langCode ) ;
2015-09-24 22:52:02 +02:00
public static native void native_setJava ( boolean useJavaByteBuffers ) ;
2018-07-30 04:07:02 +02:00
public static native void native_setPushConnectionEnabled ( int currentAccount , boolean value ) ;
2019-08-22 01:53:26 +02:00
public static native void native_applyDnsConfig ( int currentAccount , long address , String phone , int date ) ;
2018-07-30 04:07:02 +02:00
public static native long native_checkProxy ( int currentAccount , String address , int port , String username , String password , String secret , RequestTimeDelegate requestTimeDelegate ) ;
2019-05-14 14:08:05 +02:00
public static native void native_onHostNameResolved ( String host , long address , String ip ) ;
2015-09-24 22:52:02 +02:00
2018-07-30 04:07:02 +02:00
public static int generateClassGuid ( ) {
2015-09-24 22:52:02 +02:00
return lastClassGuid + + ;
}
public void setIsUpdating ( final boolean value ) {
2019-01-23 18:03:33 +01:00
AndroidUtilities . runOnUIThread ( ( ) - > {
if ( isUpdating = = value ) {
return ;
}
isUpdating = value ;
if ( connectionState = = ConnectionStateConnected ) {
2019-07-18 15:01:39 +02:00
AccountInstance . getInstance ( currentAccount ) . getNotificationCenter ( ) . postNotificationName ( NotificationCenter . didUpdateConnectionState ) ;
2015-09-24 22:52:02 +02:00
}
} ) ;
}
@SuppressLint ( " NewApi " )
2022-06-21 04:51:00 +02:00
protected byte getIpStrategy ( ) {
2015-09-24 22:52:02 +02:00
if ( Build . VERSION . SDK_INT < 19 ) {
2021-02-24 02:02:54 +01:00
return USE_IPV4_ONLY ;
2015-09-24 22:52:02 +02:00
}
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
2015-09-24 22:52:02 +02:00
try {
NetworkInterface networkInterface ;
Enumeration < NetworkInterface > networkInterfaces = NetworkInterface . getNetworkInterfaces ( ) ;
while ( networkInterfaces . hasMoreElements ( ) ) {
networkInterface = networkInterfaces . nextElement ( ) ;
if ( ! networkInterface . isUp ( ) | | networkInterface . isLoopback ( ) | | networkInterface . getInterfaceAddresses ( ) . isEmpty ( ) ) {
continue ;
}
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " valid interface: " + networkInterface ) ;
}
2015-09-24 22:52:02 +02:00
List < InterfaceAddress > interfaceAddresses = networkInterface . getInterfaceAddresses ( ) ;
for ( int a = 0 ; a < interfaceAddresses . size ( ) ; a + + ) {
InterfaceAddress address = interfaceAddresses . get ( a ) ;
InetAddress inetAddress = address . getAddress ( ) ;
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " address: " + inetAddress . getHostAddress ( ) ) ;
2015-09-24 22:52:02 +02:00
}
if ( inetAddress . isLinkLocalAddress ( ) | | inetAddress . isLoopbackAddress ( ) | | inetAddress . isMulticastAddress ( ) ) {
continue ;
}
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " address is good " ) ;
2015-09-24 22:52:02 +02:00
}
}
}
} catch ( Throwable e ) {
2017-03-31 01:58:05 +02:00
FileLog . e ( e ) ;
2015-09-24 22:52:02 +02:00
}
}
try {
NetworkInterface networkInterface ;
Enumeration < NetworkInterface > networkInterfaces = NetworkInterface . getNetworkInterfaces ( ) ;
boolean hasIpv4 = false ;
boolean hasIpv6 = false ;
2021-02-24 02:02:54 +01:00
boolean hasStrangeIpv4 = false ;
2015-09-24 22:52:02 +02:00
while ( networkInterfaces . hasMoreElements ( ) ) {
networkInterface = networkInterfaces . nextElement ( ) ;
if ( ! networkInterface . isUp ( ) | | networkInterface . isLoopback ( ) ) {
continue ;
}
List < InterfaceAddress > interfaceAddresses = networkInterface . getInterfaceAddresses ( ) ;
for ( int a = 0 ; a < interfaceAddresses . size ( ) ; a + + ) {
InterfaceAddress address = interfaceAddresses . get ( a ) ;
InetAddress inetAddress = address . getAddress ( ) ;
if ( inetAddress . isLinkLocalAddress ( ) | | inetAddress . isLoopbackAddress ( ) | | inetAddress . isMulticastAddress ( ) ) {
continue ;
}
if ( inetAddress instanceof Inet6Address ) {
hasIpv6 = true ;
} else if ( inetAddress instanceof Inet4Address ) {
String addrr = inetAddress . getHostAddress ( ) ;
if ( ! addrr . startsWith ( " 192.0.0. " ) ) {
hasIpv4 = true ;
2021-02-24 02:02:54 +01:00
} else {
hasStrangeIpv4 = true ;
2015-09-24 22:52:02 +02:00
}
}
}
}
2021-02-24 02:02:54 +01:00
if ( hasIpv6 ) {
2022-06-21 04:51:00 +02:00
if ( forceTryIpV6 ) {
return USE_IPV6_ONLY ;
}
2021-02-24 02:02:54 +01:00
if ( hasStrangeIpv4 ) {
return USE_IPV4_IPV6_RANDOM ;
}
if ( ! hasIpv4 ) {
return USE_IPV6_ONLY ;
}
2015-09-24 22:52:02 +02:00
}
} catch ( Throwable e ) {
2017-03-31 01:58:05 +02:00
FileLog . e ( e ) ;
2015-09-24 22:52:02 +02:00
}
2021-02-24 02:02:54 +01:00
return USE_IPV4_ONLY ;
2015-09-24 22:52:02 +02:00
}
2019-07-18 15:01:39 +02:00
private static class ResolveHostByNameTask extends AsyncTask < Void , Void , ResolvedDomain > {
2019-05-14 14:08:05 +02:00
2019-06-04 12:14:50 +02:00
private ArrayList < Long > addresses = new ArrayList < > ( ) ;
2019-05-14 14:08:05 +02:00
private String currentHostName ;
2019-06-04 12:14:50 +02:00
public ResolveHostByNameTask ( String hostName ) {
2019-05-14 14:08:05 +02:00
super ( ) ;
currentHostName = hostName ;
}
2019-06-04 12:14:50 +02:00
public void addAddress ( long address ) {
if ( addresses . contains ( address ) ) {
return ;
}
addresses . add ( address ) ;
}
2019-07-18 15:01:39 +02:00
protected ResolvedDomain doInBackground ( Void . . . voids ) {
2019-05-14 14:08:05 +02:00
ByteArrayOutputStream outbuf = null ;
InputStream httpConnectionStream = null ;
boolean done = false ;
try {
URL downloadUrl = new URL ( " https://www.google.com/resolve?name= " + currentHostName + " &type=A " ) ;
URLConnection httpConnection = downloadUrl . openConnection ( ) ;
httpConnection . addRequestProperty ( " User-Agent " , " Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1 " ) ;
httpConnection . addRequestProperty ( " Host " , " dns.google.com " ) ;
httpConnection . setConnectTimeout ( 1000 ) ;
httpConnection . setReadTimeout ( 2000 ) ;
httpConnection . connect ( ) ;
httpConnectionStream = httpConnection . getInputStream ( ) ;
outbuf = new ByteArrayOutputStream ( ) ;
byte [ ] data = new byte [ 1024 * 32 ] ;
while ( true ) {
int read = httpConnectionStream . read ( data ) ;
if ( read > 0 ) {
outbuf . write ( data , 0 , read ) ;
} else if ( read = = - 1 ) {
break ;
} else {
break ;
}
}
JSONObject jsonObject = new JSONObject ( new String ( outbuf . toByteArray ( ) ) ) ;
if ( jsonObject . has ( " Answer " ) ) {
JSONArray array = jsonObject . getJSONArray ( " Answer " ) ;
int len = array . length ( ) ;
if ( len > 0 ) {
ArrayList < String > addresses = new ArrayList < > ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
addresses . add ( array . getJSONObject ( a ) . getString ( " data " ) ) ;
}
2019-07-18 15:01:39 +02:00
return new ResolvedDomain ( addresses , SystemClock . elapsedRealtime ( ) ) ;
2019-05-14 14:08:05 +02:00
}
}
done = true ;
} catch ( Throwable e ) {
2021-12-30 11:52:40 +01:00
FileLog . e ( e , false ) ;
2019-05-14 14:08:05 +02:00
} finally {
try {
if ( httpConnectionStream ! = null ) {
httpConnectionStream . close ( ) ;
}
} catch ( Throwable e ) {
2021-12-30 11:52:40 +01:00
FileLog . e ( e , false ) ;
2019-05-14 14:08:05 +02:00
}
try {
if ( outbuf ! = null ) {
outbuf . close ( ) ;
}
} catch ( Exception ignore ) {
}
}
if ( ! done ) {
try {
InetAddress address = InetAddress . getByName ( currentHostName ) ;
2019-07-18 15:01:39 +02:00
ArrayList < String > addresses = new ArrayList < > ( 1 ) ;
addresses . add ( address . getHostAddress ( ) ) ;
return new ResolvedDomain ( addresses , SystemClock . elapsedRealtime ( ) ) ;
2019-05-14 14:08:05 +02:00
} catch ( Exception e ) {
2021-12-30 11:52:40 +01:00
FileLog . e ( e , false ) ;
2019-05-14 14:08:05 +02:00
}
}
2019-07-18 15:01:39 +02:00
return null ;
2019-05-14 14:08:05 +02:00
}
@Override
2019-07-18 15:01:39 +02:00
protected void onPostExecute ( final ResolvedDomain result ) {
if ( result ! = null ) {
dnsCache . put ( currentHostName , result ) ;
for ( int a = 0 , N = addresses . size ( ) ; a < N ; a + + ) {
native_onHostNameResolved ( currentHostName , addresses . get ( a ) , result . getAddress ( ) ) ;
}
} else {
for ( int a = 0 , N = addresses . size ( ) ; a < N ; a + + ) {
native_onHostNameResolved ( currentHostName , addresses . get ( a ) , " " ) ;
}
2019-06-04 12:14:50 +02:00
}
resolvingHostnameTasks . remove ( currentHostName ) ;
2019-05-14 14:08:05 +02:00
}
}
2017-07-08 18:32:04 +02:00
private static class DnsTxtLoadTask extends AsyncTask < Void , Void , NativeByteBuffer > {
2018-07-30 04:07:02 +02:00
private int currentAccount ;
2019-08-22 01:53:26 +02:00
private int responseDate ;
2017-07-08 18:32:04 +02:00
2018-07-30 04:07:02 +02:00
public DnsTxtLoadTask ( int instance ) {
super ( ) ;
currentAccount = instance ;
}
protected NativeByteBuffer doInBackground ( Void . . . voids ) {
ByteArrayOutputStream outbuf = null ;
InputStream httpConnectionStream = null ;
for ( int i = 0 ; i < 3 ; i + + ) {
try {
String googleDomain ;
if ( i = = 0 ) {
googleDomain = " www.google.com " ;
} else if ( i = = 1 ) {
googleDomain = " www.google.ru " ;
2017-07-08 18:32:04 +02:00
} else {
2018-07-30 04:07:02 +02:00
googleDomain = " google.com " ;
2017-07-08 18:32:04 +02:00
}
2019-08-22 01:53:26 +02:00
String domain = native_isTestBackend ( currentAccount ) ! = 0 ? " tapv3.stel.com " : AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . dcDomainName ;
2019-02-08 03:30:32 +01:00
int len = Utilities . random . nextInt ( 116 ) + 13 ;
final String characters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 " ;
StringBuilder padding = new StringBuilder ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
padding . append ( characters . charAt ( Utilities . random . nextInt ( characters . length ( ) ) ) ) ;
}
URL downloadUrl = new URL ( " https:// " + googleDomain + " /resolve?name= " + domain + " &type=ANY&random_padding= " + padding ) ;
2018-07-30 04:07:02 +02:00
URLConnection httpConnection = downloadUrl . openConnection ( ) ;
httpConnection . addRequestProperty ( " User-Agent " , " Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1 " ) ;
httpConnection . addRequestProperty ( " Host " , " dns.google.com " ) ;
httpConnection . setConnectTimeout ( 5000 ) ;
httpConnection . setReadTimeout ( 5000 ) ;
httpConnection . connect ( ) ;
httpConnectionStream = httpConnection . getInputStream ( ) ;
2019-08-22 01:53:26 +02:00
responseDate = ( int ) ( httpConnection . getDate ( ) / 1000 ) ;
2018-07-30 04:07:02 +02:00
outbuf = new ByteArrayOutputStream ( ) ;
byte [ ] data = new byte [ 1024 * 32 ] ;
while ( true ) {
if ( isCancelled ( ) ) {
break ;
}
int read = httpConnectionStream . read ( data ) ;
if ( read > 0 ) {
outbuf . write ( data , 0 , read ) ;
} else if ( read = = - 1 ) {
break ;
} else {
break ;
}
2017-07-08 18:32:04 +02:00
}
2018-07-30 04:07:02 +02:00
2019-05-14 14:08:05 +02:00
JSONObject jsonObject = new JSONObject ( new String ( outbuf . toByteArray ( ) ) ) ;
2018-07-30 04:07:02 +02:00
JSONArray array = jsonObject . getJSONArray ( " Answer " ) ;
2019-02-08 03:30:32 +01:00
len = array . length ( ) ;
2018-07-30 04:07:02 +02:00
ArrayList < String > arrayList = new ArrayList < > ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
2019-02-08 03:30:32 +01:00
JSONObject object = array . getJSONObject ( a ) ;
int type = object . getInt ( " type " ) ;
if ( type ! = 16 ) {
continue ;
}
arrayList . add ( object . getString ( " data " ) ) ;
2018-07-30 04:07:02 +02:00
}
2019-01-23 18:03:33 +01:00
Collections . sort ( arrayList , ( o1 , o2 ) - > {
int l1 = o1 . length ( ) ;
int l2 = o2 . length ( ) ;
if ( l1 > l2 ) {
return - 1 ;
} else if ( l1 < l2 ) {
return 1 ;
2018-07-30 04:07:02 +02:00
}
2019-01-23 18:03:33 +01:00
return 0 ;
2018-07-30 04:07:02 +02:00
} ) ;
StringBuilder builder = new StringBuilder ( ) ;
for ( int a = 0 ; a < arrayList . size ( ) ; a + + ) {
builder . append ( arrayList . get ( a ) . replace ( " \" " , " " ) ) ;
}
byte [ ] bytes = Base64 . decode ( builder . toString ( ) , Base64 . DEFAULT ) ;
NativeByteBuffer buffer = new NativeByteBuffer ( bytes . length ) ;
buffer . writeBytes ( bytes ) ;
return buffer ;
2017-07-08 18:32:04 +02:00
} catch ( Throwable e ) {
2021-12-07 14:02:02 +01:00
FileLog . e ( e , false ) ;
2018-07-30 04:07:02 +02:00
} finally {
try {
if ( httpConnectionStream ! = null ) {
httpConnectionStream . close ( ) ;
}
} catch ( Throwable e ) {
2021-12-09 17:28:33 +01:00
FileLog . e ( e , false ) ;
2018-07-30 04:07:02 +02:00
}
try {
if ( outbuf ! = null ) {
outbuf . close ( ) ;
}
} catch ( Exception ignore ) {
}
}
}
return null ;
}
@Override
protected void onPostExecute ( final NativeByteBuffer result ) {
2019-01-23 18:03:33 +01:00
Utilities . stageQueue . postRunnable ( ( ) - > {
2019-12-31 14:08:08 +01:00
currentTask = null ;
2019-01-23 18:03:33 +01:00
if ( result ! = null ) {
2019-08-22 01:53:26 +02:00
native_applyDnsConfig ( currentAccount , result . address , AccountInstance . getInstance ( currentAccount ) . getUserConfig ( ) . getClientPhone ( ) , responseDate ) ;
2019-01-23 18:03:33 +01:00
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " failed to get dns txt result " ) ;
2019-12-31 14:08:08 +01:00
FileLog . d ( " start google task " ) ;
}
GoogleDnsLoadTask task = new GoogleDnsLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
}
} ) ;
}
}
private static class GoogleDnsLoadTask extends AsyncTask < Void , Void , NativeByteBuffer > {
private int currentAccount ;
private int responseDate ;
public GoogleDnsLoadTask ( int instance ) {
super ( ) ;
currentAccount = instance ;
}
protected NativeByteBuffer doInBackground ( Void . . . voids ) {
ByteArrayOutputStream outbuf = null ;
InputStream httpConnectionStream = null ;
try {
String domain = native_isTestBackend ( currentAccount ) ! = 0 ? " tapv3.stel.com " : AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . dcDomainName ;
int len = Utilities . random . nextInt ( 116 ) + 13 ;
final String characters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 " ;
StringBuilder padding = new StringBuilder ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
padding . append ( characters . charAt ( Utilities . random . nextInt ( characters . length ( ) ) ) ) ;
}
URL downloadUrl = new URL ( " https://dns.google.com/resolve?name= " + domain + " &type=ANY&random_padding= " + padding ) ;
URLConnection httpConnection = downloadUrl . openConnection ( ) ;
httpConnection . addRequestProperty ( " User-Agent " , " Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1 " ) ;
httpConnection . setConnectTimeout ( 5000 ) ;
httpConnection . setReadTimeout ( 5000 ) ;
httpConnection . connect ( ) ;
httpConnectionStream = httpConnection . getInputStream ( ) ;
responseDate = ( int ) ( httpConnection . getDate ( ) / 1000 ) ;
outbuf = new ByteArrayOutputStream ( ) ;
byte [ ] data = new byte [ 1024 * 32 ] ;
while ( true ) {
if ( isCancelled ( ) ) {
break ;
}
int read = httpConnectionStream . read ( data ) ;
if ( read > 0 ) {
outbuf . write ( data , 0 , read ) ;
} else if ( read = = - 1 ) {
break ;
} else {
break ;
}
}
JSONObject jsonObject = new JSONObject ( new String ( outbuf . toByteArray ( ) ) ) ;
JSONArray array = jsonObject . getJSONArray ( " Answer " ) ;
len = array . length ( ) ;
ArrayList < String > arrayList = new ArrayList < > ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
JSONObject object = array . getJSONObject ( a ) ;
int type = object . getInt ( " type " ) ;
if ( type ! = 16 ) {
continue ;
}
arrayList . add ( object . getString ( " data " ) ) ;
}
Collections . sort ( arrayList , ( o1 , o2 ) - > {
int l1 = o1 . length ( ) ;
int l2 = o2 . length ( ) ;
if ( l1 > l2 ) {
return - 1 ;
} else if ( l1 < l2 ) {
return 1 ;
}
return 0 ;
} ) ;
StringBuilder builder = new StringBuilder ( ) ;
for ( int a = 0 ; a < arrayList . size ( ) ; a + + ) {
builder . append ( arrayList . get ( a ) . replace ( " \" " , " " ) ) ;
}
byte [ ] bytes = Base64 . decode ( builder . toString ( ) , Base64 . DEFAULT ) ;
NativeByteBuffer buffer = new NativeByteBuffer ( bytes . length ) ;
buffer . writeBytes ( bytes ) ;
return buffer ;
} catch ( Throwable e ) {
2023-02-25 09:01:39 +01:00
FileLog . e ( e , ! ( e instanceof SocketTimeoutException | | e instanceof SSLException ) ) ;
2019-12-31 14:08:08 +01:00
} finally {
try {
if ( httpConnectionStream ! = null ) {
httpConnectionStream . close ( ) ;
}
} catch ( Throwable e ) {
FileLog . e ( e ) ;
}
try {
if ( outbuf ! = null ) {
outbuf . close ( ) ;
}
} catch ( Exception ignore ) {
}
}
return null ;
}
@Override
protected void onPostExecute ( final NativeByteBuffer result ) {
Utilities . stageQueue . postRunnable ( ( ) - > {
currentTask = null ;
if ( result ! = null ) {
native_applyDnsConfig ( currentAccount , result . address , AccountInstance . getInstance ( currentAccount ) . getUserConfig ( ) . getClientPhone ( ) , responseDate ) ;
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " failed to get google result " ) ;
FileLog . d ( " start mozilla task " ) ;
}
MozillaDnsLoadTask task = new MozillaDnsLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
}
} ) ;
}
}
private static class MozillaDnsLoadTask extends AsyncTask < Void , Void , NativeByteBuffer > {
private int currentAccount ;
private int responseDate ;
public MozillaDnsLoadTask ( int instance ) {
super ( ) ;
currentAccount = instance ;
}
protected NativeByteBuffer doInBackground ( Void . . . voids ) {
ByteArrayOutputStream outbuf = null ;
InputStream httpConnectionStream = null ;
try {
String domain = native_isTestBackend ( currentAccount ) ! = 0 ? " tapv3.stel.com " : AccountInstance . getInstance ( currentAccount ) . getMessagesController ( ) . dcDomainName ;
int len = Utilities . random . nextInt ( 116 ) + 13 ;
final String characters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 " ;
StringBuilder padding = new StringBuilder ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
padding . append ( characters . charAt ( Utilities . random . nextInt ( characters . length ( ) ) ) ) ;
}
2020-03-30 14:00:09 +02:00
URL downloadUrl = new URL ( " https://mozilla.cloudflare-dns.com/dns-query?name= " + domain + " &type=TXT&random_padding= " + padding ) ;
2019-12-31 14:08:08 +01:00
URLConnection httpConnection = downloadUrl . openConnection ( ) ;
httpConnection . addRequestProperty ( " User-Agent " , " Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1 " ) ;
httpConnection . addRequestProperty ( " accept " , " application/dns-json " ) ;
httpConnection . setConnectTimeout ( 5000 ) ;
httpConnection . setReadTimeout ( 5000 ) ;
httpConnection . connect ( ) ;
httpConnectionStream = httpConnection . getInputStream ( ) ;
responseDate = ( int ) ( httpConnection . getDate ( ) / 1000 ) ;
outbuf = new ByteArrayOutputStream ( ) ;
byte [ ] data = new byte [ 1024 * 32 ] ;
while ( true ) {
if ( isCancelled ( ) ) {
break ;
}
int read = httpConnectionStream . read ( data ) ;
if ( read > 0 ) {
outbuf . write ( data , 0 , read ) ;
} else if ( read = = - 1 ) {
break ;
} else {
break ;
}
}
JSONObject jsonObject = new JSONObject ( new String ( outbuf . toByteArray ( ) ) ) ;
JSONArray array = jsonObject . getJSONArray ( " Answer " ) ;
len = array . length ( ) ;
ArrayList < String > arrayList = new ArrayList < > ( len ) ;
for ( int a = 0 ; a < len ; a + + ) {
JSONObject object = array . getJSONObject ( a ) ;
int type = object . getInt ( " type " ) ;
if ( type ! = 16 ) {
continue ;
}
arrayList . add ( object . getString ( " data " ) ) ;
}
Collections . sort ( arrayList , ( o1 , o2 ) - > {
int l1 = o1 . length ( ) ;
int l2 = o2 . length ( ) ;
if ( l1 > l2 ) {
return - 1 ;
} else if ( l1 < l2 ) {
return 1 ;
}
return 0 ;
} ) ;
StringBuilder builder = new StringBuilder ( ) ;
for ( int a = 0 ; a < arrayList . size ( ) ; a + + ) {
builder . append ( arrayList . get ( a ) . replace ( " \" " , " " ) ) ;
}
byte [ ] bytes = Base64 . decode ( builder . toString ( ) , Base64 . DEFAULT ) ;
NativeByteBuffer buffer = new NativeByteBuffer ( bytes . length ) ;
buffer . writeBytes ( bytes ) ;
return buffer ;
} catch ( Throwable e ) {
2022-11-05 13:34:47 +01:00
FileLog . e ( e , false ) ;
2019-12-31 14:08:08 +01:00
} finally {
try {
if ( httpConnectionStream ! = null ) {
httpConnectionStream . close ( ) ;
}
} catch ( Throwable e ) {
FileLog . e ( e ) ;
}
try {
if ( outbuf ! = null ) {
outbuf . close ( ) ;
2018-07-30 04:07:02 +02:00
}
2019-12-31 14:08:08 +01:00
} catch ( Exception ignore ) {
2018-07-30 04:07:02 +02:00
}
2019-12-31 14:08:08 +01:00
}
return null ;
}
@Override
protected void onPostExecute ( final NativeByteBuffer result ) {
Utilities . stageQueue . postRunnable ( ( ) - > {
2019-08-22 01:53:26 +02:00
currentTask = null ;
2019-12-31 14:08:08 +01:00
if ( result ! = null ) {
native_applyDnsConfig ( currentAccount , result . address , AccountInstance . getInstance ( currentAccount ) . getUserConfig ( ) . getClientPhone ( ) , responseDate ) ;
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " failed to get mozilla txt result " ) ;
}
}
2018-07-30 04:07:02 +02:00
} ) ;
}
}
private static class FirebaseTask extends AsyncTask < Void , Void , NativeByteBuffer > {
private int currentAccount ;
private FirebaseRemoteConfig firebaseRemoteConfig ;
public FirebaseTask ( int instance ) {
super ( ) ;
currentAccount = instance ;
}
protected NativeByteBuffer doInBackground ( Void . . . voids ) {
try {
if ( native_isTestBackend ( currentAccount ) ! = 0 ) {
throw new Exception ( " test backend " ) ;
2017-07-08 18:32:04 +02:00
}
2018-07-30 04:07:02 +02:00
firebaseRemoteConfig = FirebaseRemoteConfig . getInstance ( ) ;
2019-08-22 01:53:26 +02:00
String currentValue = firebaseRemoteConfig . getString ( " ipconfigv3 " ) ;
2018-07-30 04:07:02 +02:00
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " current firebase value = " + currentValue ) ;
2017-07-08 18:32:04 +02:00
}
2018-07-30 04:07:02 +02:00
2019-01-23 18:03:33 +01:00
firebaseRemoteConfig . fetch ( 0 ) . addOnCompleteListener ( finishedTask - > {
final boolean success = finishedTask . isSuccessful ( ) ;
Utilities . stageQueue . postRunnable ( ( ) - > {
if ( success ) {
2020-12-23 08:48:30 +01:00
firebaseRemoteConfig . activate ( ) . addOnCompleteListener ( finishedTask2 - > {
currentTask = null ;
String config = firebaseRemoteConfig . getString ( " ipconfigv3 " ) ;
if ( ! TextUtils . isEmpty ( config ) ) {
byte [ ] bytes = Base64 . decode ( config , Base64 . DEFAULT ) ;
try {
NativeByteBuffer buffer = new NativeByteBuffer ( bytes . length ) ;
buffer . writeBytes ( bytes ) ;
int date = ( int ) ( firebaseRemoteConfig . getInfo ( ) . getFetchTimeMillis ( ) / 1000 ) ;
native_applyDnsConfig ( currentAccount , buffer . address , AccountInstance . getInstance ( currentAccount ) . getUserConfig ( ) . getClientPhone ( ) , date ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
} else {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " failed to get firebase result " ) ;
FileLog . d ( " start dns txt task " ) ;
}
DnsTxtLoadTask task = new DnsTxtLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
}
} ) ;
2019-01-23 18:03:33 +01:00
}
} ) ;
2017-07-08 18:32:04 +02:00
} ) ;
} catch ( Throwable e ) {
2019-01-23 18:03:33 +01:00
Utilities . stageQueue . postRunnable ( ( ) - > {
if ( BuildVars . LOGS_ENABLED ) {
FileLog . d ( " failed to get firebase result " ) ;
FileLog . d ( " start dns txt task " ) ;
2018-07-30 04:07:02 +02:00
}
2019-01-23 18:03:33 +01:00
DnsTxtLoadTask task = new DnsTxtLoadTask ( currentAccount ) ;
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , null , null , null ) ;
currentTask = task ;
2018-07-30 04:07:02 +02:00
} ) ;
2022-11-05 13:34:47 +01:00
FileLog . e ( e , false ) ;
2017-07-08 18:32:04 +02:00
}
return null ;
}
@Override
protected void onPostExecute ( NativeByteBuffer result ) {
2018-07-30 04:07:02 +02:00
2017-07-08 18:32:04 +02:00
}
}
2015-09-24 22:52:02 +02:00
}