调研通 v3.0.3版本的 MD5 值为:fe075d21227d488bdb9f6aa09d3b3f35

以下内容为反编译后的 HostManager.java 源代码,内容仅作参考


package com.xiaomi.network;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Process;
import android.text.TextUtils;
import androidx.exifinterface.media.ExifInterface;
import c.c.a.m.j1;
import com.huawei.hms.push.constant.RemoteMessageConst;
import com.tencent.stat.DeviceInfo;
import com.xiaomi.channel.commonutils.network.d;
import com.xiaomi.mipush.sdk.Constants;
import com.xiaomi.push.service.module.PushChannelRegion;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class HostManager {
    private static HostManagerFactory factory;
    protected static Context sAppContext;
    private static String sAppName;
    private static String sAppVersion;
    private static HostManager sInstance;
    private final long MAX_REQUEST_FAILURE_CNT;
    private String currentISP;
    private long lastRemoteRequestTimestamp;
    protected Map<String, Fallbacks> mHostsMapping;
    private long remoteRequestFailureCount;
    private HostFilter sHostFilter;
    protected HttpGet sHttpGetter;
    private String sUserId;
    protected static Map<String, Fallback> sReservedHosts = new HashMap();
    protected static boolean hostLoaded = false;

    public interface HostManagerFactory {
        HostManager a(Context context, HostFilter hostFilter, HttpGet httpGet, String str);
    }

    public interface HttpGet {
        String a(String str);
    }

    public HostManager(Context context, HostFilter hostFilter, HttpGet httpGet, String str) {
        this(context, hostFilter, httpGet, str, null, null);
    }

    protected HostManager(Context context, HostFilter hostFilter, HttpGet httpGet, String str, String str2, String str3) {
        this.mHostsMapping = new HashMap();
        this.sUserId = "0";
        this.remoteRequestFailureCount = 0L;
        this.MAX_REQUEST_FAILURE_CNT = 15L;
        this.lastRemoteRequestTimestamp = 0L;
        this.currentISP = "isp_prov_city_country_ip";
        this.sHttpGetter = httpGet;
        this.sHostFilter = hostFilter == null ? new a(this) : hostFilter;
        this.sUserId = str;
        sAppName = str2 == null ? context.getPackageName() : str2;
        sAppVersion = str3 == null ? getVersionName() : str3;
    }

    public static void addReservedHost(String str, String str2) {
        Fallback fallback = sReservedHosts.get(str);
        synchronized (sReservedHosts) {
            if (fallback == null) {
                Fallback fallback2 = new Fallback(str);
                fallback2.a(com.google.android.gcm.b.f4081a);
                fallback2.b(str2);
                sReservedHosts.put(str, fallback2);
            } else {
                fallback.b(str2);
            }
        }
    }

    public static String getActiveNetworkLabel() {
        ConnectivityManager connectivityManager;
        NetworkInfo activeNetworkInfo;
        Context context = sAppContext;
        if (context == null) {
            return "unknown";
        }
        try {
            connectivityManager = (ConnectivityManager) context.getSystemService("connectivity");
        } catch (Throwable unused) {
        }
        if (connectivityManager == null || (activeNetworkInfo = connectivityManager.getActiveNetworkInfo()) == null) {
            return "unknown";
        }
        if (activeNetworkInfo.getType() != 1) {
            return activeNetworkInfo.getTypeName() + Constants.ACCEPT_TIME_SEPARATOR_SERVER + activeNetworkInfo.getSubtypeName();
        }
        WifiManager wifiManager = (WifiManager) sAppContext.getSystemService("wifi");
        if (wifiManager != null && wifiManager.getConnectionInfo() != null) {
            return "WIFI-" + wifiManager.getConnectionInfo().getSSID();
        }
        return "unknown";
    }

    public static synchronized HostManager getInstance() {
        HostManager hostManager;
        synchronized (HostManager.class) {
            hostManager = sInstance;
            if (hostManager == null) {
                throw new IllegalStateException("the host manager is not initialized yet.");
            }
        }
        return hostManager;
    }

    private String getVersionName() {
        try {
            PackageInfo packageInfo = sAppContext.getPackageManager().getPackageInfo(sAppContext.getPackageName(), 16384);
            return packageInfo != null ? packageInfo.versionName : "0";
        } catch (Exception unused) {
            return "0";
        }
    }

    public static synchronized void init(Context context, HostFilter hostFilter, HttpGet httpGet, String str, String str2, String str3) {
        synchronized (HostManager.class) {
            Context applicationContext = context.getApplicationContext();
            sAppContext = applicationContext;
            if (applicationContext == null) {
                sAppContext = context;
            }
            if (sInstance == null) {
                HostManagerFactory hostManagerFactory = factory;
                if (hostManagerFactory == null) {
                    sInstance = new HostManager(context, hostFilter, httpGet, str, str2, str3);
                } else {
                    sInstance = hostManagerFactory.a(context, hostFilter, httpGet, str);
                }
            }
        }
    }

    static String obfuscate(String str) {
        try {
            int length = str.length();
            byte[] bytes = str.getBytes("UTF-8");
            for (int i = 0; i < bytes.length; i++) {
                byte b2 = bytes[i];
                int i2 = b2 & 240;
                if (i2 != 240) {
                    bytes[i] = (byte) (((b2 & 15) ^ ((byte) (((b2 >> 4) + length) & 15))) | i2);
                }
            }
            return new String(bytes);
        } catch (UnsupportedEncodingException unused) {
            return str;
        }
    }

    private ArrayList<Fallback> requestRemoteFallbacks(ArrayList<String> arrayList) {
        JSONObject jSONObject;
        JSONObject jSONObject2;
        purge();
        synchronized (this.mHostsMapping) {
            checkHostMapping();
            for (String str : this.mHostsMapping.keySet()) {
                if (!arrayList.contains(str)) {
                    arrayList.add(str);
                }
            }
        }
        boolean isEmpty = sReservedHosts.isEmpty();
        synchronized (sReservedHosts) {
            for (Object obj : sReservedHosts.values().toArray()) {
                Fallback fallback = (Fallback) obj;
                if (!fallback.b()) {
                    sReservedHosts.remove(fallback.f9878b);
                    isEmpty = true;
                }
            }
        }
        if (!arrayList.contains(getHost())) {
            arrayList.add(getHost());
        }
        ArrayList<Fallback> arrayList2 = new ArrayList<>(arrayList.size());
        for (int i = 0; i < arrayList.size(); i++) {
            arrayList2.add(null);
        }
        try {
            String str2 = d.e(sAppContext) ? "wifi" : "wap";
            String remoteFallbackJSON = getRemoteFallbackJSON(arrayList, str2, this.sUserId, isEmpty);
            if (!TextUtils.isEmpty(remoteFallbackJSON)) {
                JSONObject jSONObject3 = new JSONObject(remoteFallbackJSON);
                com.xiaomi.channel.commonutils.logger.b.b(remoteFallbackJSON);
                if ("OK".equalsIgnoreCase(jSONObject3.getString(ExifInterface.LATITUDE_SOUTH))) {
                    JSONObject jSONObject4 = jSONObject3.getJSONObject("R");
                    String string = jSONObject4.getString("province");
                    String string2 = jSONObject4.getString("city");
                    String string3 = jSONObject4.getString("isp");
                    String string4 = jSONObject4.getString("ip");
                    String string5 = jSONObject4.getString("country");
                    JSONObject jSONObject5 = jSONObject4.getJSONObject(str2);
                    if (str2.equals("wap")) {
                        str2 = getActiveNetworkLabel();
                    }
                    com.xiaomi.channel.commonutils.logger.b.c("get bucket: ip = " + string4 + " net = " + string3 + str2 + " hosts = " + jSONObject5.toString());
                    int i2 = 0;
                    while (i2 < arrayList.size()) {
                        String str3 = arrayList.get(i2);
                        JSONArray optJSONArray = jSONObject5.optJSONArray(str3);
                        if (optJSONArray == null) {
                            com.xiaomi.channel.commonutils.logger.b.a("no bucket found for " + str3);
                            jSONObject = jSONObject5;
                        } else {
                            Fallback fallback2 = new Fallback(str3);
                            int i3 = 0;
                            while (i3 < optJSONArray.length()) {
                                String string6 = optJSONArray.getString(i3);
                                if (TextUtils.isEmpty(string6)) {
                                    jSONObject2 = jSONObject5;
                                } else {
                                    jSONObject2 = jSONObject5;
                                    fallback2.a(new c(string6, optJSONArray.length() - i3));
                                }
                                i3++;
                                jSONObject5 = jSONObject2;
                            }
                            jSONObject = jSONObject5;
                            arrayList2.set(i2, fallback2);
                            fallback2.g = string5;
                            fallback2.f9879c = string;
                            fallback2.f9881e = string3;
                            fallback2.f9882f = string4;
                            fallback2.f9880d = string2;
                            if (jSONObject4.has("stat-percent")) {
                                fallback2.a(jSONObject4.getDouble("stat-percent"));
                            }
                            if (jSONObject4.has("stat-domain")) {
                                fallback2.c(jSONObject4.getString("stat-domain"));
                            }
                            if (jSONObject4.has(RemoteMessageConst.TTL)) {
                                fallback2.a(jSONObject4.getInt(RemoteMessageConst.TTL) * 1000);
                            }
                            setCurrentISP(fallback2.e());
                        }
                        i2++;
                        jSONObject5 = jSONObject;
                    }
                    JSONObject optJSONObject = jSONObject4.optJSONObject("reserved");
                    if (optJSONObject != null) {
                        long j = com.google.android.gcm.b.f4081a;
                        if (jSONObject4.has("reserved-ttl")) {
                            j = jSONObject4.getInt("reserved-ttl") * 1000;
                        }
                        Iterator<String> keys = optJSONObject.keys();
                        while (keys.hasNext()) {
                            String next = keys.next();
                            JSONArray optJSONArray2 = optJSONObject.optJSONArray(next);
                            if (optJSONArray2 == null) {
                                com.xiaomi.channel.commonutils.logger.b.a("no bucket found for " + next);
                            } else {
                                Fallback fallback3 = new Fallback(next);
                                fallback3.a(j);
                                for (int i4 = 0; i4 < optJSONArray2.length(); i4++) {
                                    String string7 = optJSONArray2.getString(i4);
                                    if (!TextUtils.isEmpty(string7)) {
                                        fallback3.a(new c(string7, optJSONArray2.length() - i4));
                                    }
                                }
                                synchronized (sReservedHosts) {
                                    if (this.sHostFilter.a(next)) {
                                        sReservedHosts.put(next, fallback3);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e2) {
            com.xiaomi.channel.commonutils.logger.b.a("failed to get bucket " + e2.getMessage());
        }
        for (int i5 = 0; i5 < arrayList.size(); i5++) {
            Fallback fallback4 = arrayList2.get(i5);
            if (fallback4 != null) {
                updateFallbacks(arrayList.get(i5), fallback4);
            }
        }
        persist();
        return arrayList2;
    }

    public static synchronized void setHostManagerFactory(HostManagerFactory hostManagerFactory) {
        synchronized (HostManager.class) {
            factory = hostManagerFactory;
            sInstance = null;
        }
    }

    protected boolean checkHostMapping() {
        synchronized (this.mHostsMapping) {
            if (hostLoaded) {
                return true;
            }
            hostLoaded = true;
            this.mHostsMapping.clear();
            try {
                String loadHosts = loadHosts();
                if (!TextUtils.isEmpty(loadHosts)) {
                    fromJSON(loadHosts);
                    com.xiaomi.channel.commonutils.logger.b.b("loading the new hosts succeed");
                    return true;
                }
            } catch (Throwable th) {
                com.xiaomi.channel.commonutils.logger.b.a("load bucket failure: " + th.getMessage());
            }
            return false;
        }
    }

    public void clear() {
        synchronized (this.mHostsMapping) {
            this.mHostsMapping.clear();
        }
    }

    public String dump() {
        StringBuilder sb = new StringBuilder();
        synchronized (this.mHostsMapping) {
            for (Map.Entry<String, Fallbacks> entry : this.mHostsMapping.entrySet()) {
                sb.append(entry.getKey());
                sb.append(":\n");
                sb.append(entry.getValue().toString());
                sb.append("\n");
            }
        }
        return sb.toString();
    }

    protected void fromJSON(String str) {
        synchronized (this.mHostsMapping) {
            this.mHostsMapping.clear();
            JSONObject jSONObject = new JSONObject(str);
            if (jSONObject.optInt(DeviceInfo.TAG_VERSION) != 2) {
                throw new JSONException("Bad version");
            }
            JSONArray optJSONArray = jSONObject.optJSONArray("data");
            for (int i = 0; i < optJSONArray.length(); i++) {
                Fallbacks fromJSON = new Fallbacks().fromJSON(optJSONArray.getJSONObject(i));
                this.mHostsMapping.put(fromJSON.getHost(), fromJSON);
            }
            JSONArray optJSONArray2 = jSONObject.optJSONArray("reserved");
            for (int i2 = 0; i2 < optJSONArray2.length(); i2++) {
                Fallback a2 = new Fallback("").a(optJSONArray2.getJSONObject(i2));
                sReservedHosts.put(a2.f9878b, a2);
            }
        }
    }

    public Fallback getFallbacksByHost(String str) {
        return getFallbacksByHost(str, true);
    }

    public Fallback getFallbacksByHost(String str, boolean z) {
        Fallback requestRemoteFallback;
        if (TextUtils.isEmpty(str)) {
            throw new IllegalArgumentException("the host is empty");
        }
        if (!this.sHostFilter.a(str)) {
            return null;
        }
        Fallback localFallback = getLocalFallback(str);
        return (localFallback == null || !localFallback.b()) ? (z && d.c(sAppContext) && (requestRemoteFallback = requestRemoteFallback(str)) != null) ? requestRemoteFallback : new b(this, str, localFallback) : localFallback;
    }

    public Fallback getFallbacksByURL(String str) {
        if (TextUtils.isEmpty(str)) {
            throw new IllegalArgumentException("the url is empty");
        }
        return getFallbacksByHost(new URL(str).getHost(), true);
    }

    protected String getHost() {
        String a2 = com.xiaomi.push.service.a.a(sAppContext).a();
        return (TextUtils.isEmpty(a2) || !PushChannelRegion.Europe.name().equals(a2)) ? "resolver.msg.xiaomi.net" : "resolver.msg.global.xiaomi.net";
    }

    protected Fallback getLocalFallback(String str) {
        Fallbacks fallbacks;
        Fallback fallback;
        synchronized (this.mHostsMapping) {
            checkHostMapping();
            fallbacks = this.mHostsMapping.get(str);
        }
        if (fallbacks == null || (fallback = fallbacks.getFallback()) == null) {
            return null;
        }
        return fallback;
    }

    protected String getProcessName() {
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = ((ActivityManager) sAppContext.getSystemService("activity")).getRunningAppProcesses();
        if (runningAppProcesses == null) {
            return "com.xiaomi";
        }
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
            if (runningAppProcessInfo.pid == Process.myPid()) {
                return runningAppProcessInfo.processName;
            }
        }
        return "com.xiaomi";
    }

    public String getRemoteFallbackJSON(ArrayList<String> arrayList, String str, String str2, boolean z) {
        ArrayList<String> arrayList2 = new ArrayList<>();
        ArrayList<com.xiaomi.channel.commonutils.network.c> arrayList3 = new ArrayList();
        arrayList3.add(new com.xiaomi.channel.commonutils.network.a("type", str));
        if (str.equals("wap")) {
            arrayList3.add(new com.xiaomi.channel.commonutils.network.a("conpt", obfuscate(d.k(sAppContext))));
        }
        if (z) {
            arrayList3.add(new com.xiaomi.channel.commonutils.network.a("reserved", "1"));
        }
        arrayList3.add(new com.xiaomi.channel.commonutils.network.a(j1.l, str2));
        arrayList3.add(new com.xiaomi.channel.commonutils.network.a("list", com.xiaomi.channel.commonutils.string.d.a(arrayList, Constants.ACCEPT_TIME_SEPARATOR_SP)));
        Fallback localFallback = getLocalFallback(getHost());
        String format = String.format(Locale.US, "http://%1$s/gslb/?ver=4.0", getHost());
        if (localFallback == null) {
            arrayList2.add(format);
            synchronized (sReservedHosts) {
                Fallback fallback = sReservedHosts.get("resolver.msg.xiaomi.net");
                if (fallback != null) {
                    Iterator<String> it = fallback.a(true).iterator();
                    while (it.hasNext()) {
                        arrayList2.add(String.format(Locale.US, "http://%1$s/gslb/?ver=4.0", it.next()));
                    }
                }
            }
        } else {
            arrayList2 = localFallback.a(format);
        }
        Iterator<String> it2 = arrayList2.iterator();
        IOException e2 = null;
        while (it2.hasNext()) {
            Uri.Builder buildUpon = Uri.parse(it2.next()).buildUpon();
            for (com.xiaomi.channel.commonutils.network.c cVar : arrayList3) {
                buildUpon.appendQueryParameter(cVar.a(), cVar.b());
            }
            try {
                HttpGet httpGet = this.sHttpGetter;
                return httpGet == null ? d.a(sAppContext, new URL(buildUpon.toString())) : httpGet.a(buildUpon.toString());
            } catch (IOException e3) {
                e2 = e3;
            }
        }
        if (e2 == null) {
            return null;
        }
        com.xiaomi.channel.commonutils.logger.b.a("network exception: " + e2.getMessage());
        throw e2;
    }

    protected String loadHosts() {
        BufferedReader bufferedReader;
        File file;
        try {
            file = new File(sAppContext.getFilesDir(), getProcessName());
        } catch (Throwable th) {
            th = th;
            bufferedReader = null;
        }
        if (!file.isFile()) {
            com.xiaomi.channel.commonutils.file.b.a((Closeable) null);
            return null;
        }
        bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        try {
            StringBuilder sb = new StringBuilder();
            while (true) {
                String readLine = bufferedReader.readLine();
                if (readLine == null) {
                    return sb.toString();
                }
                sb.append(readLine);
            }
        } catch (Throwable th2) {
            th = th2;
            try {
                com.xiaomi.channel.commonutils.logger.b.a("load host exception " + th.getMessage());
                return null;
            } finally {
                com.xiaomi.channel.commonutils.file.b.a(bufferedReader);
            }
        }
    }

    public void persist() {
        synchronized (this.mHostsMapping) {
            try {
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(sAppContext.openFileOutput(getProcessName(), 0)));
                String jSONObject = toJSON().toString();
                if (!TextUtils.isEmpty(jSONObject)) {
                    bufferedWriter.write(jSONObject);
                }
                bufferedWriter.close();
            } catch (Exception e2) {
                com.xiaomi.channel.commonutils.logger.b.a("persist bucket failure: " + e2.getMessage());
            }
        }
    }

    public void purge() {
        String next;
        synchronized (this.mHostsMapping) {
            Iterator<Fallbacks> it = this.mHostsMapping.values().iterator();
            while (it.hasNext()) {
                it.next().purge(true);
            }
            while (true) {
                for (boolean z = false; !z; z = true) {
                    Iterator<String> it2 = this.mHostsMapping.keySet().iterator();
                    while (it2.hasNext()) {
                        next = it2.next();
                        if (this.mHostsMapping.get(next).getFallbacks().isEmpty()) {
                            break;
                        }
                    }
                }
                this.mHostsMapping.remove(next);
            }
        }
    }

    public void refreshFallbacks() {
        ArrayList<String> arrayList;
        synchronized (this.mHostsMapping) {
            checkHostMapping();
            arrayList = new ArrayList<>(this.mHostsMapping.keySet());
            for (int size = arrayList.size() - 1; size >= 0; size--) {
                Fallbacks fallbacks = this.mHostsMapping.get(arrayList.get(size));
                if (fallbacks != null && fallbacks.getFallback() != null) {
                    arrayList.remove(size);
                }
            }
        }
        ArrayList<Fallback> requestRemoteFallbacks = requestRemoteFallbacks(arrayList);
        for (int i = 0; i < arrayList.size(); i++) {
            if (requestRemoteFallbacks.get(i) != null) {
                updateFallbacks(arrayList.get(i), requestRemoteFallbacks.get(i));
            }
        }
    }

    protected Fallback requestRemoteFallback(String str) {
        if (System.currentTimeMillis() - this.lastRemoteRequestTimestamp <= this.remoteRequestFailureCount * 60 * 1000) {
            return null;
        }
        this.lastRemoteRequestTimestamp = System.currentTimeMillis();
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add(str);
        Fallback fallback = requestRemoteFallbacks(arrayList).get(0);
        if (fallback != null) {
            this.remoteRequestFailureCount = 0L;
            return fallback;
        }
        long j = this.remoteRequestFailureCount;
        if (j >= 15) {
            return null;
        }
        this.remoteRequestFailureCount = j + 1;
        return null;
    }

    public void setCurrentISP(String str) {
        this.currentISP = str;
    }

    protected JSONObject toJSON() {
        JSONObject jSONObject;
        synchronized (this.mHostsMapping) {
            jSONObject = new JSONObject();
            jSONObject.put(DeviceInfo.TAG_VERSION, 2);
            JSONArray jSONArray = new JSONArray();
            Iterator<Fallbacks> it = this.mHostsMapping.values().iterator();
            while (it.hasNext()) {
                jSONArray.put(it.next().toJSON());
            }
            jSONObject.put("data", jSONArray);
            JSONArray jSONArray2 = new JSONArray();
            Iterator<Fallback> it2 = sReservedHosts.values().iterator();
            while (it2.hasNext()) {
                jSONArray2.put(it2.next().f());
            }
            jSONObject.put("reserved", jSONArray2);
        }
        return jSONObject;
    }

    public void updateFallbacks(String str, Fallback fallback) {
        if (TextUtils.isEmpty(str) || fallback == null) {
            throw new IllegalArgumentException("the argument is invalid " + str + ", " + fallback);
        }
        if (this.sHostFilter.a(str)) {
            synchronized (this.mHostsMapping) {
                checkHostMapping();
                if (this.mHostsMapping.containsKey(str)) {
                    this.mHostsMapping.get(str).addFallback(fallback);
                } else {
                    Fallbacks fallbacks = new Fallbacks(str);
                    fallbacks.addFallback(fallback);
                    this.mHostsMapping.put(str, fallbacks);
                }
            }
        }
    }
}