导航菜单

页面标题

页面副标题

xDrip+ v04633772025.07.16 - DesertComms.java 源代码

正在查看: xDrip+ v04633772025.07.16 应用的 DesertComms.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package com.eveningoutpost.dexdrip.utilitymodels.desertsync;

import android.os.PowerManager;
import com.eveningoutpost.dexdrip.Home;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.driver.UsbId;
import com.eveningoutpost.dexdrip.models.DesertSync;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Pref;
import com.eveningoutpost.dexdrip.utilitymodels.StatusItem;
import com.eveningoutpost.dexdrip.webservices.XdripWebService;
import com.google.gson.annotations.Expose;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class DesertComms {
    private static final String TAG = "DesertComms";
    private static volatile int comms_failures;
    private static volatile String lastLoadedIP;
    private static OkHttpClient okHttpClient;
    private static final LinkedBlockingDeque<QueueItem> queue = new LinkedBlockingDeque<>();

    public static boolean pushToOasis(String str, String str2, String str3) {
        if (Home.get_follower()) {
            String oasisIP = getOasisIP();
            if (oasisIP.length() == 0) {
                return false;
            }
            String httpUrl = HttpUrl.parse(getInitialUrl(oasisIP)).newBuilder().addPathSegment("sync").addPathSegment("push").addPathSegment(str).addPathSegment(str2).addEncodedPathSegment(urlEncode(str3)).build().toString();
            UserError.Log.d(TAG, "To master: " + httpUrl);
            queue.add(new QueueItem(httpUrl));
            runInBackground();
            return true;
        }
        if (!Home.get_master()) {
            return true;
        }
        UserError.Log.d(TAG, "We are master so push to followers.");
        for (String str4 : DesertSync.getActivePeers()) {
            String str5 = TAG;
            UserError.Log.d(str5, "Master attempting to push to follower: " + str4);
            String httpUrl2 = HttpUrl.parse(getInitialUrl(str4)).newBuilder().addPathSegment("sync").addPathSegment("push").addPathSegment(str).addPathSegment(str2).addEncodedPathSegment(urlEncode(str3)).build().toString();
            UserError.Log.d(str5, "To follower: " + httpUrl2);
            queue.add(new QueueItem(httpUrl2).setHandler(QueueHandler.ToFollower));
        }
        runInBackground();
        return true;
    }

    public static boolean pullFromOasis(String str, long j) {
        String oasisIP = getOasisIP();
        if (oasisIP.length() == 0) {
            return false;
        }
        try {
            String httpUrl = HttpUrl.parse(getInitialUrl(oasisIP)).newBuilder().addPathSegment("sync").addPathSegment("pull").addPathSegment("" + j).addPathSegment(str).build().toString();
            UserError.Log.d(TAG, httpUrl);
            queue.add(new QueueItem(httpUrl).setHandler(QueueHandler.Pull));
            runInBackground();
            return true;
        } catch (NullPointerException unused) {
            UserError.Log.e(TAG, "Exception parsing url: -" + oasisIP + "- probably invalid ip");
            return false;
        }
    }

    public static boolean probeOasis(String str, String str2) {
        if (JoH.emptyString(str2)) {
            return false;
        }
        if (Home.get_follower()) {
            String httpUrl = HttpUrl.parse(getInitialUrl(str2)).newBuilder().addPathSegment("sync").addPathSegment("id").addPathSegment(str).build().toString();
            UserError.Log.d(TAG, "PROBE: " + httpUrl);
            queue.add(new QueueItem(httpUrl).setHandler(QueueHandler.MasterPing));
            runInBackground();
            return true;
        }
        UserError.Log.e(TAG, "Probe cancelled as not follower");
        return true;
    }

    private static String getOasisIPfromPrefs() {
        return Pref.getString("desert_sync_master_ip", "").trim().replace("/", "");
    }

    private static String getOasisIP() {
        String oasisIPfromPrefs = getOasisIPfromPrefs();
        if (JoH.emptyString(lastLoadedIP)) {
            lastLoadedIP = oasisIPfromPrefs;
        }
        setCurrentToBackup(oasisIPfromPrefs, lastLoadedIP);
        return oasisIPfromPrefs;
    }

    public static void setOasisIP(String str) {
        setCurrentToBackup(str, null);
        Pref.setString("desert_sync_master_ip", str);
        UserError.Log.uel(TAG, "Master IP updated to: " + str);
    }

    private static void setCurrentToBackup(String str, String str2) {
        if (str2 == null) {
            str2 = getOasisIPfromPrefs();
        }
        if (str2.equals(str) || str2.equals(PersistentStore.getString("DesertComms-OasisIP")) || JoH.emptyString(str2)) {
            return;
        }
        PersistentStore.setString("DesertComms-OasisIP", str2);
        UserError.Log.d(TAG, "Saving to backup: " + str2);
    }

    public static String getOasisBackupIP() {
        String string = PersistentStore.getString("DesertComms-OasisIP");
        if (JoH.emptyString(string)) {
            return null;
        }
        return string;
    }

    private static void runInBackground() {
        new Thread(new Runnable() {
            @Override
            public final void run() {
                DesertComms.lambda$runInBackground$0();
            }
        }).start();
    }

    public static void lambda$runInBackground$0() {
        LinkedBlockingDeque<QueueItem> linkedBlockingDeque = queue;
        if (linkedBlockingDeque.size() == 0) {
            return;
        }
        PowerManager.WakeLock wakeLock = JoH.getWakeLock("DesertComms send", UsbId.SILABS_CP2102);
        UserError.Log.d(TAG, "Queue size: " + linkedBlockingDeque.size());
        try {
            String httpNext = httpNext();
            checkCommsFailures(httpNext == null);
            if ((httpNext != null && linkedBlockingDeque.size() > 0) || Home.get_master()) {
                runInBackground();
            }
        } finally {
            JoH.releaseWakeLock(wakeLock);
        }
    }

    private static String httpNext() {
        LinkedBlockingDeque<QueueItem> linkedBlockingDeque = queue;
        if (linkedBlockingDeque.peekFirst() == null) {
            return null;
        }
        try {
            QueueItem takeFirst = linkedBlockingDeque.takeFirst();
            takeFirst.retried++;
            takeFirst.updateLastProcessed();
            UserError.Log.d(TAG, "Next item: " + takeFirst.toS());
            String httpGet = httpGet(takeFirst.getUrl((!Home.get_follower() || takeFirst.handler == QueueHandler.MasterPing) ? null : getOasisIP()));
            takeFirst.result = httpGet;
            takeFirst.handler.process(takeFirst);
            if (httpGet != null || takeFirst.expired()) {
                linkedBlockingDeque.remove(takeFirst);
            }
            return httpGet;
        } catch (InterruptedException unused) {
            UserError.Log.e(TAG, "Got interrupted");
            return null;
        }
    }

    private static String httpGet(String str) {
        if (str == null) {
            return null;
        }
        String hashPassword = XdripWebService.hashPassword(Pref.getString(DesertSync.PREF_WEBSERVICE_SECRET, ""));
        Request.Builder addHeader = new Request.Builder().url(str).addHeader("User-Agent", "xDrip+ Desert Comms");
        if (hashPassword != null) {
            addHeader.addHeader("api-secret", hashPassword);
        }
        try {
            Response execute = getHttpInstance().newCall(addHeader.build()).execute();
            try {
                if (execute.isSuccessful()) {
                    String string = execute.body().string();
                    execute.close();
                    return string;
                }
                if (JoH.ratelimit("desert-error-response", 180)) {
                    UserError.Log.wtf(TAG, "Got error code: " + execute.code() + " " + execute.message() + " " + execute.body().toString());
                }
                execute.close();
                return null;
            } catch (Throwable th) {
                if (execute != null) {
                    try {
                        execute.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        } catch (IOException | NullPointerException unused) {
            return null;
        }
    }

    private static OkHttpClient getHttpInstance() {
        if (okHttpClient == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            TimeUnit timeUnit = TimeUnit.SECONDS;
            builder.connectTimeout(10L, timeUnit);
            builder.readTimeout(40L, timeUnit);
            builder.writeTimeout(20L, timeUnit);
            try {
                builder.sslSocketFactory(TrustManager.getSSLSocketFactory(), TrustManager.getNaiveTrustManager());
            } catch (Exception unused) {
                UserError.Log.wtf(TAG, "Failed to set up https!");
            }
            builder.hostnameVerifier(TrustManager.getXdripHostVerifier());
            okHttpClient = builder.build();
        }
        return okHttpClient;
    }

    private static String urlEncode(String str) {
        try {
            return URLEncoder.encode(str, "UTF-8");
        } catch (Exception unused) {
            return null;
        }
    }

    private static void checkCommsFailures(boolean z) {
        if (z) {
            comms_failures++;
            String str = TAG;
            UserError.Log.d(str, "Comms failures increased to: " + comms_failures);
            if (Home.get_master() || comms_failures <= 2 || !JoH.pratelimit("desert-check-comms", 1800) || RouteTools.reachable(getOasisIP())) {
                return;
            }
            UserError.Log.e(str, "Oasis master IP appears unreachable: " + getOasisIP());
            JoH.showNotification("Desert Sync Failure", "Master unreachable: " + getOasisIP() + " changed?", null, 1017, false, true, false);
            return;
        }
        if (!Home.get_master() && comms_failures > 0) {
            UserError.Log.d(TAG, "Comms restored after " + comms_failures + " failures");
            if (comms_failures > 2) {
                JoH.cancelNotification(1017);
            }
        }
        comms_failures = 0;
    }

    private static String getInitialUrl(String str) {
        StringBuilder sb = new StringBuilder();
        sb.append("http");
        sb.append(useHTTPS() ? "s" : "");
        sb.append("://");
        sb.append(str);
        sb.append(":1758");
        sb.append(useHTTPS() ? "1" : "0");
        return sb.toString();
    }

    private static boolean useHTTPS() {
        return Pref.getBooleanDefaultFalse("desert_use_https");
    }

    private static class QueueItem {
        String result;

        @Expose
        final String url;

        @Expose
        long lastProcessedTime = -1;

        @Expose
        int retried = 0;

        @Expose
        QueueHandler handler = QueueHandler.None;

        @Expose
        final long entryTime = JoH.tsl();

        QueueItem(String str) {
            this.url = str;
        }

        QueueItem setHandler(QueueHandler queueHandler) {
            this.handler = queueHandler;
            return this;
        }

        String getUrl(String str) {
            if (JoH.emptyString(str)) {
                return this.url;
            }
            try {
                return HttpUrl.parse(this.url).newBuilder().host(str).build().toString();
            } catch (NullPointerException unused) {
                return null;
            }
        }

        String urlIP() {
            try {
                return HttpUrl.parse(this.url).host();
            } catch (NullPointerException unused) {
                return null;
            }
        }

        void updateLastProcessed() {
            this.lastProcessedTime = JoH.tsl();
        }

        boolean expired() {
            return oneHit() || this.retried > 10 || JoH.msSince(this.entryTime) > 86400000;
        }

        boolean oneHit() {
            QueueHandler queueHandler = this.handler;
            return queueHandler == QueueHandler.ToFollower || queueHandler == QueueHandler.MasterPing || queueHandler == QueueHandler.Pull;
        }

        String toS() {
            return JoH.defaultGsonInstance().toJson(this);
        }
    }

    static class AnonymousClass1 {
        static final int[] $SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler;

        static {
            int[] iArr = new int[QueueHandler.values().length];
            $SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler = iArr;
            try {
                iArr[QueueHandler.Pull.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[QueueHandler.ToFollower.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
            try {
                $SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[QueueHandler.MasterPing.ordinal()] = 3;
            } catch (NoSuchFieldError unused3) {
            }
        }
    }

    enum QueueHandler {
        None,
        Pull,
        MasterPing,
        ToFollower;

        void process(QueueItem queueItem) {
            int i = AnonymousClass1.$SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[ordinal()];
            if (i == 1) {
                String str = queueItem.result;
                if (str == null) {
                    DesertSync.pullFailed(queueItem.urlIP());
                    return;
                } else {
                    DesertSync.fromPull(str);
                    return;
                }
            }
            if (i == 2) {
                DesertSync.checkIpChange(queueItem.result);
            } else {
                if (i != 3) {
                    return;
                }
                DesertSync.masterIdReply(queueItem.result, queueItem.urlIP());
            }
        }
    }

    public static List<StatusItem> megaStatus() {
        ArrayList arrayList = new ArrayList();
        if (Home.get_follower()) {
            if (JoH.emptyString(getOasisIP())) {
                arrayList.add(new StatusItem("Desert Master", "Not known yet - needs QR code scan?"));
            } else {
                arrayList.add(new StatusItem("Desert Master", getOasisIP(), RouteTools.reachable(getOasisIP()) ? StatusItem.Highlight.NORMAL : StatusItem.Highlight.BAD));
            }
            if (Home.get_engineering_mode()) {
                arrayList.add(new StatusItem("Desert Backup", getOasisBackupIP()));
                arrayList.add(new StatusItem("Our IP", RouteTools.getBestInterfaceAddress()));
            }
        }
        return arrayList;
    }
}