Skip to content
Permalink
Browse files

Merge remote-tracking branch 'andyremote/wear_upgrade' into dev-wear

  • Loading branch information...
AdrianLxM committed Mar 18, 2019
2 parents f9904d1 + 02f20b9 commit d4d499587b73138e2a5b07f97eaa4d76fc0b836a
@@ -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

@@ -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"
@@ -77,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
@@ -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'
@@ -169,7 +169,63 @@
android:name=".plugins.general.wear.wearintegration.WatchUpdaterService"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
<!-- <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> -->
<!-- listeners receive events that match the action and data filters -->
<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />

<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_data" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_data_resend" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_cancel_bolus" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_confirmactionstring" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_initiateactionstring" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/openwearsettings" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/sendstatustowear" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/sendpreferencestowear" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_basal" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_bolusprogress" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_actionconfirmationrequest" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_changeconfirmationrequest" />
<data
android:scheme="wear"
android:host="*"
android:pathPrefix="/nightscout_watch_cancelnotificationrequest" />
</intent-filter>
</service>
<service
@@ -216,4 +272,4 @@
android:label="@string/pairing_information" />
</application>

</manifest>
</manifest>
@@ -2,6 +2,7 @@

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.squareup.otto.Subscribe;

@@ -35,6 +36,8 @@
private final Context ctx;

private static WearPlugin wearPlugin;
private static String TAG = "WearPlugin";


public static WearPlugin getPlugin() {
return wearPlugin;
@@ -76,7 +79,10 @@ protected void onStop() {
}

private void sendDataToWatch(boolean status, boolean basals, boolean bgValue) {
if (isEnabled(getType())) { //only start service when this plugin is enabled

//Log.d(TAG, "WR: WearPlugin:sendDataToWatch (status=" + status + ",basals=" + basals + ",bgValue=" + bgValue + ")");

if (isEnabled(getType())) { // only start service when this plugin is enabled

if (bgValue) {
ctx.startService(new Intent(ctx, WatchUpdaterService.class));
@@ -93,15 +99,20 @@ private void sendDataToWatch(boolean status, boolean basals, boolean bgValue) {
}

void resendDataToWatch() {
//Log.d(TAG, "WR: WearPlugin:resendDataToWatch");
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_RESEND));
}

void openSettings() {
//Log.d(TAG, "WR: WearPlugin:openSettings");
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS));
}

void requestNotificationCancel(String actionstring) {
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION);
//Log.d(TAG, "WR: WearPlugin:requestNotificationCancel");

Intent intent = new Intent(ctx, WatchUpdaterService.class)
.setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION);
intent.putExtra("actionstring", actionstring);
ctx.startService(intent);
}
@@ -13,40 +13,127 @@
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.
*/
class SendToDataLayerThread extends AsyncTask<DataMap,Void,Void> {
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) {
if (testlockup) {
try {
Log.e(TAG, logPrefix + "WARNING RUNNING TEST LOCK UP CODE - NEVER FOR PRODUCTION");
Thread.sleep(1000000); // DEEEBBUUGGGG
} catch (Exception e) {
}
}
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 {
final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15, TimeUnit.SECONDS);
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();
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, TimeUnit.SECONDS);
state = 7;
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15,
TimeUnit.SECONDS);
state = 8;
if (result.getStatus().isSuccess()) {
Log.d(TAG, "DataMap: " + dataMap + " sent to: " + node.getDisplayName());
Log.d(TAG, logPrefix + "DataMap: " + dataMap + " sent to: " + node.getDisplayName());
} else {
Log.d(TAG, "ERROR: failed to send DataMap");
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, "Got exception sending data to wear: " + e.toString());
Log.e(TAG, logPrefix + "Got exception in sendToWear: " + e.toString());
} finally {
lastlock = 0;
lock.unlock();
}
return null;
}


private static long tsl() {
return System.currentTimeMillis();
}


private static String hourMinuteString(long timestamp) {
return android.text.format.DateFormat.format("kk:mm", timestamp).toString();
}
}
Oops, something went wrong.

0 comments on commit d4d4995

Please sign in to comment.
You can’t perform that action at this time.