From 4ca906ee8f48ec46513c248f9ff3e2b2986cdc99 Mon Sep 17 00:00:00 2001
From: Volker Richert <v.richert@addmore.de>
Date: Sun, 8 Jan 2017 13:26:18 +0100
Subject: [PATCH] split MedtronicCnlAlarmReceiver into AlarmReceiver &
 AlarmManager reduce poll interval to half in case of pump isn't near CNL

---
 .../android/medtronic/MainActivity.java       |  9 +-
 .../service/MedtronicCnlAlarmManager.java     | 83 +++++++++++++++++++
 .../service/MedtronicCnlAlarmReceiver.java    | 55 +-----------
 .../service/MedtronicCnlIntentService.java    |  4 +
 4 files changed, 92 insertions(+), 59 deletions(-)
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java

diff --git a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
index ee789de..067b36e 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
@@ -75,6 +75,7 @@ import info.nightscout.android.R;
 import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.eula.Eula;
 import info.nightscout.android.eula.Eula.OnEulaAgreedTo;
+import info.nightscout.android.medtronic.service.MedtronicCnlAlarmManager;
 import info.nightscout.android.medtronic.service.MedtronicCnlAlarmReceiver;
 import info.nightscout.android.medtronic.service.MedtronicCnlIntentService;
 import info.nightscout.android.model.medtronicNg.PumpInfo;
@@ -328,7 +329,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
 
         // setup self handling alarm receiver
-        medtronicCnlAlarmReceiver.setContext(getBaseContext());
+        MedtronicCnlAlarmManager.setContext(getBaseContext());
     }
 
     @Override
@@ -403,11 +404,9 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             return;
         }
 
-        //clearLogText();
-
         // Cancel any existing polling.
         stopCgmService();
-        medtronicCnlAlarmReceiver.setAlarm(initialPoll);
+        MedtronicCnlAlarmManager.setAlarm(initialPoll);
     }
 
     private void uploadCgmData() {
@@ -416,7 +415,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
 
     private void stopCgmService() {
         Log.i(TAG, "stopCgmService called");
-        medtronicCnlAlarmReceiver.cancelAlarm();
+        MedtronicCnlAlarmManager.cancelAlarm();
     }
 
     private void showDisconnectionNotification(String title, String message) {
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java
new file mode 100644
index 0000000..9547688
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java
@@ -0,0 +1,83 @@
+package info.nightscout.android.medtronic.service;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.support.v4.content.WakefulBroadcastReceiver;
+import android.util.Log;
+
+import java.util.Date;
+
+import info.nightscout.android.medtronic.MainActivity;
+
+/**
+ * Created by lgoedhart on 14/07/2016.
+ */
+public class MedtronicCnlAlarmManager {
+    private static final String TAG = MedtronicCnlAlarmManager.class.getSimpleName();
+    private static final int ALARM_ID = 102; // Alarm id
+
+    private static PendingIntent pendingIntent = null;
+    private static AlarmManager alarmManager = null;
+    private static long nextAlarm = Long.MAX_VALUE;
+
+    public static void setContext(Context context) {
+        cancelAlarm();
+
+        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        Intent intent = new Intent(context, MedtronicCnlAlarmReceiver.class);
+        pendingIntent = PendingIntent.getBroadcast(context, ALARM_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    // Setting the alarm in 15 seconds from now
+    public static void setAlarm() {
+        setAlarm(System.currentTimeMillis());
+    }
+
+    // Setting the alarm to call onRecieve
+    public static void setAlarm(long millis) {
+        if (alarmManager == null || pendingIntent == null)
+            return;
+
+        long now = System.currentTimeMillis();
+        // don't trigger the past
+        if (millis < now)
+            millis = now;
+
+        // only accept alarm nearer than the last one
+        if (nextAlarm < millis && nextAlarm >= now) {
+            return;
+        }
+
+        cancelAlarm();
+
+        nextAlarm = millis;
+
+        Log.d(TAG, "AlarmManager set to fire   at " + new Date(millis));
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(millis, null), pendingIntent);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            // Android 5.0.0 + 5.0.1 (e.g. Galaxy S4) has a bug.
+            // Alarms are not exact. Fixed in 5.0.2 oder CM12
+            alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, pendingIntent);
+        } else {
+            alarmManager.set(AlarmManager.RTC_WAKEUP, millis, pendingIntent);
+        }
+    }
+
+    // restarting the alarm after MedtronicCnlIntentService.POLL_PERIOD_MS from now
+    public static void restartAlarm() {
+        setAlarm(System.currentTimeMillis() + MainActivity.pollInterval + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS);
+    }
+
+    // Cancel the alarm.
+    public static void cancelAlarm() {
+        if (alarmManager == null || pendingIntent == null)
+            return;
+
+        alarmManager.cancel(pendingIntent);
+    }
+
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java
index 69b0270..d86076c 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java
@@ -22,9 +22,6 @@ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver {
     private static final String TAG = MedtronicCnlAlarmReceiver.class.getSimpleName();
     private static final int ALARM_ID = 102; // Alarm id
 
-    private static PendingIntent pendingIntent = null;
-    private static AlarmManager alarmManager = null;
-
     public MedtronicCnlAlarmReceiver() {
         super();
     }
@@ -35,56 +32,6 @@ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver {
         Log.d(TAG, "Received broadcast message at " + new Date(System.currentTimeMillis()));
         Intent service = new Intent(context, MedtronicCnlIntentService.class);
         startWakefulService(context, service);
-        restartAlarm();
+        MedtronicCnlAlarmManager.restartAlarm();
     }
-
-    public void setContext(Context context) {
-        cancelAlarm();
-
-        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-        Intent intent = new Intent(context, MedtronicCnlAlarmReceiver.class);
-        pendingIntent = PendingIntent.getBroadcast(context, ALARM_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    // Setting the alarm in 15 seconds from now
-    public void setAlarm() {
-        setAlarm(System.currentTimeMillis());
-    }
-
-    // Setting the alarm to call onRecieve
-    public void setAlarm(long millis) {
-        if (alarmManager == null || pendingIntent == null)
-            return;
-
-        cancelAlarm();
-
-        // don't trigger the past and at least 30 sec away
-        if (millis < System.currentTimeMillis())
-            millis = System.currentTimeMillis();
-
-        Log.d(TAG, "AlarmManager set to fire   at " + new Date(millis));
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-            alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(millis, null), pendingIntent);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            // Android 5.0.0 + 5.0.1 (e.g. Galaxy S4) has a bug.
-            // Alarms are not exact. Fixed in 5.0.2 oder CM12
-            alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, pendingIntent);
-        } else {
-            alarmManager.set(AlarmManager.RTC_WAKEUP, millis, pendingIntent);
-        }
-    }
-
-    // restarting the alarm after MedtronicCnlIntentService.POLL_PERIOD_MS from now
-    public void restartAlarm() {
-        setAlarm(System.currentTimeMillis() + MainActivity.pollInterval + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS);
-    }
-
-    // Cancel the alarm.
-    public void cancelAlarm() {
-        if (alarmManager == null || pendingIntent == null)
-            return;
-
-        alarmManager.cancel(pendingIntent);
-    }
-
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
index d8c3319..1f46e22 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
@@ -197,6 +197,10 @@ public class MedtronicCnlIntentService extends IntentService {
                 if (radioChannel == 0) {
                     sendStatus("Could not communicate with the 640g. Are you near the pump?");
                     Log.i(TAG, "Could not communicate with the 640g. Are you near the pump?");
+
+                    // reduce polling interval to half until pump is available
+                    //TODO: make it configurable???
+                    MedtronicCnlAlarmManager.setAlarm(System.currentTimeMillis() + MainActivity.pollInterval/2L);
                 } else {
                     activePump.setLastRadioChannel(radioChannel);
                     sendStatus(String.format(Locale.getDefault(), "Connected to Contour Next Link on channel %d.", (int) radioChannel));
-- 
GitLab