diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java index 03e621f6de..9cff079ee2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java @@ -106,7 +106,7 @@ public class DetermineBasalAdapterMAJS { log.debug("Result: " + result); try { JSONObject resultJson = new JSONObject(result); - OpenHumansUploader.INSTANCE.enqueueAMAData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, resultJson); + OpenHumansUploader.INSTANCE.enqueueMAData(mProfile, mGlucoseStatus, mIobData, mMealData, mCurrentTemp, resultJson); determineBasalResultMA = new DetermineBasalResultMA(jsResult, resultJson); } catch (JSONException e) { log.error("Unhandled exception", e); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt index a232ffc669..8253e14ae2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt @@ -13,8 +13,10 @@ class OHUploadWorker( ) : RxWorker(context, workerParameters) { override fun createWork() = Single.defer { - val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager - if (SP.getBoolean("key_oh_wifi_only", true) && wifiManager.isWifiEnabled && wifiManager.connectionInfo.networkId != -1) { + val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager + val wifiOnly = SP.getBoolean("key_oh_wifi_only", true) + val isConnectedToWifi = wifiManager?.isWifiEnabled ?: false && wifiManager?.connectionInfo?.networkId != -1 + if (!wifiOnly || (wifiOnly && isConnectedToWifi)) { OpenHumansUploader.uploadData() .andThen(Single.just(Result.success())) .onErrorResumeNext { Single.just(Result.retry()) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt index 2736f94dca..70dc24f533 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt @@ -6,12 +6,12 @@ import io.reactivex.Completable import io.reactivex.Single import io.reactivex.disposables.Disposables import okhttp3.* +import okio.BufferedSink import org.json.JSONArray import org.json.JSONObject import java.io.IOException import java.text.SimpleDateFormat import java.util.* -import okio.BufferedSink class OpenHumansAPI( private val baseUrl: String, @@ -32,7 +32,7 @@ class OpenHumansAPI( fun refreshAccessToken(refreshToken: String): Single = sendTokenRequest(FormBody.Builder() .add("grant_type", "refresh_token") .add("redirect_uri", redirectUri) - .add("code", refreshToken) + .add("refresh_token", refreshToken) .build()) private fun sendTokenRequest(body: FormBody) = Request.Builder() @@ -49,8 +49,10 @@ class OpenHumansAPI( if (jsonObject == null) throw OHHttpException(response.code, response.message, "No body") if (!jsonObject.has("expires_in")) throw OHMissingFieldException("expires_in") OAuthTokens( - accessToken = jsonObject.getString("access_token") ?: throw OHMissingFieldException("access_token"), - refreshToken = jsonObject.getString("refresh_token") ?: throw OHMissingFieldException("refresh_token"), + accessToken = jsonObject.getString("access_token") + ?: throw OHMissingFieldException("access_token"), + refreshToken = jsonObject.getString("refresh_token") + ?: throw OHMissingFieldException("refresh_token"), expiresAt = response.sentRequestAtMillis + jsonObject.getInt("expires_in") * 1000L ) } @@ -61,7 +63,10 @@ class OpenHumansAPI( .get() .build() .toSingle() - .map { it.jsonBody.getString("project_member_id") ?: throw OHMissingFieldException("project_member_id") } + .map { + it.jsonBody.getString("project_member_id") + ?: throw OHMissingFieldException("project_member_id") + } fun prepareFileUpload(accessToken: String, fileName: String, metadata: FileMetadata): Single = Request.Builder() .url("$baseUrl/api/direct-sharing/project/files/upload/direct/?access_token=$accessToken") @@ -109,7 +114,6 @@ class OpenHumansAPI( .doOnSuccess { it.jsonBody } .ignoreElement() - private fun Request.toSingle() = Single.create { val call = client.newCall(this) call.enqueue(object : Callback { @@ -124,11 +128,13 @@ class OpenHumansAPI( it.setDisposable(Disposables.fromRunnable { call.cancel() }) } - private val Response.jsonBody get() = use { _ -> - val jsonObject = body?.let { JSONObject(it.string()) } ?: throw OHHttpException(code, message, null) - if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail")) - jsonObject - } + private val Response.jsonBody + get() = use { _ -> + val jsonObject = body?.let { JSONObject(it.string()) } + ?: throw OHHttpException(code, message, null) + if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail")) + jsonObject + } data class OAuthTokens( val accessToken: String, @@ -144,6 +150,7 @@ class OpenHumansAPI( val startDate: Long? = null, val endDate: Long? = null ) { + fun toJSON(): JSONObject { val jsonObject = JSONObject() jsonObject.put("tags", JSONArray().apply { tags.forEach { put(it) } }) @@ -166,12 +173,14 @@ class OpenHumansAPI( val meaning: String, val detail: String? ) : RuntimeException() { + override val message: String get() = toString() } data class OHMissingFieldException( val name: String ) : RuntimeException() { + override val message: String get() = toString() } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansUploader.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansUploader.kt index 24c31428ea..1807e07137 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansUploader.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansUploader.kt @@ -52,16 +52,16 @@ object OpenHumansUploader : PluginBase( private val log = LoggerFactory.getLogger(L.OPENHUMANS) - const val OPEN_HUMANS_URL = "https://www.openhumans.org" - const val CLIENT_ID = "oie6DvnaEOagTxSoD6BukkLPwDhVr6cMlN74Ihz1" - const val CLIENT_SECRET = "jR0N8pkH1jOwtozHc7CsB1UPcJzFN95ldHcK4VGYIApecr8zGJox0v06xLwPLMASScngT12aIaIHXAVCJeKquEXAWG1XekZdbubSpccgNiQBmuVmIF8nc1xSKSNJltCf" - const val REDIRECT_URL = "androidaps://setup-openhumans" + private const val OPEN_HUMANS_URL = "https://www.openhumans.org" + private const val CLIENT_ID = "oie6DvnaEOagTxSoD6BukkLPwDhVr6cMlN74Ihz1" + private const val CLIENT_SECRET = "jR0N8pkH1jOwtozHc7CsB1UPcJzFN95ldHcK4VGYIApecr8zGJox0v06xLwPLMASScngT12aIaIHXAVCJeKquEXAWG1XekZdbubSpccgNiQBmuVmIF8nc1xSKSNJltCf" + private const val REDIRECT_URL = "androidaps://setup-openhumans" const val AUTH_URL = "https://www.openhumans.org/direct-sharing/projects/oauth2/authorize/?client_id=$CLIENT_ID&response_type=code" const val WORK_NAME = "Open Humans" - const val COPY_NOTIFICATION_ID = 3122 - const val FAILURE_NOTIFICATION_ID = 3123 - const val SUCCESS_NOTIFICATION_ID = 3124 - const val SIGNED_OUT_NOTIFICATION_ID = 3125 + private const val COPY_NOTIFICATION_ID = 3122 + private const val FAILURE_NOTIFICATION_ID = 3123 + private const val SUCCESS_NOTIFICATION_ID = 3124 + private const val SIGNED_OUT_NOTIFICATION_ID = 3125 private val openHumansAPI = OpenHumansAPI(OPEN_HUMANS_URL, CLIENT_ID, CLIENT_SECRET, REDIRECT_URL) private val FILE_NAME_DATE_FORMAT = SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.US).apply { timeZone = TimeZone.getTimeZone("UTC") } @@ -123,13 +123,13 @@ object OpenHumansUploader : PluginBase( super.onStart() setupNotificationChannel() if (isSetup) scheduleWorker(false) - SP.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + SP.registerListener(this) } override fun onStop() { copyDisposable?.dispose() cancelWorker() - SP.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + SP.unregisterListener(this) super.onStop() } @@ -250,7 +250,7 @@ object OpenHumansUploader : PluginBase( put("result", result) } - fun enqueueAMAData(profile: JSONObject, glucoseStatus: JSONObject, iobData: JSONObject, mealData: JSONObject, currentTemp: JSONObject, result: JSONObject) = insertQueueItem("APSData") { + fun enqueueMAData(profile: JSONObject, glucoseStatus: JSONObject, iobData: JSONObject, mealData: JSONObject, currentTemp: JSONObject, result: JSONObject) = insertQueueItem("APSData") { put("algorithm", "MA") put("profile", profile) put("glucoseStatus", glucoseStatus) @@ -290,6 +290,9 @@ object OpenHumansUploader : PluginBase( copyExistingDataToQueue() RxBus.send(OpenHumansFragment.UpdateViewEvent) } + .doOnError { + log.error("Failed to login to Open Humans", it) + } .ignoreElement() fun logout() { @@ -318,22 +321,22 @@ object OpenHumansUploader : PluginBase( .map { enqueueBGReading(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allCareportalEvents) }) - .map { enqueueCareportalEvent(it); increaseCounter() } + .map { enqueueCareportalEvent(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allExtendedBoluses) }) - .map { enqueueExtendedBolus(it); increaseCounter() } + .map { enqueueExtendedBolus(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allProfileSwitches) }) - .map { enqueueProfileSwitch(it); increaseCounter() } + .map { enqueueProfileSwitch(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTDDs) }) - .map { enqueueTotalDailyDose(it); increaseCounter() } + .map { enqueueTotalDailyDose(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTemporaryBasals) }) - .map { enqueueTemporaryBasal(it); increaseCounter() } + .map { enqueueTemporaryBasal(it); increaseCounter() } .ignoreElements() .andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allTempTargets) }) - .map { enqueueTempTarget(it); increaseCounter() } + .map { enqueueTempTarget(it); increaseCounter() } .ignoreElements() .doOnSubscribe { wakeLock.acquire(TimeUnit.MINUTES.toMillis(20)) @@ -362,7 +365,8 @@ object OpenHumansUploader : PluginBase( .setContentTitle(MainApp.gs(R.string.finishing_open_humans_setup)) .setContentText(MainApp.gs(R.string.this_may_take_a_while)) .setStyle(NotificationCompat.BigTextStyle()) - .setProgress(maxProgress?.toInt() ?: 0, currentProgress?.toInt() ?: 0, maxProgress == null || currentProgress == null) + .setProgress(maxProgress?.toInt() ?: 0, currentProgress?.toInt() + ?: 0, maxProgress == null || currentProgress == null) .setOngoing(true) .setAutoCancel(false) .setSmallIcon(R.drawable.notif_icon) @@ -406,8 +410,15 @@ object OpenHumansUploader : PluginBase( if (it is OpenHumansAPI.OHHttpException && it.code == 401 && it.detail == "Invalid token.") { handleSignOut() } + log.error("Error while uploading to Open Humans", it) + } + .doOnComplete { + log.info("Upload successful") + RxBus.send(OpenHumansFragment.UpdateQueueEvent) + } + .doOnSubscribe { + log.info("Starting upload") } - .doOnComplete { RxBus.send(OpenHumansFragment.UpdateQueueEvent) } private fun uploadFile(accessToken: String, uploadData: UploadData) = Completable.defer { openHumansAPI.prepareFileUpload(accessToken, uploadData.fileName, uploadData.metadata) @@ -450,7 +461,7 @@ object OpenHumansUploader : PluginBase( zos.writeFile("ApplicationInfo.json", applicationInfo.toString().toByteArray()) tags.add("ApplicationInfo") - val preferences = JSONObject(SP.sharedPreferences.all.filterKeys { it.isAllowedKey() }) + val preferences = JSONObject(SP.getAll().filterKeys { it.isAllowedKey() }) zos.writeFile("Preferences.json", preferences.toString().toByteArray()) tags.add("Preferences") diff --git a/app/src/main/java/info/nightscout/androidaps/utils/SP.java b/app/src/main/java/info/nightscout/androidaps/utils/SP.java index ec8e1ab529..7f5ea73b51 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/SP.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/SP.java @@ -12,7 +12,7 @@ import info.nightscout.androidaps.MainApp; */ public class SP { - public static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); + private static final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); static public Map getAll() { return sharedPreferences.getAll(); @@ -26,6 +26,14 @@ public class SP { return sharedPreferences.contains(key); } + static public void registerListener(SharedPreferences.OnSharedPreferenceChangeListener listener) { + sharedPreferences.registerOnSharedPreferenceChangeListener(listener); + } + + static public void unregisterListener(SharedPreferences.OnSharedPreferenceChangeListener listener) { + sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener); + } + static public boolean contains(int resourceId) { return sharedPreferences.contains(MainApp.gs(resourceId)); }