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();
}
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 final String jsonrpc = "2.0";
public final String method;

View file

@ -37,6 +37,8 @@ import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import org.json.JSONObject;
import org.thoughtcrime.securesms.connect.AccountManager;
@ -54,6 +56,7 @@ import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate {
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 DcContext dcContext;
private Rpc rpc;
private DcMsg dcAppMsg;
private String baseURL;
private String sourceCodeUrl = "";
@ -136,6 +140,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
@Override
protected void onCreate(Bundle state, boolean ready) {
super.onCreate(state, ready);
rpc = DcHelper.getRpc(this);
Bundle b = getIntent().getExtras();
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());
eventCenter.addObserver(DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE, 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 accountId = b.getInt(EXTRA_ACCOUNT_ID);
@ -341,16 +347,24 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
return res;
}
private void callJavaScriptFunction(String func) {
if (internetAccess) {
webView.evaluateJavascript("window." + func + ";", null);
} else {
webView.evaluateJavascript("document.getElementById('frame').contentWindow." + func + ";", null);
}
}
@Override
public void handleEvent(@NonNull DcEvent event) {
int eventId = event.getId();
if ((eventId == DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE && event.getData1Int() == dcAppMsg.getId())) {
Log.i(TAG, "handleEvent");
if (internetAccess) {
webView.loadUrl("javascript:window.__webxdcUpdate();");
} else {
webView.loadUrl("javascript:document.getElementById('frame').contentWindow.__webxdcUpdate();");
}
Log.i(TAG, "handling status update event");
callJavaScriptFunction("__webxdcUpdate()");
} else if ((eventId == DcContext.DC_EVENT_WEBXDC_REALTIME_DATA && event.getData1Int() == dcAppMsg.getId())) {
Log.i(TAG, "handling realtime data event");
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())) {
this.dcAppMsg = this.dcContext.getMsg(event.getData2Int()); // msg changed, reload data from db
Util.runOnAnyBackgroundThread(() -> {
@ -496,5 +510,46 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
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 = () => {
const base64Data = null; // TODO: get base64Data somehow
window.__webxdcRealtimeData = (base64Data) => {
if (realtimeChannel) {
const data = Uint8Array.from(atob(base64Data), (m) => m.codePointAt(0));
realtimeChannel.__receive(data);