1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-29 05:16:51 +01:00

Pebble: webview. Implement two way communication with JS.

The support within JS is a bit hacky and sometimes conflicts with the configuration page.
This commit is contained in:
Daniele Gobbetti 2017-01-03 15:04:51 +01:00
parent 0efacfbad5
commit c9cfaa9bd8
3 changed files with 69 additions and 4 deletions

View File

@ -141,7 +141,11 @@ function gbPebble() {
this.sendAppMessage = function (dict, callbackAck, callbackNack){
try {
self.configurationValues = JSON.stringify(dict);
if (document.getElementById("step2").style.display == 'block') { //intercept the values
document.getElementById("jsondata").innerHTML=self.configurationValues;
} else { //pass them silently
GBjs.sendAppMessage(JSON.stringify(dict));
}
return callbackAck;
}
catch (e) {
@ -179,8 +183,8 @@ function gbPebble() {
if (str.split(needle)[1] !== undefined) {
var t = new Object();
t.response = decodeURIComponent(str.split(needle)[1]);
self.evaluate('webviewclosed',[t]);
showStep("step2");
self.evaluate('webviewclosed',[t]);
} else {
console.error("No valid configuration found in the entered string.");
}

View File

@ -140,6 +140,11 @@ class PebbleIoThread extends GBDeviceIoThread {
}
};
private void sendAppMessageJS(GBDeviceEventAppMessage appMessage) {
WebViewSingleton.getorInitWebView(getContext(), gbDevice, appMessage.appUUID);
WebViewSingleton.appMessage(appMessage.message);
}
private void sendAppMessageIntent(GBDeviceEventAppMessage appMessage) {
Intent intent = new Intent();
intent.setAction(PEBBLEKIT_ACTION_APP_RECEIVE);
@ -582,6 +587,7 @@ class PebbleIoThread extends GBDeviceIoThread {
setInstallSlot(appInfoEvent.freeSlot);
return false;
} else if (deviceEvent instanceof GBDeviceEventAppMessage) {
sendAppMessageJS((GBDeviceEventAppMessage) deviceEvent);
if (mEnablePebblekit) {
LOG.info("Got AppMessage event");
sendAppMessageIntent((GBDeviceEventAppMessage) deviceEvent);

View File

@ -19,6 +19,7 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
@ -32,6 +33,7 @@ import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.UUID;
@ -107,18 +109,22 @@ public class WebViewSingleton extends Activity {
}
public static void appMessage(final String message) {
final String appMessage = jsInterface.parseIncomingAppMessage(message);
LOG.debug("to WEBVIEW: " + appMessage);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
instance.evaluateJavascript("Pebble.evaluate('appmessage',[{'payload':" + message + "}]);", new ValueCallback<String>() {
instance.evaluateJavascript("Pebble.evaluate('appmessage',[" + appMessage + "]);", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
LOG.debug("Callback from showConfiguration", s);
}
});
} else {
instance.loadUrl("javascript:Pebble.evaluate('appmessage',[{'payload':" + message + "}]);");
instance.loadUrl("javascript:Pebble.evaluate('appmessage',[" + appMessage + "]);");
}
}
});
@ -129,6 +135,13 @@ public class WebViewSingleton extends Activity {
@Override
public void run() {
if (instance != null) {
instance.setWebChromeClient(null);
instance.setWebViewClient(null);
instance.clearHistory();
instance.clearCache(true);
instance.loadUrl("about:blank");
instance.freeMemory();
instance.pauseTimers();
instance.destroy();
instance = null;
contextWrapper = null;
@ -202,6 +215,48 @@ public class WebViewSingleton extends Activity {
this.mUuid = mUuid;
}
public String parseIncomingAppMessage(String msg) {
JSONObject jsAppMessage = new JSONObject();
JSONObject knownKeys = getAppConfigurationKeys(this.mUuid);
HashMap<Integer, String> appKeysMap = new HashMap<Integer, String>();
String inKey, outKey;
//knownKeys contains "name"->"index", we need to reverse that
for (Iterator<String> key = knownKeys.keys(); key.hasNext(); ) {
inKey = key.next();
appKeysMap.put(knownKeys.optInt(inKey), inKey);
}
try {
JSONArray incoming = new JSONArray(msg);
JSONObject outgoing = new JSONObject();
for (int i = 0; i < incoming.length(); i++) {
JSONObject in = incoming.getJSONObject(i);
outKey = null;
Object outValue = null;
for (Iterator<String> key = in.keys(); key.hasNext(); ) {
inKey = key.next();
switch (inKey) {
case "key":
outKey = appKeysMap.get(in.optInt(inKey));
break;
case "value":
outValue = in.get(inKey);
}
}
if (outKey != null && outValue != null) {
outgoing.put(outKey, outValue);
}
}
jsAppMessage.put("payload", outgoing);
} catch (JSONException e) {
e.printStackTrace();
}
return jsAppMessage.toString();
}
@JavascriptInterface
public void gbLog(String msg) {
LOG.debug("WEBVIEW", msg);