FabricPrivacy, notifications

This commit is contained in:
Milos Kozak 2020-01-03 14:30:39 +01:00
parent c88058752f
commit a622bfa559
86 changed files with 702 additions and 723 deletions

View file

@ -123,7 +123,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
if (!loopPlugin.isEnabled(PluginType.LOOP))
VersionCheckerUtilsKt.triggerCheckVersion();
FabricPrivacy.setUserStats();
FabricPrivacy.getInstance().setUserStats();
setupTabs();
setupViews();
@ -140,12 +140,12 @@ public class MainActivity extends NoSplashAppCompatActivity {
setupViews();
}
setWakeLock();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventPreferenceChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
.subscribe(this::processPreferenceChange, exception -> FabricPrivacy.getInstance().logException(exception))
);
if (!sp.getBoolean(R.string.key_setupwizard_processed, false)) {

View file

@ -1,5 +1,10 @@
package info.nightscout.androidaps;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.SystemClock;
@ -7,6 +12,8 @@ import android.os.SystemClock;
import androidx.annotation.ColorRes;
import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -99,6 +106,7 @@ import info.nightscout.androidaps.utils.ActivityMonitor;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import io.fabric.sdk.android.Fabric;
import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
@ -110,7 +118,7 @@ public class MainApp extends DaggerApplication {
static MainApp sInstance;
private static Resources sResources;
static FirebaseAnalytics mFirebaseAnalytics;
static FirebaseAnalytics firebaseAnalytics;
static DatabaseHelper sDatabaseHelper = null;
@ -122,8 +130,14 @@ public class MainApp extends DaggerApplication {
public static boolean devBranch;
public static boolean engineeringMode;
private String CHANNEL_ID = "AndroidAPS-Ongoing";
private int ONGOING_NOTIFICATION_ID = 4711;
private Notification notification;
@Inject AAPSLogger aapsLogger;
@Inject ActivityMonitor activityMonitor;
@Inject FabricPrivacy fabricPrivacy;
@Inject ResourceHelper resourceHelper;
@Inject ActionsPlugin actionsPlugin;
@Inject AutomationPlugin automationPlugin;
@ -150,6 +164,7 @@ public class MainApp extends DaggerApplication {
@Inject OverviewPlugin overviewPlugin;
@Inject PersistentNotificationPlugin persistentNotificationPlugin;
@Inject RandomBgPlugin randomBgPlugin;
@Inject SignatureVerifierPlugin signatureVerifierPlugin;
@Inject DexcomPlugin dexcomPlugin;
@Inject EversensePlugin eversensePlugin;
@Inject GlimpPlugin glimpPlugin;
@ -174,6 +189,7 @@ public class MainApp extends DaggerApplication {
sInstance = this;
sResources = getResources();
LocaleHelper.INSTANCE.update(this);
generateEmptyNotification();
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
/* TODO: put back
@ -187,7 +203,7 @@ public class MainApp extends DaggerApplication {
*/
try {
if (FabricPrivacy.fabricEnabled()) {
if (fabricPrivacy.fabricEnabled()) {
Fabric.with(this, new Crashlytics());
}
} catch (Exception e) {
@ -196,8 +212,8 @@ public class MainApp extends DaggerApplication {
registerActivityLifecycleCallbacks(activityMonitor);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase") && FabricPrivacy.fabricEnabled());
firebaseAnalytics = FirebaseAnalytics.getInstance(this);
firebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase") && fabricPrivacy.fabricEnabled());
JodaTimeAndroid.init(this);
@ -249,7 +265,7 @@ public class MainApp extends DaggerApplication {
if (!Config.NSCLIENT) pluginsList.add(safetyPlugin);
if (!Config.NSCLIENT) pluginsList.add(versionCheckerPlugin);
if (Config.APS) pluginsList.add(StorageConstraintPlugin.getPlugin());
if (Config.APS) pluginsList.add(SignatureVerifierPlugin.getPlugin());
if (Config.APS) pluginsList.add(signatureVerifierPlugin);
if (Config.APS) pluginsList.add(objectivesPlugin);
pluginsList.add(xdripPlugin);
pluginsList.add(nSClientSourcePlugin);
@ -373,8 +389,8 @@ public class MainApp extends DaggerApplication {
return sDatabaseHelper;
}
public static FirebaseAnalytics getFirebaseAnalytics() {
return mFirebaseAnalytics;
public FirebaseAnalytics getFirebaseAnalytics() {
return firebaseAnalytics;
}
public static ArrayList<PluginBase> getPluginsList() {
@ -449,6 +465,42 @@ public class MainApp extends DaggerApplication {
return devBranch;
}
// global Notification has been moved to MainApp because PersistentNotificationPlugin is initialized too late
private void generateEmptyNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setOngoing(true)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_STATUS)
.setSmallIcon(resourceHelper.getNotificationIcon())
.setLargeIcon(resourceHelper.decodeResource(resourceHelper.getIcon()));
builder.setContentTitle(resourceHelper.gs(R.string.loading));
Intent resultIntent = new Intent(this, MainApp.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notification = builder.build();
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
}
public int notificationId() {
return ONGOING_NOTIFICATION_ID;
}
public String channelId() {
return CHANNEL_ID;
}
public void setNotification(Notification notification) {
this.notification = notification;
}
public Notification getNotification() {
return notification;
}
@Override
public void onTerminate() {

View file

@ -80,7 +80,7 @@ public class TDDStatsActivity extends NoSplashAppCompatActivity {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventPumpStatusChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> statusView.setText(event.getStatus()), FabricPrivacy::logException)
.subscribe(event -> statusView.setText(event.getStatus()), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventDanaRSyncStatus.class)
@ -88,7 +88,7 @@ public class TDDStatsActivity extends NoSplashAppCompatActivity {
.subscribe(event -> {
log.debug("EventDanaRSyncStatus: " + event.getMessage());
statusView.setText(event.getMessage());
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -70,7 +70,7 @@ public class Profile {
if (units != null)
this.units = units;
else {
FabricPrivacy.log("Profile failover failed too");
FabricPrivacy.getInstance().log("Profile failover failed too");
this.units = Constants.MGDL;
}
}
@ -182,7 +182,7 @@ public class Profile {
} catch (Exception e) {
log.error("Unhandled exception", e);
log.error(json.toString());
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
}
}

View file

@ -30,6 +30,7 @@ class BolusProgressDialog : DaggerDialogFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy
private val disposable = CompositeDisposable()
@ -98,12 +99,12 @@ class BolusProgressDialog : DaggerDialogFragment() {
disposable.add(rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ overview_bolusprogress_status.text = it.getStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ overview_bolusprogress_status.text = it.getStatus() }) { fabricPrivacy.logException(it) }
)
disposable.add(rxBus
.toObservable(EventDismissBolusProgressIfRunning::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ if (running) dismiss() }) { FabricPrivacy.logException(it) }
.subscribe({ if (running) dismiss() }) { fabricPrivacy.logException(it) }
)
disposable.add(rxBus
.toObservable(EventOverviewBolusProgress::class.java)
@ -117,7 +118,7 @@ class BolusProgressDialog : DaggerDialogFragment() {
scheduleDismiss()
}
state = it.status
}) { FabricPrivacy.logException(it) }
}) { fabricPrivacy.logException(it) }
)
}

View file

@ -52,6 +52,7 @@ class WizardDialog : DaggerDialogFragment() {
@Inject lateinit var mainApp: MainApp
@Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@ -171,9 +172,7 @@ class WizardDialog : DaggerDialogFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
activity?.runOnUiThread { calculateInsulin() }
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
)
}

View file

@ -190,7 +190,7 @@ public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
updateGUI("EventAutosensCalculationFinished");
}
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventIobCalculationProgress.class)
@ -198,7 +198,7 @@ public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
.subscribe(event -> {
if (iobCalculationProgressView != null)
iobCalculationProgressView.setText(event.getProgress());
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
// set start of current day
Calendar calendar = Calendar.getInstance();

View file

@ -25,6 +25,7 @@ class LoopFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var loopPlugin: LoopPlugin
private var disposable: CompositeDisposable = CompositeDisposable()
@ -51,9 +52,7 @@ class LoopFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGUI()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventLoopSetLastRunGui::class.java)
@ -61,9 +60,7 @@ class LoopFragment : DaggerFragment() {
.subscribe({
clearGUI()
loop_lastrun.text = it.text
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGUI()
sp.putBoolean(R.string.key_objectiveuseloop, true)

View file

@ -149,7 +149,7 @@ public class LoopPlugin extends PluginBase {
disposable.add(rxBus
.toObservable(EventTempTargetChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> invoke("EventTempTargetChange", true), FabricPrivacy::logException)
.subscribe(event -> invoke("EventTempTargetChange", true), exception -> FabricPrivacy.getInstance().logException(exception))
);
/**
* This method is triggered once autosens calculation has completed, so the LoopPlugin
@ -173,7 +173,7 @@ public class LoopPlugin extends PluginBase {
lastBgTriggeredRun = bgReading.date;
invoke("AutosenseCalculation for " + bgReading, true);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -27,10 +27,11 @@ import javax.inject.Inject
class OpenAPSAMAFragment : DaggerFragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
@Inject lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -54,17 +55,13 @@ class OpenAPSAMAFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGUI()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventOpenAPSUpdateResultGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateResultGUI(it.text)
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -211,7 +211,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
isTempTarget
);
} catch (JSONException e) {
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
return;
}

View file

@ -21,8 +21,9 @@ import javax.inject.Inject
class OpenAPSMAFragment : DaggerFragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
@Inject lateinit var openAPSMAPlugin: OpenAPSMAPlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var openAPSMAPlugin: OpenAPSMAPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -47,17 +48,13 @@ class OpenAPSMAFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGUI()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventOpenAPSUpdateResultGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateResultGUI(it.text)
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -192,7 +192,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
try {
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, configBuilderPlugin.getActivePump().getBaseBasalRate(), iobTotal, glucoseStatus, mealData);
} catch (JSONException e) {
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
return;
}
Profiler.log(aapsLogger, LTag.APS, "MA calculation", start);

View file

@ -28,10 +28,11 @@ import javax.inject.Inject
class OpenAPSSMBFragment : DaggerFragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
@Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -54,17 +55,13 @@ class OpenAPSSMBFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGUI()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventOpenAPSUpdateResultGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateResultGUI(it.text)
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -252,7 +252,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
advancedFiltering.value()
);
} catch (JSONException e) {
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
return;
}

View file

@ -33,6 +33,7 @@ class ConfigBuilderFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy
private var disposable: CompositeDisposable = CompositeDisposable()
private val pluginViewHolders = ArrayList<PluginViewHolder>()
@ -66,9 +67,7 @@ class ConfigBuilderFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
for (pluginViewHolder in pluginViewHolders) pluginViewHolder.update()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -73,7 +73,7 @@ public class ProfileFunctions implements ProfileFunction {
RxBus.Companion.getINSTANCE().send(new EventNewBasalProfile());
}
});
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -28,7 +28,11 @@ import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObj
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SntpClient
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -42,6 +46,7 @@ class ObjectivesFragment : DaggerFragment() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var objectivesPlugin: ObjectivesPlugin
private val objectivesAdapter = ObjectivesAdapter()
@ -83,9 +88,7 @@ class ObjectivesFragment : DaggerFragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
objectives_recyclerview.adapter?.notifyDataSetChanged()
}, {
FabricPrivacy.logException(it)
}
}, { fabricPrivacy.logException(it) }
)
}

View file

@ -23,6 +23,7 @@ class NtpProgressDialog : DaggerDialogFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
private val disposable = CompositeDisposable()
@ -73,7 +74,7 @@ class NtpProgressDialog : DaggerDialogFragment() {
}
state = event.status
percent = event.percent
}) { FabricPrivacy.logException(it) }
}) { fabricPrivacy.logException(it) }
}
override fun onPause() {

View file

@ -1,243 +0,0 @@
package info.nightscout.androidaps.plugins.constraints.signatureVerifier;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.utils.SP;
/**
* AndroidAPS is meant to be build by the user.
* In case someone decides to leak a ready-to-use APK nonetheless, we can still disable it.
* Self-compiled APKs with privately held certificates cannot and will not be disabled.
*/
public class SignatureVerifierPlugin extends PluginBase implements ConstraintsInterface {
private static final String REVOKED_CERTS_URL = "https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/src/main/assets/revoked_certs.txt";
private static final long UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(1);
private static SignatureVerifierPlugin plugin = new SignatureVerifierPlugin();
private Logger log = LoggerFactory.getLogger(L.CORE);
private final Object $lock = new Object[0];
private File revokedCertsFile;
private List<byte[]> revokedCerts;
@Deprecated
public static SignatureVerifierPlugin getPlugin() {
return plugin;
}
private SignatureVerifierPlugin() {
super(new PluginDescription()
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.signature_verifier));
}
@Override
protected void onStart() {
super.onStart();
revokedCertsFile = new File(MainApp.instance().getFilesDir(), "revoked_certs.txt");
new Thread(() -> {
loadLocalRevokedCerts();
if (shouldDownloadCerts()) {
try {
downloadAndSaveRevokedCerts();
} catch (IOException e) {
log.error("Could not download revoked certs", e);
}
}
if (hasIllegalSignature()) showNotification();
}).start();
}
@Override
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
if (hasIllegalSignature()) {
showNotification();
value.set(false);
}
if (shouldDownloadCerts()) {
new Thread(() -> {
try {
downloadAndSaveRevokedCerts();
} catch (IOException e) {
log.error("Could not download revoked certs", e);
}
}).start();
}
return value;
}
private void showNotification() {
Notification notification = new Notification(Notification.INVALID_VERSION, MainApp.gs(R.string.running_invalid_version), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
}
private boolean hasIllegalSignature() {
try {
synchronized ($lock) {
if (revokedCerts == null) return false;
Signature[] signatures = MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), PackageManager.GET_SIGNATURES).signatures;
if (signatures != null) {
for (Signature signature : signatures) {
MessageDigest digest = MessageDigest.getInstance("SHA256");
byte[] fingerprint = digest.digest(signature.toByteArray());
for (byte[] cert : revokedCerts) {
if (Arrays.equals(cert, fingerprint)) {
return true;
}
}
}
}
}
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
log.error("Error in SignatureVerifierPlugin", e);
}
return false;
}
public List<String> shortHashes() {
List<String> hashes = new ArrayList<>();
try {
Signature[] signatures = MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), PackageManager.GET_SIGNATURES).signatures;
if (signatures != null) {
for (Signature signature : signatures) {
MessageDigest digest = MessageDigest.getInstance("SHA256");
byte[] fingerprint = digest.digest(signature.toByteArray());
String hash = Hex.toHexString(fingerprint);
log.debug("Found signature: " + hash);
log.debug("Found signature (short): " + singleCharMap(fingerprint));
hashes.add(singleCharMap(fingerprint));
}
}
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
log.error("Error in SignatureVerifierPlugin", e);
}
return hashes;
}
String map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?,.-;:_<>|°^`´\\@€*'#+~{}[]¿¡áéíóúàèìòùöäü`ÁÉÍÓÚÀÈÌÒÙÖÄÜßÆÇÊËÎÏԌ۟æçêëîïôœûÿĆČĐŠŽćđšžñΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ\u03A2ΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗ";
private String singleCharMap(byte[] array) {
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(map.charAt(b & 0xFF));
}
return sb.toString();
}
public String singleCharUnMap(String shortHash) {
byte[] array = new byte[shortHash.length()];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i != 0) sb.append(":");
sb.append(String.format("%02X", 0xFF & map.charAt(map.indexOf(shortHash.charAt(i)))));
}
return sb.toString();
}
private boolean shouldDownloadCerts() {
return System.currentTimeMillis() - SP.getLong(R.string.key_last_revoked_certs_check, 0L) >= UPDATE_INTERVAL;
}
private void downloadAndSaveRevokedCerts() throws IOException {
String download = downloadRevokedCerts();
saveRevokedCerts(download);
SP.putLong(R.string.key_last_revoked_certs_check, System.currentTimeMillis());
synchronized ($lock) {
revokedCerts = parseRevokedCertsFile(download);
}
}
private void loadLocalRevokedCerts() {
try {
String revokedCerts = readCachedDownloadedRevokedCerts();
if (revokedCerts == null) revokedCerts = readRevokedCertsInAssets();
synchronized ($lock) {
this.revokedCerts = parseRevokedCertsFile(revokedCerts);
}
} catch (IOException e) {
log.error("Error in SignatureVerifierPlugin", e);
}
}
private void saveRevokedCerts(String revokedCerts) throws IOException {
OutputStream outputStream = new FileOutputStream(revokedCertsFile);
outputStream.write(revokedCerts.getBytes(StandardCharsets.UTF_8));
outputStream.close();
}
private String downloadRevokedCerts() throws IOException {
URLConnection connection = new URL(REVOKED_CERTS_URL).openConnection();
return readInputStream(connection.getInputStream());
}
private String readInputStream(InputStream inputStream) throws IOException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, read);
}
baos.flush();
return new String(baos.toByteArray(), StandardCharsets.UTF_8);
} finally {
inputStream.close();
}
}
private String readRevokedCertsInAssets() throws IOException {
InputStream inputStream = MainApp.instance().getAssets().open("revoked_certs.txt");
return readInputStream(inputStream);
}
private String readCachedDownloadedRevokedCerts() throws IOException {
if (!revokedCertsFile.exists()) return null;
return readInputStream(new FileInputStream(revokedCertsFile));
}
private List<byte[]> parseRevokedCertsFile(String file) {
List<byte[]> revokedCerts = new ArrayList<>();
for (String line : file.split("\n")) {
if (line.startsWith("#")) continue;
revokedCerts.add(Hex.decode(line.replace(" ", "").replace(":", "")));
}
return revokedCerts;
}
}

View file

@ -0,0 +1,225 @@
package info.nightscout.androidaps.plugins.constraints.signatureVerifier
import android.content.pm.PackageManager
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ConstraintsInterface
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.slf4j.LoggerFactory
import org.spongycastle.util.encoders.Hex
import java.io.*
import java.net.URL
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
/**
* AndroidAPS is meant to be build by the user.
* In case someone decides to leak a ready-to-use APK nonetheless, we can still disable it.
* Self-compiled APKs with privately held certificates cannot and will not be disabled.
*/
@Singleton
class SignatureVerifierPlugin @Inject constructor(
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
private val mainApp: MainApp
) : PluginBase(PluginDescription()
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.signature_verifier)), ConstraintsInterface {
private val REVOKED_CERTS_URL = "https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/src/main/assets/revoked_certs.txt"
private val UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(1)
private val log = LoggerFactory.getLogger(L.CORE)
private val lock: Any = arrayOfNulls<Any>(0)
private var revokedCertsFile: File? = null
private var revokedCerts: List<ByteArray>? = null
override fun onStart() {
super.onStart()
revokedCertsFile = File(mainApp.filesDir, "revoked_certs.txt")
Thread(Runnable {
loadLocalRevokedCerts()
if (shouldDownloadCerts()) {
try {
downloadAndSaveRevokedCerts()
} catch (e: IOException) {
log.error("Could not download revoked certs", e)
}
}
if (hasIllegalSignature()) showNotification()
}).start()
}
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
if (hasIllegalSignature()) {
showNotification()
value.set(false)
}
if (shouldDownloadCerts()) {
Thread(Runnable {
try {
downloadAndSaveRevokedCerts()
} catch (e: IOException) {
log.error("Could not download revoked certs", e)
}
}).start()
}
return value
}
private fun showNotification() {
val notification = Notification(Notification.INVALID_VERSION, resourceHelper.gs(R.string.running_invalid_version), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
}
private fun hasIllegalSignature(): Boolean {
try {
synchronized(lock) {
if (revokedCerts == null) return false
val signatures = mainApp.packageManager.getPackageInfo(mainApp.packageName, PackageManager.GET_SIGNATURES).signatures
if (signatures != null) {
for (signature in signatures) {
val digest = MessageDigest.getInstance("SHA256")
val fingerprint = digest.digest(signature.toByteArray())
for (cert in revokedCerts!!) {
if (Arrays.equals(cert, fingerprint)) {
return true
}
}
}
}
}
} catch (e: PackageManager.NameNotFoundException) {
log.error("Error in SignatureVerifierPlugin", e)
} catch (e: NoSuchAlgorithmException) {
log.error("Error in SignatureVerifierPlugin", e)
}
return false
}
fun shortHashes(): List<String> {
val hashes: MutableList<String> = ArrayList()
try {
val signatures = mainApp.packageManager.getPackageInfo(mainApp.packageName, PackageManager.GET_SIGNATURES).signatures
if (signatures != null) {
for (signature in signatures) {
val digest = MessageDigest.getInstance("SHA256")
val fingerprint = digest.digest(signature.toByteArray())
val hash = Hex.toHexString(fingerprint)
log.debug("Found signature: $hash")
log.debug("Found signature (short): " + singleCharMap(fingerprint))
hashes.add(singleCharMap(fingerprint))
}
}
} catch (e: PackageManager.NameNotFoundException) {
log.error("Error in SignatureVerifierPlugin", e)
} catch (e: NoSuchAlgorithmException) {
log.error("Error in SignatureVerifierPlugin", e)
}
return hashes
}
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?,.-;:_<>|°^`´\\@€*'#+~{}[]¿¡áéíóúàèìòùöäü`ÁÉÍÓÚÀÈÌÒÙÖÄÜßÆÇÊËÎÏԌ۟æçêëîïôœûÿĆČĐŠŽćđšžñΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ\u03A2ΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗ"
private fun singleCharMap(array: ByteArray): String {
val sb = StringBuilder()
for (b in array) {
sb.append(map[b.toInt() and 0xFF])
}
return sb.toString()
}
fun singleCharUnMap(shortHash: String): String {
val array = ByteArray(shortHash.length)
val sb = StringBuilder()
for (i in array.indices) {
if (i != 0) sb.append(":")
sb.append(String.format("%02X", 0xFF and map[map.indexOf(shortHash[i])].toInt()))
}
return sb.toString()
}
private fun shouldDownloadCerts(): Boolean {
return System.currentTimeMillis() - sp.getLong(R.string.key_last_revoked_certs_check, 0L) >= UPDATE_INTERVAL
}
@Throws(IOException::class) private fun downloadAndSaveRevokedCerts() {
val download = downloadRevokedCerts()
saveRevokedCerts(download)
sp.putLong(R.string.key_last_revoked_certs_check, System.currentTimeMillis())
synchronized(lock) { revokedCerts = parseRevokedCertsFile(download) }
}
private fun loadLocalRevokedCerts() {
try {
var revokedCerts = readCachedDownloadedRevokedCerts()
if (revokedCerts == null) revokedCerts = readRevokedCertsInAssets()
synchronized(lock) { this.revokedCerts = parseRevokedCertsFile(revokedCerts) }
} catch (e: IOException) {
log.error("Error in SignatureVerifierPlugin", e)
}
}
@Throws(IOException::class)
private fun saveRevokedCerts(revokedCerts: String) {
val outputStream: OutputStream = FileOutputStream(revokedCertsFile)
outputStream.write(revokedCerts.toByteArray(StandardCharsets.UTF_8))
outputStream.close()
}
@Throws(IOException::class) private fun downloadRevokedCerts(): String {
val connection = URL(REVOKED_CERTS_URL).openConnection()
return readInputStream(connection.getInputStream())
}
@Throws(IOException::class)
private fun readInputStream(inputStream: InputStream): String {
return try {
val baos = ByteArrayOutputStream()
val buffer = ByteArray(1024)
var read: Int
while (inputStream.read(buffer).also { read = it } != -1) {
baos.write(buffer, 0, read)
}
baos.flush()
String(baos.toByteArray(), StandardCharsets.UTF_8)
} finally {
inputStream.close()
}
}
@Throws(IOException::class) private fun readRevokedCertsInAssets(): String {
val inputStream = mainApp.assets.open("revoked_certs.txt")
return readInputStream(inputStream)
}
@Throws(IOException::class)
private fun readCachedDownloadedRevokedCerts(): String? {
return if (!revokedCertsFile!!.exists()) null else readInputStream(FileInputStream(revokedCertsFile))
}
private fun parseRevokedCertsFile(file: String?): List<ByteArray> {
val revokedCerts: MutableList<ByteArray> = ArrayList()
for (line in file!!.split("\n").toTypedArray()) {
if (line.startsWith("#")) continue
revokedCerts.add(Hex.decode(line.replace(" ", "").replace(":", "")))
}
return revokedCerts
}
}

View file

@ -43,6 +43,7 @@ class ActionsFragment : DaggerFragment() {
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@ -125,27 +126,27 @@ class ActionsFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventRefreshOverview::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventCustomActionsChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventCareportalEventChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
updateGui()
}

View file

@ -42,8 +42,9 @@ import javax.inject.Inject
class AutomationFragment : DaggerFragment(), OnStartDragListener {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var automationPlugin: AutomationPlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var automationPlugin: AutomationPlugin
private var disposable: CompositeDisposable = CompositeDisposable()
private lateinit var eventListAdapter: EventListAdapter
@ -86,17 +87,13 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventAutomationDataChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
eventListAdapter.notifyDataSetChanged()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
updateGui()
}

View file

@ -25,10 +25,10 @@ import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.services.LocationService
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONArray
@ -44,7 +44,8 @@ class AutomationPlugin @Inject constructor(
private val aapsLogger: AAPSLogger,
private val resourceHelper: ResourceHelper,
private val mainApp: MainApp,
private val sp :SP,
private val sp: SP,
private val fabricPrivacy: FabricPrivacy,
private val loopPlugin: LoopPlugin
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -92,15 +93,11 @@ class AutomationPlugin @Inject constructor(
else
mainApp.startService(Intent(mainApp, LocationService::class.java))
}
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventAutomationDataChanged::class.java)
.observeOn(Schedulers.io())
.subscribe({ storeToSP() }, {
FabricPrivacy.logException(it)
})
.subscribe({ storeToSP() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventLocationChange::class.java)
.observeOn(Schedulers.io())
@ -109,27 +106,19 @@ class AutomationPlugin @Inject constructor(
aapsLogger.debug(LTag.AUTOMATION, "Grabbed location: $it.location.latitude $it.location.longitude Provider: $it.location.provider")
processActions()
}
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventChargingState::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {
FabricPrivacy.logException(it)
})
.subscribe({ processActions() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventNetworkChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {
FabricPrivacy.logException(it)
})
.subscribe({ processActions() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {
FabricPrivacy.logException(it)
})
.subscribe({ processActions() }, { fabricPrivacy.logException(it) })
}
override fun onStop() {

View file

@ -31,6 +31,7 @@ import javax.inject.Inject
class EditEventDialog : DialogFragmentWithDate() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var automationPlugin: AutomationPlugin
private var actionListAdapter: ActionListAdapter? = null
@ -80,9 +81,7 @@ class EditEventDialog : DialogFragmentWithDate() {
.subscribe({
actionListAdapter?.notifyDataSetChanged()
showPreconditions()
}, {
FabricPrivacy.logException(it)
}
}, { fabricPrivacy.logException(it) }
)
disposable += rxBus
.toObservable(EventAutomationAddAction::class.java)
@ -90,9 +89,7 @@ class EditEventDialog : DialogFragmentWithDate() {
.subscribe({
event.addAction(it.action)
actionListAdapter?.notifyDataSetChanged()
}, {
FabricPrivacy.logException(it)
}
}, { fabricPrivacy.logException(it) }
)
disposable += rxBus
.toObservable(EventAutomationUpdateTrigger::class.java)
@ -100,9 +97,7 @@ class EditEventDialog : DialogFragmentWithDate() {
.subscribe({
event.trigger = it.trigger
automation_triggerDescription.text = event.trigger.friendlyDescription()
}, {
FabricPrivacy.logException(it)
}
}, { fabricPrivacy.logException(it) }
)
disposable += rxBus
.toObservable(EventAutomationUpdateAction::class.java)
@ -110,9 +105,7 @@ class EditEventDialog : DialogFragmentWithDate() {
.subscribe({
event.actions[it.position] = it.action
actionListAdapter?.notifyDataSetChanged()
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
}
override fun submit(): Boolean {

View file

@ -4,9 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventCareportalEventChange
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -27,6 +25,7 @@ class CareportalFragment : DaggerFragment(), View.OnClickListener {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
private val disposable = CompositeDisposable()
@ -60,11 +59,11 @@ class CareportalFragment : DaggerFragment(), View.OnClickListener {
val profileStore = configBuilderPlugin.activeProfileInterface.profile
if (profileStore == null) {
profileview_noprofile.setVisibility(View.VISIBLE)
careportal_buttons.setVisibility(View.GONE)
profileview_noprofile.visibility = View.VISIBLE
careportal_buttons.visibility = View.GONE
} else {
profileview_noprofile.setVisibility(View.GONE)
careportal_buttons.setVisibility(View.VISIBLE)
profileview_noprofile.visibility = View.GONE
careportal_buttons.visibility = View.VISIBLE
}
}
@ -73,7 +72,7 @@ class CareportalFragment : DaggerFragment(), View.OnClickListener {
disposable.add(rxBus
.toObservable(EventCareportalEventChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGUI() }) { fabricPrivacy.logException(it) }
)
updateGUI()
}
@ -133,7 +132,7 @@ class CareportalFragment : DaggerFragment(), View.OnClickListener {
}
}
protected fun updateGUI() {
private fun updateGUI() {
statusLightHandler.updateAge(careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
}
}

View file

@ -33,6 +33,7 @@ class FoodFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var foodPlugin: FoodPlugin
private val disposable = CompositeDisposable()
@ -95,7 +96,7 @@ class FoodFragment : DaggerFragment() {
disposable.add(rxBus
.toObservable(EventFoodDatabaseChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
)
updateGui()
}

View file

@ -61,7 +61,7 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
this.createFoodFromJsonIfNotExists(array);
else
this.deleteNS(array);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -85,7 +85,7 @@ public class NSClientFragment extends Fragment implements View.OnClickListener,
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventNSClientUpdateGUI.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGui();
}

View file

@ -116,17 +116,17 @@ public class NSClientPlugin extends PluginBase {
.subscribe(event -> {
status = event.getStatus();
RxBus.Companion.getINSTANCE().send(new EventNSClientUpdateGUI());
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventNetworkChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), FabricPrivacy::logException)
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventPreferenceChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), FabricPrivacy::logException)
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAppExit.class)
@ -135,7 +135,7 @@ public class NSClientPlugin extends PluginBase {
if (nsClientService != null) {
MainApp.instance().getApplicationContext().unbindService(mConnection);
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventNSClientNewLog.class)
@ -144,12 +144,12 @@ public class NSClientPlugin extends PluginBase {
addToLog(event);
if (L.isEnabled(L.NSCLIENT))
log.debug(event.getAction() + " " + event.getLogText());
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventChargingState.class)
.observeOn(Schedulers.io())
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), FabricPrivacy::logException)
.subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -151,7 +151,7 @@ public class NSClientService extends DaggerService {
destroy();
initialize();
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventPreferenceChange.class)
@ -165,7 +165,7 @@ public class NSClientService extends DaggerService {
destroy();
initialize();
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventAppExit.class)
@ -175,7 +175,7 @@ public class NSClientService extends DaggerService {
log.debug("EventAppExit received");
destroy();
stopSelf();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventNSClientRestart.class)
@ -183,22 +183,22 @@ public class NSClientService extends DaggerService {
.subscribe(event -> {
latestDateInReceivedData = 0;
restart();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(NSAuthAck.class)
.observeOn(Schedulers.io())
.subscribe(this::processAuthAck, FabricPrivacy::logException)
.subscribe(this::processAuthAck, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(NSUpdateAck.class)
.observeOn(Schedulers.io())
.subscribe(this::processUpdateAck, FabricPrivacy::logException)
.subscribe(this::processUpdateAck, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(NSAddAck.class)
.observeOn(Schedulers.io())
.subscribe(this::processAddAck, FabricPrivacy::logException)
.subscribe(this::processAddAck, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -380,79 +380,79 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
.toObservable(EventRefreshOverview.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(eventOpenAPSUpdateGui -> scheduleUpdateGUI(eventOpenAPSUpdateGui.getFrom()),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventExtendedBolusChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventExtendedBolusChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventTempBasalChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventTempBasalChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventTreatmentChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventTreatmentChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventTempTargetChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventTempTargetChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventAcceptOpenLoopChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventAcceptOpenLoopChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventCareportalEventChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventCareportalEventChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventInitializationChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventInitializationChanged"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventAutosensCalculationFinished"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventProfileNeedsUpdate"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventPreferenceChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventPreferenceChange"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventNewOpenLoopNotification.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> scheduleUpdateGUI("EventNewOpenLoopNotification"),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventPumpStatusChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updatePumpStatus(event.getStatus()),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventIobCalculationProgress.class)
@ -461,7 +461,7 @@ public class OverviewFragment extends DaggerFragment implements View.OnClickList
if (iobCalculationProgressView != null)
iobCalculationProgressView.setText(event.getProgress());
},
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
sRefreshLoop = () -> {
scheduleUpdateGUI("refreshLoop");

View file

@ -19,7 +19,8 @@ import javax.inject.Singleton
@Singleton
class OverviewPlugin @Inject constructor(
private val rxBus: RxBusWrapper,
private val notificationStore: NotificationStore
private val notificationStore: NotificationStore,
private val fabricPrivacy: FabricPrivacy
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(OverviewFragment::class.qualifiedName)
@ -41,18 +42,14 @@ class OverviewPlugin @Inject constructor(
.subscribe({ n ->
if (notificationStore.add(n.notification))
rxBus.send(EventRefreshOverview("EventNewNotification"))
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventDismissNotification::class.java)
.observeOn(Schedulers.io())
.subscribe({ n ->
if (notificationStore.remove(n.id))
rxBus.send(EventRefreshOverview("EventDismissNotification"))
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
}
override fun onStop() {

View file

@ -11,7 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.utils.wizard.QuickWizard
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
import info.nightscout.androidaps.plugins.general.overview.events.EventQuickWizardChange
@ -19,6 +18,7 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.wizard.QuickWizard
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.overview_quickwizardlist_activity.*
@ -27,6 +27,7 @@ import javax.inject.Inject
class QuickWizardListActivity : NoSplashAppCompatActivity() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var quickWizard: QuickWizard
private var disposable: CompositeDisposable = CompositeDisposable()
@ -94,9 +95,7 @@ class QuickWizardListActivity : NoSplashAppCompatActivity() {
.subscribe({
val adapter = RecyclerViewAdapter(supportFragmentManager)
overview_quickwizardactivity_recyclerview?.swapAdapter(adapter, false)
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
}
override fun onPause() {

View file

@ -4,6 +4,7 @@ import android.app.Service
import android.content.Intent
import android.os.IBinder
import dagger.android.DaggerService
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -20,7 +21,8 @@ class DummyService : DaggerService() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var persistentNotificationPlugin: PersistentNotificationPlugin
@Inject lateinit var mainApp: MainApp
@Inject lateinit var fabricPrivacy: FabricPrivacy
private val disposable = CompositeDisposable()
@ -30,14 +32,14 @@ class DummyService : DaggerService() {
super.onCreate()
// TODO: I guess this was moved here in order to adhere to the 5 seconds rule to call "startForeground" after a Service was called as Foreground service?
// As onCreate() is not called every time a service is started, copied to onStartCommand().
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, persistentNotificationPlugin.getLastNotification())
startForeground(mainApp.notificationId(), mainApp.notification)
disposable.add(rxBus
.toObservable(EventAppExit::class.java)
.observeOn(Schedulers.io())
.subscribe({
aapsLogger.debug(LTag.CORE, "EventAppExit received")
stopSelf()
}) { FabricPrivacy.logException(it) }
}) { fabricPrivacy.logException(it) }
)
}
@ -50,7 +52,7 @@ class DummyService : DaggerService() {
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, persistentNotificationPlugin.getLastNotification())
startForeground(mainApp.notificationId(), mainApp.notification)
return Service.START_STICKY
}
}

View file

@ -50,6 +50,7 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
@Inject lateinit var mainApp: MainApp
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
@ -64,53 +65,49 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
// End Android auto
private val disposable = CompositeDisposable()
private var notification: Notification? = null
val CHANNEL_ID = "AndroidAPS-Ongoing"
val ONGOING_NOTIFICATION_ID = 4711
override fun onStart() {
override fun onStart() {
super.onStart()
createNotificationChannel() // make sure channels exist before triggering updates through the bus
disposable.add(rxBus
.toObservable(EventRefreshOverview::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTreatmentChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventNewBasalProfile::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ triggerNotificationUpdate(false) }) { FabricPrivacy.logException(it) })
triggerNotificationUpdate(true)
.subscribe({ triggerNotificationUpdate() }) { fabricPrivacy.logException(it) })
triggerNotificationUpdate()
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val mNotificationManager = mainApp.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(CHANNEL_ID, CHANNEL_ID as CharSequence, NotificationManager.IMPORTANCE_HIGH)
val channel = NotificationChannel(mainApp.channelId(), mainApp.channelId() as CharSequence, NotificationManager.IMPORTANCE_HIGH)
mNotificationManager.createNotificationChannel(channel)
}
}
@ -121,23 +118,21 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
super.onStop()
}
private fun triggerNotificationUpdate(boot: Boolean) {
updateNotification(boot)
private fun triggerNotificationUpdate() {
updateNotification()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
mainApp.startForegroundService(Intent(mainApp, DummyService::class.java))
else
mainApp.startService(Intent(mainApp, DummyService::class.java))
}
private fun updateNotification(boot: Boolean) {
private fun updateNotification() {
val pump = configBuilderPlugin.activePump ?: return
var line1: String?
var line2: String? = null
var line3: String? = null
var unreadConversationBuilder: NotificationCompat.CarExtender.UnreadConversation.Builder? = null
if (boot) {
line1 = resourceHelper.gs(R.string.loading)
} else if (profileFunction.isProfileValid("Notification")) {
if (profileFunction.isProfileValid("Notification")) {
var line1_aa: String
val units = profileFunction.getUnits()
val lastBG = DatabaseHelper.lastBg()
@ -179,20 +174,20 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
val msgReadIntent = Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(READ_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.putExtra(CONVERSATION_ID, mainApp.notificationId())
.setPackage(PACKAGE)
val msgReadPendingIntent = PendingIntent.getBroadcast(mainApp,
ONGOING_NOTIFICATION_ID,
mainApp.notificationId(),
msgReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
val msgReplyIntent = Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(REPLY_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.putExtra(CONVERSATION_ID, mainApp.notificationId())
.setPackage(PACKAGE)
val msgReplyPendingIntent = PendingIntent.getBroadcast(
mainApp,
ONGOING_NOTIFICATION_ID,
mainApp.notificationId(),
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
// Build a RemoteInput for receiving voice input from devices
@ -208,7 +203,7 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
} else {
line1 = resourceHelper.gs(R.string.noprofileset)
}
val builder = NotificationCompat.Builder(mainApp, CHANNEL_ID)
val builder = NotificationCompat.Builder(mainApp, mainApp.channelId())
builder.setOngoing(true)
builder.setOnlyAlertOnce(true)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
@ -234,13 +229,7 @@ class PersistentNotificationPlugin @Inject constructor() : PluginBase(PluginDesc
builder.setContentIntent(resultPendingIntent)
val mNotificationManager = mainApp.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = builder.build()
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification)
this.notification = notification
}
fun getLastNotification(): Notification {
if (notification == null)
updateNotification(true)
return notification!!
mNotificationManager.notify(mainApp.notificationId(), notification)
mainApp.notification = notification
}
}

View file

@ -20,8 +20,9 @@ import javax.inject.Inject
import kotlin.math.max
class SmsCommunicatorFragment : DaggerFragment() {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var fabricPrivacy : FabricPrivacy
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
private val disposable = CompositeDisposable()
@ -36,7 +37,7 @@ class SmsCommunicatorFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventSmsCommunicatorUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
updateGui()
}

View file

@ -58,6 +58,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private val aapsLogger: AAPSLogger,
private val rxBus: RxBusWrapper,
private val profileFunction: ProfileFunction,
private val fabricPrivacy: FabricPrivacy,
private val configBuilderPlugin: ConfigBuilderPlugin,
private val treatmentsPlugin: TreatmentsPlugin,
private val loopPlugin: LoopPlugin,
@ -100,7 +101,7 @@ class SmsCommunicatorPlugin @Inject constructor(
disposable += rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ event: EventPreferenceChange? -> processSettings(event) }) { FabricPrivacy.logException(it) }
.subscribe({ event: EventPreferenceChange? -> processSettings(event) }) { fabricPrivacy.logException(it) }
}
override fun onStop() {

View file

@ -25,6 +25,7 @@ class TidepoolFragment : DaggerFragment() {
@Inject lateinit var tidepoolPlugin: TidepoolPlugin
@Inject lateinit var tidepoolUploader: TidepoolUploader
@Inject lateinit var sp: SP
@Inject lateinit var fabricPrivacy: FabricPrivacy
private var disposable: CompositeDisposable = CompositeDisposable()
@ -52,9 +53,7 @@ class TidepoolFragment : DaggerFragment() {
tidepool_status?.text = tidepoolUploader.connectionStatus.name
tidepool_log?.text = tidepoolPlugin.textLog
tidepool_logscrollview?.fullScroll(ScrollView.FOCUS_DOWN)
}, {
FabricPrivacy.logException(it)
})
}, { fabricPrivacy.logException(it) })
}
@Synchronized

View file

@ -44,6 +44,7 @@ class TidepoolPlugin @Inject constructor(
private val rxBus: RxBusWrapper,
private val mainApp: MainApp,
private val resourceHelper: ResourceHelper,
private val fabricPrivacy: FabricPrivacy,
private val tidepoolUploader: TidepoolUploader,
private val uploadChunk: UploadChunk,
private val sp: SP
@ -66,9 +67,7 @@ class TidepoolPlugin @Inject constructor(
disposable += rxBus
.toObservable(EventTidepoolDoUpload::class.java)
.observeOn(Schedulers.io())
.subscribe({ doUpload() }, {
FabricPrivacy.logException(it)
})
.subscribe({ doUpload() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventTidepoolResetData::class.java)
.observeOn(Schedulers.io())
@ -81,13 +80,13 @@ class TidepoolPlugin @Inject constructor(
tidepoolUploader.doLogin()
}
}, {
FabricPrivacy.logException(it)
fabricPrivacy.logException(it)
})
disposable += rxBus
.toObservable(EventTidepoolStatus::class.java)
.observeOn(Schedulers.io())
.subscribe({ event -> addToLog(event) }, {
FabricPrivacy.logException(it)
fabricPrivacy.logException(it)
})
disposable += rxBus
.toObservable(EventNewBG::class.java)
@ -103,7 +102,7 @@ class TidepoolPlugin @Inject constructor(
&& RateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt()))
doUpload()
}, {
FabricPrivacy.logException(it)
fabricPrivacy.logException(it)
})
disposable += rxBus
.toObservable(EventPreferenceChange::class.java)
@ -115,13 +114,13 @@ class TidepoolPlugin @Inject constructor(
)
tidepoolUploader.resetInstance()
}, {
FabricPrivacy.logException(it)
fabricPrivacy.logException(it)
})
disposable += rxBus
.toObservable(EventNetworkChange::class.java)
.observeOn(Schedulers.io())
.subscribe({}, {
FabricPrivacy.logException(it)
fabricPrivacy.logException(it)
}) // TODO start upload on wifi connect
}

View file

@ -29,6 +29,7 @@ class WearPlugin @Inject constructor(
private val resourceHelper: ResourceHelper,
private val sp: SP,
private val mainApp: MainApp,
private val fabricPrivacy: FabricPrivacy,
private val loopPlugin: Lazy<LoopPlugin>
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -45,27 +46,27 @@ class WearPlugin @Inject constructor(
disposable.add(rxBus
.toObservable(EventOpenAPSUpdateGui::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTreatmentChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventNewBasalProfile::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = false, basals = true, bgValue = false) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = false, basals = true, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = true) }) { FabricPrivacy.logException(it) })
.subscribe({ sendDataToWatch(status = true, basals = true, bgValue = true) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
@ -74,13 +75,13 @@ class WearPlugin @Inject constructor(
resendDataToWatch()
// status may be formatted differently
sendDataToWatch(status = true, basals = false, bgValue = false)
}) { FabricPrivacy.logException(it) })
}) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventRefreshOverview::class.java)
.observeOn(Schedulers.io())
.subscribe({
if (WatchUpdaterService.shouldReportLoopStatus(loopPlugin.get().isEnabled(PluginType.LOOP)))
sendDataToWatch(status = true, basals = false, bgValue = false) }) { FabricPrivacy.logException(it) })
sendDataToWatch(status = true, basals = false, bgValue = false) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventBolusRequested::class.java)
.observeOn(Schedulers.io())
@ -90,7 +91,7 @@ class WearPlugin @Inject constructor(
intent.putExtra("progresspercent", 0)
intent.putExtra("progressstatus", status)
mainApp.startService(intent)
}) { FabricPrivacy.logException(it) })
}) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventDismissBolusProgressIfRunning::class.java)
.observeOn(Schedulers.io())
@ -105,7 +106,7 @@ class WearPlugin @Inject constructor(
intent.putExtra("progresspercent", 100)
intent.putExtra("progressstatus", status)
mainApp.startService(intent)
}) { FabricPrivacy.logException(it) })
}) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventOverviewBolusProgress::class.java)
.observeOn(Schedulers.io())
@ -116,7 +117,7 @@ class WearPlugin @Inject constructor(
intent.putExtra("progressstatus", event.status)
mainApp.startService(intent)
}
}) { FabricPrivacy.logException(it) })
}) { fabricPrivacy.logException(it) })
}
override fun onStop() {

View file

@ -33,6 +33,7 @@ class StatusLinePlugin @Inject constructor(
private val profileFunction: ProfileFunction,
private val resourceHelper: ResourceHelper,
private val mainApp: MainApp,
private val fabricPrivacy: FabricPrivacy,
private val configBuilderPlugin: ConfigBuilderPlugin,
private val treatmentsPlugin: TreatmentsPlugin,
private val loopPlugin: LoopPlugin,
@ -63,28 +64,28 @@ class StatusLinePlugin @Inject constructor(
super.onStart()
disposable += rxBus.toObservable(EventRefreshOverview::class.java)
.observeOn(Schedulers.io())
.subscribe({ if (lastLoopStatus != loopPlugin.isEnabled(PluginType.LOOP)) sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ if (lastLoopStatus != loopPlugin.isEnabled(PluginType.LOOP)) sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventTempBasalChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventTreatmentChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventConfigBuilderChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventAppInitialized::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ sendStatus() }) { fabricPrivacy.logException(it) }
}
override fun onStop() {

View file

@ -37,7 +37,7 @@ public class InsulinFragment extends Fragment {
return view;
} catch (Exception e) {
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
}
return null;

View file

@ -128,7 +128,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
autosensDataTable = new LongSparseArray<>();
}
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, true, event);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
// EventNewBasalProfile
disposable.add(rxBus
@ -146,7 +146,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
basalDataTable = new LongSparseArray<>();
}
runCalculation("onNewProfile", System.currentTimeMillis(), false, true, event);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
// EventNewBG
disposable.add(rxBus
@ -155,7 +155,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
.subscribe(event -> {
stopCalculation("onEventNewBG");
runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, event);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
// EventPreferenceChange
disposable.add(rxBus
@ -180,19 +180,19 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, true, event);
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
// EventAppInitialized
disposable.add(rxBus
.toObservable(EventAppInitialized.class)
.observeOn(Schedulers.io())
.subscribe(event -> runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, true, event), FabricPrivacy::logException)
.subscribe(event -> runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, true, event), exception -> FabricPrivacy.getInstance().logException(exception))
);
// EventNewHistoryData
disposable.add(rxBus
.toObservable(EventNewHistoryData.class)
.observeOn(Schedulers.io())
.subscribe(event -> newHistoryData(event), FabricPrivacy::logException)
.subscribe(event -> newHistoryData(event), exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -222,7 +222,7 @@ public class IobCobOref1Thread extends Thread {
}
} catch (Exception e) {
log.error("Unhandled exception", e);
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());

View file

@ -221,7 +221,7 @@ public class IobCobThread extends Thread {
}
} catch (Exception e) {
log.error("Unhandled exception", e);
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logException(e);
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());

View file

@ -30,6 +30,7 @@ class LocalProfileFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
private var disposable: CompositeDisposable = CompositeDisposable()
@ -207,7 +208,7 @@ class LocalProfileFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventLocalProfileChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ build() }, { FabricPrivacy.logException(it) }
.subscribe({ build() }, { fabricPrivacy.logException(it) }
)
build()
}

View file

@ -39,6 +39,7 @@ class LocalProfilePlugin @Inject constructor(
) : PluginBase(PluginDescription()
.mainType(PluginType.PROFILE)
.fragmentClass(LocalProfileFragment::class.java.name)
.enableByDefault(true)
.pluginName(R.string.localprofile)
.shortName(R.string.localprofile_shortname)
.description(R.string.description_profile_local)), ProfileInterface {

View file

@ -30,6 +30,7 @@ class NSProfileFragment : DaggerFragment() {
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var profileFunction: ProfileFunction
private var disposable: CompositeDisposable = CompositeDisposable()
@ -108,7 +109,7 @@ class NSProfileFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventNSProfileUpdateGUI::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -72,12 +72,12 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventComboPumpUpdateGUI.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventQueueChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGui();
}

View file

@ -97,7 +97,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
.observeOn(Schedulers.io())
.subscribe(event -> {
MainApp.instance().getApplicationContext().unbindService(serviceConnection);
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
onStartCustomActions();
}

View file

@ -39,6 +39,7 @@ import javax.inject.Inject
class DanaRFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var danaRKoreanPlugin: DanaRKoreanPlugin
@ -100,19 +101,19 @@ class DanaRFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventDanaRNewStatus::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventQueueChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
@ -134,7 +135,7 @@ class DanaRFragment : DaggerFragment() {
} else {
dana_pumpstatuslayout?.visibility = View.GONE
}
}, { FabricPrivacy.logException(it) })
}, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -99,12 +99,12 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
sExecutionService.extendedBolusStop();
}
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> mainApp.unbindService(mConnection), FabricPrivacy::logException)
.subscribe(event -> mainApp.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
);
super.onStart();
}

View file

@ -43,6 +43,7 @@ class DanaRHistoryActivity : NoSplashAppCompatActivity() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var danaRKoreanPlugin: DanaRKoreanPlugin
@Inject lateinit var danaRSPlugin: DanaRSPlugin
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@ -61,14 +62,14 @@ class DanaRHistoryActivity : NoSplashAppCompatActivity() {
disposable += rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ danar_history_status.text = it.getStatus() }) { FabricPrivacy.logException(it) }
.subscribe({ danar_history_status.text = it.getStatus() }) { fabricPrivacy.logException(it) }
disposable += rxBus
.toObservable(EventDanaRSyncStatus::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
aapsLogger.debug(LTag.PUMP, "EventDanaRSyncStatus: " + it.message)
danar_history_status.text = it.message
}) { FabricPrivacy.logException(it) }
}) { fabricPrivacy.logException(it) }
}
override fun onPause() {

View file

@ -33,6 +33,7 @@ import kotlin.math.min
class DanaRUserOptionsActivity : NoSplashAppCompatActivity() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var mainApp: MainApp
@Inject lateinit var danaRSPlugin: DanaRSPlugin
@ -54,7 +55,7 @@ class DanaRUserOptionsActivity : NoSplashAppCompatActivity() {
disposable += rxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ setData() }) { FabricPrivacy.logException(it) }
.subscribe({ setData() }) { fabricPrivacy.logException(it) }
}
@Synchronized

View file

@ -88,7 +88,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService {
.subscribe(event -> {
if (mSerialIOThread != null)
mSerialIOThread.disconnect("EventPreferenceChange");
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAppExit.class)
@ -101,7 +101,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.disconnect("Application exit");
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
stopSelf();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -102,12 +102,12 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
sExecutionService.extendedBolusStop();
}
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> mainApp.unbindService(mConnection), FabricPrivacy::logException)
.subscribe(event -> mainApp.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
);
super.onStart();
}

View file

@ -80,7 +80,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
.subscribe(event -> {
if (mSerialIOThread != null)
mSerialIOThread.disconnect("EventPreferenceChange");
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAppExit.class)
@ -93,7 +93,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.disconnect("Application exit");
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
stopSelf();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -145,12 +145,12 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> mainApp.unbindService(mConnection), FabricPrivacy::logException)
.subscribe(event -> mainApp.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventDanaRSDeviceChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> loadAddress(), FabricPrivacy::logException)
.subscribe(event -> loadAddress(), exception -> FabricPrivacy.getInstance().logException(exception))
);
loadAddress(); // load device name
super.onStart();

View file

@ -112,7 +112,7 @@ public class PairingProgressDialog extends DialogFragment {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventDanaRSPairingSuccess.class)
.observeOn(Schedulers.io())
.subscribe(event -> pairingEnded = true, FabricPrivacy::logException)
.subscribe(event -> pairingEnded = true, exception -> FabricPrivacy.getInstance().logException(exception))
);
if (pairingEnded) dismiss();
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

View file

@ -110,7 +110,7 @@ public class DanaRSService extends Service {
.subscribe(event -> {
if (L.isEnabled(L.PUMP)) log.debug("EventAppExit received");
stopSelf();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -94,7 +94,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> mainApp.unbindService(mConnection), FabricPrivacy::logException)
.subscribe(event -> mainApp.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
);
super.onStart();
}

View file

@ -104,7 +104,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
.subscribe(event -> {
if (mSerialIOThread != null)
mSerialIOThread.disconnect("EventPreferenceChange");
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAppExit.class)
@ -117,7 +117,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.disconnect("Application exit");
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
stopSelf();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -72,7 +72,7 @@ public class LocalInsightFragment extends Fragment implements View.OnClickListen
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventLocalInsightUpdateGUI.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGUI(), FabricPrivacy::logException)
.subscribe(event -> updateGUI(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGUI();
}

View file

@ -49,6 +49,7 @@ import javax.inject.Inject
class MedtronicFragment : DaggerFragment() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var mainApp: MainApp
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@ -118,26 +119,26 @@ class MedtronicFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventRefreshButtonState::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ medtronic_refresh.isEnabled = it.newState }, { FabricPrivacy.logException(it) })
.subscribe({ medtronic_refresh.isEnabled = it.newState }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventMedtronicDeviceStatusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
aapsLogger.debug(LTag.PUMP, "onStatusEvent(EventMedtronicDeviceStatusChange): $it")
setDeviceStatus()
}, { FabricPrivacy.logException(it) })
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventMedtronicPumpValuesChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventMedtronicPumpConfigurationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
@ -145,15 +146,15 @@ class MedtronicFragment : DaggerFragment() {
aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered")
MedtronicUtil.getPumpStatus().verifyConfiguration()
updateGUI()
}, { FabricPrivacy.logException(it) })
}, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventQueueChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGUI() }, { fabricPrivacy.logException(it) })
updateGUI()
}

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.medtronic;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
@ -25,9 +24,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
@ -44,7 +43,6 @@ import info.nightscout.androidaps.plugins.common.ManufacturerType;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction;
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
@ -100,8 +98,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// variables for handling statuses and history
private boolean firstRun = true;
private boolean isRefresh = false;
private boolean isBasalProfileInvalid = false;
private boolean basalProfileChanged = false;
private Map<MedtronicStatusRefreshType, Long> statusRefreshMap = new HashMap<>();
private boolean isInitialized = false;
private MedtronicHistoryData medtronicHistoryData;
@ -110,7 +106,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
public static boolean isBusy = false;
private List<Long> busyTimestamps = new ArrayList<>();
private boolean sentIdToFirebase = false;
private boolean hasTimeDateOrTimeZoneChanged = false;
@ -577,14 +572,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
pumpState = PumpDriverState.Initialized;
}
if (!sentIdToFirebase) {
Bundle params = new Bundle();
params.putString("version", BuildConfig.VERSION);
MainApp.getFirebaseAnalytics().logEvent("MedtronicPumpInit", params);
sentIdToFirebase = true;
}
isInitialized = true;
// this.pumpState = PumpDriverState.Initialized;

View file

@ -24,6 +24,7 @@ import javax.inject.Inject
class VirtualPumpFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var virtualPumpPlugin: VirtualPumpPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@ -49,15 +50,15 @@ class VirtualPumpFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventVirtualPumpUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
.subscribe({ updateGui() }, { fabricPrivacy.logException(it) })
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
updateGui()
}

View file

@ -47,6 +47,7 @@ import javax.inject.Singleton
class VirtualPumpPlugin @Inject constructor(
private val aapsLogger: AAPSLogger,
private val rxBus: RxBusWrapper,
private var fabricPrivacy: FabricPrivacy,
private val resourceHelper: ResourceHelper,
private val sp: SP,
private val profileFunction: ProfileFunction,
@ -117,7 +118,7 @@ class VirtualPumpPlugin @Inject constructor(
disposable += rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ event: EventPreferenceChange -> if (event.isChanged(resourceHelper, R.string.key_virtualpump_type)) refreshConfiguration() }) { FabricPrivacy.logException(it) }
.subscribe({ event: EventPreferenceChange -> if (event.isChanged(resourceHelper, R.string.key_virtualpump_type)) refreshConfiguration() }) { fabricPrivacy.logException(it) }
refreshConfiguration()
}

View file

@ -29,6 +29,7 @@ import javax.inject.Inject
class BGSourceFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@ -55,7 +56,7 @@ class BGSourceFragment : DaggerFragment() {
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGUI() }) { fabricPrivacy.logException(it) }
)
}

View file

@ -73,7 +73,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
} else { // EventNsTreatment.REMOVE
this.deleteNS(payload);
}
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -23,6 +23,7 @@ import javax.inject.Inject
class TreatmentsFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
private val disposable = CompositeDisposable()
@ -73,7 +74,7 @@ class TreatmentsFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
updateGui()
}

View file

@ -139,19 +139,19 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
updateTotalIOBTreatments();
rxBus.send(event.getNext());
},
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventReloadProfileSwitchData.class)
.observeOn(Schedulers.io())
.subscribe(event -> initializeProfileSwitchData(range()),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventTempTargetChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> initializeTempTargetData(range()),
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
disposable.add(rxBus
.toObservable(EventReloadTempBasalData.class)
@ -161,7 +161,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
initializeTempBasalData(range());
updateTotalIOBTempBasals();
},
FabricPrivacy::logException
exception -> FabricPrivacy.getInstance().logException(exception)
));
}

View file

@ -39,6 +39,7 @@ class TreatmentsBolusFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var profileFunction: ProfileFunction
@ -84,12 +85,12 @@ class TreatmentsBolusFragment : DaggerFragment() {
disposable.add(rxBus
.toObservable(EventTreatmentChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
)
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
)
updateGui()
}

View file

@ -36,6 +36,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -82,7 +83,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
disposable.add(rxBus
.toObservable(EventCareportalEventChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGui() }) { fabricPrivacy.logException(it) }
)
updateGui()
}

View file

@ -169,12 +169,12 @@ public class TreatmentsExtendedBolusesFragment extends Fragment {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventExtendedBolusChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAutosensCalculationFinished.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGui();
}

View file

@ -42,6 +42,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
@Inject lateinit var sp: SP
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -72,7 +73,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }) { FabricPrivacy.logException(it) }
.subscribe({ updateGUI() }) { fabricPrivacy.logException(it) }
)
updateGUI()
}

View file

@ -181,7 +181,7 @@ public class TreatmentsTempTargetFragment extends Fragment {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventTempTargetChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGui();
}

View file

@ -199,12 +199,12 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment {
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventTempBasalChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(RxBus.Companion.getINSTANCE()
.toObservable(EventAutosensCalculationFinished.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGui(), FabricPrivacy::logException)
.subscribe(event -> updateGui(), exception -> FabricPrivacy.getInstance().logException(exception))
);
updateGui();
}

View file

@ -6,17 +6,17 @@ import android.media.AudioManager
import android.media.MediaPlayer
import android.os.IBinder
import dagger.android.DaggerService
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class AlarmSoundService : DaggerService() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var persistentNotificationPlugin: PersistentNotificationPlugin
@Inject lateinit var mainApp: MainApp
private var player: MediaPlayer? = null
private var resourceId = R.raw.error
@ -26,13 +26,11 @@ class AlarmSoundService : DaggerService() {
override fun onCreate() {
super.onCreate()
aapsLogger.debug(LTag.CORE, "onCreate")
val notification = persistentNotificationPlugin.getLastNotification()
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification)
startForeground(mainApp.notificationId(), mainApp.notification)
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val notification = persistentNotificationPlugin.getLastNotification()
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification)
startForeground(mainApp.notificationId(), mainApp.notification)
player?.let { if (it.isPlaying) it.stop() }

View file

@ -10,17 +10,15 @@ import android.location.LocationManager
import android.os.Bundle
import android.os.IBinder
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.tasks.OnSuccessListener
import dagger.android.DaggerService
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventLocationChange
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -32,7 +30,8 @@ class LocationService : DaggerService() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var persistentNotificationPlugin: PersistentNotificationPlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var mainApp: MainApp
private val disposable = CompositeDisposable()
private var locationManager: LocationManager? = null
@ -77,13 +76,13 @@ class LocationService : DaggerService() {
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, persistentNotificationPlugin.getLastNotification())
startForeground(mainApp.notificationId(), mainApp.getNotification())
return Service.START_STICKY
}
override fun onCreate() {
super.onCreate()
startForeground(persistentNotificationPlugin.ONGOING_NOTIFICATION_ID, persistentNotificationPlugin.getLastNotification())
startForeground(mainApp.notificationId(), mainApp.getNotification())
// Get last location once until we get regular update
LocationServices.getFusedLocationProviderClient(this).lastLocation.addOnSuccessListener {
@ -122,7 +121,7 @@ class LocationService : DaggerService() {
.subscribe({
aapsLogger.debug(LTag.LOCATION, "EventAppExit received")
stopSelf()
}) { FabricPrivacy.logException(it) }
}) { fabricPrivacy.logException(it) }
)
}

View file

@ -248,7 +248,6 @@ class SWDefinition @Inject constructor(
.add(SWPlugin()
.option(PluginType.PROFILE, R.string.configbuilder_profile_description)
.label(R.string.configbuilder_profile))
.validator { configBuilderPlugin.activeProfileInterface != null }
private val screenNsProfile = SWScreen(R.string.nsprofile)
.skippable(false)
.add(SWInfotext()

View file

@ -90,22 +90,22 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity {
disposable.add(rxBus
.toObservable(EventPumpStatusChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateButtons(), FabricPrivacy::logException)
.subscribe(event -> updateButtons(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventNSClientStatus.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateButtons(), FabricPrivacy::logException)
.subscribe(event -> updateButtons(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateButtons(), FabricPrivacy::logException)
.subscribe(event -> updateButtons(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventProfileStoreChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateButtons(), FabricPrivacy::logException)
.subscribe(event -> updateButtons(), exception -> FabricPrivacy.getInstance().logException(exception))
);
disposable.add(rxBus
.toObservable(EventSWUpdate.class)
@ -113,7 +113,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity {
.subscribe(event -> {
if (event.getRedraw()) generateLayout();
updateButtons();
}, FabricPrivacy::logException)
}, exception -> FabricPrivacy.getInstance().logException(exception))
);
}

View file

@ -1,152 +0,0 @@
package info.nightscout.androidaps.utils;
import android.os.Bundle;
import com.crashlytics.android.Crashlytics;
import com.google.firebase.analytics.FirebaseAnalytics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Locale;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin;
/**
* Created by jamorham on 21/02/2018.
* <p>
* Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way
* to disable them and make calls from a potentially invalid singleton reference. This wrapper
* emulates the methods but ignores the request if the instance is null or invalid.
*/
public class FabricPrivacy {
private static Logger log = LoggerFactory.getLogger(L.CORE);
private static volatile FabricPrivacy instance;
public static FabricPrivacy getInstance() {
if (instance == null) {
initSelf();
}
return instance;
}
private static synchronized void initSelf() {
if (instance == null) {
instance = new FabricPrivacy();
}
}
// Crashlytics logException
public static void logException(Throwable throwable) {
try {
final Crashlytics crashlytics = Crashlytics.getInstance();
crashlytics.core.logException(throwable);
} catch (NullPointerException | IllegalStateException e) {
if (L.isEnabled(L.CORE))
log.debug("Ignoring opted out non-initialized log: " + throwable);
}
}
// Crashlytics log
public static void log(String msg) {
try {
final Crashlytics crashlytics = Crashlytics.getInstance();
crashlytics.core.log(msg);
} catch (NullPointerException | IllegalStateException e) {
if (L.isEnabled(L.CORE))
log.debug("Ignoring opted out non-initialized log: " + msg);
}
}
// Crashlytics log
public static void log(int priority, String tag, String msg) {
try {
final Crashlytics crashlytics = Crashlytics.getInstance();
crashlytics.core.log(priority, tag, msg);
} catch (NullPointerException | IllegalStateException e) {
if (L.isEnabled(L.CORE))
log.debug("Ignoring opted out non-initialized log: " + msg);
}
}
public static boolean fabricEnabled() {
return SP.getBoolean("enable_fabric", true);
}
// Analytics logCustom
public void logCustom(Bundle event) {
try {
if (fabricEnabled()) {
MainApp.getFirebaseAnalytics().logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, event);
} else {
if (L.isEnabled(L.CORE))
log.debug("Ignoring recently opted-out event: " + event.toString());
}
} catch (NullPointerException | IllegalStateException e) {
if (L.isEnabled(L.CORE))
log.debug("Ignoring opted-out non-initialized event: " + event.toString());
}
}
// Analytics logCustom
public void logCustom(String event) {
try {
if (fabricEnabled()) {
MainApp.getFirebaseAnalytics().logEvent(event, new Bundle());
} else {
if (L.isEnabled(L.CORE))
log.debug("Ignoring recently opted-out event: " + event);
}
} catch (NullPointerException | IllegalStateException e) {
if (L.isEnabled(L.CORE))
log.debug("Ignoring opted-out non-initialized event: " + event);
}
}
public static void setUserStats() {
if (!fabricEnabled()) return;
String closedLoopEnabled = ConstraintChecker.getInstance().isClosedLoopAllowed().value() ? "CLOSED_LOOP_ENABLED" : "CLOSED_LOOP_DISABLED";
// Size is limited to 36 chars
String remote = BuildConfig.REMOTE.toLowerCase()
.replace("https://", "")
.replace("http://", "")
.replace(".git", "")
.replace(".com/", ":")
.replace(".org/", ":")
.replace(".net/", ":");
MainApp.getFirebaseAnalytics().setUserProperty("Mode", BuildConfig.APPLICATION_ID + "-" + closedLoopEnabled);
MainApp.getFirebaseAnalytics().setUserProperty("Language", SP.getString(R.string.key_language, Locale.getDefault().getLanguage()));
MainApp.getFirebaseAnalytics().setUserProperty("Version", BuildConfig.VERSION);
MainApp.getFirebaseAnalytics().setUserProperty("HEAD", BuildConfig.HEAD);
MainApp.getFirebaseAnalytics().setUserProperty("Remote", remote);
List<String> hashes = SignatureVerifierPlugin.getPlugin().shortHashes();
if (hashes.size() >= 1)
MainApp.getFirebaseAnalytics().setUserProperty("Hash", hashes.get(0));
if (ConfigBuilderPlugin.getPlugin().getActivePump() != null)
MainApp.getFirebaseAnalytics().setUserProperty("Pump", ConfigBuilderPlugin.getPlugin().getActivePump().getClass().getSimpleName());
if (ConfigBuilderPlugin.getPlugin().getActiveAPS() != null)
MainApp.getFirebaseAnalytics().setUserProperty("Aps", ConfigBuilderPlugin.getPlugin().getActiveAPS().getClass().getSimpleName());
if (ConfigBuilderPlugin.getPlugin().getActiveBgSource() != null)
MainApp.getFirebaseAnalytics().setUserProperty("BgSource", ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().getSimpleName());
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null)
MainApp.getFirebaseAnalytics().setUserProperty("Profile", ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getSimpleName());
if (ConfigBuilderPlugin.getPlugin().getActiveSensitivity() != null)
MainApp.getFirebaseAnalytics().setUserProperty("Sensitivity", ConfigBuilderPlugin.getPlugin().getActiveSensitivity().getClass().getSimpleName());
if (ConfigBuilderPlugin.getPlugin().getActiveInsulin() != null)
MainApp.getFirebaseAnalytics().setUserProperty("Insulin", ConfigBuilderPlugin.getPlugin().getActiveInsulin().getClass().getSimpleName());
}
}

View file

@ -0,0 +1,139 @@
package info.nightscout.androidaps.utils
import android.os.Bundle
import com.crashlytics.android.Crashlytics
import com.google.firebase.analytics.FirebaseAnalytics
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
/**
* Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way
* to disable them and make calls from a potentially invalid singleton reference. This wrapper
* emulates the methods but ignores the request if the instance is null or invalid.
*/
@Singleton
class FabricPrivacy @Inject constructor(
private val aapsLogger: AAPSLogger,
private val sp: SP,
private val constraintChecker: ConstraintChecker,
private val mainApp: MainApp,
private val signatureVerifierPlugin: SignatureVerifierPlugin,
private val configBuilderPlugin: ConfigBuilderPlugin
) {
init {
instance = this
}
companion object {
private lateinit var instance: FabricPrivacy
@JvmStatic
fun getInstance(): FabricPrivacy = instance
}
// Analytics logCustom
fun logCustom(event: Bundle) {
try {
if (fabricEnabled()) {
mainApp.firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, event)
} else {
aapsLogger.debug(LTag.CORE, "Ignoring recently opted-out event: $event")
}
} catch (e: NullPointerException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted-out non-initialized event: $event")
} catch (e: IllegalStateException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted-out non-initialized event: $event")
}
}
// Analytics logCustom
fun logCustom(event: String) {
try {
if (fabricEnabled()) {
mainApp.firebaseAnalytics.logEvent(event, Bundle())
} else {
aapsLogger.debug(LTag.CORE, "Ignoring recently opted-out event: $event")
}
} catch (e: NullPointerException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted-out non-initialized event: $event")
} catch (e: IllegalStateException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted-out non-initialized event: $event")
}
}
// Crashlytics logException
fun logException(throwable: Throwable) {
try {
val crashlytics = Crashlytics.getInstance()
crashlytics.core.logException(throwable)
} catch (e: NullPointerException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $throwable")
} catch (e: IllegalStateException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $throwable")
}
}
// Crashlytics log
fun log(msg: String) {
try {
val crashlytics = Crashlytics.getInstance()
crashlytics.core.log(msg)
} catch (e: NullPointerException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg")
} catch (e: IllegalStateException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg")
}
}
// Crashlytics log
fun log(priority: Int, tag: String?, msg: String) {
try {
val crashlytics = Crashlytics.getInstance()
crashlytics.core.log(priority, tag, msg)
} catch (e: NullPointerException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg")
} catch (e: IllegalStateException) {
aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg")
}
}
fun fabricEnabled(): Boolean {
return sp.getBoolean(R.string.key_enable_fabric, true)
}
fun setUserStats() {
if (!fabricEnabled()) return
val closedLoopEnabled = if (constraintChecker.isClosedLoopAllowed().value()) "CLOSED_LOOP_ENABLED" else "CLOSED_LOOP_DISABLED"
// Size is limited to 36 chars
val remote = BuildConfig.REMOTE.toLowerCase(Locale.getDefault())
.replace("https://", "")
.replace("http://", "")
.replace(".git", "")
.replace(".com/", ":")
.replace(".org/", ":")
.replace(".net/", ":")
mainApp.firebaseAnalytics.setUserProperty("Mode", BuildConfig.APPLICATION_ID + "-" + closedLoopEnabled)
mainApp.firebaseAnalytics.setUserProperty("Language", sp.getString(R.string.key_language, Locale.getDefault().language))
mainApp.firebaseAnalytics.setUserProperty("Version", BuildConfig.VERSION)
mainApp.firebaseAnalytics.setUserProperty("HEAD", BuildConfig.HEAD)
mainApp.firebaseAnalytics.setUserProperty("Remote", remote)
val hashes: List<String> = signatureVerifierPlugin.shortHashes()
if (hashes.isNotEmpty()) mainApp.firebaseAnalytics.setUserProperty("Hash", hashes[0])
configBuilderPlugin.activePump?.let { mainApp.firebaseAnalytics.setUserProperty("Pump", it::class.java.simpleName) }
configBuilderPlugin.activeAPS?.let { mainApp.firebaseAnalytics.setUserProperty("Aps", it::class.java.simpleName) }
configBuilderPlugin.activeBgSource?.let { mainApp.firebaseAnalytics.setUserProperty("BgSource", it::class.java.simpleName) }
mainApp.firebaseAnalytics.setUserProperty("Profile", configBuilderPlugin.activeProfileInterface.javaClass.simpleName)
configBuilderPlugin.activeSensitivity?.let { mainApp.firebaseAnalytics.setUserProperty("Sensitivity", it::class.java.simpleName) }
configBuilderPlugin.activeInsulin?.let { mainApp.firebaseAnalytics.setUserProperty("Insulin", it::class.java.simpleName) }
}
}

View file

@ -1691,5 +1691,6 @@
<string name="key_snoozedTo" translatable="false">snoozedTo</string>
<string name="key_snooze_dst_in24h" translatable="false">snooze_dst_in24h</string>
<string name="key_snooze_loopdisabled" translatable="false">snooze_loopdisabled</string>
<string name="key_enable_fabric">enable_fabric</string>
</resources>

View file

@ -9,7 +9,7 @@
<SwitchPreference
android:defaultValue="true"
android:key="enable_fabric"
android:key="@string/key_enable_fabric"
android:summary="@string/allow_automated_crash_reporting"
android:title="@string/fabric_upload" />