mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-09 16:36:48 +01:00
Pebble: JS basic implementation of transaction acknowledgment
JAVA side: - first trivial handling of ACK/NACK message, - fake the location age until an update mechanism is implemented, - make the appmessage parsing more robust, - comment the forecast mimicked reply as it was wrong and confusing for some watchfaces JS side: first trivial handling of ACK/NACK message
This commit is contained in:
parent
5939c244fb
commit
aa28625d9f
@ -159,17 +159,33 @@ function gbPebble() {
|
|||||||
if (document.getElementById("step2").style.display == 'block') { //intercept the values
|
if (document.getElementById("step2").style.display == 'block') { //intercept the values
|
||||||
document.getElementById("jsondata").innerHTML=self.configurationValues;
|
document.getElementById("jsondata").innerHTML=self.configurationValues;
|
||||||
} else { //pass them silently
|
} else { //pass them silently
|
||||||
GBjs.sendAppMessage(JSON.stringify(dict));
|
var needsTransaction = false;
|
||||||
|
if (callbackAck != undefined || callbackNack != undefined) {
|
||||||
|
needsTransaction = true;
|
||||||
}
|
}
|
||||||
|
var transactionId = GBjs.sendAppMessage(JSON.stringify(dict), needsTransaction);
|
||||||
|
if (needsTransaction) {
|
||||||
if (callbackAck != undefined) {
|
if (callbackAck != undefined) {
|
||||||
callbackAck();
|
this.addEventListener("ACK"+transactionId, function(e) {
|
||||||
|
// console.log("ACK FOR " + JSON.stringify(e));
|
||||||
|
callbackAck(e);
|
||||||
|
self.removeEventListener("ACK"+transactionId);
|
||||||
|
self.removeEventListener("NACK"+transactionId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (callbackNack != undefined) {
|
||||||
|
this.addEventListener("NACK"+transactionId, function(e) {
|
||||||
|
// console.log("NACK FOR " + JSON.stringify(e));
|
||||||
|
callbackNack(e);
|
||||||
|
self.removeEventListener("ACK"+transactionId);
|
||||||
|
self.removeEventListener("NACK"+transactionId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
GBjs.gbLog("sendAppMessage failed");
|
GBjs.gbLog("sendAppMessage failed");
|
||||||
if (callbackNack != undefined) {
|
|
||||||
callbackNack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,22 +123,31 @@ public class WebViewSingleton {
|
|||||||
|
|
||||||
public static void appMessage(GBDeviceEventAppMessage message) {
|
public static void appMessage(GBDeviceEventAppMessage message) {
|
||||||
|
|
||||||
|
final String jsEvent;
|
||||||
if (webViewSingleton.instance == null) {
|
if (webViewSingleton.instance == null) {
|
||||||
LOG.warn("WEBVIEW is not initialized, cannot send appMessages to it");
|
LOG.warn("WEBVIEW is not initialized, cannot send appMessages to it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!message.appUUID.equals(currentRunningUUID)) {
|
||||||
|
LOG.info("WEBVIEW ignoring message for app that is not currently running: " + message.appUUID + " message: " + message.message + " type: " + message.type);
|
||||||
|
// return; //TODO: ignoring would be the right thing to do here, but sometimes appUUID is apparently wrong
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: handle ACK and NACK types with ids
|
// TODO: handle ACK and NACK types with ids
|
||||||
if (message.type != GBDeviceEventAppMessage.TYPE_APPMESSAGE) {
|
if (message.type != GBDeviceEventAppMessage.TYPE_APPMESSAGE) {
|
||||||
return;
|
jsEvent = (GBDeviceEventAppMessage.TYPE_NACK == GBDeviceEventAppMessage.TYPE_APPMESSAGE) ? "NACK" + message.id : "ACK" + message.id;
|
||||||
|
LOG.debug("WEBVIEW received ACK/NACK:" + message.message + " for uuid: " + message.appUUID + " ID: " + message.id);
|
||||||
|
} else {
|
||||||
|
jsEvent = "appmessage";
|
||||||
}
|
}
|
||||||
|
|
||||||
final String appMessage = parseIncomingAppMessage(message.message, message.appUUID);
|
final String appMessage = parseIncomingAppMessage(message.message, message.appUUID);
|
||||||
LOG.debug("to WEBVIEW: " + appMessage);
|
LOG.debug("to WEBVIEW: event: " + jsEvent + " message: " + appMessage);
|
||||||
new Handler(webViewSingleton.mainLooper).post(new Runnable() {
|
new Handler(webViewSingleton.mainLooper).post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
webViewSingleton.instance.evaluateJavascript("Pebble.evaluate('appmessage',[" + appMessage + "]);", new ValueCallback<String>() {
|
webViewSingleton.instance.evaluateJavascript("Pebble.evaluate('" + jsEvent + "',[" + appMessage + "]);", new ValueCallback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceiveValue(String s) {
|
public void onReceiveValue(String s) {
|
||||||
//TODO: the message should be acked here instead of in PebbleIoThread
|
//TODO: the message should be acked here instead of in PebbleIoThread
|
||||||
@ -192,6 +201,7 @@ public class WebViewSingleton {
|
|||||||
Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
|
Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
|
||||||
if (lastKnownLocation != null) {
|
if (lastKnownLocation != null) {
|
||||||
this.timestamp = lastKnownLocation.getTime();
|
this.timestamp = lastKnownLocation.getTime();
|
||||||
|
this.timestamp = System.currentTimeMillis() - 1000; //TODO: request updating the location and don't fake its age
|
||||||
|
|
||||||
this.latitude = (float) lastKnownLocation.getLatitude();
|
this.latitude = (float) lastKnownLocation.getLatitude();
|
||||||
this.longitude = (float) lastKnownLocation.getLongitude();
|
this.longitude = (float) lastKnownLocation.getLongitude();
|
||||||
@ -260,20 +270,20 @@ public class WebViewSingleton {
|
|||||||
resp.put("cod", 200);
|
resp.put("cod", 200);
|
||||||
resp.put("coord", coordObject(currentPosition));
|
resp.put("coord", coordObject(currentPosition));
|
||||||
resp.put("sys", sysObject(currentPosition));
|
resp.put("sys", sysObject(currentPosition));
|
||||||
} else if ("/data/2.5/forecast".equals(type) && Weather.getInstance().getWeather2().reconstructedForecast != null) { //this is wrong, as we only have daily data. Unfortunately it looks like daily forecasts cannot be reconstructed
|
// } else if ("/data/2.5/forecast".equals(type) && Weather.getInstance().getWeather2().reconstructedForecast != null) { //this is wrong, as we only have daily data. Unfortunately it looks like daily forecasts cannot be reconstructed
|
||||||
resp = new JSONObject(Weather.getInstance().getWeather2().reconstructedForecast.toString());
|
// resp = new JSONObject(Weather.getInstance().getWeather2().reconstructedForecast.toString());
|
||||||
|
//
|
||||||
JSONObject city = resp.getJSONObject("city");
|
// JSONObject city = resp.getJSONObject("city");
|
||||||
city.put("coord", coordObject(currentPosition));
|
// city.put("coord", coordObject(currentPosition));
|
||||||
|
//
|
||||||
JSONArray list = resp.getJSONArray("list");
|
// JSONArray list = resp.getJSONArray("list");
|
||||||
for (int i = 0, size = list.length(); i < size; i++) {
|
// for (int i = 0, size = list.length(); i < size; i++) {
|
||||||
JSONObject item = list.getJSONObject(i);
|
// JSONObject item = list.getJSONObject(i);
|
||||||
JSONObject main = item.getJSONObject("main");
|
// JSONObject main = item.getJSONObject("main");
|
||||||
convertTemps(main, units); //caller might want different units
|
// convertTemps(main, units); //caller might want different units
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
resp.put("cod", 200);
|
// resp.put("cod", 200);
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("WEBVIEW - cannot mimick request of type " + type + " (unsupported or lack of data)");
|
LOG.warn("WEBVIEW - cannot mimick request of type " + type + " (unsupported or lack of data)");
|
||||||
return null;
|
return null;
|
||||||
@ -393,6 +403,10 @@ public class WebViewSingleton {
|
|||||||
JSONObject knownKeys = getAppConfigurationKeys(uuid);
|
JSONObject knownKeys = getAppConfigurationKeys(uuid);
|
||||||
SparseArray<String> appKeysMap = new SparseArray<>();
|
SparseArray<String> appKeysMap = new SparseArray<>();
|
||||||
|
|
||||||
|
if (knownKeys == null) {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
|
||||||
String inKey, outKey;
|
String inKey, outKey;
|
||||||
//knownKeys contains "name"->"index", we need to reverse that
|
//knownKeys contains "name"->"index", we need to reverse that
|
||||||
for (Iterator<String> key = knownKeys.keys(); key.hasNext(); ) {
|
for (Iterator<String> key = knownKeys.keys(); key.hasNext(); ) {
|
||||||
@ -423,7 +437,7 @@ public class WebViewSingleton {
|
|||||||
}
|
}
|
||||||
jsAppMessage.put("payload", outgoing);
|
jsAppMessage.put("payload", outgoing);
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (Exception e) {
|
||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
}
|
}
|
||||||
return jsAppMessage.toString();
|
return jsAppMessage.toString();
|
||||||
@ -433,11 +447,13 @@ public class WebViewSingleton {
|
|||||||
|
|
||||||
UUID mUuid;
|
UUID mUuid;
|
||||||
GBDevice device;
|
GBDevice device;
|
||||||
|
Integer lastTransaction;
|
||||||
|
|
||||||
private JSInterface(GBDevice device, UUID mUuid) {
|
private JSInterface(GBDevice device, UUID mUuid) {
|
||||||
LOG.debug("Creating JS interface for UUID: " + mUuid.toString());
|
LOG.debug("Creating JS interface for UUID: " + mUuid.toString());
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.mUuid = mUuid;
|
this.mUuid = mUuid;
|
||||||
|
this.lastTransaction = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -451,8 +467,9 @@ public class WebViewSingleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public void sendAppMessage(String msg) {
|
public String sendAppMessage(String msg, String needsTransactionMsg) {
|
||||||
LOG.debug("from WEBVIEW: " + msg);
|
boolean needsTransaction = "true".equals(needsTransactionMsg);
|
||||||
|
LOG.debug("from WEBVIEW: " + msg + " needs a transaction: " + needsTransaction);
|
||||||
JSONObject knownKeys = getAppConfigurationKeys(this.mUuid);
|
JSONObject knownKeys = getAppConfigurationKeys(this.mUuid);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -486,11 +503,18 @@ public class WebViewSingleton {
|
|||||||
|
|
||||||
}
|
}
|
||||||
LOG.info("WEBVIEW message to pebble: " + out.toString());
|
LOG.info("WEBVIEW message to pebble: " + out.toString());
|
||||||
GBApplication.deviceService().onAppConfiguration(this.mUuid, out.toString(), null); // TODO: insert local id for transaction
|
if (needsTransaction) {
|
||||||
|
this.lastTransaction++;
|
||||||
|
GBApplication.deviceService().onAppConfiguration(this.mUuid, out.toString(), this.lastTransaction);
|
||||||
|
return this.lastTransaction.toString();
|
||||||
|
} else {
|
||||||
|
GBApplication.deviceService().onAppConfiguration(this.mUuid, out.toString(), null);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
|
Loading…
x
Reference in New Issue
Block a user