1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-29 13:26:50 +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){ this.sendAppMessage = function (dict, callbackAck, callbackNack){
try { try {
self.configurationValues = JSON.stringify(dict); self.configurationValues = JSON.stringify(dict);
document.getElementById("jsondata").innerHTML=self.configurationValues; 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; return callbackAck;
} }
catch (e) { catch (e) {
@ -179,8 +183,8 @@ function gbPebble() {
if (str.split(needle)[1] !== undefined) { if (str.split(needle)[1] !== undefined) {
var t = new Object(); var t = new Object();
t.response = decodeURIComponent(str.split(needle)[1]); t.response = decodeURIComponent(str.split(needle)[1]);
self.evaluate('webviewclosed',[t]);
showStep("step2"); showStep("step2");
self.evaluate('webviewclosed',[t]);
} else { } else {
console.error("No valid configuration found in the entered string."); 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) { private void sendAppMessageIntent(GBDeviceEventAppMessage appMessage) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(PEBBLEKIT_ACTION_APP_RECEIVE); intent.setAction(PEBBLEKIT_ACTION_APP_RECEIVE);
@ -582,6 +587,7 @@ class PebbleIoThread extends GBDeviceIoThread {
setInstallSlot(appInfoEvent.freeSlot); setInstallSlot(appInfoEvent.freeSlot);
return false; return false;
} else if (deviceEvent instanceof GBDeviceEventAppMessage) { } else if (deviceEvent instanceof GBDeviceEventAppMessage) {
sendAppMessageJS((GBDeviceEventAppMessage) deviceEvent);
if (mEnablePebblekit) { if (mEnablePebblekit) {
LOG.info("Got AppMessage event"); LOG.info("Got AppMessage event");
sendAppMessageIntent((GBDeviceEventAppMessage) deviceEvent); sendAppMessageIntent((GBDeviceEventAppMessage) deviceEvent);

View File

@ -19,6 +19,7 @@ import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.widget.Toast; import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -32,6 +33,7 @@ import java.io.UnsupportedEncodingException;
import java.io.Writer; import java.io.Writer;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Scanner; import java.util.Scanner;
import java.util.UUID; import java.util.UUID;
@ -107,18 +109,22 @@ public class WebViewSingleton extends Activity {
} }
public static void appMessage(final String message) { 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() { new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override @Override
public void run() { public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 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 @Override
public void onReceiveValue(String s) { public void onReceiveValue(String s) {
LOG.debug("Callback from showConfiguration", s); LOG.debug("Callback from showConfiguration", s);
} }
}); });
} else { } 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 @Override
public void run() { public void run() {
if (instance != null) { 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.destroy();
instance = null; instance = null;
contextWrapper = null; contextWrapper = null;
@ -202,6 +215,48 @@ public class WebViewSingleton extends Activity {
this.mUuid = mUuid; 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 @JavascriptInterface
public void gbLog(String msg) { public void gbLog(String msg) {
LOG.debug("WEBVIEW", msg); LOG.debug("WEBVIEW", msg);