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 49e648c68cc37df7ca643e632c9c76b1457b32f0..75ad384182f5f83a57c0948f2fa0eb649a4eed6c 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 @@ -6,10 +6,11 @@ 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.utils.Logger; + /** * Created by lgoedhart on 14/07/2016. */ @@ -19,17 +20,26 @@ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver { private static PendingIntent pendingIntent = null; private static AlarmManager alarmManager = null; + private Logger logger; + private Context context; @Override public void onReceive(final Context context, Intent intent) { // Start the IntentService - Log.d(TAG, "Received broadcast message at " + new Date(System.currentTimeMillis())); + + this.context = context; + logger = new Logger(TAG, context.getApplicationContext()); + logger.d("Received broadcast message at " + new Date(System.currentTimeMillis())); Intent service = new Intent(context, MedtronicCnlIntentService.class); startWakefulService(context, service); restartAlarm(); } public void setContext(Context context) { + this.context = context; + + logger = new Logger(TAG, context.getApplicationContext()); + cancelAlarm(); alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); @@ -46,6 +56,7 @@ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver { public void setAlarm(long millis) { if (alarmManager == null || pendingIntent == null) return; + logger = new Logger(TAG, this.context.getApplicationContext()); cancelAlarm(); @@ -53,7 +64,7 @@ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver { if (millis < System.currentTimeMillis()) millis = System.currentTimeMillis(); - Log.d(TAG, "AlarmManager set to fire at " + new Date(millis)); + logger.d("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) { 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 814f29de870282cf6b54da5c6619dbbadc4f6864..b133a967248eb71fe9d965ffeccd0f69c7dca1ba 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 @@ -13,7 +13,6 @@ import android.os.Build; import android.preference.PreferenceManager; import android.support.v4.app.NotificationManagerCompat; import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; import java.io.IOException; import java.security.NoSuchAlgorithmException; @@ -33,6 +32,7 @@ import info.nightscout.android.model.medtronicNg.ContourNextLinkInfo; import info.nightscout.android.model.medtronicNg.PumpInfo; import info.nightscout.android.model.medtronicNg.PumpStatusEvent; import info.nightscout.android.upload.nightscout.NightscoutUploadReceiver; +import info.nightscout.android.utils.Logger; import info.nightscout.android.xdrip_plus.XDripPlusUploadReceiver; import io.realm.Realm; import io.realm.RealmResults; @@ -44,7 +44,10 @@ public class MedtronicCnlIntentService extends IntentService { public final static long POLL_PERIOD_MS = 300000L; // Number of additional seconds to wait after the next expected CGM poll, so that we don't interfere with CGM radio comms. public final static long POLL_GRACE_PERIOD_MS = 30000L; + private static final String TAG = MedtronicCnlIntentService.class.getSimpleName(); + private Logger logger; + private UsbHidDriver mHidDevice; private Context mContext; private NotificationManagerCompat nm; @@ -54,13 +57,6 @@ public class MedtronicCnlIntentService extends IntentService { super(MedtronicCnlIntentService.class.getName()); } - protected void sendStatus(String message) { - Intent localIntent = - new Intent(Constants.ACTION_STATUS_MESSAGE) - .putExtra(Constants.EXTENDED_DATA, message); - LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); - } - protected void sendMessage(String action) { Intent localIntent = new Intent(action); @@ -71,16 +67,18 @@ public class MedtronicCnlIntentService extends IntentService { public void onCreate() { super.onCreate(); - Log.i(TAG, "onCreate called"); + logger = new Logger(TAG, getApplicationContext()); + logger.d("onCreate called"); mContext = this.getBaseContext(); mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); + } @Override public void onDestroy() { super.onDestroy(); - Log.d(TAG, "onDestroy called"); + logger.d("onDestroy called"); if (nm != null) { nm.cancelAll(); @@ -88,18 +86,17 @@ public class MedtronicCnlIntentService extends IntentService { } if (mHidDevice != null) { - Log.i(TAG, "Closing serial device..."); + logger.d("Closing serial device..."); mHidDevice.close(); mHidDevice = null; } } protected void onHandleIntent(Intent intent) { - Log.d(TAG, "onHandleIntent called"); + logger.d("onHandleIntent called"); if (!hasUsbHostFeature()) { - sendStatus("It appears that this device doesn't support USB OTG."); - Log.e(TAG, "Device does not support USB OTG"); + logger.e("It appears that this device doesn't support USB OTG."); MedtronicCnlAlarmReceiver.completeWakefulIntent(intent); // TODO - throw, don't return return; @@ -107,8 +104,7 @@ public class MedtronicCnlIntentService extends IntentService { UsbDevice cnlStick = UsbHidDriver.getUsbDevice(mUsbManager, USB_VID, USB_PID); if (cnlStick == null) { - sendStatus("USB connection error. Is the Bayer Contour Next Link plugged in?"); - Log.w(TAG, "USB connection error. Is the CNL plugged in?"); + logger.e("USB connection error. Is the Bayer Contour Next Link plugged in?"); // TODO - set status if offline or Nightscout not reachable uploadToNightscout(); @@ -128,7 +124,7 @@ public class MedtronicCnlIntentService extends IntentService { try { mHidDevice.open(); } catch (Exception e) { - Log.e(TAG, "Unable to open serial device", e); + logger.e("Unable to open serial device", e); MedtronicCnlAlarmReceiver.completeWakefulIntent(intent); // TODO - throw, don't return return; @@ -140,8 +136,7 @@ public class MedtronicCnlIntentService extends IntentService { realm.beginTransaction(); try { - sendStatus("Connecting to the Contour Next Link..."); - Log.d(TAG, "Connecting to the Contour Next Link."); + logger.i("Connecting to the Contour Next Link."); cnlReader.requestDeviceInfo(); // Is the device already configured? @@ -198,7 +193,7 @@ public class MedtronicCnlIntentService extends IntentService { cnlReader.getPumpSession().setKey(MessageUtils.hexStringToByteArray(key)); long pumpMAC = cnlReader.getPumpSession().getPumpMAC(); - Log.i(TAG, "PumpInfo MAC: " + (pumpMAC & 0xffffff)); + logger.d("PumpInfo MAC: " + (pumpMAC & 0xffffff)); MainActivity.setActivePumpMac(pumpMAC); PumpInfo activePump = realm .where(PumpInfo.class) @@ -212,12 +207,10 @@ public class MedtronicCnlIntentService extends IntentService { byte radioChannel = cnlReader.negotiateChannel(activePump.getLastRadioChannel()); 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?"); + logger.e("Could not communicate with the 640g. Are you near the pump?"); } else { activePump.setLastRadioChannel(radioChannel); - sendStatus(String.format(Locale.getDefault(), "Connected to Contour Next Link on channel %d.", (int) radioChannel)); - Log.d(TAG, String.format("Connected to Contour Next Link on channel %d.", (int) radioChannel)); + logger.i(String.format(Locale.getDefault(), "Connected to Contour Next Link on channel %d.", (int) radioChannel)); cnlReader.beginEHSMSession(); PumpStatusEvent pumpRecord = realm.createObject(PumpStatusEvent.class); @@ -230,7 +223,7 @@ public class MedtronicCnlIntentService extends IntentService { long pumpTime = cnlReader.getPumpTime().getTime(); long pumpOffset = pumpTime - System.currentTimeMillis(); - Log.d(TAG, "Time offset between pump and device: " + pumpOffset + " millis."); + logger.d("Time offset between pump and device: " + pumpOffset + " millis."); // TODO - send ACTION to MainActivity to show offset between pump and uploader. pumpRecord.setPumpTimeOffset(pumpOffset); @@ -264,32 +257,24 @@ public class MedtronicCnlIntentService extends IntentService { } } } catch (UnexpectedMessageException e) { - Log.e(TAG, "Unexpected Message", e); - sendStatus("Communication Error: " + e.getMessage()); + logger.e("Communication Error:", e); } catch (NoSuchAlgorithmException e) { - Log.e(TAG, "Could not determine CNL HMAC", e); - sendStatus("Error connecting to Contour Next Link: Hashing error."); + logger.e("Error connecting to Contour Next Link: Hashing error.", e); } finally { - //TODO : 05.11.2016 has the close to be here? cnlReader.closeConnection(); cnlReader.endPassthroughMode(); cnlReader.endControlMode(); } } catch (IOException e) { - Log.e(TAG, "Error connecting to Contour Next Link.", e); - sendStatus("Error connecting to Contour Next Link."); + logger.e("Error connecting to Contour Next Link.", e); } catch (ChecksumException e) { - Log.e(TAG, "Checksum error getting message from the Contour Next Link.", e); - sendStatus("Checksum error getting message from the Contour Next Link."); + logger.e("Checksum error getting message from the Contour Next Link.", e); } catch (EncryptionException e) { - Log.e(TAG, "Error decrypting messages from Contour Next Link.", e); - sendStatus("Error decrypting messages from Contour Next Link."); + logger.e("Error decrypting messages from Contour Next Link.", e); } catch (TimeoutException e) { - Log.e(TAG, "Timeout communicating with the Contour Next Link.", e); - sendStatus("Timeout communicating with the Contour Next Link."); + logger.e("Timeout communicating with the Contour Next Link.", e); } catch (UnexpectedMessageException e) { - Log.e(TAG, "Could not close connection.", e); - sendStatus("Could not close connection: " + e.getMessage()); + logger.e("Could not close connection.", e); } finally { if (!realm.isClosed()) { if (realm.isInTransaction()) { @@ -323,7 +308,7 @@ public class MedtronicCnlIntentService extends IntentService { final Intent receiverIntent = new Intent(this, XDripPlusUploadReceiver.class); final long timestamp = System.currentTimeMillis() + 500L; final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) timestamp, receiverIntent, PendingIntent.FLAG_ONE_SHOT); - Log.d(TAG, "Scheduling xDrip+ send"); + logger.d("Scheduling xDrip+ send"); wakeUpIntent(getApplicationContext(), timestamp, pendingIntent); } } diff --git a/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java b/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java index 6ac7129878dfdcf45118b3f1f4cf83538766de24..a084cc4ce692f65ac9ee89a0df0dc468f004083a 100644 --- a/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java +++ b/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java @@ -8,10 +8,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import org.apache.http.HttpResponse; -import org.apache.http.StatusLine; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; @@ -35,6 +32,7 @@ import info.nightscout.android.R; import info.nightscout.android.medtronic.MainActivity; import info.nightscout.android.model.medtronicNg.PumpStatusEvent; import info.nightscout.android.upload.nightscout.serializer.EntriesSerializer; +import info.nightscout.android.utils.Logger; import io.realm.Realm; import io.realm.RealmResults; @@ -46,6 +44,8 @@ public class NightscoutUploadIntentService extends IntentService { private static final int CONNECTION_TIMEOUT = 30 * 1000; Context mContext; private Realm mRealm; + private Logger logger; + public NightscoutUploadIntentService() { super(NightscoutUploadIntentService.class.getName()); @@ -62,13 +62,14 @@ public class NightscoutUploadIntentService extends IntentService { public void onCreate() { super.onCreate(); - Log.i(TAG, "onCreate called"); + logger = new Logger(TAG, getApplicationContext()); + logger.d("onCreate called"); mContext = this.getBaseContext(); } @Override protected void onHandleIntent(Intent intent) { - Log.d(TAG, "onHandleIntent called"); + logger.d("onHandleIntent called"); mRealm = Realm.getDefaultInstance(); RealmResults<PumpStatusEvent> records = mRealm @@ -84,15 +85,15 @@ public class NightscoutUploadIntentService extends IntentService { try { if (enableRESTUpload) { long start = System.currentTimeMillis(); - Log.i(TAG, String.format("Starting upload of %s record using a REST API", records.size())); + logger.i(String.format("Starting upload of %s record using a REST API", records.size())); doRESTUpload(prefs, records); - Log.i(TAG, String.format("Finished upload of %s record using a REST API in %s ms", records.size(), System.currentTimeMillis() - start)); + logger.i(String.format("Finished upload of %s record using a REST API in %s ms", records.size(), System.currentTimeMillis() - start)); } } catch (Exception e) { - Log.e(TAG, "ERROR uploading data!!!!!", e); + logger.e("ERROR uploading data!!!!!", e); } } else { - Log.i(TAG, "No records has to be uploaded"); + logger.i("No records has to be uploaded"); } NightscoutUploadReceiver.completeWakefulIntent(intent); @@ -132,7 +133,7 @@ public class NightscoutUploadIntentService extends IntentService { try { doRESTUploadTo(uploadUrl, records); } catch (Exception e) { - Log.e(TAG, "Unable to do REST API Upload to: " + uploadUrl, e); + logger.e("Unable to do REST API Upload to: " + uploadUrl, e); } } @@ -188,7 +189,7 @@ public class NightscoutUploadIntentService extends IntentService { } } catch (Exception e) { - Log.e(TAG, "Unable to post data", e); + logger.e("Unable to post data", e); } } @@ -201,7 +202,7 @@ public class NightscoutUploadIntentService extends IntentService { } private boolean uploadToNightscout(URL endpoint, String secret, String httpBody) throws Exception { - Log.i(TAG, "postURL: " + endpoint.toString()); + logger.d("postURL: " + endpoint.toString()); HttpPost post = new HttpPost(endpoint.toString()); @@ -226,7 +227,7 @@ public class NightscoutUploadIntentService extends IntentService { DefaultHttpClient httpclient = new DefaultHttpClient(params); - Log.i(TAG, "Upload JSON: " + httpBody); + logger.d("Upload JSON: " + httpBody); try { StringEntity se = new StringEntity(httpBody); @@ -237,7 +238,7 @@ public class NightscoutUploadIntentService extends IntentService { ResponseHandler responseHandler = new BasicResponseHandler(); httpclient.execute(post, responseHandler); } catch (Exception e) { - Log.w(TAG, "Unable to post data to: '" + post.getURI().toString() + "'", e); + logger.e("Unable to post data to: '" + post.getURI().toString() + "'", e); return false; } @@ -276,7 +277,7 @@ public class NightscoutUploadIntentService extends IntentService { json.put("pump", pumpInfo); String jsonString = json.toString(); - Log.i(TAG, "Device Status JSON: " + jsonString); + logger.d("Device Status JSON: " + jsonString); devicestatusArray.put(json); } diff --git a/app/src/main/java/info/nightscout/android/utils/Logger.java b/app/src/main/java/info/nightscout/android/utils/Logger.java new file mode 100644 index 0000000000000000000000000000000000000000..f6b06d3f4bcd212c8e594bb4ab1ec8229d52f3c7 --- /dev/null +++ b/app/src/main/java/info/nightscout/android/utils/Logger.java @@ -0,0 +1,128 @@ +package info.nightscout.android.utils; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import info.nightscout.android.R; +import info.nightscout.android.medtronic.service.MedtronicCnlIntentService; + +/** + * Wraps android log to send messages to UI + */ + +public class Logger { + private final Context context; + private final String tag; + private int logLevel = Log.ASSERT; + + public Logger(String tag, Context context) { + this.tag = tag; + this.context = context; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); + String currentLogLevel = prefs.getString("logLevel", "0"); + int pos = Integer.parseInt(currentLogLevel) - 1; + String[] logLevelNames = context.getResources().getStringArray(R.array.levelList); + if (pos >= 0 && pos < logLevelNames.length) { + currentLogLevel = logLevelNames[pos].toLowerCase(); + if ("error".equals(currentLogLevel)) { + logLevel = Log.ERROR; + } else if ("warning".equals(currentLogLevel)) { + logLevel = Log.WARN; + } else if ("info".equals(currentLogLevel)) { + logLevel = Log.INFO; + } else if ("debug".equals(currentLogLevel)) { + logLevel = Log.DEBUG; + } else if ("verbose".equals(currentLogLevel)) { + logLevel = Log.VERBOSE; + } + } + } + + public int v(String msg) { + if (logLevel <= Log.VERBOSE) { + sendStatus(msg); + } + return Log.v(tag, msg); + } + + public int v(String msg, Throwable tr) { + if (logLevel <= Log.VERBOSE) { + sendStatus(msg); + }return Log.v(tag, msg, tr); + } + + public int d(String msg) { + if (logLevel <= Log.DEBUG) { + sendStatus("(D) " + tag + ": " + msg); + } + return Log.d(tag, msg); + } + + public int d(String msg, Throwable tr) { + if (logLevel <= Log.DEBUG) { + sendStatus("(D) " + tag + ": " + msg); + } + return Log.d(tag, msg, tr); + } + + public int i(String msg) { + if (logLevel <= Log.INFO) { + sendStatus(msg); + } + return Log.i(tag, msg); + } + + public int i(String msg, Throwable tr) { + if (logLevel <= Log.INFO) { + sendStatus(msg); + } + return Log.i(tag, msg, tr); + } + + public int w(String msg) { + if (logLevel <= Log.WARN) { + sendStatus(msg); + } + return Log.w(tag, msg); + } + + public int w(String msg, Throwable tr) { + if (logLevel <= Log.WARN) { + sendStatus(msg); + } + return Log.w(tag, msg, tr); + } + + public int w(Throwable tr) { + if (logLevel <= Log.WARN) { + sendStatus(tr.getMessage()); + } + return Log.w(tag, tr); + } + + public int e(String msg) { + if (logLevel <= Log.ERROR) { + sendStatus("(E): " + msg); + } + return Log.e(tag, msg); + } + + public int e(String msg, Throwable tr) { + if (logLevel <= Log.ERROR) { + sendStatus("(E): " + msg + "(" + tr.getMessage() + ")"); + } + return Log.e(tag, msg, tr); + } + + protected void sendStatus(String message) { + Intent localIntent = + new Intent(MedtronicCnlIntentService.Constants.ACTION_STATUS_MESSAGE) + .putExtra(MedtronicCnlIntentService.Constants.EXTENDED_DATA, message); + LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent); + } +}