正在查看: xDrip+ v04633772025.07.16 应用的 BlueJayService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 BlueJayService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.watch.thinjam;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Pair;
import androidx.databinding.ObservableField;
import ar.com.hjg.pngj.chunks.ChunkCopyBehaviour;
import com.eveningoutpost.dexdrip.Home;
import com.eveningoutpost.dexdrip.NewDataObserver$$ExternalSyntheticLambda2;
import com.eveningoutpost.dexdrip.cloud.jamcm.Pusher;
import com.eveningoutpost.dexdrip.g5model.CalibrationState;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.util.HexDump;
import com.eveningoutpost.dexdrip.models.BgReading;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.Treatments;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.services.JamBaseBluetoothSequencer;
import com.eveningoutpost.dexdrip.services.Ob1G5CollectionService;
import com.eveningoutpost.dexdrip.ui.activities.ThinJamActivity;
import com.eveningoutpost.dexdrip.utilitymodels.AlertPlayer;
import com.eveningoutpost.dexdrip.utilitymodels.BroadcastSnooze;
import com.eveningoutpost.dexdrip.utilitymodels.Inevitable;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Pref;
import com.eveningoutpost.dexdrip.utilitymodels.StatusItem;
import com.eveningoutpost.dexdrip.utilitymodels.Unitized;
import com.eveningoutpost.dexdrip.utils.BytesGenerator;
import com.eveningoutpost.dexdrip.utils.bt.Helper;
import com.eveningoutpost.dexdrip.utils.bt.ReplyProcessor;
import com.eveningoutpost.dexdrip.utils.bt.Subscription;
import com.eveningoutpost.dexdrip.utils.framework.WakeLockTrampoline;
import com.eveningoutpost.dexdrip.utils.time.SlidingWindowConstraint;
import com.eveningoutpost.dexdrip.watch.thinjam.BlueJayService;
import com.eveningoutpost.dexdrip.watch.thinjam.firmware.BlueJayFirmware;
import com.eveningoutpost.dexdrip.watch.thinjam.firmware.FirmwareDownload;
import com.eveningoutpost.dexdrip.watch.thinjam.firmware.FirmwareInfo;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.AuthReqTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.BackFillTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.BulkUpRequestTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.BulkUpTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.DefineWindowTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.GlucoseTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.PushRx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.RBulkUpTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.ResetPersistTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.SetTimeTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.SetTxIdTx;
import com.eveningoutpost.dexdrip.watch.thinjam.messages.StandbyTx;
import com.eveningoutpost.dexdrip.watch.thinjam.utils.BitmapTools;
import com.eveningoutpost.dexdrip.xdrip;
import com.google.gson.annotations.Expose;
import com.polidea.rxandroidble2.RxBleDeviceServices;
import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException;
import com.polidea.rxandroidble2.exceptions.BleCharacteristicNotFoundException;
import com.polidea.rxandroidble2.exceptions.BleDisconnectedException;
import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
@SuppressLint({"CheckResult"})
public class BlueJayService extends JamBaseBluetoothSequencer {
private static volatile long awaiting_easy_auth;
static final List<UUID> huntCharacterstics;
private static volatile long lastBulkOk;
private static volatile long lastLongPress1;
private static volatile long lastUsableGlucoseTimestamp;
private volatile int lastActionedRevisedOffset;
volatile Subscription notificationSubscription;
private volatile Runnable postQueueRunnable;
ObservableField<Integer> progressIndicator;
private volatile int revisedOffset;
private volatile SetTimeTx timeOutbound;
private static final SlidingWindowConstraint connectionTracker = new SlidingWindowConstraint(50.0d, 1200000, "max_bluejay_reconnects");
public static volatile boolean flashIsRunning = false;
public static final ConcurrentLinkedQueue<ThinJamItem> commandQueue = new ConcurrentLinkedQueue<>();
static volatile boolean busy = false;
private final IBinder binder = new LocalBinder();
private final DebugUnitTestLogger debug = new DebugUnitTestLogger(this);
public volatile boolean sleepAfterReset = false;
public StringBuilder notificationString = new StringBuilder();
public ObservableField<String> stringObservableField = new ObservableField<>();
private void audioStreamCallBack(byte[] bArr) {
}
public static ObservableSource lambda$enableNotifications$14(Observable observable) throws Exception {
return observable;
}
private static int recordsPerHour() {
return 12;
}
private long whenToRetryNext() {
return 600000L;
}
public BlueJayService() {
this.mState = new ThinJamState().setLI(this.I);
this.I.backgroundStepDelay = 0;
this.I.autoReConnect = true;
this.I.connectTimeoutMinutes = 55;
this.I.resetWhenAlreadyConnected = true;
this.I.useReconnectHandler = true;
this.I.reconnectConstraint = new SlidingWindowConstraint(30.0d, 60000L, "max_reconnections");
this.I.queue_write_characterstic = Const.THINJAM_WRITE;
setMac(BlueJay.getMac());
this.revisedOffset = 0;
this.lastActionedRevisedOffset = -1;
}
static {
ArrayList arrayList = new ArrayList();
huntCharacterstics = arrayList;
arrayList.add(Const.THINJAM_WRITE);
}
public void setPostQueueRunnable(Runnable runnable) {
this.postQueueRunnable = runnable;
}
public void setProgressIndicator(ObservableField<Integer> observableField) {
this.progressIndicator = observableField;
}
public static class ThinJamItem {
final byte[] buffer;
@Expose
final int height;
volatile boolean inProgress;
Integer specificId;
@Expose
final int width;
@Expose
final int x;
@Expose
final int y;
int type = 1;
int windowType = 1;
int colourEffect = 0;
boolean quiet = true;
int retries = 20;
int retried = 0;
int sequence = 0;
long queuedTimestamp = System.currentTimeMillis();
public ThinJamItem(int i, int i2, int i3, int i4, byte[] bArr) {
this.x = i;
this.y = i2;
this.width = i3;
this.height = i4;
this.buffer = bArr;
}
public String toS() {
return JoH.defaultGsonInstance().toJson(this);
}
public ThinJamItem setType(int i) {
this.type = i;
return this;
}
public ThinJamItem useAck() {
this.quiet = false;
return this;
}
public ThinJamItem setWindowType(int i) {
this.windowType = i;
return this;
}
public ThinJamItem setSpecificId(int i) {
this.specificId = Integer.valueOf(i);
return this;
}
public ThinJamItem setSequence(int i) {
this.sequence = i;
return this;
}
public boolean retryCounterOk() {
int i = this.retries;
int i2 = this.retried;
if (i == i2) {
return false;
}
this.retried = i2 + 1;
return true;
}
public void dontRetryAgain() {
this.retries = this.retried;
}
public int getId() {
Integer num = this.specificId;
return num != null ? num.intValue() : this.width == 0 ? 0 : 1;
}
}
public BlueJayInfo getInfo() {
return BlueJayInfo.getInfo(this.I.address);
}
public void setMac(String str) {
setAddress(str);
BlueJay.setMac(str);
}
public void setSettings() {
setSettings(Pref.getString("dex_txid", "").trim().toUpperCase());
}
public void setSettings(String str) {
if (str.length() == 4) {
str = "0B" + str;
}
if (str.length() == 6) {
queueGenericCommand(new SetTxIdTx(str, "00:00:00:00:00:00").getBytes(), "Set TxId: " + str, null);
return;
}
JoH.static_toast_long("Invalid TXID: " + str);
}
public void setTime() {
new JamBaseBluetoothSequencer.QueueMe(this).setGenerator(new BytesGenerator() {
@Override
public byte[] produce() {
BlueJayService.this.timeOutbound = new SetTimeTx();
return BlueJayService.this.timeOutbound.getBytes();
}
}).setDescription("Set time").expireInSeconds(30).setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
SetTimeTx setTimeTx = new SetTimeTx(bArr);
UserError.Log.d("BlueJayServiceR", "Time Process callback: " + JoH.bytesToHex(bArr));
BlueJayService.this.getInfo().parseSetTime(setTimeTx, BlueJayService.this.timeOutbound);
UserError.Log.d("BlueJayServiceR", "Time difference with watch: " + ((BlueJayService.this.timeOutbound.getTimestamp() - setTimeTx.getTimestamp()) / 1000.0d));
}
}).queue();
}
public void getBackFill(int i) {
if (BlueJay.haveAuthKey(this.I.address)) {
if (!flashRunning()) {
JamBaseBluetoothSequencer.QueueMe expireInSeconds = new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new BackFillTx(i).getBytes()).setDescription("Get BackFill " + i).expireInSeconds(30);
expireInSeconds.setProcessor(new AuthReplyProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "BackFill request response: " + JoH.bytesToHex(bArr));
}
}).setTag(expireInSeconds)).queue();
return;
}
UserError.Log.d("BlueJayServiceR", "No backfill as flash running");
return;
}
UserError.Log.d("BlueJayServiceR", "Cannot back fill as we don't have auth key");
}
private static Pair<Long, Long> getBackFillStatus() {
long maxBackFillHours = getMaxBackFillHours() * 3600000;
int maxBackFillHours2 = getMaxBackFillHours() * recordsPerHour();
UserError.Log.d("BlueJayServiceR", "Checking " + maxBackFillHours2 + " for backfill requirement");
List<BgReading> latest_by_size = BgReading.latest_by_size(maxBackFillHours2);
long tsl = JoH.tsl() - maxBackFillHours;
long tsl2 = JoH.tsl();
boolean z = true;
if (latest_by_size != null && latest_by_size.size() == maxBackFillHours2) {
int i = 0;
while (i < latest_by_size.size()) {
BgReading bgReading = latest_by_size.get(i);
if (bgReading != null) {
List<BgReading> list = latest_by_size;
if (JoH.msSince(bgReading.timestamp) <= (i * 300000) + 420000) {
tsl2 = bgReading.timestamp;
i++;
latest_by_size = list;
}
}
if (bgReading != null && JoH.msSince(bgReading.timestamp) <= maxBackFillHours) {
tsl = bgReading.timestamp;
}
if (bgReading != null) {
UserError.Log.d("BlueJayServiceR", "Flagging backfill tripped by reading: " + i + " at time: " + JoH.dateTimeText(bgReading.timestamp) + " creating backfill window: " + JoH.dateTimeText(tsl));
} else {
UserError.Log.d("BlueJayServiceR", "Flagging backfill tripped by null reading: " + i);
}
}
z = false;
}
if (!z) {
tsl = -1;
}
return new Pair<>(Long.valueOf(tsl), Long.valueOf(tsl2));
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void getStatus() {
setTime();
setTime();
getStatus1();
getStatus2();
getStatus3();
doQueue();
}
public JamBaseBluetoothSequencer.Inst getI() {
return this.I;
}
public void getStatus1() {
new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new byte[]{33}).setDescription("Get Status 1").expireInSeconds(30).setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Status 1 Process callback: " + JoH.bytesToHex(bArr));
BlueJayInfo.getInfo(((JamBaseBluetoothSequencer) BlueJayService.this).I.address).parseStatus1(bArr);
}
}).queue();
}
public void getStatus2() {
new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new byte[]{34}).setDescription("Get Status 2").expireInSeconds(30).setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Status 2 Process callback: " + JoH.bytesToHex(bArr));
BlueJayInfo.getInfo(((JamBaseBluetoothSequencer) BlueJayService.this).I.address).parseStatus2(bArr);
UserError.Log.d("BlueJayServiceR", BlueJayInfo.getInfo(((JamBaseBluetoothSequencer) BlueJayService.this).I.address).toS());
BlueJayService.this.addToLog("Status information received");
if (BlueJay.isCollector()) {
BlueJayService.this.processInboundGlucose();
}
}
}).queueUnique();
}
public void getStatus3() {
if (BlueJayInfo.getInfo(this.I.address).buildNumber >= 2092) {
new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new byte[]{35}).setDescription("Get Status 3").expireInSeconds(30).setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Status 3 Process callback: " + JoH.bytesToHex(bArr));
BlueJayInfo.getInfo(((JamBaseBluetoothSequencer) BlueJayService.this).I.address).parseStatus3(bArr);
UserError.Log.d("BlueJayServiceR", BlueJayInfo.getInfo(((JamBaseBluetoothSequencer) BlueJayService.this).I.address).toS());
}
}).queueUnique();
}
}
public void processInboundGlucose() {
BlueJayInfo info = BlueJayInfo.getInfo(this.I.address);
long timestamp = info.getTimestamp();
UserError.Log.d("BlueJayServiceR", "Processing inbound glucose: " + JoH.dateTimeText(info.getTimestamp()) + " " + info.toS());
if (timestamp > 1561900000000L && timestamp < JoH.tsl() + 300000) {
BgReading last = BgReading.last();
if (last == null || JoH.msSince(last.timestamp) > 240000) {
Ob1G5CollectionService.processCalibrationStateLite(CalibrationState.parse(info.state), timestamp);
if (Ob1G5CollectionService.lastSensorState.usableGlucose()) {
UserError.Log.d("BlueJayServiceR", "USABLE GLUCOSE");
lastUsableGlucoseTimestamp = timestamp;
if (BgReading.getForPreciseTimestamp(timestamp, 240000L, false) == null) {
BgReading last2 = BgReading.last();
BgReading bgReadingInsertFromG5 = BgReading.bgReadingInsertFromG5(info.glucose, timestamp, "BlueJay");
try {
bgReadingInsertFromG5.calculated_value_slope = info.getTrend().doubleValue() / 60000.0d;
if (last.calculated_value_slope == Double.NaN) {
last.hide_slope = true;
}
} catch (Exception unused) {
}
if (bgReadingInsertFromG5 == null || bgReadingInsertFromG5.timestamp <= last2.timestamp) {
return;
}
UserError.Log.d("BlueJayServiceR", "Post processing new reading: " + JoH.dateTimeText(bgReadingInsertFromG5.timestamp));
bgReadingInsertFromG5.postProcess(false);
return;
}
UserError.Log.d("BlueJayServiceR", "Ignoring status glucose reading as we already have one within 4 mins");
return;
}
UserError.Log.d("BlueJayServiceR", "Glucose value not reported as usable");
return;
}
return;
}
UserError.Log.d("BlueJayServiceR", "No valid timestamp for inbound glucose data");
}
public void sendGlucose() {
BgReading last = BgReading.last();
if (last == null || JoH.msSince(last.timestamp) >= 3600000) {
return;
}
final BlueJayInfo info = BlueJayInfo.getInfo(BlueJay.getMac());
if (Math.abs(info.lastReadingTime - last.timestamp) > 180000) {
GlucoseTx glucoseTx = new GlucoseTx(last);
if (glucoseTx.isValid()) {
JamBaseBluetoothSequencer.QueueMe description = new JamBaseBluetoothSequencer.QueueMe(this).setBytes(glucoseTx.getBytes()).expireInSeconds(60).setDescription("Glucose to watch");
description.setProcessor(new AuthReplyProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Glucose Incoming reply processor: " + HexDump.dumpHexString(bArr));
info.displayUpdated();
}
}).setTag(description));
description.queue();
doQueue();
return;
}
UserError.Log.d("BlueJayServiceR", "GlucoseTX wasn't valid so not sending.");
return;
}
UserError.Log.d("BlueJayServiceR", "Watch already has recent reading");
}
public void standby() {
if (BlueJayInfo.getInfo(this.I.address).buildNumber > 39) {
addToLog("Requesting watch standby");
JamBaseBluetoothSequencer.QueueMe bytes = new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new StandbyTx().getBytes());
bytes.setDescription("Watch Standby").setProcessor(new AuthReplyProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Reply for: Watch Standby " + JoH.bytesToHex(bArr));
}
}).setTag(bytes)).expireInSeconds(60);
bytes.queueUnique();
doQueue();
invalidateCache();
return;
}
JoH.static_toast_long("Needs BlueJay firmware upgrade to support standby");
}
public void reboot() {
queueSingleByteCommand((byte) 81, "Reset all");
invalidateCache();
}
public void factoryReset() {
queueGenericCommand(new ResetPersistTx(this.sleepAfterReset).getBytes(), "Factory Reset", null);
invalidateCache();
}
public void showQrCode() {
addToLog("Asking watch to show a QR code");
queueSingleByteCommand((byte) 68, "Show QR Code", new Runnable() {
@Override
public final void run() {
ThinJamActivity.launchQRScan();
}
});
}
public void easyAuth() {
addToLog("Attempting easy authentication");
new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new byte[]{86}).setDescription("Get easy auth").expireInSeconds(60).setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
if (bArr.length == 18) {
if (bArr[0] == 65 && bArr[1] == -109) {
String bytesToHex = JoH.bytesToHex(Arrays.copyOfRange(bArr, 2, 18));
UserError.Log.d("BlueJayServiceR", "Storing easy auth " + ((JamBaseBluetoothSequencer) BlueJayService.this).I.address + " of: " + bytesToHex);
BlueJay.storeAuthKey(((JamBaseBluetoothSequencer) BlueJayService.this).I.address, bytesToHex);
BlueJayService.this.identify();
return;
}
return;
}
if (bArr.length == 2) {
byte b = bArr[1];
if (b == 0) {
BlueJayService.this.addToLog("Easy Auth mode - press the button for 2 seconds");
long unused = BlueJayService.awaiting_easy_auth = JoH.tsl();
return;
} else if (b == 1) {
BlueJayService.this.addToLog("Cannot easy auth as not connected to charger");
return;
} else if (b == 3) {
BlueJayService.this.addToLog("Already authenticated, no need to easy auth");
return;
} else {
if (b != 5) {
return;
}
BlueJayService.this.addToLog("Cannot easy auth as button is already pressed");
return;
}
}
UserError.Log.d("BlueJayServiceR", "Wrong size for easy auth reply: " + bArr.length);
}
}).queue();
doQueue();
}
public void identify() {
addToLog("Pairing / Identifying Watch");
JamBaseBluetoothSequencer.QueueMe expireInSeconds = new JamBaseBluetoothSequencer.QueueMe(this).setBytes(new byte[]{65}).setDescription("Get identity value").setDelayMs(300).expireInSeconds(60);
expireInSeconds.setProcessor(new AuthReplyProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
if (bArr.length == 18) {
if (bArr[0] == 65 && bArr[1] == -110) {
String bytesToHex = JoH.bytesToHex(Arrays.copyOfRange(bArr, 2, 18));
UserError.Log.d("BlueJayServiceR", "Storing identity for " + ((JamBaseBluetoothSequencer) BlueJayService.this).I.address + " of: " + bytesToHex);
BlueJay.storeIdentityKey(((JamBaseBluetoothSequencer) BlueJayService.this).I.address, bytesToHex);
return;
}
return;
}
BlueJayService.this.addToLog("Got wrong reply from pairing - try again");
UserError.Log.d("BlueJayServiceR", "Wrong size for identity reply: " + bArr.length + " " + JoH.bytesToHex(bArr));
}
}).setTag(expireInSeconds)).queue();
doQueue();
}
public boolean isAuthRequiredPacket(byte[] bArr) {
return bArr != null && bArr.length == 2 && bArr[1] == 15;
}
public void authenticate(final JamBaseBluetoothSequencer.QueueMe queueMe) {
new JamBaseBluetoothSequencer.QueueMe(this).setBytes(AuthReqTx.getNextAuthPacket(null).getBytes()).setDescription("Auth hello packet").setProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "Processing likely auth challenge");
AuthReqTx nextAuthPacket = AuthReqTx.getNextAuthPacket(bArr);
if (nextAuthPacket != null) {
new JamBaseBluetoothSequencer.QueueMe(BlueJayService.this).setBytes(nextAuthPacket.getBytes()).setDescription("Auth challenge reply").setProcessor(new ReplyProcessor(((JamBaseBluetoothSequencer) BlueJayService.this).I.connection) {
@Override
public void process(byte[] bArr2) {
if (AuthReqTx.isAccessGranted(bArr2)) {
UserError.Log.d("BlueJayServiceR", "Authentication complete!");
JamBaseBluetoothSequencer.QueueMe queueMe2 = queueMe;
if (queueMe2 != null) {
queueMe2.insert();
return;
}
return;
}
UserError.Log.e("BlueJayServiceR", "Authentication failed! " + JoH.bytesToHex(bArr2));
}
}).insert();
}
}
}).expireInSeconds(60).insert();
}
public void queueSingleByteCommand(byte b, String str) {
queueSingleByteCommand(b, str, null);
}
public void queueSingleByteCommand(byte b, String str, Runnable runnable) {
queueGenericCommand(new byte[]{b}, str, runnable);
}
void queueGenericCommand(byte[] bArr, String str, Runnable runnable) {
queueGenericCommand(bArr, str, runnable, null);
}
JamBaseBluetoothSequencer.QueueMe queueGenericCommand(byte[] bArr, final String str, Runnable runnable, ReplyProcessor replyProcessor) {
JamBaseBluetoothSequencer.QueueMe bytes = new JamBaseBluetoothSequencer.QueueMe(this).setBytes(bArr);
if (replyProcessor != null) {
replyProcessor.setTag(bytes);
}
JamBaseBluetoothSequencer.QueueMe description = bytes.setDescription(str);
if (replyProcessor == null) {
replyProcessor = new AuthReplyProcessor(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr2) {
UserError.Log.d("BlueJayServiceR", "Reply for: " + str + " " + JoH.bytesToHex(bArr2));
}
}).setTag(bytes);
}
description.setProcessor(replyProcessor).expireInSeconds(60);
if (runnable != null) {
bytes.setRunnable(runnable);
}
bytes.queue();
doQueue();
return bytes;
}
public void enqueueWrappedBitmap(BitmapTools.Wrapper wrapper, int i, int i2) {
int i3;
if (wrapper != null) {
int i4 = wrapper.width;
if (i4 > 0 && (i3 = wrapper.height) > 0 && i4 <= 240 && i3 <= 240) {
UserError.Log.d("BlueJayServiceR", "Wrapped bitmap: width: " + i + " height:" + i2);
enqueue(i, i2, wrapper.width, wrapper.height, wrapper.body, wrapper.type);
return;
}
UserError.Log.e("BlueJayServiceR", "Wrapped bitmap out of range: " + wrapper.toS());
return;
}
UserError.Log.e("BlueJayServiceR", "Wrapped bitmap is null");
}
public void enqueue(int i, int i2, int i3, int i4, byte[] bArr, BitmapTools.TJ_BitmapType tJ_BitmapType) {
if (bArr.length > 256) {
UserError.Log.d("BlueJayServiceR", "Breaking image up in to smaller");
enqueueBig(i, i2, i3, i4, bArr, tJ_BitmapType);
return;
}
UserError.Log.d("BlueJayServiceR", "Added new queue item: " + i + " " + i2 + " " + i3 + " " + i4 + " size: " + bArr.length);
commandQueue.add(new ThinJamItem(i, i2, i3, i4, bArr).setWindowType(tJ_BitmapType.getValue()));
Inevitable.task("run-thinjam-queue", 100L, new Runnable() {
@Override
public final void run() {
BlueJayService.this.background_automata();
}
});
}
private class ImageSegment {
BitmapTools.TJ_BitmapType bitmapType;
byte[] buffer;
int current_x;
int current_y;
final int height;
int height_left;
final int start_x;
final int start_y;
byte[] unpacked;
final int width;
int width_left;
ImageSegment(int i, int i2, int i3, int i4, byte[] bArr, BitmapTools.TJ_BitmapType tJ_BitmapType) {
this.width = i;
this.height = i2;
this.start_x = i3;
this.start_y = i4;
this.buffer = bArr;
this.bitmapType = tJ_BitmapType;
this.width_left = i;
this.height_left = i2;
}
byte[] getUnpacked() {
if (this.unpacked == null) {
this.unpacked = BitmapTools.unpackMonoBytesToRGB565(this.buffer);
}
return this.unpacked;
}
String toS() {
return this.width + " " + this.height + " " + this.bitmapType + " " + this.width_left + " " + this.height_left + " " + this.current_x + " " + this.current_y;
}
}
private void cropAndQueueSegment(ImageSegment imageSegment, int i, int i2) {
byte[] cropRGB565;
int i3 = AnonymousClass23.$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$utils$BitmapTools$TJ_BitmapType[imageSegment.bitmapType.ordinal()];
if (i3 == 1) {
cropRGB565 = cropRGB565(imageSegment.current_x, imageSegment.current_y, i2, i, imageSegment.width, imageSegment.height, imageSegment.buffer);
} else if (i3 == 2) {
cropRGB565 = BitmapTools.packRGB565bytesToMono(cropRGB565(imageSegment.current_x, imageSegment.current_y, i2, i, imageSegment.width, imageSegment.height, imageSegment.getUnpacked()));
} else {
throw new RuntimeException("Invalid type in crop and queue segment");
}
byte[] bArr = cropRGB565;
if (bArr != null && bArr.length > 0) {
enqueue(imageSegment.start_x + imageSegment.current_x, imageSegment.start_y + imageSegment.current_y, i2, i, bArr, imageSegment.bitmapType);
} else {
UserError.Log.e("BlueJayServiceR", "Cropped bytes invalid: " + imageSegment.toS());
}
imageSegment.current_x += i2;
imageSegment.width_left -= i2;
}
private void processSegment(ImageSegment imageSegment, int i, int i2) {
while (imageSegment.height_left >= i) {
imageSegment.current_x = 0;
imageSegment.width_left = imageSegment.width;
while (true) {
int i3 = imageSegment.width_left;
if (i3 > 0) {
if (i3 >= i2) {
i3 = i2;
}
cropAndQueueSegment(imageSegment, i, i3);
}
}
imageSegment.current_y += i;
imageSegment.height_left -= i;
}
}
private void processSegmentProgression(ImageSegment imageSegment, int i, int i2) {
while (i > 0) {
processSegment(imageSegment, i, i2);
i /= 2;
i2 *= 2;
}
}
private Pair<Integer, Integer> getBestProgressionParameters(int i, int i2, BitmapTools.TJ_BitmapType tJ_BitmapType) {
int i3;
if (AnonymousClass23.$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$utils$BitmapTools$TJ_BitmapType[tJ_BitmapType.ordinal()] == 2 && i2 <= 256) {
i3 = 2048 / i2;
} else {
i2 = 16;
i3 = 8;
}
return new Pair<>(Integer.valueOf(i2), Integer.valueOf(i3));
}
public void enqueueBig(int i, int i2, int i3, int i4, byte[] bArr, BitmapTools.TJ_BitmapType tJ_BitmapType) {
UserError.Log.d("BlueJayServiceR", "Big enqueue for: " + i + " " + i2 + " w:" + i3 + " h:" + i4 + " size: " + bArr.length);
ImageSegment imageSegment = new ImageSegment(i3, i4, i, i2, bArr, tJ_BitmapType);
Pair<Integer, Integer> bestProgressionParameters = getBestProgressionParameters(i3, i4, tJ_BitmapType);
processSegmentProgression(imageSegment, ((Integer) bestProgressionParameters.first).intValue(), ((Integer) bestProgressionParameters.second).intValue());
}
public byte[] cropRGB565(int i, int i2, int i3, int i4, int i5, int i6, byte[] bArr) {
int i7;
int i8;
byte[] bArr2 = new byte[i3 * i4 * 2];
int i9 = i5 * 2;
int i10 = (i * 2) + (i2 * i9);
int i11 = 0;
try {
UserError.Log.d("BlueJayServiceR", "cropRGB565 Start ptr: " + i10);
i7 = 0;
int i12 = 0;
while (i7 < i4) {
i8 = 0;
while (i8 < i3 * 2) {
int i13 = i12 + 1;
try {
bArr2[i12] = bArr[i10 + i8];
i8++;
i12 = i13;
} catch (ArrayIndexOutOfBoundsException unused) {
i11 = i13;
UserError.Log.wtf("BlueJayServiceR", "ARRAY OUT OF BOUNDS: @ p" + i11 + " start_pyt:" + i10 + " i:" + i8 + " j:" + i7 + " " + i + " " + i2 + " " + i3 + " " + i4 + " " + i5 + " " + i6 + " " + bArr.length);
return bArr2;
}
}
i10 += i9;
i7++;
}
} catch (ArrayIndexOutOfBoundsException unused2) {
i7 = 0;
i8 = 0;
}
return bArr2;
}
private static int getMaxBackFillHours() {
int i = Pref.getInt("bluejay_backfill_hours", 3);
if (i == 0) {
return 1;
}
return i;
}
public void scheduleInterimEvents() {
if (JoH.pratelimit("bluejay-interim-events", 600)) {
UserError.Log.d("BlueJayServiceR", "Interim event trigger");
schedulePeriodicEvents();
doQueue();
}
}
public void schedulePeriodicEvents() {
BlueJayInfo info = getInfo();
if (info.status1Due()) {
getStatus1();
if (Home.get_engineering_mode()) {
getStatus3();
}
}
if (BlueJay.isCollector() && info.status2Due()) {
getStatus2();
}
if (info.isTimeSetDue()) {
setTime();
}
if (info.isDisplayUpdatedue() && BlueJay.shouldSendReadings()) {
Inevitable.task("bj-periodic-display-update", 3000L, new NewDataObserver$$ExternalSyntheticLambda2());
}
if (BlueJay.isCollector() && JoH.msSince(lastUsableGlucoseTimestamp) < 1200000) {
Pair<Long, Long> backFillStatus = getBackFillStatus();
if (((Long) backFillStatus.first).longValue() > 0 && backFillOkayToAsk(((Long) backFillStatus.first).longValue())) {
int msSince = (int) ((JoH.msSince(((Long) backFillStatus.first).longValue()) / 300000) + 2);
UserError.Log.d("BlueJayServiceR", "Earliest backfill time: " + JoH.dateTimeText(((Long) backFillStatus.first).longValue()) + " Would like " + msSince + " backfill records");
getBackFill(Math.min(msSince, getMaxBackFillHours() * recordsPerHour()));
}
} else {
UserError.Log.d("BlueJayServiceR", "Not checking for backfill data as bluejay is not set as collector or doesn't have recent good data, last timestamp: " + JoH.dateTimeText(lastUsableGlucoseTimestamp));
}
UserError.Log.d("BlueJayServiceR", "schedule periodic events done");
changeNextState();
}
public synchronized void processQueue() {
ConcurrentLinkedQueue<ThinJamItem> concurrentLinkedQueue = commandQueue;
ThinJamItem peek = concurrentLinkedQueue.peek();
if (peek != null) {
if (peek.retryCounterOk()) {
runQueueItem(peek);
} else {
UserError.Log.d("BlueJayServiceR", "ThinJam queue item exceeded retries - removing");
concurrentLinkedQueue.poll();
Inevitable.task("tj-next-queue", 500L, new BlueJayService$$ExternalSyntheticLambda4(this));
}
} else {
UserError.Log.d("BlueJayServiceR", "Queue is empty");
if (this.postQueueRunnable != null) {
this.postQueueRunnable.run();
}
}
}
private void invalidateCache() {
getInfo().invalidateStatus();
getInfo().invalidateTime();
}
private synchronized void sendOtaChunks(final List<byte[]> list) {
Thread thread = new Thread(new Runnable() {
@Override
public final void run() {
BlueJayService.this.lambda$sendOtaChunks$2(list);
}
});
thread.setPriority(10);
thread.start();
}
public void lambda$sendOtaChunks$2(final List list) {
boolean z;
try {
flashIsRunning = true;
UserError.Log.d("BlueJayServiceR", "Running on thread: " + Thread.currentThread());
if (list == null) {
UserError.Log.e("BlueJayServiceR", "OTA chunks null");
return;
}
UserError.Log.d("BlueJayServiceR", "Running OTA sequence");
doSafetyQueue();
JoH.threadSleep(2000L);
addToLog("Starting to send firmware data\n");
Iterator it = list.iterator();
int i = 0;
int i2 = 0;
while (true) {
if (!it.hasNext()) {
break;
}
byte[] bArr = (byte[]) it.next();
busy = true;
if (!sendOtaChunk(Const.THINJAM_OTA, bArr)) {
UserError.Log.d("BlueJayServiceR", "Failed to send OTA chunk: " + i);
busy = false;
break;
}
long tsl = JoH.tsl() + 20000;
while (busy && this.I.isConnected) {
if (JoH.tsl() > tsl) {
z = true;
break;
}
JoH.threadSleep(20L);
}
z = false;
if (z) {
UserError.Log.e("BlueJayServiceR", "Timed out during send: " + i);
busy = false;
break;
}
if (i < 200) {
JoH.threadSleep(200 - i);
}
i++;
final int i3 = i2 + 1;
if (i2 % 30 == 1 && this.progressIndicator != null) {
JoH.runOnUiThreadDelayed(new Runnable() {
@Override
public final void run() {
BlueJayService.this.lambda$sendOtaChunks$1(i3, list);
}
}, 100L);
}
i2 = i3;
}
if (i == list.size()) {
UserError.Log.d("BlueJayServiceR", "ALL CHUNKS SENT");
addToLog("All firmware data sent\n");
} else {
UserError.Log.d("BlueJayServiceR", "ERROR SENDING CHUNKS: " + i + " vs " + list.size());
addToLog("Failed to send all firmware data\n");
}
invalidateCache();
JoH.threadSleep(10000L);
try {
this.progressIndicator.set(0);
this.progressIndicator = null;
} catch (NullPointerException unused) {
}
Inevitable.task("bj-recheck-status", 500L, new Runnable() {
@Override
public final void run() {
BlueJayService.this.getStatus();
}
});
} finally {
flashIsRunning = false;
}
}
public void lambda$sendOtaChunks$1(int i, List list) {
this.progressIndicator.set(Integer.valueOf(((i * 100) / list.size()) + 1));
}
boolean sendOtaChunk(UUID uuid, byte[] bArr) {
if (this.I.connection == null || !this.I.isConnected) {
return false;
}
this.I.connection.writeCharacteristic(uuid, bArr).observeOn(Schedulers.io()).subscribeOn(Schedulers.io()).subscribe(new Consumer() {
public final void accept(Object obj) {
BlueJayService.busy = false;
}
}, new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$sendOtaChunk$4((Throwable) obj);
}
});
return true;
}
public void lambda$sendOtaChunk$4(Throwable th) throws Exception {
UserError.Log.e("BlueJayServiceR", "Failed to write record request: " + th);
if (th instanceof BleGattCharacteristicException) {
UserError.Log.e("BlueJayServiceR", "Got status message: " + Helper.getStatusName(((BleGattCharacteristicException) th).getStatus()));
return;
}
if (th instanceof BleDisconnectedException) {
changeState("Closing");
}
UserError.Log.d("BlueJayServiceR", "Throwable in Record End write: " + th);
}
private void bulkSend(final int i, final byte[] bArr, final int i2, final boolean z) {
UserError.Log.d("BlueJayServiceR", "bulksend called: opcode " + i + " total " + bArr.length + " offset: " + i2 + " quiet:" + z);
if (i2 < bArr.length) {
final BulkUpTx rBulkUpTx = i >= 132 ? new RBulkUpTx(i, bArr, i2) : new BulkUpTx(i, bArr, i2);
if (z) {
rBulkUpTx.setQuiet();
}
if (i2 == 0) {
this.revisedOffset = 0;
this.lastActionedRevisedOffset = -1;
}
this.I.connection.writeCharacteristic(z ? Const.THINJAM_BULK : Const.THINJAM_WRITE, rBulkUpTx.getBytes()).observeOn(Schedulers.newThread()).subscribe(new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$bulkSend$5(rBulkUpTx, i2, bArr, z, i, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
BlueJayService.lambda$bulkSend$6((Throwable) obj);
}
});
return;
}
UserError.Log.d("BlueJayServiceR", "Invalid buffer in bulkSend");
Inevitable.task("tj-next-queue", 4000L, new BlueJayService$$ExternalSyntheticLambda4(this));
}
public void lambda$bulkSend$5(BulkUpTx bulkUpTx, int i, byte[] bArr, boolean z, int i2, byte[] bArr2) throws Exception {
int bytesIncluded;
if (bulkUpTx.responseOk(bArr2)) {
if (this.revisedOffset != 0 && this.revisedOffset < i && this.revisedOffset != this.lastActionedRevisedOffset) {
bytesIncluded = this.revisedOffset;
this.lastActionedRevisedOffset = bytesIncluded;
UserError.Log.d("BlueJayServiceR", "Retrying bulk send from: " + bytesIncluded);
} else {
bytesIncluded = i + bulkUpTx.getBytesIncluded();
}
this.revisedOffset = 0;
if (bytesIncluded < bArr.length) {
if (!z) {
JoH.threadSleep(100L);
} else {
JoH.threadSleep(1L);
}
bulkSend(i2, bArr, bytesIncluded, bulkUpTx.isQuiet());
return;
}
UserError.Log.d("BlueJayServiceR", "Bulk send completed!");
if (!(bulkUpTx instanceof RBulkUpTx)) {
commandQueue.poll();
Inevitable.task("tj-next-queue", 10L, new BlueJayService$$ExternalSyntheticLambda4(this));
return;
} else {
Inevitable.task("tj-next-queue", 4000L, new BlueJayService$$ExternalSyntheticLambda4(this));
return;
}
}
UserError.Log.d("BlueJayServiceR", "Bulk Send failed: " + bulkUpTx.responseText(bArr2));
if (!z) {
Inevitable.task("tj-next-queue", 20000L, new BlueJayService$$ExternalSyntheticLambda4(this));
if (JoH.ratelimit("tj-allow-bulk-retry", 2)) {
UserError.Log.d("BlueJayServiceR", "Retrying packet");
bulkSend(i2, bArr, i, z);
return;
}
return;
}
UserError.Log.d("BlueJayServiceR", "Quiet is set so not attempting any response to failure here");
}
public static void lambda$bulkSend$6(Throwable th) throws Exception {
UserError.Log.e("BlueJayServiceR", "Failed to write bulk Send: " + th);
if (th instanceof BleGattCharacteristicException) {
UserError.Log.e("BlueJayServiceR", "Got status message: " + Helper.getStatusName(((BleGattCharacteristicException) th).getStatus()));
return;
}
UserError.Log.d("BlueJayServiceR", "Throwable in Bulk SEnd write: " + th);
}
public synchronized void requestBulk(final ThinJamItem thinJamItem) {
if (thinJamItem.buffer == null) {
UserError.Log.d("BlueJayServiceR", "ThinJamItem buffer is null! " + thinJamItem.toS());
return;
}
if (thinJamItem.inProgress) {
UserError.Log.d("BlueJayServiceR", "Blocking duplicate request for in progress item: " + thinJamItem.queuedTimestamp);
return;
}
thinJamItem.inProgress = true;
final BulkUpRequestTx bulkUpRequestTx = new BulkUpRequestTx(thinJamItem.type, thinJamItem.getId(), BulkUpRequestTx.encodeLength(thinJamItem.sequence, thinJamItem.buffer.length), thinJamItem.buffer, thinJamItem.quiet);
if (this.I.connection == null) {
thinJamItem.inProgress = false;
UserError.Log.d("BlueJayServiceR", "Connection is null skipping");
}
this.I.connection.writeCharacteristic(Const.THINJAM_WRITE, bulkUpRequestTx.getBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$requestBulk$8(bulkUpRequestTx, thinJamItem, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
BlueJayService.lambda$requestBulk$9(BlueJayService.ThinJamItem.this, (Throwable) obj);
}
});
}
public void lambda$requestBulk$8(BulkUpRequestTx bulkUpRequestTx, final ThinJamItem thinJamItem, byte[] bArr) throws Exception {
if (bulkUpRequestTx.responseOk(bArr)) {
lastBulkOk = JoH.tsl();
UserError.Log.d("BlueJayServiceR", "Bulk channel opcode: " + bulkUpRequestTx.getBulkUpOpcode(bArr));
bulkSend(bulkUpRequestTx.getBulkUpOpcode(bArr), thinJamItem.buffer, 15, thinJamItem.quiet);
} else {
UserError.Log.d("BlueJayServiceR", "Bulk request failed: " + bulkUpRequestTx.responseText(bArr));
if (bulkUpRequestTx.responseText(bArr).toLowerCase().contains("busy") && thinJamItem.retryCounterOk()) {
UserError.Log.d("BlueJayServiceR", "Device is busy, scheduling retry");
Inevitable.task("bulk-retry-" + thinJamItem.toS(), 3000L, new Runnable() {
@Override
public final void run() {
BlueJayService.this.lambda$requestBulk$7(thinJamItem);
}
});
} else if (bulkUpRequestTx.responseText(bArr).toLowerCase().contains("out of range") || bulkUpRequestTx.responseText(bArr).toLowerCase().contains("unknown error")) {
UserError.Log.d("BlueJayServiceR", "Setting item to not retry again due to out of range");
thinJamItem.inProgress = false;
thinJamItem.dontRetryAgain();
Inevitable.task("tj-next-queue", 0L, new BlueJayService$$ExternalSyntheticLambda4(this));
}
}
thinJamItem.inProgress = false;
}
public void lambda$requestBulk$7(ThinJamItem thinJamItem) {
UserError.Log.d("BlueJayServiceR", "Retrying requestBulk: " + thinJamItem.toS());
thinJamItem.inProgress = false;
requestBulk(thinJamItem);
}
public static void lambda$requestBulk$9(ThinJamItem thinJamItem, Throwable th) throws Exception {
UserError.Log.e("BlueJayServiceR", "Failed to write bulk request: " + th);
if (th instanceof BleGattCharacteristicException) {
UserError.Log.e("BlueJayServiceR", "Got status message: " + Helper.getStatusName(((BleGattCharacteristicException) th).getStatus()));
} else {
UserError.Log.d("BlueJayServiceR", "Throwable in Bulk End write: " + th);
}
thinJamItem.inProgress = false;
}
public void doQueue() {
((ThinJamState) this.mState).getPacketQueueSequence();
changeState("Initializing");
}
public void doThinJamQueue() {
((ThinJamState) this.mState).thinJamQueueSequence();
changeState("Initializing");
}
public void doSafetyQueue() {
((ThinJamState) this.mState).getPacketQueueSequence();
}
public void doOtaMain() {
otaFlashUpdate(1);
}
public void doOtaCore() {
otaFlashUpdate(2);
}
public void otaFlashUpdate(int i) {
addToLog("OTA flash request: " + i);
final byte[] latestFirmwareBytes = FirmwareDownload.getLatestFirmwareBytes(this.I.address, i);
StringBuilder sb = new StringBuilder();
sb.append("Got bytes: ");
sb.append(latestFirmwareBytes != null ? Integer.valueOf(latestFirmwareBytes.length) : "null!");
UserError.Log.d("BlueJayServiceR", sb.toString());
if (latestFirmwareBytes != null) {
Inevitable.task("bluejay-background-fw-up,", 200L, new Runnable() {
@Override
public final void run() {
BlueJayService.this.lambda$otaFlashUpdate$10(latestFirmwareBytes);
}
});
} else {
addToLog("Unable to get firmware for update");
}
}
public void lambda$otaFlashUpdate$10(byte[] bArr) {
sendOtaChunks(BlueJayFirmware.split(BlueJayFirmware.parse(bArr)));
}
private void sendTime() {
final SetTimeTx setTimeTx = new SetTimeTx();
UserError.Log.d("BlueJayServiceR", "Outbound: " + JoH.bytesToHex(setTimeTx.getBytes()));
this.I.connection.writeCharacteristic(Const.THINJAM_WRITE, setTimeTx.getBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$sendTime$11(setTimeTx, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$sendTime$12((Throwable) obj);
}
});
}
public void lambda$sendTime$11(SetTimeTx setTimeTx, byte[] bArr) throws Exception {
SetTimeTx setTimeTx2 = new SetTimeTx(bArr);
UserError.Log.e("BlueJayServiceR", "Time difference with watch: " + ((setTimeTx.getTimestamp() - setTimeTx2.getTimestamp()) / 1000.0d));
changeNextState();
}
public void lambda$sendTime$12(Throwable th) throws Exception {
UserError.Log.e("BlueJayServiceR", "Failed to write SetTime request: " + th);
if (th instanceof BleGattCharacteristicException) {
UserError.Log.e("BlueJayServiceR", "Got status message: " + Helper.getStatusName(((BleGattCharacteristicException) th).getStatus()));
return;
}
UserError.Log.d("BlueJayServiceR", "Throwable in SetTime " + th);
if (th instanceof BleCharacteristicNotFoundException) {
UserError.Log.d("BlueJayServiceR", "Assuming wrong firmware version");
changeNextState();
} else {
changeState("Closing");
}
}
public void sendNotification(java.lang.String r9, java.lang.String r10) {
throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.watch.thinjam.BlueJayService.sendNotification(java.lang.String, java.lang.String):void");
}
private void sendPng(BitmapTools.Wrapper wrapper) {
if (wrapper != null) {
enqueueWrappedBitmap(wrapper, 0, BlueJayInfo.getInfo(this.I.address).buildNumber > 2000 ? 199 : 110);
doThinJamQueue();
} else {
UserError.Log.d("BlueJayServiceR", "Null bitmap in sendPng:");
}
}
private void sendColourPng(byte[] bArr, String str) {
sendPng(BitmapTools.loadPNGBytesToRGB565(bArr));
}
private void sendMonoPng(byte[] bArr, String str) {
sendPng(BitmapTools.convertWrappedToMono(BitmapTools.loadPNGBytesToRGB565(bArr)));
}
public void addToLog(String str) {
this.notificationString.append(str);
this.notificationString.append("\n");
Inevitable.task("tj update notifi", 250L, new Runnable() {
@Override
public void run() {
BlueJayService blueJayService = BlueJayService.this;
blueJayService.stringObservableField.set(blueJayService.notificationString.toString());
}
});
}
static class AnonymousClass23 {
static final int[] $SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type;
static final int[] $SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$utils$BitmapTools$TJ_BitmapType;
static {
int[] iArr = new int[PushRx.Type.values().length];
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type = iArr;
try {
iArr[PushRx.Type.LongPress1.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[PushRx.Type.BackFill.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[PushRx.Type.Choice.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[PushRx.Type.AssetRequest.ordinal()] = 4;
} catch (NoSuchFieldError unused4) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[PushRx.Type.CarbInfo.ordinal()] = 5;
} catch (NoSuchFieldError unused5) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[PushRx.Type.InsulinInfo.ordinal()] = 6;
} catch (NoSuchFieldError unused6) {
}
int[] iArr2 = new int[BitmapTools.TJ_BitmapType.values().length];
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$utils$BitmapTools$TJ_BitmapType = iArr2;
try {
iArr2[BitmapTools.TJ_BitmapType.RGB565.ordinal()] = 1;
} catch (NoSuchFieldError unused7) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$utils$BitmapTools$TJ_BitmapType[BitmapTools.TJ_BitmapType.Mono.ordinal()] = 2;
} catch (NoSuchFieldError unused8) {
}
}
}
public void processPushRxActions(PushRx pushRx) {
long j = 0;
switch (AnonymousClass23.$SwitchMap$com$eveningoutpost$dexdrip$watch$thinjam$messages$PushRx$Type[pushRx.type.ordinal()]) {
case 1:
lastLongPress1 = JoH.tsl();
if (JoH.msSince(awaiting_easy_auth) < 300000) {
addToLog("Processing easy auth");
awaiting_easy_auth = 0L;
easyAuth();
return;
}
if (!AlertPlayer.getPlayer().OpportunisticSnooze() && JoH.pratelimit("bluejay-snooze", 60)) {
if (Pusher.enabled()) {
UserError.Log.d("BlueJayServiceR", "Attempting full snooze");
AlertPlayer.getPlayer().Snooze(xdrip.getAppContext(), -1);
} else {
UserError.Log.d("BlueJayServiceR", "xDrip cloud not enabled so avoiding networked snooze");
}
}
BroadcastSnooze.send();
BlueJayEmit.sendButtonPress(1);
return;
case 2:
boolean z = false;
boolean z2 = false;
boolean z3 = false;
for (PushRx.BackFillRecord backFillRecord : pushRx.backfills) {
long msSince = JoH.msSince(backFillRecord.timestamp);
if (msSince > 21600000 || msSince < j) {
UserError.Log.wtf("BlueJayServiceR", "Backfill timestamp unrealistic: " + JoH.dateTimeText(backFillRecord.timestamp) + " (ignored)");
} else {
if (backFillRecord.mgdl > 12 && BgReading.getForPreciseTimestamp(backFillRecord.timestamp, 240000L, z) == null) {
try {
BgReading.bgReadingInsertFromG5(backFillRecord.mgdl, backFillRecord.timestamp, "Backfill").appendSourceInfo("BlueJay", true);
UserError.Log.d("BlueJayServiceR", "Adding backfilled reading: " + JoH.dateTimeText(backFillRecord.timestamp) + " " + Unitized.unitized_string_static(backFillRecord.mgdl));
if (msSince < 60000) {
lastUsableGlucoseTimestamp = backFillRecord.timestamp;
z3 = true;
}
z2 = true;
} catch (NullPointerException unused) {
UserError.Log.e("BlueJayServiceR", "Got null pointer when trying to add backfilled data");
}
}
UserError.Log.d("BlueJayServiceR", "Backsie: " + JoH.dateTimeText(backFillRecord.timestamp) + " " + Unitized.unitized_string_static(backFillRecord.mgdl));
}
z = false;
j = 0;
}
if (z2) {
Home.staticRefreshBGChartsOnIdle();
scheduleInterimEvents();
}
if (!z3 && JoH.quietratelimit("bluejay-backfill-received", 20)) {
backFillReceived();
break;
}
break;
case 3:
UserError.Log.d("BlueJayServiceR", "Push Choice: " + pushRx.value + " :: " + pushRx.text);
BlueJayEmit.sendChoice(pushRx.getValue(), pushRx.text);
break;
case 4:
UserError.Log.d("BlueJayServiceR", "Asset request: " + pushRx.value);
BlueJayAsset.queueAssetRequest(pushRx.getValue());
if (commandQueue.size() == 0 || JoH.msSince(lastBulkOk) > 60000) {
BlueJayAsset.processAssetQueue(this);
break;
}
break;
case 5:
UserError.Log.d("BlueJayServiceR", "Carb info: " + pushRx.getNumber() + " " + JoH.dateTimeText(pushRx.getTimestamp()));
Treatments.create(pushRx.getNumber(), BgReading.BESTOFFSET, pushRx.getTimestamp());
break;
case 6:
UserError.Log.d("BlueJayServiceR", "Insulin info: " + pushRx.getNumber() + " " + JoH.dateTimeText(pushRx.getTimestamp()));
Treatments.create(BgReading.BESTOFFSET, pushRx.getNumber(), pushRx.getTimestamp());
break;
}
}
private void enableNotifications() {
UserError.Log.d("BlueJayServiceR", "enableNotifications called()");
if (this.I.isNotificationEnabled) {
UserError.Log.d("BlueJayServiceR", "Notifications already enabled");
changeNextState();
return;
}
if (this.notificationSubscription != null) {
this.notificationSubscription.unsubscribe();
}
JoH.threadSleep(500L);
UserError.Log.d("BlueJayServiceR", "Requesting to enable notifications");
if (this.I.connection == null) {
UserError.Log.d("BlueJayServiceR", "Connection went away before we could enable notifications");
} else {
this.notificationSubscription = new Subscription(this.I.connection.setupNotification(Const.THINJAM_WRITE).observeOn(Schedulers.newThread()).doOnNext(new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$enableNotifications$13((Observable) obj);
}
}).flatMap(new Function() {
public final Object apply(Object obj) {
ObservableSource lambda$enableNotifications$14;
lambda$enableNotifications$14 = BlueJayService.lambda$enableNotifications$14((Observable) obj);
return lambda$enableNotifications$14;
}
}).observeOn(Schedulers.newThread()).subscribe(new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$enableNotifications$15((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
BlueJayService.this.lambda$enableNotifications$16((Throwable) obj);
}
}));
}
}
public void lambda$enableNotifications$13(Observable observable) throws Exception {
UserError.Log.d("BlueJayServiceR", "Notifications enabled");
this.I.connection.writeCharacteristic(Const.THINJAM_BULK, new byte[]{85});
JoH.threadSleep(500L);
this.I.isNotificationEnabled = true;
changeNextState();
}
public void lambda$enableNotifications$15(byte[] bArr) throws Exception {
UserError.Log.d("BlueJayServiceR", "Received notification bytes: " + JoH.bytesToHex(bArr));
PushRx parse = PushRx.parse(bArr);
if (parse != null) {
UserError.Log.d("BlueJayServiceR", "Received PushRX: " + parse.toS());
getInfo().processPushRx(parse);
processPushRxActions(parse);
return;
}
byte b = bArr[0];
if (b != 6) {
if (b == -2) {
audioStreamCallBack(bArr);
return;
} else {
if (ThinJamActivity.isD()) {
this.notificationString.append(new String(bArr));
Inevitable.task("tj update notifi", 250L, new Runnable() {
@Override
public void run() {
BlueJayService blueJayService = BlueJayService.this;
blueJayService.stringObservableField.set(blueJayService.notificationString.toString());
}
});
return;
}
return;
}
}
int i = bArr[1] & 255;
if (i == 0) {
UserError.Log.d("BlueJayServiceR", "Bulk up success reply marker received! - removing queue head item");
commandQueue.poll();
UserError.Log.d("BlueJayServiceR", "Scheduling immediate run of queue");
Inevitable.kill("tj-next-queue");
Inevitable.task("tj-next-queue", 0L, new BlueJayService$$ExternalSyntheticLambda4(this));
return;
}
this.revisedOffset = i;
UserError.Log.d("BlueJayServiceR", "Bulk up failure at: " + this.revisedOffset);
}
public void lambda$enableNotifications$16(Throwable th) throws Exception {
UserError.Log.d("BlueJayServiceR", "Throwable in Record Notification: " + th);
this.I.isNotificationEnabled = false;
if (th instanceof BleCharacteristicNotFoundException) {
UserError.Log.d("BlueJayServiceR", "Characteristic not found for notification");
this.debug.processTestSuite("logcharerror");
tryGattRefresh(getI().connection);
}
if (th instanceof BleCannotSetCharacteristicNotificationException) {
UserError.Log.e("BlueJayServiceR", "Problems setting notifications - disconnecting");
changeState("Closing");
}
if (th instanceof BleDisconnectedException) {
UserError.Log.d("BlueJayServiceR", "Disconnected while enabling notifications");
changeState("Closing");
}
}
void queueBufferForAssetStorage(int i, byte[] bArr) {
UserError.Log.d("BlueJayServiceR", "QUEUE BUFFER FOR ASSET STORAGE: " + i + " " + bArr.length);
if (bArr.length > 65535) {
throw new RuntimeException("To big for page");
}
commandQueue.clear();
int i2 = 1;
while (bArr.length > 0) {
byte[] copyOfRange = Arrays.copyOfRange(bArr, 0, Math.min(bArr.length, ChunkCopyBehaviour.COPY_ALMOSTALL));
UserError.Log.d("BlueJayServiceR", "Buffer Chunk size: " + copyOfRange.length);
bArr = Arrays.copyOfRange(bArr, copyOfRange.length, bArr.length);
UserError.Log.d("BlueJayServiceR", "buffer size remaining: " + bArr.length + " chunk: " + i2);
commandQueue.add(new ThinJamItem(0, 0, 0, 0, copyOfRange).setSpecificId(((i >> 7) & 255) | (-128)).setType(i & 127).useAck().setSequence(i2));
i2++;
}
}
private synchronized void runQueueItem(final ThinJamItem thinJamItem) {
UserError.Log.d("BlueJayServiceR", "Running queue item queued: " + thinJamItem.queuedTimestamp);
int i = thinJamItem.width;
if (i > 0) {
final DefineWindowTx defineWindowTx = new DefineWindowTx((byte) 1, (byte) thinJamItem.windowType, (byte) thinJamItem.x, (byte) thinJamItem.y, (byte) i, (byte) thinJamItem.height, (byte) 0, (byte) thinJamItem.colourEffect);
queueGenericCommand(defineWindowTx.getBytes(), "define window: (" + thinJamItem.windowType + ") " + thinJamItem.x + "," + thinJamItem.y + " w:" + thinJamItem.width + " h:" + thinJamItem.height, null, getARInstance(new ReplyProcessor(this.I.connection) {
@Override
public void process(byte[] bArr) {
if (defineWindowTx.responseOk(bArr)) {
BlueJayService.this.requestBulk(thinJamItem);
return;
}
UserError.Log.d("BlueJayServiceR", "Define Window failed: " + defineWindowTx.responseText(bArr));
}
}));
} else {
requestBulk(thinJamItem);
}
}
@Override
public int onStartCommand(android.content.Intent r8, int r9, int r10) {
throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.watch.thinjam.BlueJayService.onStartCommand(android.content.Intent, int, int):int");
}
private boolean shouldServiceRun() {
return BlueJayEntry.isEnabled();
}
public class LocalBinder extends Binder {
public LocalBinder() {
}
public BlueJayService getService() {
return BlueJayService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return this.binder;
}
private boolean flashRunning() {
return flashIsRunning;
}
static class ThinJamState extends JamBaseBluetoothSequencer.BaseState {
ThinJamState() {
setTimeSequence();
}
void setTimeSequence() {
UserError.Log.d("BlueJayServiceR", "SET TIME SEQUENCE");
this.sequence.clear();
this.sequence.add("Initializing");
this.sequence.add("Connecting");
this.sequence.add("Discover Services");
this.sequence.add("Schedule Items");
this.sequence.add("Set Time");
this.sequence.add("Sleeping");
}
void thinJamQueueSequence() {
UserError.Log.d("BlueJayServiceR", "RUN QUEUE SEQUENCE");
this.sequence.clear();
this.sequence.add("Initializing");
this.sequence.add("Connecting");
this.sequence.add("Discover Services");
this.sequence.add("Enable Notifications");
this.sequence.add("Run Queue");
this.sequence.add("Sleeping");
}
void getPacketQueueSequence() {
this.sequence.clear();
this.sequence.add("Initializing");
this.sequence.add("Connecting");
this.sequence.add("Discover Services");
this.sequence.add("Enable Notifications");
this.sequence.add("Schedule Items");
this.sequence.add("Sending Queue");
this.sequence.add("Sleeping");
}
}
@Override
protected synchronized boolean automata() {
char c;
extendWakeLock(1000L);
if (shouldServiceRun()) {
String str = this.I.state;
switch (str.hashCode()) {
case -1953718728:
if (str.equals("OTA UI")) {
c = 7;
break;
}
c = 65535;
break;
case -1828736507:
if (str.equals("Log Tests")) {
c = '\b';
break;
}
c = 65535;
break;
case -1600768752:
if (str.equals("Prototype Test")) {
c = 6;
break;
}
c = 65535;
break;
case -1321219637:
if (str.equals("Sleeping")) {
c = '\t';
break;
}
c = 65535;
break;
case -1153287029:
if (str.equals("Sending Queue")) {
c = 11;
break;
}
c = 65535;
break;
case -301350148:
if (str.equals("Run Queue")) {
c = 4;
break;
}
c = 65535;
break;
case -235759507:
if (str.equals("Initializing")) {
c = 0;
break;
}
c = 65535;
break;
case 75952821:
if (str.equals("Discover Services")) {
c = 1;
break;
}
c = 65535;
break;
case 1421069323:
if (str.equals("Set Time")) {
c = 5;
break;
}
c = 65535;
break;
case 1922751735:
if (str.equals("Schedule Items")) {
c = 3;
break;
}
c = 65535;
break;
case 2021313932:
if (str.equals("Closed")) {
c = '\n';
break;
}
c = 65535;
break;
case 2121003275:
if (str.equals("Enable Notifications")) {
c = 2;
break;
}
c = 65535;
break;
default:
c = 65535;
break;
}
switch (c) {
case 0:
changeNextState();
break;
case 1:
if (JoH.msSince(this.I.getLastConnected()) < 500) {
connectionTracker.add(1.0d);
}
return super.automata();
case 2:
enableNotifications();
break;
case 3:
cancelRetryTimer();
if (commandQueue.peek() == null) {
schedulePeriodicEvents();
break;
} else {
UserError.Log.d("BlueJayServiceR", "Skipping schedule items as queue is not empty");
changeNextState();
break;
}
case 4:
cancelRetryTimer();
processQueue();
break;
case 5:
sendTime();
break;
case 6:
break;
case 7:
this.debug.processTestSuite("otaprototype-pending");
break;
case '\b':
this.debug.processTestSuite("gl");
break;
case '\t':
cancelRetryTimer();
return super.automata();
case '\n':
setRetryTimerReal();
this.I.isNotificationEnabled = false;
this.I.discoverOnce = false;
return super.automata();
case 11:
if (!flashRunning()) {
return super.automata();
}
UserError.Log.d("BlueJayServiceR", "Not sending queue as firmware update in progress");
break;
default:
return super.automata();
}
} else {
UserError.Log.d("BlueJayServiceR", "Service should not be running inside automata");
stopSelf();
}
return true;
}
void checkConnection() {
if (this.I.isConnected) {
return;
}
UserError.Log.d("BlueJayServiceR", "Attempting connect as we are not connected");
changeState("Initializing");
}
@Override
public void btCallback(String str, String str2) {
UserError.Log.d("BlueJayServiceR", "Ignoring callback: " + str + " :: " + str2);
}
@Override
protected void onServicesDiscovered(RxBleDeviceServices rxBleDeviceServices) {
super.onServicesDiscovered(rxBleDeviceServices);
Iterator it = rxBleDeviceServices.getBluetoothGattServices().iterator();
while (it.hasNext()) {
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : ((BluetoothGattService) it.next()).getCharacteristics()) {
for (UUID uuid : huntCharacterstics) {
if (bluetoothGattCharacteristic.getUuid().equals(uuid)) {
this.I.readCharacteristic = uuid;
}
}
}
}
this.I.isDiscoveryComplete = true;
this.I.discoverOnce = true;
changeNextState();
}
@Override
protected void setRetryTimerReal() {
if (shouldServiceRun()) {
long whenToRetryNext = whenToRetryNext();
UserError.Log.d("BlueJayServiceR", "setRetryTimer: Restarting in: " + (whenToRetryNext / 1000) + " seconds");
this.I.serviceIntent = WakeLockTrampoline.getPendingIntent(getClass(), 1025, "wakeup");
this.I.retry_time = JoH.wakeUpIntent(xdrip.getAppContext(), whenToRetryNext, this.I.serviceIntent);
this.I.wakeup_time = JoH.tsl() + whenToRetryNext;
return;
}
UserError.Log.d("BlueJayServiceR", "Not setting retry timer as service should not be running");
}
private void cancelRetryTimer() {
JoH.cancelAlarm(xdrip.getAppContext(), this.I.serviceIntent);
this.I.wakeup_time = 0L;
}
public AuthReplyProcessor getARInstance(ReplyProcessor replyProcessor) {
return new AuthReplyProcessor(replyProcessor);
}
class AuthReplyProcessor extends ReplyProcessor {
final ReplyProcessor secondary;
public AuthReplyProcessor(ReplyProcessor replyProcessor) {
super(replyProcessor.getConnection());
this.secondary = replyProcessor;
}
@Override
public void process(byte[] bArr) {
if (BlueJayService.this.isAuthRequiredPacket(bArr)) {
UserError.Log.d("BlueJayServiceR", "Authentication is required");
if (getTag() != null) {
BlueJayService.this.authenticate((JamBaseBluetoothSequencer.QueueMe) getTag());
return;
} else if (this.secondary.getTag() != null) {
BlueJayService.this.authenticate((JamBaseBluetoothSequencer.QueueMe) this.secondary.getTag());
return;
} else {
UserError.Log.d("BlueJayServiceR", "AuthReplyProcessor: neither inner or outer contain reference tag for packet");
return;
}
}
UserError.Log.d("BlueJayServiceR", "Authentication is not required");
this.secondary.process(bArr);
}
}
private boolean backFillOkayToAsk(long j) {
if (flashRunning() || !BlueJay.hasIdentityKey()) {
return false;
}
long j2 = PersistentStore.getLong("bluejay-backfill-asked" + this.I.address);
UserError.Log.d("BlueJayServiceR", "Backfill Okay To Ask: " + j + " vs " + j2);
long j3 = j2 / 300000;
if (j / 300000 == j3) {
if (PersistentStore.getLong("bluejay-backfill-received" + this.I.address) / 300000 == j3) {
long j4 = PersistentStore.getLong("bluejay-backfill-counter" + this.I.address);
UserError.Log.d("BlueJayServiceR", "Backfill counter at: " + j4);
if (j4 > 4) {
UserError.Log.d("BlueJayServiceR", "Already received a backfill when asked for: " + JoH.dateTimeText(j));
return false;
}
}
} else {
UserError.Log.d("BlueJayServiceR", "Zero backfill counter");
PersistentStore.setLong("bluejay-backfill-counter" + this.I.address, 0L);
}
PersistentStore.setLong("bluejay-backfill-asked" + this.I.address, j);
return true;
}
private void backFillReceived() {
PersistentStore.setLong("bluejay-backfill-received" + this.I.address, PersistentStore.getLong("bluejay-backfill-asked" + this.I.address));
PersistentStore.incrementLong("bluejay-backfill-counter" + this.I.address);
}
public static List<StatusItem> megaStatus() {
String str;
ArrayList arrayList = new ArrayList();
JamBaseBluetoothSequencer.Inst inst = JamBaseBluetoothSequencer.Inst.get(BlueJayService.class.getSimpleName());
BlueJayInfo info = BlueJayInfo.getInfo(inst.address);
arrayList.add(new StatusItem("Mac address", inst.address));
if (BlueJay.getAuthKey(inst.address) == null) {
arrayList.add(new StatusItem("Pairing", "Not Paired! Tap to pair", StatusItem.Highlight.CRITICAL, "long-press", new Runnable() {
@Override
public final void run() {
ThinJamActivity.requestQrCode();
}
}));
} else if (BlueJay.getIdentityKey(inst.address) == null) {
arrayList.add(new StatusItem("Identity", "Not Identified! Tap to pair", StatusItem.Highlight.CRITICAL, "long-press", new Runnable() {
@Override
public final void run() {
ThinJamActivity.requestQrCode();
}
}));
}
arrayList.add(new StatusItem("Connected", xdrip.gs(inst.isConnected ? 2131757071 : 2131755900)));
if (inst.wakeup_time != 0 && !inst.isConnected) {
long msTill = JoH.msTill(inst.wakeup_time);
if (msTill > 0) {
arrayList.add(new StatusItem("Retry Wake Up", JoH.niceTimeScalar(msTill)));
}
}
if (Home.get_engineering_mode()) {
arrayList.add(new StatusItem("Connections", ((int) connectionTracker.totalRecords()) + " last 20 min"));
if (info.buildNumber >= 2092 && info.fragmentationLevel > 0) {
StringBuilder sb = new StringBuilder();
sb.append(info.fragmentationLevel);
sb.append("% (");
sb.append(info.fragmentationCounter);
sb.append(",");
sb.append(info.fragmentationIndex - 4096);
sb.append(")");
arrayList.add(new StatusItem("Fragmentation", sb.toString(), info.fragmentationLevel > 0 ? StatusItem.Highlight.NOTICE : StatusItem.Highlight.NORMAL));
}
}
arrayList.add(new StatusItem("State", inst.state));
int queueSize = inst.getQueueSize();
int size = commandQueue.size();
if (size > 0 || queueSize > 0) {
if (size > 0) {
arrayList.add(new StatusItem("Queue", "(" + size + ") " + queueSize + " items"));
} else {
arrayList.add(new StatusItem("Queue", queueSize + " items"));
}
}
if (info.hasCoreModule()) {
arrayList.add(new StatusItem("xDrip Core", "Installed", StatusItem.Highlight.GOOD));
} else {
arrayList.add(new StatusItem("xDrip Core", "Not Installed", StatusItem.Highlight.BAD, "long-press", new Runnable() {
@Override
public void run() {
ThinJamActivity.installCorePrompt();
}
}));
}
int captureSuccessPercent = info.captureSuccessPercent();
if (captureSuccessPercent > -1) {
arrayList.add(new StatusItem("Capture Rate", String.format(Locale.US, "%d%% (%d)", Integer.valueOf(captureSuccessPercent), Integer.valueOf(info.successfulReplies))));
}
int i = info.thinJamVersion;
if (i != 2) {
arrayList.add(new StatusItem("ThinJam Version", Integer.valueOf(i), StatusItem.Highlight.NOTICE));
}
long timestamp = info.getTimestamp();
if (timestamp > 0 && timestamp > 1728497951000L) {
arrayList.add(new StatusItem("Last Reading", String.format("%s ago", JoH.niceTimeScalar(JoH.msSince(info.getTimestamp())))));
}
StringBuilder sb2 = new StringBuilder();
sb2.append(info.isChargerConnected() ? "Connected" : "Not connected");
if (!Home.get_engineering_mode() || info.batteryPercent == -1) {
str = "";
} else {
str = " " + info.batteryPercent + "%";
}
sb2.append(str);
arrayList.add(new StatusItem("Charger", sb2.toString()));
arrayList.add(new StatusItem("Uptime", JoH.niceTimeScalar(info.getUptimeTimeStamp())));
int latestMainFirmware = FirmwareInfo.getLatestMainFirmware();
arrayList.add(new StatusItem("Firmware Version", "" + info.buildNumber, info.buildNumber < info.coreNumber ? StatusItem.Highlight.NOTICE : StatusItem.Highlight.NORMAL, "long-press", new Runnable() {
@Override
public void run() {
}
}));
if (latestMainFirmware > info.buildNumber && inst.isConnected && queueSize == 0) {
arrayList.add(new StatusItem("Update Available", "Tap to update " + latestMainFirmware, StatusItem.Highlight.NOTICE, "long-press", new Runnable() {
@Override
public void run() {
ThinJamActivity.updateMainPrompt();
}
}));
}
if (info.coreNumber > 0 && inst.isConnected) {
int latestCoreFirmware = FirmwareInfo.getLatestCoreFirmware();
arrayList.add(new StatusItem("Core Module", "xDrip v" + info.coreNumber, info.coreNumber < info.buildNumber ? StatusItem.Highlight.NOTICE : StatusItem.Highlight.NORMAL, "long-press", new Runnable() {
@Override
public void run() {
}
}));
if (latestCoreFirmware > info.coreNumber && queueSize == 0) {
arrayList.add(new StatusItem("Core Update Available", "Tap to update " + latestCoreFirmware, StatusItem.Highlight.NOTICE, "long-press", new Runnable() {
@Override
public void run() {
ThinJamActivity.updateCorePrompt();
}
}));
}
}
arrayList.add(new StatusItem("Admin Panel", "Tap to open", StatusItem.Highlight.NORMAL, "long-press", new Runnable() {
@Override
public void run() {
JoH.startActivity(ThinJamActivity.class);
}
}));
return arrayList;
}
}