add API to JavaScriptInterface and Rpc, listent to realtime data event

This commit is contained in:
adbenitez 2024-05-29 19:06:01 +02:00
parent 5c57fbbd84
commit 07d895594e
3 changed files with 74 additions and 8 deletions

View file

@ -126,6 +126,18 @@ public class Rpc {
return getResult("draft_self_report", accountId).getAsInt(); return getResult("draft_self_report", accountId).getAsInt();
} }
public void sendWebxdcRealtimeData(Integer accountId, Integer instanceMsgId, List<Integer> data) throws RpcException {
getResult("send_webxdc_realtime_data", accountId, instanceMsgId, data);
}
public void sendWebxdcRealtimeAdvertisement(Integer accountId, Integer instanceMsgId) throws RpcException {
getResult("send_webxdc_realtime_advertisement", accountId, instanceMsgId);
}
public void leaveWebxdcRealtime(Integer accountId, Integer instanceMessageId) throws RpcException {
getResult("leave_webxdc_realtime", accountId, instanceMessageId);
}
private static class Request { private static class Request {
private final String jsonrpc = "2.0"; private final String jsonrpc = "2.0";
public final String method; public final String method;

View file

@ -37,6 +37,8 @@ import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext; import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent; import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcMsg; import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import org.json.JSONObject; import org.json.JSONObject;
import org.thoughtcrime.securesms.connect.AccountManager; import org.thoughtcrime.securesms.connect.AccountManager;
@ -54,6 +56,7 @@ import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.ArrayList;
public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate { public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate {
private static final String TAG = WebxdcActivity.class.getSimpleName(); private static final String TAG = WebxdcActivity.class.getSimpleName();
@ -64,6 +67,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
private ValueCallback<Uri[]> filePathCallback; private ValueCallback<Uri[]> filePathCallback;
private DcContext dcContext; private DcContext dcContext;
private Rpc rpc;
private DcMsg dcAppMsg; private DcMsg dcAppMsg;
private String baseURL; private String baseURL;
private String sourceCodeUrl = ""; private String sourceCodeUrl = "";
@ -136,6 +140,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
@Override @Override
protected void onCreate(Bundle state, boolean ready) { protected void onCreate(Bundle state, boolean ready) {
super.onCreate(state, ready); super.onCreate(state, ready);
rpc = DcHelper.getRpc(this);
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
hideActionBar = b.getBoolean(EXTRA_HIDE_ACTION_BAR, false); hideActionBar = b.getBoolean(EXTRA_HIDE_ACTION_BAR, false);
@ -164,6 +169,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
DcEventCenter eventCenter = DcHelper.getEventCenter(WebxdcActivity.this.getApplicationContext()); DcEventCenter eventCenter = DcHelper.getEventCenter(WebxdcActivity.this.getApplicationContext());
eventCenter.addObserver(DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE, this); eventCenter.addObserver(DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSGS_CHANGED, this); eventCenter.addObserver(DcContext.DC_EVENT_MSGS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_WEBXDC_REALTIME_DATA, this);
int appMessageId = b.getInt(EXTRA_APP_MSG_ID); int appMessageId = b.getInt(EXTRA_APP_MSG_ID);
int accountId = b.getInt(EXTRA_ACCOUNT_ID); int accountId = b.getInt(EXTRA_ACCOUNT_ID);
@ -341,16 +347,24 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
return res; return res;
} }
private void callJavaScriptFunction(String func) {
if (internetAccess) {
webView.evaluateJavascript("window." + func + ";", null);
} else {
webView.evaluateJavascript("document.getElementById('frame').contentWindow." + func + ";", null);
}
}
@Override @Override
public void handleEvent(@NonNull DcEvent event) { public void handleEvent(@NonNull DcEvent event) {
int eventId = event.getId(); int eventId = event.getId();
if ((eventId == DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE && event.getData1Int() == dcAppMsg.getId())) { if ((eventId == DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE && event.getData1Int() == dcAppMsg.getId())) {
Log.i(TAG, "handleEvent"); Log.i(TAG, "handling status update event");
if (internetAccess) { callJavaScriptFunction("__webxdcUpdate()");
webView.loadUrl("javascript:window.__webxdcUpdate();"); } else if ((eventId == DcContext.DC_EVENT_WEBXDC_REALTIME_DATA && event.getData1Int() == dcAppMsg.getId())) {
} else { Log.i(TAG, "handling realtime data event");
webView.loadUrl("javascript:document.getElementById('frame').contentWindow.__webxdcUpdate();"); String base64 = Base64.encodeToString(event.getData2Blob(), Base64.NO_WRAP | Base64.NO_PADDING);
} callJavaScriptFunction("__webxdcRealtimeData(\"" + base64 + "\")");
} else if ((eventId == DcContext.DC_EVENT_MSGS_CHANGED && event.getData2Int() == dcAppMsg.getId())) { } else if ((eventId == DcContext.DC_EVENT_MSGS_CHANGED && event.getData2Int() == dcAppMsg.getId())) {
this.dcAppMsg = this.dcContext.getMsg(event.getData2Int()); // msg changed, reload data from db this.dcAppMsg = this.dcContext.getMsg(event.getData2Int()); // msg changed, reload data from db
Util.runOnAnyBackgroundThread(() -> { Util.runOnAnyBackgroundThread(() -> {
@ -496,5 +510,46 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
return e.toString(); return e.toString();
} }
} }
/** @noinspection unused*/
@JavascriptInterface
public void sendRealtimeAdvertisement() {
int accountId = WebxdcActivity.this.dcContext.getAccountId();
int msgId = WebxdcActivity.this.dcAppMsg.getId();
try {
rpc.sendWebxdcRealtimeAdvertisement(accountId, msgId);
} catch (RpcException e) {
e.printStackTrace();
}
}
/** @noinspection unused*/
@JavascriptInterface
public void leaveRealtimeChannel() {
int accountId = WebxdcActivity.this.dcContext.getAccountId();
int msgId = WebxdcActivity.this.dcAppMsg.getId();
try {
rpc.leaveWebxdcRealtime(accountId, msgId);
} catch (RpcException e) {
e.printStackTrace();
}
}
/** @noinspection unused*/
@JavascriptInterface
public void sendRealtimeData(String base64Data) {
int accountId = WebxdcActivity.this.dcContext.getAccountId();
int msgId = WebxdcActivity.this.dcAppMsg.getId();
byte[] bytes = Base64.decode(base64Data, Base64.NO_WRAP | Base64.NO_PADDING);
ArrayList<Integer> data = new ArrayList<>();
for (byte b : bytes) {
data.add(Integer.valueOf(b));
}
try {
rpc.sendWebxdcRealtimeData(accountId, msgId, data);
} catch (RpcException e) {
e.printStackTrace();
}
}
} }
} }

View file

@ -16,8 +16,7 @@ window.webxdc = (() => {
} }
}; };
window.__webxdcRealtimeData = () => { window.__webxdcRealtimeData = (base64Data) => {
const base64Data = null; // TODO: get base64Data somehow
if (realtimeChannel) { if (realtimeChannel) {
const data = Uint8Array.from(atob(base64Data), (m) => m.codePointAt(0)); const data = Uint8Array.from(atob(base64Data), (m) => m.codePointAt(0));
realtimeChannel.__receive(data); realtimeChannel.__receive(data);