正在查看: xDrip+ v04633772025.07.16 应用的 UiBasedCollector.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 UiBasedCollector.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.services;
import android.app.Activity;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RemoteViews;
import android.widget.TextView;
import com.eveningoutpost.dexdrip.BestGlucose;
import com.eveningoutpost.dexdrip.alert.Persist$DoubleTimeout;
import com.eveningoutpost.dexdrip.cgm.dex.BlueTails;
import com.eveningoutpost.dexdrip.cgm.dex.ClassifierAction;
import com.eveningoutpost.dexdrip.models.BgReading;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.Sensor;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Unitized;
import com.eveningoutpost.dexdrip.utils.DexCollectionType;
import com.eveningoutpost.dexdrip.xdrip;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UiBasedCollector extends NotificationListenerService {
private static final String TAG = "UiBasedCollector";
private static final HashSet<String> coOptedPackages;
private static final HashSet<String> coOptedPackagesAll;
private static final HashSet<String> companionAppIoBPackages;
private static final HashSet<Pattern> companionAppIoBRegexes;
private static boolean debug;
private static final Persist$DoubleTimeout iob_store = new Persist$DoubleTimeout("COMPANION_APP_IOB_VALUE", 300000);
String lastPackage;
@Override
public void onNotificationRemoved(StatusBarNotification statusBarNotification) {
}
static {
HashSet<String> hashSet = new HashSet<>();
coOptedPackages = hashSet;
HashSet<String> hashSet2 = new HashSet<>();
coOptedPackagesAll = hashSet2;
HashSet<String> hashSet3 = new HashSet<>();
companionAppIoBPackages = hashSet3;
HashSet<Pattern> hashSet4 = new HashSet<>();
companionAppIoBRegexes = hashSet4;
debug = false;
hashSet.add("com.dexcom.g6");
hashSet.add("com.dexcom.g6.region1.mmol");
hashSet.add("com.dexcom.g6.region2.mgdl");
hashSet.add("com.dexcom.g6.region3.mgdl");
hashSet.add("com.dexcom.g6.region4.mmol");
hashSet.add("com.dexcom.g6.region5.mmol");
hashSet.add("com.dexcom.g6.region6.mgdl");
hashSet.add("com.dexcom.g6.region7.mmol");
hashSet.add("com.dexcom.g6.region8.mmol");
hashSet.add("com.dexcom.g6.region9.mgdl");
hashSet.add("com.dexcom.g6.region10.mgdl");
hashSet.add("com.dexcom.g6.region11.mmol");
hashSet.add("com.dexcom.dexcomone");
hashSet.add("com.dexcom.stelo");
hashSet.add("com.dexcom.g7");
hashSet.add("com.dexcom.d1plus");
hashSet.add("com.camdiab.fx_alert.mmoll");
hashSet.add("com.camdiab.fx_alert.mgdl");
hashSet.add("com.camdiab.fx_alert.hx.mmoll");
hashSet.add("com.camdiab.fx_alert.hx.mgdl");
hashSet.add("com.camdiab.fx_alert.mmoll.ca");
hashSet.add("com.medtronic.diabetes.guardian");
hashSet.add("com.medtronic.diabetes.guardianconnect");
hashSet.add("com.medtronic.diabetes.guardianconnect.us");
hashSet.add("com.medtronic.diabetes.minimedmobile.eu");
hashSet.add("com.medtronic.diabetes.minimedmobile.us");
hashSet.add("com.medtronic.diabetes.simplera.eu");
hashSet.add("com.senseonics.gen12androidapp");
hashSet.add("com.senseonics.androidapp");
hashSet.add("com.microtech.aidexx.mgdl");
hashSet.add("com.ottai.seas");
hashSet.add("com.microtech.aidexx");
hashSet.add("com.ottai.tag");
hashSet.add("com.senseonics.eversense365.us");
hashSet.add("com.kakaohealthcare.pasta");
hashSet.add("com.sinocare.cgm.ce");
hashSet.add("com.sinocare.ican.health.ce");
hashSet2.add("com.dexcom.dexcomone");
hashSet2.add("com.dexcom.d1plus");
hashSet2.add("com.dexcom.stelo");
hashSet2.add("com.medtronic.diabetes.guardian");
hashSet2.add("com.medtronic.diabetes.simplera.eu");
hashSet2.add("com.senseonics.gen12androidapp");
hashSet2.add("com.senseonics.androidapp");
hashSet2.add("com.microtech.aidexx.mgdl");
hashSet2.add("com.ottai.seas");
hashSet2.add("com.microtech.aidexx");
hashSet2.add("com.ottai.tag");
hashSet2.add("com.senseonics.eversense365.us");
hashSet2.add("com.kakaohealthcare.pasta");
hashSet2.add("com.sinocare.cgm.ce");
hashSet2.add("com.sinocare.ican.health.ce");
hashSet3.add("com.insulet.myblue.pdm");
hashSet4.add(Pattern.compile("IOB: ([\\d\\.,]+) U"));
}
@Override
public void onNotificationPosted(StatusBarNotification statusBarNotification) {
String packageName = statusBarNotification.getPackageName();
if (coOptedPackages.contains(packageName)) {
if (DexCollectionType.getDexCollectionType() == DexCollectionType.UiBased) {
UserError.Log.d(TAG, "Notification from: " + packageName);
if (statusBarNotification.isOngoing() || coOptedPackagesAll.contains(packageName)) {
this.lastPackage = packageName;
processNotification(statusBarNotification.getNotification());
BlueTails.immortality();
}
} else if (JoH.pratelimit("warn-notification-access", 7200)) {
UserError.Log.wtf(TAG, "Receiving notifications that we are not enabled to process: " + packageName);
}
}
if (companionAppIoBPackages.contains(packageName)) {
processCompanionAppIoBNotification(statusBarNotification.getNotification());
}
}
private void processCompanionAppIoBNotification(Notification notification) {
if (notification == null) {
UserError.Log.e(TAG, "Null notification");
return;
}
RemoteViews remoteViews = notification.contentView;
if (remoteViews != null) {
processCompanionAppIoBNotificationCV(remoteViews);
} else {
UserError.Log.e(TAG, "Content is empty");
}
}
private void processCompanionAppIoBNotificationCV(RemoteViews remoteViews) {
if (remoteViews == null) {
return;
}
Double d = null;
ViewGroup viewGroup = (ViewGroup) remoteViews.apply(this, null).getRootView();
ArrayList arrayList = new ArrayList();
getTextViews(arrayList, viewGroup);
if (debug) {
UserError.Log.d(TAG, "Text views: " + arrayList.size());
}
try {
Iterator it = arrayList.iterator();
while (it.hasNext()) {
TextView textView = (TextView) it.next();
String charSequence = textView.getText() != null ? textView.getText().toString() : "";
String charSequence2 = textView.getContentDescription() != null ? textView.getContentDescription().toString() : "";
if (debug) {
UserError.Log.d(TAG, "Examining: >" + charSequence + "< : >" + charSequence2 + "<");
}
d = parseIoB(charSequence);
if (d != null) {
break;
}
}
if (d != null) {
if (debug) {
UserError.Log.d(TAG, "Inserting new IoB value: " + d);
}
iob_store.set(d);
}
} catch (Exception e) {
UserError.Log.e(TAG, "exception in processCompanionAppIoBNotificationCV: " + e);
}
arrayList.clear();
}
Double parseIoB(String str) {
Iterator<Pattern> it = companionAppIoBRegexes.iterator();
while (it.hasNext()) {
Matcher matcher = it.next().matcher(str);
if (matcher.find()) {
return Double.valueOf(JoH.tolerantParseDouble(matcher.group(1)));
}
}
return null;
}
public static Double getCurrentIoB() {
return iob_store.get();
}
@Override
public IBinder onBind(Intent intent) {
return super.onBind(intent);
}
private void processNotification(Notification notification) {
int tryExtractString;
String channelId;
if (notification == null) {
UserError.Log.e(TAG, "Null notification");
return;
}
Bundle bundle = notification.extras;
String str = TAG;
JoH.dumpBundle(bundle, str);
if (notification.contentView != null) {
if (Build.VERSION.SDK_INT >= 26) {
channelId = notification.getChannelId();
UserError.Log.d(str, "Channel ID: " + channelId);
}
processRemote(notification.contentView);
return;
}
Bundle bundle2 = notification.extras;
if (bundle2 != null) {
String string = bundle2.getString("android.title");
if (isValidString(string) && (tryExtractString = tryExtractString(string)) > 0) {
handleNewValue(tryExtractString);
return;
}
}
UserError.Log.e(str, "Content is empty");
}
private boolean isValidString(String str) {
return (str == null || str.trim().isEmpty()) ? false : true;
}
String filterString(String str) {
String str2 = this.lastPackage;
if (str2 == null) {
return str;
}
str2.hashCode();
return basicFilterString(arrowFilterString(str)).trim();
}
String basicFilterString(String str) {
return str.replace(" ", " ").replace("\u2060", "").replace("\\", "/").replace("mmol/L", "").replace("mmol/l", "").replace("mg/dL", "").replace("mg/dl", "").replace("≤", "").replace("≥", "");
}
String arrowFilterString(String str) {
return filterUnicodeRange(filterUnicodeRange(filterUnicodeRange(filterUnicodeRange(str, (char) 8592, (char) 8703), (char) 9984, (char) 10175), (char) 10496, (char) 10623), (char) 11008, (char) 11263);
}
public String filterUnicodeRange(String str, char c, char c2) {
if (c > c2) {
throw new RuntimeException("bottom and top of character range invalid");
}
StringBuilder sb = new StringBuilder(str.length());
for (char c3 : str.toCharArray()) {
if (c3 < c || c3 > c2) {
sb.append(c3);
}
}
return sb.toString();
}
private boolean processRemote(RemoteViews remoteViews) {
if (remoteViews == null) {
return false;
}
ViewGroup viewGroup = (ViewGroup) remoteViews.apply(this, null).getRootView();
ArrayList arrayList = new ArrayList();
getTextViews(arrayList, viewGroup);
UserError.Log.d(TAG, "Text views: " + arrayList.size());
Iterator it = arrayList.iterator();
int i = 0;
int i2 = 0;
while (it.hasNext()) {
TextView textView = (TextView) it.next();
try {
String charSequence = textView.getText() != null ? textView.getText().toString() : "";
String charSequence2 = textView.getContentDescription() != null ? textView.getContentDescription().toString() : "";
UserError.Log.d(TAG, "Examining: >" + charSequence + "< : >" + charSequence2 + "<");
int tryExtractString = tryExtractString(charSequence);
if (tryExtractString > 0) {
i++;
i2 = tryExtractString;
}
} catch (Exception unused) {
}
}
arrayList.clear();
if (i == 0) {
UserError.Log.d(TAG, "Did not find any matches");
} else if (i > 1) {
UserError.Log.e(TAG, "Found too many matches: " + i);
} else {
handleNewValue(i2);
return true;
}
return false;
}
int tryExtractString(String str) {
int round;
try {
String filterString = filterString(str);
if (Unitized.usingMgDl()) {
round = Integer.parseInt(filterString);
} else {
if (!isValidMmol(filterString)) {
return -1;
}
double d = JoH.tolerantParseDouble(filterString, -1.0d);
if (d == -1.0d) {
return -1;
}
round = (int) Math.round(Unitized.mgdlConvert(d));
}
return round;
} catch (Exception e) {
UserError.Log.d(TAG, "Got exception in tryExtractString: " + e);
return -1;
}
}
boolean handleNewValue(int i) {
return handleNewValue(JoH.tsl(), i);
}
boolean handleNewValue(long j, int i) {
Sensor.createDefaultIfMissing();
String str = TAG;
UserError.Log.d(str, "Found specific value: " + i);
if (i >= 40 && i <= 405) {
long currentSamplePeriod = DexCollectionType.getCurrentSamplePeriod() * 4;
boolean z = JoH.msSince(ClassifierAction.lastReadingTimestamp) < currentSamplePeriod;
long currentDeduplicationPeriod = (z || !isDifferentToLast(i)) ? DexCollectionType.getCurrentDeduplicationPeriod() : 10000L;
if (!z) {
currentSamplePeriod = currentDeduplicationPeriod;
}
BgReading forPreciseTimestamp = BgReading.getForPreciseTimestamp(j, currentSamplePeriod, false);
if (forPreciseTimestamp == null) {
if (isJammed(i)) {
UserError.Log.wtf(str, "Apparently value is jammed at: " + i);
} else {
UserError.Log.d(str, "Inserting new value");
PersistentStore.setLong("UI_BASED_STORE_LAST_VALUE", i);
BgReading bgReadingInsertFromG5 = BgReading.bgReadingInsertFromG5(i, j);
if (bgReadingInsertFromG5 != null) {
bgReadingInsertFromG5.find_slope();
bgReadingInsertFromG5.noRawWillBeAvailable();
bgReadingInsertFromG5.injectDisplayGlucose(BestGlucose.getDisplayGlucose());
return true;
}
}
} else {
UserError.Log.d(str, "Duplicate value: " + forPreciseTimestamp.timeStamp());
}
} else {
UserError.Log.wtf(str, "Glucose value outside acceptable range: " + i);
}
return false;
}
static boolean isValidMmol(String str) {
return str.matches("[0-9]+[.,][0-9]+");
}
private boolean isDifferentToLast(int i) {
return PersistentStore.getLong("UI_BASED_STORE_LAST_VALUE") != ((long) i);
}
private boolean isJammed(int i) {
if (PersistentStore.getLong("UI_BASED_STORE_LAST_VALUE") == i) {
PersistentStore.incrementLong("UI_BASED_STORE_LAST_REPEAT");
} else {
PersistentStore.setLong("UI_BASED_STORE_LAST_REPEAT", 0L);
}
long j = PersistentStore.getLong("UI_BASED_STORE_LAST_REPEAT");
UserError.Log.d(TAG, "Last repeat: " + j);
return j > ((long) jamThreshold());
}
private int jamThreshold() {
String str = this.lastPackage;
return (str == null || !str.startsWith("com.medtronic")) ? 6 : 9;
}
private void getTextViews(List<TextView> list, ViewGroup viewGroup) {
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View childAt = viewGroup.getChildAt(i);
if (childAt.getVisibility() == 0) {
if (childAt instanceof TextView) {
list.add((TextView) childAt);
} else if (childAt instanceof ViewGroup) {
getTextViews(list, (ViewGroup) childAt);
}
}
}
}
public static void onEnableCheckPermission(Activity activity) {
if (DexCollectionType.getDexCollectionType() == DexCollectionType.UiBased) {
UserError.Log.d(TAG, "Detected that we are enabled");
switchToAndEnable(activity);
}
}
public static SharedPreferences.OnSharedPreferenceChangeListener getListener(final Activity activity) {
return new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public final void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String str) {
UiBasedCollector.lambda$getListener$0(activity, sharedPreferences, str);
}
};
}
public static void lambda$getListener$0(Activity activity, SharedPreferences sharedPreferences, String str) {
if (str.equals("dex_collection_method")) {
try {
onEnableCheckPermission(activity);
} catch (Exception unused) {
}
}
if (str.equals("fetch_iob_from_companion_app")) {
try {
enableNotificationService(activity);
} catch (Exception e) {
UserError.Log.e(TAG, "Exception when enabling NotificationService: " + e);
}
}
}
public static void switchToAndEnable(Activity activity) {
DexCollectionType.setDexCollectionType(DexCollectionType.UiBased);
Sensor.createDefaultIfMissing();
enableNotificationService(activity);
}
private static void enableNotificationService(final Activity activity) {
if (isNotificationServiceEnabled()) {
return;
}
JoH.show_ok_dialog(activity, xdrip.gs(2131756012), "Permission is needed to receive data from other applications. xDrip does not do anything beyond this scope. Please enable xDrip on the next screen", new Runnable() {
@Override
public final void run() {
UiBasedCollector.lambda$enableNotificationService$1(activity);
}
});
}
public static void lambda$enableNotificationService$1(Activity activity) {
activity.startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
}
private static boolean isNotificationServiceEnabled() {
String packageName = xdrip.getAppContext().getPackageName();
String string = Settings.Secure.getString(xdrip.getAppContext().getContentResolver(), "enabled_notification_listeners");
if (!TextUtils.isEmpty(string)) {
for (String str : string.split(":")) {
ComponentName unflattenFromString = ComponentName.unflattenFromString(str);
if (unflattenFromString != null && TextUtils.equals(packageName, unflattenFromString.getPackageName())) {
return true;
}
}
}
return false;
}
}