From e342f4e2ae03164bde0b173af55a593efa65a828 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Mon, 4 Mar 2019 23:13:55 +0000 Subject: [PATCH 1/9] d --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d1e1e8a47c..4409852b76 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # AndroidAPS +ddd + * Check the wiki: http://wiki.androidaps.org * Everyone who’s been looping with AndroidAPS needs to fill out the form after 3 days of looping https://docs.google.com/forms/d/14KcMjlINPMJHVt28MDRupa4sz4DDIooI4SrW0P3HSN8/viewform?c=0&w=1 From fda43c423def635a297995dcb444b2916c9133ee Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Mon, 4 Mar 2019 23:23:51 +0000 Subject: [PATCH 2/9] - Change wear versions to highest --- wear/build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wear/build.gradle b/wear/build.gradle index cf846f51ae..276a921b7f 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -1,7 +1,8 @@ apply plugin: 'com.android.application' ext { - wearableVersion = "2.0.1" + wearableVersion = "2.4.0" + playServicesWearable = "16.0.1" } def generateGitBuild = { -> @@ -89,7 +90,7 @@ dependencies { //compile "com.ustwo.android:clockwise-wearable:1.0.2" compileOnly "com.google.android.wearable:wearable:${wearableVersion}" implementation "com.google.android.support:wearable:${wearableVersion}" - implementation "com.google.android.gms:play-services-wearable:7.3.0" + implementation "com.google.android.gms:play-services-wearable:${playServicesWearable}" implementation(name:"ustwo-clockwise-debug", ext:"aar") implementation "com.android.support:support-v4:27.0.1" implementation 'com.android.support:wear:27.0.1' From 056ad650cdec4dbbb91198f50bbc46b3db32e06d Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Tue, 5 Mar 2019 01:05:16 +0000 Subject: [PATCH 3/9] - changed wear versions - added some code to listener - added some log entries --- wear/build.gradle | 4 +- wear/src/main/AndroidManifest.xml | 20 +++- .../androidaps/data/ListenerService.java | 101 ++++++++++++++++-- .../interaction/utils/WearUtil.java | 19 ++++ 4 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.java diff --git a/wear/build.gradle b/wear/build.gradle index 276a921b7f..1dd07ff1a5 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -1,8 +1,8 @@ apply plugin: 'com.android.application' ext { - wearableVersion = "2.4.0" - playServicesWearable = "16.0.1" + wearableVersion = "2.0.1" + playServicesWearable = "9.4.0" } def generateGitBuild = { -> diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index e6750c515d..119b83a3f5 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -168,12 +168,28 @@ + - + + + + + + + + + + + + + + + + + - diff --git a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java index 52dfc97ad1..326d154079 100644 --- a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java +++ b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java @@ -7,16 +7,19 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationManagerCompat; +import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.wearable.ChannelApi; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; import com.google.android.gms.wearable.DataMap; @@ -33,12 +36,15 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.interaction.actions.AcceptActivity; import info.nightscout.androidaps.interaction.actions.CPPActivity; import info.nightscout.androidaps.interaction.utils.SafeParse; +import info.nightscout.androidaps.interaction.utils.WearUtil; + /** * Created by emmablack on 12/26/14. */ public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, - GoogleApiClient.OnConnectionFailedListener { + GoogleApiClient.OnConnectionFailedListener, ChannelApi.ChannelListener { + private static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; private static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend"; private static final String WEARABLE_CANCELBOLUS_PATH = "/nightscout_watch_cancel_bolus"; @@ -67,19 +73,35 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String ACTION_RESEND_BULK = "com.dexdrip.stephenblack.nightwatch.RESEND_BULK_DATA"; + GoogleApiClient googleApiClient; private long lastRequest = 0; private DismissThread confirmThread; private DismissThread bolusprogressThread; + private static final String TAG = "ListenerService"; + + private DataRequester mDataRequester = null; public class DataRequester extends AsyncTask { Context mContext; + String path; + byte[] payload; - DataRequester(Context context) { - mContext = context; +// DataRequester(Context context) { +// mContext = context; +// } + + + + DataRequester(Context context, String thispath, byte[] thispayload) { + path = thispath; + payload = thispayload; + Log.d(TAG, "DataRequester DataRequester: " + thispath + " lastRequest:" + lastRequest); } + + @Override protected Void doInBackground(Void... params) { if (googleApiClient.isConnected()) { @@ -154,6 +176,9 @@ public class ListenerService extends WearableListenerService implements GoogleAp @Override protected Void doInBackground(Void... params) { + + forceGoogleApiConnect(); + if (googleApiClient.isConnected()) { NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); @@ -176,7 +201,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp } public void requestData() { - new DataRequester(this).execute(); + sendData(WEARABLE_RESEND_PATH, null); } public void cancelBolus() { @@ -191,7 +216,48 @@ public class ListenerService extends WearableListenerService implements GoogleAp new MessageActionTask(this, WEARABLE_INITIATE_ACTIONSTRING_PATH, actionstring).execute(); } - public void googleApiConnect() { + + private synchronized void sendData(String path, byte[] payload) { + if (path == null) return; + if (mDataRequester != null) { + Log.d(TAG, "sendData DataRequester != null lastRequest:" + WearUtil.dateTimeText(lastRequest)); + if (mDataRequester.getStatus() != AsyncTask.Status.FINISHED) { + Log.d(TAG, "sendData Should be canceled? Let run 'til finished."); + //mDataRequester.cancel(true); + } + //mDataRequester = null; + } + + Log.d(TAG, "sendData: execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); + mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute(); + + +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { +// Log.d(TAG, "sendData SDK < M call execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); +// mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute(); +// } else { +// Log.d(TAG, "sendData SDK >= M call executeOnExecutor lastRequest:" + WearUtil.dateTimeText(lastRequest)); +// // TODO xdrip executor +// mDataRequester = (DataRequester) new DataRequester(this, path, payload).executeOnExecutor(xdrip.executor); +// } + } + + + private void googleApiConnect() { + if (googleApiClient != null) { + // Remove old listener(s) + try { + Wearable.ChannelApi.removeListener(googleApiClient, this); + } catch (Exception e) { + // + } + try { + Wearable.MessageApi.removeListener(googleApiClient, this); + } catch (Exception e) { + // + } + } + googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) @@ -201,6 +267,20 @@ public class ListenerService extends WearableListenerService implements GoogleAp } + + private void forceGoogleApiConnect() { + if ((googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) || googleApiClient == null) { + try { + Log.d(TAG, "forceGoogleApiConnect: forcing google api reconnection"); + googleApiConnect(); + Thread.sleep(2000); + } catch (InterruptedException e) { + // + } + } + } + + @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null && ACTION_RESEND.equals(intent.getAction())) { @@ -261,8 +341,10 @@ public class ListenerService extends WearableListenerService implements GoogleAp if (event.getType() == DataEvent.TYPE_CHANGED) { - String path = event.getDataItem().getUri().getPath(); + + Log.d(TAG, "Path: {}" + path + ", Event=" + event); + if (path.equals(OPEN_SETTINGS)) { Intent intent = new Intent(this, AAPSPreferences.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -480,6 +562,9 @@ public class ListenerService extends WearableListenerService implements GoogleAp @Override public void onConnected(Bundle bundle) { + Log.d(TAG, "onConnected call requestData"); + + Wearable.ChannelApi.addListener(googleApiClient, this); requestData(); } @@ -499,8 +584,10 @@ public class ListenerService extends WearableListenerService implements GoogleAp if (googleApiClient != null && googleApiClient.isConnected()) { googleApiClient.disconnect(); } + if (googleApiClient != null) { Wearable.MessageApi.removeListener(googleApiClient, this); + Wearable.ChannelApi.removeListener(googleApiClient, this); } - } + } } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.java new file mode 100644 index 0000000000..ca63749888 --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.java @@ -0,0 +1,19 @@ +package info.nightscout.androidaps.interaction.utils; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + * Created by andy on 3/5/19. + */ + +public class WearUtil { + + + public static String dateTimeText(long timeInMs) { + Date d = new Date(timeInMs); + return "" + d.getDay() + "." + d.getMonth() + "." + d.getYear() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds(); + } + + +} From 6e500c1e750b98c43901317ac933d943dd85a108 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Wed, 6 Mar 2019 23:38:18 +0000 Subject: [PATCH 4/9] On both sides changed BIND_LISTENER in manifest and added a lot of logging, some might be commented out. On AAPS side: - added some capabilites - fully refactored SendToDataLayerThread (copied from xdrip) - updated code - all tasks are now executed on Executor (and not by itself) - main problem that some data was not sent On Wear side: - added capabilities and refactored code in ListenerService (by looking at xdrip code) --- app/build.gradle | 3 +- app/src/main/AndroidManifest.xml | 61 ++++- .../plugins/general/wear/WearPlugin.java | 15 +- .../SendToDataLayerThread.java | 122 +++++++-- .../wearintegration/WatchUpdaterService.java | 133 +++++++-- app/src/main/res/values/wear.xml | 18 ++ wear/build.gradle | 2 +- .../androidaps/data/ListenerService.java | 258 +++++++++++++++--- wear/src/main/res/values/wear.xml | 18 ++ 9 files changed, 547 insertions(+), 83 deletions(-) create mode 100644 app/src/main/res/values/wear.xml create mode 100644 wear/src/main/res/values/wear.xml diff --git a/app/build.gradle b/app/build.gradle index 3dbe684a74..fe60a69960 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,6 +68,7 @@ android { buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + // if you change minSdkVersion to less than 11, you need to change executeTask for wear ndk { moduleName "BleCommandUtil" @@ -194,7 +195,7 @@ dependencies { implementation "org.slf4j:slf4j-api:1.7.12" implementation "com.jjoe64:graphview:4.0.1" implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1" - implementation "com.google.android.gms:play-services-wearable:7.5.0" + implementation 'com.google.android.gms:play-services-wearable:10.2.1' implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar") implementation(name: "sightparser-release", ext: "aar") implementation 'com.madgag.spongycastle:core:1.58.0.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2ec11e5a33..da3643e662 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -135,6 +135,7 @@ + - + + + + + + + + + + + + + + + + + + { private GoogleApiClient googleApiClient; - private static final String TAG = "SendDataThread"; - String path; + private static final String TAG = "SendToDataLayerThread"; + private String path; + private String logPrefix = ""; // "WR: "; + private static int concurrency = 0; + private static int state = 0; + private static final ReentrantLock lock = new ReentrantLock(); + private static long lastlock = 0; + private static final boolean testlockup = false; // always false in production + SendToDataLayerThread(String path, GoogleApiClient pGoogleApiClient) { + // Log.d(TAG, logPrefix + "SendToDataLayerThread: " + path); this.path = path; googleApiClient = pGoogleApiClient; } + + @Override + protected void onPreExecute() { + concurrency++; + if ((concurrency > 12) || ((concurrency > 3 && (lastlock != 0) && (tsl() - lastlock) > 300000))) { + // error if 9 concurrent threads or lock held for >5 minutes with concurrency of 4 + final String err = "Wear Integration deadlock detected!! " + ((lastlock != 0) ? "locked" : "") + " state:" + + state + " @" + hourMinuteString(tsl()); + // Home.toaststaticnext(err); + Log.e(TAG, logPrefix + err); + } + if (concurrency < 0) + Log.d(TAG, logPrefix + "Wear Integration impossible concurrency!!"); + + Log.d(TAG, logPrefix + "SendDataToLayerThread pre-execute concurrency: " + concurrency); + } + + @Override protected Void doInBackground(DataMap... params) { - try { - final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15, TimeUnit.SECONDS); - for (Node node : nodes.getNodes()) { - for (DataMap dataMap : params) { - PutDataMapRequest putDMR = PutDataMapRequest.create(path); - putDMR.getDataMap().putAll(dataMap); - PutDataRequest request = putDMR.asPutDataRequest(); - DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, TimeUnit.SECONDS); - if (result.getStatus().isSuccess()) { - Log.d(TAG, "DataMap: " + dataMap + " sent to: " + node.getDisplayName()); - } else { - Log.d(TAG, "ERROR: failed to send DataMap"); - } - } + if (testlockup) { + try { + Log.e(TAG, logPrefix + "WARNING RUNNING TEST LOCK UP CODE - NEVER FOR PRODUCTION"); + Thread.sleep(1000000); // DEEEBBUUGGGG + } catch (Exception e) { } - } catch (Exception e) { - Log.e(TAG, "Got exception sending data to wear: " + e.toString()); } + sendToWear(params); + concurrency--; + Log.d(TAG, logPrefix + "SendDataToLayerThread post-execute concurrency: " + concurrency); return null; } + + + // Debug function to expose where it might be locking up + private synchronized void sendToWear(final DataMap... params) { + if (!lock.tryLock()) { + Log.d(TAG, logPrefix + "Concurrent access - waiting for thread unlock"); + lock.lock(); // enforce single threading + Log.d(TAG, logPrefix + "Thread unlocked - proceeding"); + } + lastlock = tsl(); + try { + if (state != 0) { + Log.e(TAG, logPrefix + "WEAR STATE ERROR: state=" + state); + } + state = 1; + final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15, + TimeUnit.SECONDS); + + Log.d(TAG, logPrefix + "Nodes: " + nodes); + + state = 2; + for (Node node : nodes.getNodes()) { + state = 3; + for (DataMap dataMap : params) { + state = 4; + PutDataMapRequest putDMR = PutDataMapRequest.create(path); + state = 5; + putDMR.getDataMap().putAll(dataMap); + putDMR.setUrgent(); + state = 6; + PutDataRequest request = putDMR.asPutDataRequest(); + state = 7; + DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, + TimeUnit.SECONDS); + state = 8; + if (result.getStatus().isSuccess()) { + Log.d(TAG, logPrefix + "DataMap: " + dataMap + " sent to: " + node.getDisplayName()); + } else { + Log.e(TAG, logPrefix + "ERROR: failed to send DataMap"); + result = Wearable.DataApi.putDataItem(googleApiClient, request).await(30, TimeUnit.SECONDS); + if (result.getStatus().isSuccess()) { + Log.d(TAG, logPrefix + "DataMap retry: " + dataMap + " sent to: " + node.getDisplayName()); + } else { + Log.e(TAG, logPrefix + "ERROR on retry: failed to send DataMap: " + + result.getStatus().toString()); + } + } + state = 9; + } + } + state = 0; + } catch (Exception e) { + Log.e(TAG, logPrefix + "Got exception in sendToWear: " + e.toString()); + } finally { + lastlock = 0; + lock.unlock(); + } + } + + + private static long tsl() { + return System.currentTimeMillis(); + } + + + private static String hourMinuteString(long timestamp) { + return android.text.format.DateFormat.format("kk:mm", timestamp).toString(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 12dc116895..806ee9d31f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -1,9 +1,17 @@ package info.nightscout.androidaps.plugins.general.wear.wearintegration; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.os.BatteryManager; import android.os.Bundle; import android.os.Handler; @@ -14,8 +22,11 @@ import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.wearable.CapabilityApi; +import com.google.android.gms.wearable.CapabilityInfo; import com.google.android.gms.wearable.DataMap; import com.google.android.gms.wearable.MessageEvent; +import com.google.android.gms.wearable.Node; import com.google.android.gms.wearable.PutDataMapRequest; import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; @@ -42,21 +53,24 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.WearPlugin; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.treatments.Treatment; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.ToastUtils; -public class WatchUpdaterService extends WearableListenerService implements - GoogleApiClient.ConnectionCallbacks, - GoogleApiClient.OnConnectionFailedListener { +public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { + public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend"); public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings"); public static final String ACTION_SEND_STATUS = WatchUpdaterService.class.getName().concat(".SendStatus"); @@ -91,6 +105,17 @@ public class WatchUpdaterService extends WearableListenerService implements private Handler handler; + // Phone + private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs"; + private static final String MESSAGE_PATH_PHONE = "/phone_message_path"; + // Wear + private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs"; + private static final String MESSAGE_PATH_WEAR = "/wear_message_path"; + private String mWearNodeId = null; + private String localnode = null; + private String logPrefix = ""; // "WR: " + + @Override public void onCreate() { mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); @@ -112,24 +137,24 @@ public class WatchUpdaterService extends WearableListenerService implements public void setSettings() { wear_integration = WearPlugin.getPlugin().isEnabled(PluginType.GENERAL); + // Log.d(TAG, "WR: wear_integration=" + wear_integration); if (wear_integration) { googleApiConnect(); } } - public void googleApiConnect() { + + private void googleApiConnect() { if (googleApiClient != null && (googleApiClient.isConnected() || googleApiClient.isConnecting())) { googleApiClient.disconnect(); } - googleApiClient = new GoogleApiClient.Builder(this) - .addConnectionCallbacks(this) - .addOnConnectionFailedListener(this) - .addApi(Wearable.API) - .build(); + googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this) + .addOnConnectionFailedListener(this).addApi(Wearable.API).build(); Wearable.MessageApi.addListener(googleApiClient, this); if (googleApiClient.isConnected()) { - Log.d("WatchUpdater", "API client is connected"); + Log.d(TAG, logPrefix + "API client is connected"); } else { + // Log.d("WatchUpdater", logPrefix + "API client is not connected and is trying to connect"); googleApiClient.connect(); } } @@ -138,6 +163,8 @@ public class WatchUpdaterService extends WearableListenerService implements public int onStartCommand(Intent intent, int flags, int startId) { String action = intent != null ? intent.getAction() : null; + // Log.d(TAG, logPrefix + "onStartCommand: " + action); + if (wear_integration) { handler.post(() -> { if (googleApiClient.isConnected()) { @@ -177,13 +204,63 @@ public class WatchUpdaterService extends WearableListenerService implements } + private void updateWearSyncBgsCapability(CapabilityInfo capabilityInfo) { + Log.d("WatchUpdaterService", logPrefix + "CabilityInfo: " + capabilityInfo); + Set connectedNodes = capabilityInfo.getNodes(); + mWearNodeId = pickBestNodeId(connectedNodes); + } + + + private String pickBestNodeId(Set nodes) { + String bestNodeId = null; + // Find a nearby node or pick one arbitrarily + for (Node node : nodes) { + if (node.isNearby()) { + return node.getId(); + } + bestNodeId = node.getId(); + } + return bestNodeId; + } + + @Override public void onConnected(Bundle connectionHint) { + CapabilityApi.CapabilityListener capabilityListener = capabilityInfo -> { + updateWearSyncBgsCapability(capabilityInfo); + // Log.d(TAG, logPrefix + "onConnected onCapabilityChanged mWearNodeID:" + mWearNodeId); + // new CheckWearableConnected().execute(); + }; + + Wearable.CapabilityApi.addCapabilityListener(googleApiClient, capabilityListener, CAPABILITY_WEAR_APP); sendData(); } + + @Override + public void onPeerConnected(com.google.android.gms.wearable.Node peer) {// KS + super.onPeerConnected(peer); + String id = peer.getId(); + String name = peer.getDisplayName(); + // Log.d(TAG, logPrefix + "onPeerConnected peer name & ID: " + name + "|" + id); + } + + + @Override + public void onPeerDisconnected(com.google.android.gms.wearable.Node peer) {// KS + super.onPeerDisconnected(peer); + String id = peer.getId(); + String name = peer.getDisplayName(); + // Log.d(TAG, logPrefix + "onPeerDisconnected peer name & ID: " + name + "|" + id); + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + } + + @Override public void onMessageReceived(MessageEvent event) { + + // Log.d(TAG, logPrefix + "onMessageRecieved: " + event); + if (wear_integration) { if (event != null && event.getPath().equals(WEARABLE_RESEND_PATH)) { resendData(); @@ -214,6 +291,7 @@ public class WatchUpdaterService extends WearableListenerService implements private void sendData() { BgReading lastBG = DatabaseHelper.lastBg(); + // Log.d(TAG, logPrefix + "LastBg=" + lastBG); if (lastBG != null) { GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); @@ -228,18 +306,19 @@ public class WatchUpdaterService extends WearableListenerService implements return; } - new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(dataMap); + executeTask(new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient), dataMap); } } } + private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) { String units = ProfileFunctions.getInstance().getProfileUnits(); Double lowLine = SafeParse.stringToDouble(mPrefs.getString("low_mark", "0")); Double highLine = SafeParse.stringToDouble(mPrefs.getString("high_mark", "0")); - //convert to mg/dl + // convert to mg/dl if (!units.equals(Constants.MGDL)) { lowLine *= Constants.MMOLL_TO_MGDL; highLine *= Constants.MMOLL_TO_MGDL; @@ -287,7 +366,6 @@ public class WatchUpdaterService extends WearableListenerService implements deltastring += "+"; } else { deltastring += "-"; - } boolean detailed = SP.getBoolean("wear_detailed_delta", false); @@ -352,7 +430,7 @@ public class WatchUpdaterService extends WearableListenerService implements } } entries.putDataMapArrayList("entries", dataMaps); - new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(entries); + executeTask(new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient), entries); } sendPreferences(); sendBasals(); @@ -501,7 +579,7 @@ public class WatchUpdaterService extends WearableListenerService implements dm.putDataMapArrayList("boluses", boluses); dm.putDataMapArrayList("predictions", predictions); - new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient).execute(dm); + executeTask(new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient), dm); } private DataMap tempDatamap(long startTime, double startBasal, long to, double toBasal, double amount) { @@ -548,6 +626,7 @@ public class WatchUpdaterService extends WearableListenerService implements dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); dataMapRequest.getDataMap().putString("openSettings", "openSettings"); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendNotification", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("OpenSettings", "No connection to wearable available!"); @@ -563,6 +642,7 @@ public class WatchUpdaterService extends WearableListenerService implements dataMapRequest.getDataMap().putString("progressstatus", status); dataMapRequest.getDataMap().putInt("progresspercent", progresspercent); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendBolusProgress", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("BolusProgress", "No connection to wearable available!"); @@ -582,6 +662,7 @@ public class WatchUpdaterService extends WearableListenerService implements log.debug("Requesting confirmation from wear: " + actionstring); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendActionConfirmationRequest", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("confirmationRequest", "No connection to wearable available!"); @@ -601,6 +682,7 @@ public class WatchUpdaterService extends WearableListenerService implements log.debug("Requesting confirmation from wear: " + actionstring); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendChangeConfirmationRequest", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("changeConfirmRequest", "No connection to wearable available!"); @@ -618,6 +700,7 @@ public class WatchUpdaterService extends WearableListenerService implements log.debug("Canceling notification on wear: " + actionstring); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendCancelNotificationRequest", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("cancelNotificationRequest", "No connection to wearable available!"); @@ -683,6 +766,7 @@ public class WatchUpdaterService extends WearableListenerService implements dataMapRequest.getDataMap().putBoolean("showBgi", mPrefs.getBoolean("wear_showbgi", false)); dataMapRequest.getDataMap().putInt("batteryLevel", (phoneBattery >= 30) ? 1 : 0); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendStatus", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("SendStatus", "No connection to wearable available!"); @@ -699,12 +783,29 @@ public class WatchUpdaterService extends WearableListenerService implements dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); dataMapRequest.getDataMap().putBoolean("wearcontrol", wearcontrol); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + debugData("sendPreferences", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { Log.e("SendStatus", "No connection to wearable available!"); } } + + private void debugData(String source, Object data) { + // Log.d(TAG, "WR: " + source + " " + data); + } + + + private void executeTask(AsyncTask task, DataMap... parameters) { + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, parameters); + // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + // } else { + // task.execute(); + // } + } + + @NonNull private String generateStatusString(Profile profile, String currentBasal, String iobSum, String iobDetail, String bgiString) { diff --git a/app/src/main/res/values/wear.xml b/app/src/main/res/values/wear.xml new file mode 100644 index 0000000000..41df8ef193 --- /dev/null +++ b/app/src/main/res/values/wear.xml @@ -0,0 +1,18 @@ + + + + + phone_app_sync_bgs + + \ No newline at end of file diff --git a/wear/build.gradle b/wear/build.gradle index 1dd07ff1a5..78a221837b 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' ext { wearableVersion = "2.0.1" - playServicesWearable = "9.4.0" + playServicesWearable = "10.2.1" } def generateGitBuild = { -> diff --git a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java index 326d154079..094b8aad76 100644 --- a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java +++ b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java @@ -1,5 +1,8 @@ package info.nightscout.androidaps.data; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -14,11 +17,16 @@ import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.PendingResult; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.wearable.CapabilityApi; +import com.google.android.gms.wearable.CapabilityInfo; import com.google.android.gms.wearable.ChannelApi; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; @@ -81,57 +89,156 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String TAG = "ListenerService"; private DataRequester mDataRequester = null; + private static final int GET_CAPABILITIES_TIMEOUT_MS = 5000; + // Phone + private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs"; + private static final String MESSAGE_PATH_PHONE = "/phone_message_path"; + // Wear + private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs"; + private static final String MESSAGE_PATH_WEAR = "/wear_message_path"; + private String mPhoneNodeId = null; + private String localnode = null; + private String logPrefix = ""; // "WR: " public class DataRequester extends AsyncTask { Context mContext; String path; byte[] payload; -// DataRequester(Context context) { -// mContext = context; -// } - - DataRequester(Context context, String thispath, byte[] thispayload) { path = thispath; payload = thispayload; - Log.d(TAG, "DataRequester DataRequester: " + thispath + " lastRequest:" + lastRequest); + // Log.d(TAG, logPrefix + "DataRequester DataRequester: " + thispath + " lastRequest:" + lastRequest); } @Override protected Void doInBackground(Void... params) { - if (googleApiClient.isConnected()) { - if (System.currentTimeMillis() - lastRequest > 20 * 1000) { // enforce 20-second debounce period - lastRequest = System.currentTimeMillis(); + // Log.d(TAG, logPrefix + "DataRequester: doInBack: " + params); - NodeApi.GetConnectedNodesResult nodes = - Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); - for (Node node : nodes.getNodes()) { - Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_RESEND_PATH, null); - } + try { + + forceGoogleApiConnect(); + DataMap datamap; + + if (isCancelled()) { + Log.d(TAG, "doInBackground CANCELLED programmatically"); + return null; } - } else { - googleApiClient.blockingConnect(15, TimeUnit.SECONDS); - if (googleApiClient.isConnected()) { - if (System.currentTimeMillis() - lastRequest > 20 * 1000) { // enforce 20-second debounce period + + if (googleApiClient != null) { + if (!googleApiClient.isConnected()) + googleApiClient.blockingConnect(15, TimeUnit.SECONDS); + } + + // this code might not be needed in this way, but we need to see that later + if ((googleApiClient != null) && (googleApiClient.isConnected())) { + if ((System.currentTimeMillis() - lastRequest > 20 * 1000)) { + + // enforce 20-second debounce period lastRequest = System.currentTimeMillis(); - NodeApi.GetConnectedNodesResult nodes = - Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); - for (Node node : nodes.getNodes()) { - Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_RESEND_PATH, null); + // NodeApi.GetConnectedNodesResult nodes = + // Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); + if (localnode == null || (localnode != null && localnode.isEmpty())) + setLocalNodeName(); + + CapabilityInfo capabilityInfo = getCapabilities(); + + int count = 0; + Node phoneNode = null; + + if (capabilityInfo != null) { + phoneNode = updatePhoneSyncBgsCapability(capabilityInfo); + count = capabilityInfo.getNodes().size(); } + + Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mPhoneNodeID=" + + (phoneNode != null ? phoneNode.getId() : "") + " count=" + count + " localnode=" + + localnode);// KS + + if (count > 0) { + + for (Node node : capabilityInfo.getNodes()) { + + // Log.d(TAG, "doInBackground path: " + path); + + switch (path) { + // simple send as is payloads + + case WEARABLE_RESEND_PATH: + Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), + WEARABLE_RESEND_PATH, null); + break; + case WEARABLE_DATA_PATH: + case WEARABLE_CANCELBOLUS_PATH: + case WEARABLE_CONFIRM_ACTIONSTRING_PATH: + case WEARABLE_INITIATE_ACTIONSTRING_PATH: + case OPEN_SETTINGS: + case NEW_STATUS_PATH: + case NEW_PREFERENCES_PATH: + case BASAL_DATA_PATH: + case BOLUS_PROGRESS_PATH: + case ACTION_CONFIRMATION_REQUEST_PATH: + case NEW_CHANGECONFIRMATIONREQUEST_PATH: + case ACTION_CANCELNOTIFICATION_REQUEST_PATH: { + Log.w(TAG, logPrefix + "Unhandled path"); + // sendMessagePayload(node, path, path, payload); + } + + default:// SYNC_ALL_DATA + // this fall through is messy and non-deterministic for new paths + + } + } + } else { + + Log.d(TAG, logPrefix + "doInBackground connected but getConnectedNodes returns 0."); + + } + } else { + // no resend + Log.d(TAG, logPrefix + "Inside the timeout, will not be executed"); + + } + } else { + Log.d(TAG, logPrefix + "Not connected for sending: api " + + ((googleApiClient == null) ? "is NULL!" : "not null")); + if (googleApiClient != null) { + googleApiClient.connect(); + } else { + googleApiConnect(); } } + + } catch (Exception ex) { + Log.e(TAG, logPrefix + "Error executing DataRequester in background. Exception: " + ex.getMessage()); } + return null; } } + + public CapabilityInfo getCapabilities() { + + CapabilityApi.GetCapabilityResult capabilityResult = Wearable.CapabilityApi.getCapability(googleApiClient, + CAPABILITY_PHONE_APP, CapabilityApi.FILTER_REACHABLE).await(GET_CAPABILITIES_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + + if (!capabilityResult.getStatus().isSuccess()) { + Log.e(TAG, logPrefix + "doInBackground Failed to get capabilities, status: " + + capabilityResult.getStatus().getStatusMessage()); + return null; + } + + return capabilityResult.getCapability(); + + } + public class BolusCancelTask extends AsyncTask { Context mContext; @@ -141,6 +248,8 @@ public class ListenerService extends WearableListenerService implements GoogleAp @Override protected Void doInBackground(Void... params) { + // Log.d(TAG, logPrefix + "BolusCancelTask: doInBack: " + params); + if (googleApiClient.isConnected()) { NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); @@ -217,29 +326,54 @@ public class ListenerService extends WearableListenerService implements GoogleAp } - private synchronized void sendData(String path, byte[] payload) { - if (path == null) return; - if (mDataRequester != null) { - Log.d(TAG, "sendData DataRequester != null lastRequest:" + WearUtil.dateTimeText(lastRequest)); - if (mDataRequester.getStatus() != AsyncTask.Status.FINISHED) { - Log.d(TAG, "sendData Should be canceled? Let run 'til finished."); - //mDataRequester.cancel(true); + private Node updatePhoneSyncBgsCapability(CapabilityInfo capabilityInfo) { + // Log.d(TAG, "CapabilityInfo: " + capabilityInfo); + + Set connectedNodes = capabilityInfo.getNodes(); + return pickBestNode(connectedNodes); + // mPhoneNodeId = pickBestNodeId(connectedNodes); + } + + + private Node pickBestNode(Set nodes) { + Node bestNode = null; + // Find a nearby node or pick one arbitrarily + for (Node node : nodes) { + if (node.isNearby()) { + return node; + } + bestNode = node; + } + return bestNode; + } + + + private synchronized void sendData(String path, byte[] payload) { + // Log.d(TAG, "WR: sendData: path: " + path + ", payload=" + payload); + + if (path == null) + return; + if (mDataRequester != null) { + // Log.d(TAG, logPrefix + "sendData DataRequester != null lastRequest:" + + // WearUtil.dateTimeText(lastRequest)); + if (mDataRequester.getStatus() != AsyncTask.Status.FINISHED) { + // Log.d(TAG, logPrefix + "sendData Should be canceled? Let run 'til finished."); + // mDataRequester.cancel(true); } - //mDataRequester = null; } - Log.d(TAG, "sendData: execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); - mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute(); + Log.d(TAG, logPrefix + "sendData: execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); + mDataRequester = (DataRequester)new DataRequester(this, path, payload).execute(); + // executeTask(mDataRequester); - -// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { -// Log.d(TAG, "sendData SDK < M call execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); -// mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute(); -// } else { -// Log.d(TAG, "sendData SDK >= M call executeOnExecutor lastRequest:" + WearUtil.dateTimeText(lastRequest)); -// // TODO xdrip executor -// mDataRequester = (DataRequester) new DataRequester(this, path, payload).executeOnExecutor(xdrip.executor); -// } + // if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + // Log.d(TAG, "sendData SDK < M call execute lastRequest:" + WearUtil.dateTimeText(lastRequest)); + // mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute(); + // } else { + // Log.d(TAG, "sendData SDK >= M call executeOnExecutor lastRequest:" + WearUtil.dateTimeText(lastRequest)); + // // TODO xdrip executor + // mDataRequester = (DataRequester) new DataRequester(this, path, payload).executeOnExecutor(xdrip.executor); + // } } @@ -283,6 +417,9 @@ public class ListenerService extends WearableListenerService implements GoogleAp @Override public int onStartCommand(Intent intent, int flags, int startId) { + + // Log.d(TAG, logPrefix + "onStartCommand: Intent: " + intent); + if (intent != null && ACTION_RESEND.equals(intent.getAction())) { googleApiConnect(); requestData(); @@ -336,6 +473,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp public void onDataChanged(DataEventBuffer dataEvents) { DataMap dataMap; + // Log.d(TAG, logPrefix + "onDataChanged: DataEvents=" + dataEvents); for (DataEvent event : dataEvents) { @@ -343,7 +481,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp String path = event.getDataItem().getUri().getPath(); - Log.d(TAG, "Path: {}" + path + ", Event=" + event); + //Log.d(TAG, "WR: onDataChanged: Path: " + path + ", EventDataItem=" + event.getDataItem()); if (path.equals(OPEN_SETTINGS)) { Intent intent = new Intent(this, AAPSPreferences.class); @@ -562,7 +700,19 @@ public class ListenerService extends WearableListenerService implements GoogleAp @Override public void onConnected(Bundle bundle) { - Log.d(TAG, "onConnected call requestData"); + // Log.d(TAG, logPrefix + "onConnected call requestData"); + + CapabilityApi.CapabilityListener capabilityListener = new CapabilityApi.CapabilityListener() { + + @Override + public void onCapabilityChanged(CapabilityInfo capabilityInfo) { + updatePhoneSyncBgsCapability(capabilityInfo); + Log.d(TAG, logPrefix + "onConnected onCapabilityChanged mPhoneNodeID:" + mPhoneNodeId + + ", Capability: " + capabilityInfo); + } + }; + + Wearable.CapabilityApi.addCapabilityListener(googleApiClient, capabilityListener, CAPABILITY_PHONE_APP); Wearable.ChannelApi.addListener(googleApiClient, this); requestData(); @@ -578,6 +728,28 @@ public class ListenerService extends WearableListenerService implements GoogleAp } + + private void setLocalNodeName() { + forceGoogleApiConnect(); + PendingResult result = Wearable.NodeApi.getLocalNode(googleApiClient); + result.setResultCallback(new ResultCallback() { + + @Override + public void onResult(NodeApi.GetLocalNodeResult getLocalNodeResult) { + if (!getLocalNodeResult.getStatus().isSuccess()) { + Log.e(TAG, "ERROR: failed to getLocalNode Status=" + + getLocalNodeResult.getStatus().getStatusMessage()); + } else { + Log.d(TAG, "getLocalNode Status=: " + getLocalNodeResult.getStatus().getStatusMessage()); + Node getnode = getLocalNodeResult.getNode(); + localnode = getnode != null ? getnode.getDisplayName() + "|" + getnode.getId() : ""; + Log.d(TAG, "setLocalNodeName. localnode=" + localnode); + } + } + }); + } + + @Override public void onDestroy() { super.onDestroy(); diff --git a/wear/src/main/res/values/wear.xml b/wear/src/main/res/values/wear.xml new file mode 100644 index 0000000000..41df8ef193 --- /dev/null +++ b/wear/src/main/res/values/wear.xml @@ -0,0 +1,18 @@ + + + + + phone_app_sync_bgs + + \ No newline at end of file From b91ab26863de44e6c93b44991a68880d17371f5a Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Wed, 6 Mar 2019 23:48:45 +0000 Subject: [PATCH 5/9] Wear android manifest --- wear/src/main/AndroidManifest.xml | 69 ++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index 119b83a3f5..f04e072bc7 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -173,23 +173,64 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + From a148f5d21d2fc24401cdf7db22e5bfdc43df094d Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Thu, 7 Mar 2019 00:01:19 +0000 Subject: [PATCH 6/9] Fixed some files after merge. --- .../general/wear/wearintegration/SendToDataLayerThread.java | 1 + .../general/wear/wearintegration/WatchUpdaterService.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/SendToDataLayerThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/SendToDataLayerThread.java index fcf76d207b..aa6498563d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/SendToDataLayerThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/SendToDataLayerThread.java @@ -13,6 +13,7 @@ import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; /** * Created by emmablack on 12/26/14. diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 806ee9d31f..8f58015af8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -152,7 +152,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog .addOnConnectionFailedListener(this).addApi(Wearable.API).build(); Wearable.MessageApi.addListener(googleApiClient, this); if (googleApiClient.isConnected()) { - Log.d(TAG, logPrefix + "API client is connected"); + log.debug(logPrefix + "API client is connected"); } else { // Log.d("WatchUpdater", logPrefix + "API client is not connected and is trying to connect"); googleApiClient.connect(); @@ -703,7 +703,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog debugData("sendCancelNotificationRequest", putDataRequest); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); } else { - Log.e("cancelNotificationRequest", "No connection to wearable available!"); + Log.e("cancelNotificationReq", "No connection to wearable available!"); } } From be9039d8b0f88cd4159852484b32a572da1f1464 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Tue, 12 Mar 2019 22:41:52 +0000 Subject: [PATCH 7/9] Minor changes --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fe60a69960..50f6f47ced 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,7 +78,7 @@ android { // TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0 // has been upgraded (requiring significant code changes), which currently fails release // build with a deprecation warning - abortOnError false + // abortOnError false // (disabled entirely to avoid reports on the error, which would still be displayed // and it's easy to overlook that it's ignored) checkReleaseBuilds false @@ -100,7 +100,7 @@ android { applicationId "info.nightscout.androidaps" dimension "standard" resValue "string", "app_name", "AndroidAPS" - versionName version + "-pumpcontrol" + versionName version manifestPlaceholders = [ appIcon: "@mipmap/ic_launcher", appIconRound: "@mipmap/ic_launcher_round" From b1baaf48f562f8f793bee8c0d27e2ded8b876488 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Tue, 12 Mar 2019 23:57:57 +0000 Subject: [PATCH 8/9] remove wear warning --- .../general/wear/wearintegration/WatchUpdaterService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 8f58015af8..52dbeed75c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -797,7 +797,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog private void executeTask(AsyncTask task, DataMap... parameters) { - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, parameters); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])parameters); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); // } else { From 02f20b9e8306889047d06db2c301b578041c5d82 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 14 Mar 2019 11:18:02 +0100 Subject: [PATCH 9/9] uncomment fileprovider --- app/src/main/AndroidManifest.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index da3643e662..dc9201d86c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -135,7 +135,6 @@ - + - \ No newline at end of file +