正在查看: xDrip+ v04633772025.07.16 应用的 LeFunService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 LeFunService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.watch.lefun;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.util.Pair;
import androidx.health.platform.client.error.ErrorCode;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.util.HexDump;
import com.eveningoutpost.dexdrip.models.ActiveBgAlert;
import com.eveningoutpost.dexdrip.models.BgReading;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.services.JamBaseBluetoothSequencer;
import com.eveningoutpost.dexdrip.store.FastStore;
import com.eveningoutpost.dexdrip.store.KeyStore;
import com.eveningoutpost.dexdrip.utilitymodels.AlertPlayer;
import com.eveningoutpost.dexdrip.utilitymodels.Inevitable;
import com.eveningoutpost.dexdrip.utilitymodels.StatusItem;
import com.eveningoutpost.dexdrip.utilitymodels.Unitized;
import com.eveningoutpost.dexdrip.utils.framework.IncomingCallsReceiver;
import com.eveningoutpost.dexdrip.utils.framework.WakeLockTrampoline;
import com.eveningoutpost.dexdrip.watch.PrefBindingFactory;
import com.eveningoutpost.dexdrip.watch.lefun.FunAlmanac;
import com.eveningoutpost.dexdrip.watch.lefun.messages.BaseRx;
import com.eveningoutpost.dexdrip.watch.lefun.messages.RxFind;
import com.eveningoutpost.dexdrip.watch.lefun.messages.RxPong;
import com.eveningoutpost.dexdrip.watch.lefun.messages.RxShake;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxAlert;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxPing;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxSetFeatures;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxSetLocaleFeature;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxSetScreens;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxSetTime;
import com.eveningoutpost.dexdrip.watch.lefun.messages.TxShakeDetect;
import com.eveningoutpost.dexdrip.xdrip;
import com.polidea.rxandroidble2.RxBleDeviceServices;
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.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class LeFunService extends JamBaseBluetoothSequencer {
private static final UUID[] huntCharacterstics = {Const.REPLY_CHARACTERISTIC};
private final KeyStore keyStore = FastStore.getInstance();
final Runnable canceller = new Runnable() {
@Override
public final void run() {
LeFunService.this.lambda$new$0();
}
};
public static ObservableSource lambda$enableNotification$2(Observable observable) throws Exception {
return observable;
}
public LeFunService() {
this.mState = new LeFunState().setLI(this.I);
this.I.queue_write_characterstic = Const.WRITE_CHARACTERISTIC;
}
public void lambda$new$0() {
if (ActiveBgAlert.currentlyAlerting() || IncomingCallsReceiver.isRingingNow()) {
return;
}
UserError.Log.d(this.TAG, "Clearing queue as alert / call ceased");
emptyQueue();
}
@Override
public int onStartCommand(android.content.Intent r6, int r7, int r8) {
throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.watch.lefun.LeFunService.onStartCommand(android.content.Intent, int, int):int");
}
@Override
protected void onServicesDiscovered(RxBleDeviceServices rxBleDeviceServices) {
boolean z = false;
for (BluetoothGattService bluetoothGattService : rxBleDeviceServices.getBluetoothGattServices()) {
UserError.Log.d(this.TAG, "Service: " + JamBaseBluetoothSequencer.getUUIDName(bluetoothGattService.getUuid()));
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : bluetoothGattService.getCharacteristics()) {
UserError.Log.d(this.TAG, "-- Character: " + JamBaseBluetoothSequencer.getUUIDName(bluetoothGattCharacteristic.getUuid()));
UUID[] uuidArr = huntCharacterstics;
int length = uuidArr.length;
for (int i = 0; i < length; i++) {
UUID uuid = uuidArr[i];
if (bluetoothGattCharacteristic.getUuid().equals(uuid)) {
this.I.readCharacteristic = uuid;
z = true;
}
}
}
}
if (z) {
this.I.isDiscoveryComplete = true;
enableNotification();
} else {
UserError.Log.e(this.TAG, "Could not find characteristic during service discovery. This is very unusual");
}
}
private void enableNotification() {
UserError.Log.d(this.TAG, "Enabling notifications");
this.I.isNotificationEnabled = false;
if (this.I.connection == null) {
UserError.Log.d(this.TAG, "Cannot enable as connection is null!");
} else if (this.I.readCharacteristic == null) {
UserError.Log.d(this.TAG, "Cannot enable as read characterstic is null");
} else {
this.I.connection.setupNotification(this.I.readCharacteristic).timeout(630L, TimeUnit.SECONDS).doOnNext(new Consumer() {
public final void accept(Object obj) {
LeFunService.this.lambda$enableNotification$1((Observable) obj);
}
}).flatMap(new Function() {
public final Object apply(Object obj) {
ObservableSource lambda$enableNotification$2;
lambda$enableNotification$2 = LeFunService.lambda$enableNotification$2((Observable) obj);
return lambda$enableNotification$2;
}
}).observeOn(Schedulers.newThread()).subscribe(new Consumer() {
public final void accept(Object obj) {
LeFunService.this.lambda$enableNotification$3((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
LeFunService.this.lambda$enableNotification$4((Throwable) obj);
}
});
}
}
public void lambda$enableNotification$1(Observable observable) throws Exception {
this.I.isNotificationEnabled = true;
changeState(this.mState.next());
}
public void lambda$enableNotification$3(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Received data notification bytes: " + HexDump.dumpHexString(bArr));
processAndAction(bArr);
}
public void lambda$enableNotification$4(Throwable th) throws Exception {
if (!(th instanceof TimeoutException)) {
UserError.Log.e(this.TAG, "Throwable inside setup notification: " + th);
} else {
UserError.Log.d(this.TAG, "OUTER TIMEOUT INSIDE NOTIFICATION LISTENER");
}
this.I.isNotificationEnabled = false;
changeState("Closing");
}
private void processAndAction(byte[] bArr) {
JoH.bytesToHex(bArr).hashCode();
BaseRx classify = Classifier.classify(bArr);
if (classify != null) {
UserError.Log.d(this.TAG, "Classified: " + classify.getClass().getSimpleName());
if (classify instanceof RxPong) {
LeFun.setModel(((RxPong) classify).getModel());
} else if (classify instanceof RxShake) {
shakeDetected();
} else if (classify instanceof RxFind) {
findPhone();
}
}
}
private void shakeDetected() {
UserError.Log.d(this.TAG, "Shake detected");
if (LeFun.shakeToSnooze()) {
AlertPlayer.getPlayer().OpportunisticSnooze();
emptyQueue();
UserError.Log.ueh(this.TAG, "Alert snoozed by Shake");
}
}
private void findPhone() {
UserError.Log.d(this.TAG, "Find phone function triggered");
if (!AlertPlayer.getPlayer().OpportunisticSnooze()) {
JoH.showNotification("Find Phone", "Activated from Lefun band", null, 5, true, true, false);
} else {
emptyQueue();
UserError.Log.ueh(this.TAG, "Alert snoozed by Find feature");
}
}
private void sendSettings() {
probeModelTypeIfUnknown();
for (Pair<Integer, Boolean> pair : ((LefunPrefBinding) PrefBindingFactory.getInstance(LefunPrefBinding.class)).getStates("lefun_locale_")) {
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxSetLocaleFeature(((Integer) pair.first).intValue(), ((Boolean) pair.second).booleanValue()).getBytes()).setDescription("Set Locale Features").expectReply().expireInSeconds(30).queue();
}
TxSetScreens txSetScreens = new TxSetScreens();
Iterator<Integer> it = ((LefunPrefBinding) PrefBindingFactory.getInstance(LefunPrefBinding.class)).getEnabled("lefun_screen").iterator();
while (it.hasNext()) {
txSetScreens.enable(it.next().intValue());
}
new JamBaseBluetoothSequencer.QueueMe().setBytes(txSetScreens.getBytes()).setDescription("Set screens for: ").expectReply().expireInSeconds(30).queue();
TxSetFeatures txSetFeatures = new TxSetFeatures();
Iterator<Integer> it2 = ((LefunPrefBinding) PrefBindingFactory.getInstance(LefunPrefBinding.class)).getEnabled("lefun_feature").iterator();
while (it2.hasNext()) {
txSetFeatures.enable(it2.next().intValue());
}
new JamBaseBluetoothSequencer.QueueMe().setBytes(txSetFeatures.getBytes()).setDescription("Set features for: ").expectReply().expireInSeconds(30).send();
}
private void prototype() {
LeFun.sendAlert("TEST", "12.3");
startQueueSend();
}
private void probeModelTypeIfUnknown() {
if (JoH.emptyString(LeFun.getModel())) {
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxPing().getBytes()).setDescription("Set Probe model type").expectReply().expireInSeconds(30).queue();
}
}
private void sendBG() {
FunAlmanac.Reply representation;
BgReading last = BgReading.last();
if (last == null || last.isStale()) {
representation = FunAlmanac.getRepresentation(BgReading.BESTOFFSET);
} else {
representation = FunAlmanac.getRepresentation(JoH.roundDouble(Unitized.mmolConvert(last.getDg_mgdl()), 1));
}
UserError.Log.uel(this.TAG, "Representation for: " + representation.input);
probeModelTypeIfUnknown();
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxSetTime(representation.timestamp, representation.zeroMonth, representation.zeroDay).getBytes()).setDescription("Set display for: " + representation.input).expectReply().expireInSeconds(290).send();
}
private void queueMessage() {
String s = this.keyStore.getS("LeFun-Message");
String s2 = this.keyStore.getS("LeFun-Message-Type");
UserError.Log.d(this.TAG, "Queuing message alert of type: " + s2 + " " + s);
if (!JoH.emptyString(s)) {
probeModelTypeIfUnknown();
if (s2 == null) {
s2 = "null";
}
if (s2.equals("call")) {
for (int i = 0; i < 25; i++) {
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxAlert(s, (byte) 1).getBytes()).setDescription("Send call alert: " + s).expectReply().expireInSeconds(60).setDelayMs(5000).setRunnable(this.canceller).queue();
}
UserError.Log.d(this.TAG, "Queued call alert: " + s);
} else {
for (int i2 = 0; i2 < 5; i2++) {
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxShakeDetect(false).getBytes()).setDescription("Disable Shake detection").expectReply().expireInSeconds(60).setRunnable(this.canceller).queue();
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxAlert(s).getBytes()).setDescription("Send alert: " + s).expectReply().expireInSeconds(60).setDelayMs(LeFun.shakeToSnooze() ? 1500 : 200).queue();
if (LeFun.shakeToSnooze()) {
new JamBaseBluetoothSequencer.QueueMe().setBytes(new TxShakeDetect(true).getBytes()).setDescription("Enable Shake detection").expectReply().expireInSeconds(60).setDelayMs(ErrorCode.INVALID_OWNERSHIP).queue();
}
}
}
Inevitable.task("lefun-s-queue", 200L, new Runnable() {
@Override
public final void run() {
LeFunService.this.lambda$queueMessage$5();
}
});
return;
}
UserError.Log.e(this.TAG, "Alert message requested but no message set");
}
public void lambda$queueMessage$5() {
changeState(this.mState.next());
}
static class LeFunState extends JamBaseBluetoothSequencer.BaseState {
LeFunState() {
this.sequence.clear();
this.sequence.add("Initializing");
this.sequence.add("Connecting");
this.sequence.add("Sending Queue");
this.sequence.add("Updating Settings");
this.sequence.add("Setting Time");
this.sequence.add("Sleeping");
this.sequence.add("Sending Alert");
this.sequence.add("Sending Queue");
this.sequence.add("Sleeping");
this.sequence.add("Prototype Test");
this.sequence.add("Sending Queue");
this.sequence.add("Sleeping");
this.sequence.add("Enabling notify");
this.sequence.add("Sending Queue");
this.sequence.add("Sleeping");
}
}
@Override
protected synchronized boolean automata() {
char c;
extendWakeLock(1000L);
UserError.Log.d(this.TAG, "Automata called in LeFun");
if (this.I.state.equals("Sending Alert") || alwaysConnected()) {
if (this.I.isConnected && !this.I.state.equals("Closing")) {
if (!this.I.isDiscoveryComplete) {
UserError.Log.d(this.TAG, "Services not discovered");
this.I.state = "Discover Services";
} else if (!this.I.isNotificationEnabled && JoH.ratelimit("lefun-enable-notifications", 2)) {
UserError.Log.d(this.TAG, "Notifications not enabled");
this.I.state = "Enabling notify";
}
}
String str = this.I.state;
switch (str.hashCode()) {
case -2014394435:
if (str.equals("Updating Settings")) {
c = 2;
break;
}
c = 65535;
break;
case -1600768752:
if (str.equals("Prototype Test")) {
c = 4;
break;
}
c = 65535;
break;
case -1168331562:
if (str.equals("Sending Alert")) {
c = 5;
break;
}
c = 65535;
break;
case -235759507:
if (str.equals("Initializing")) {
c = 0;
break;
}
c = 65535;
break;
case 622030557:
if (str.equals("Setting Time")) {
c = 3;
break;
}
c = 65535;
break;
case 2038536649:
if (str.equals("Enabling notify")) {
c = 1;
break;
}
c = 65535;
break;
default:
c = 65535;
break;
}
if (c == 0) {
changeState(this.mState.next());
} else if (c == 1) {
enableNotification();
} else if (c == 2) {
sendSettings();
} else if (c == 3) {
sendBG();
} else if (c == 4) {
prototype();
} else if (c == 5) {
queueMessage();
} else {
return super.automata();
}
}
return true;
}
private boolean shouldServiceRun() {
return LeFunEntry.isEnabled();
}
@Override
protected void setRetryTimerReal() {
if (shouldServiceRun()) {
long whenToRetryNext = whenToRetryNext();
UserError.Log.d(this.TAG, "setRetryTimer: Restarting in: " + (whenToRetryNext / 1000) + " seconds");
this.I.serviceIntent = WakeLockTrampoline.getPendingIntent(getClass(), 1018);
this.I.retry_time = JoH.wakeUpIntent(xdrip.getAppContext(), whenToRetryNext, this.I.serviceIntent);
this.I.wakeup_time = JoH.tsl() + whenToRetryNext;
return;
}
UserError.Log.d(this.TAG, "Not setting retry timer as service should not be running");
}
private long whenToRetryNext() {
this.I.retry_backoff += 1000;
if (this.I.retry_backoff > 300000) {
this.I.retry_backoff = 300000L;
}
return this.I.retry_backoff + 10000;
}
public static List<StatusItem> megaStatus() {
ArrayList arrayList = new ArrayList();
JamBaseBluetoothSequencer.Inst inst = JamBaseBluetoothSequencer.Inst.get(LeFunService.class.getSimpleName());
arrayList.add(new StatusItem("Model", LeFun.getModel()));
arrayList.add(new StatusItem("Mac address", LeFun.getMac()));
arrayList.add(new StatusItem("Connected", xdrip.gs(inst.isConnected ? 2131757071 : 2131755900)));
long j = inst.wakeup_time;
if (j != 0) {
long msTill = JoH.msTill(j);
if (msTill > 0) {
arrayList.add(new StatusItem("Wake Up", JoH.niceTimeScalar(msTill)));
}
}
arrayList.add(new StatusItem("State", inst.state));
int queueSize = inst.getQueueSize();
if (queueSize > 0) {
arrayList.add(new StatusItem("Queue", queueSize + " items"));
}
return arrayList;
}
}