Skip to content

Commit

Permalink
Mostly fixed message passing
Browse files Browse the repository at this point in the history
  • Loading branch information
kaidokert committed Oct 18, 2024
1 parent 1577276 commit a52146c
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 64 deletions.
35 changes: 31 additions & 4 deletions starboard/android/apk/app/src/main/assets/injected_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,41 @@ function arrayBufferToBase64(buffer) {
}

var platform_services = {
callbacks: {
},
callback_from_android: (serviceID, dataFromJava) => {
console.log("Wrapper callback received:", name, dataFromJava);
const binaryString = window.atob(dataFromJava);
console.log("message:" + binaryString);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const arrayBuffer = bytes.buffer;
window.H5vccPlatformService.callbacks[serviceID].callback(arrayBuffer);
},
has: (name) => {
console.log('platformService.has(' + name + ')');
return Android.has_platform_service(name);
},
open: (name, callback) => {
console.log('platformService.open(' + name + ',' + JSON.stringify(callback) + ')');
Android.open_platform_service(name);
// this needs to return an object with send
open: function(name, callback) {
console.log('platformService.open(' + name + ',' +
JSON.stringify(callback) + ')');
if (typeof callback !== 'function') {
console.log("THROWING Missing or invalid callback function.")
throw new Error("Missing or invalid callback function.");
} else {
console.log("callback was function!!!");
}

const serviceId = Object.keys(this.callbacks).length + 1;
// Store the callback with the service ID, name, and callback
window.H5vccPlatformService.callbacks[serviceId] = {
name: name,
callback: callback
};
Android.open_platform_service(serviceId, name);
return {
'name': name,
'send': function (data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
import dev.cobalt.coat.BuildConfig;

public class ChrobaltWebView extends WebView {
public void evalJavaScript(String javascript) { // Make sure it's public
this.evaluateJavascript(javascript, null);
}

StarboardBridge bridge = null;

WebAppInterface webAppInterface = null;

ChrobaltWebViewClient webViewClient = null;


private class ChrobaltWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.CallSuper;
import com.google.androidgamesdk.GameActivity;
import dev.cobalt.libraries.services.accountmanager.AccountManagerModule;
import dev.cobalt.util.DisplayUtil;
import dev.cobalt.libraries.services.clientloginfo.ClientLogInfoModule;
import dev.cobalt.libraries.services.FakeSoftMicModule;
Expand All @@ -50,7 +51,7 @@ public abstract class CobaltActivity extends GameActivity {

private long timeInNanoseconds;

private WebView webView;
private ChrobaltWebView webView;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Expand Down Expand Up @@ -127,6 +128,7 @@ public void handleOnBackPressed() {
webView = new ChrobaltWebView(this,getStarboardBridge());
// Load Kabuki
webView.loadUrl(startDeepLink);
getStarboardBridge().setJavaScriptCallback(javascript -> webView.evalJavaScript(javascript));

// Set the WebView as the main content view of the activity
setContentView(webView);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@

import static dev.cobalt.util.Log.TAG;

import android.util.Base64;
import dev.cobalt.util.Log;

/** Abstract class that provides an interface for Cobalt to interact with a platform service. */
public abstract class CobaltService {

interface StringCallback {
void onStringResult(long name, String result);
}

// Indicate is the service opened, and be able to send data to client
protected boolean opened = true;
private StringCallback jsCallback;

/** Interface that returns an object that extends CobaltService. */
public interface Factory {
Expand Down Expand Up @@ -55,6 +62,10 @@ public static class ResponseToClient {
public byte[] data;
}

void setCallback(StringCallback jsCallback) {
this.jsCallback = jsCallback;
}

/** Receive data from client of the service. */
@SuppressWarnings("unused")
public abstract ResponseToClient receiveFromClient(byte[] data);
Expand Down Expand Up @@ -90,8 +101,13 @@ protected void sendToClient(long nativeService, byte[] data) {
+ " platform service.");
return;
} else {
Log.w(TAG, "Hey i got the service " + nativeService);
Log.w(TAG, "But i didn't bother to send it yet");
if (this.jsCallback != null) {
String base64Data = Base64.encodeToString(data, Base64.NO_WRAP);
Log.w(TAG, "Sending : `" + base64Data + "`");
this.jsCallback.onStringResult(nativeService, base64Data);
} else {
Log.w(TAG, "Callback was null");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import dev.cobalt.util.Log;
import java.lang.reflect.Method;
Expand All @@ -43,6 +45,10 @@ public interface HostApplication {
StarboardBridge getStarboardBridge();
}

interface JavaScriptCallback {
void onStringResult(String result);
}

private NetworkStatus networkStatus;
private AdvertisingId advertisingId;
private final VolumeStateReceiver volumeStateReceiver;
Expand Down Expand Up @@ -72,6 +78,9 @@ public void run() {

private ExecutorService executor;

private JavaScriptCallback evalJavaScriptCallback;
private final Handler mainHandler = new Handler(Looper.getMainLooper());

public StarboardBridge(Context appContext, String[] args, String startDeepLink) {

this.appContext = appContext;
Expand Down Expand Up @@ -180,6 +189,18 @@ boolean hasCobaltService(String serviceName) {
return weHaveIt;
}

public void setJavaScriptCallback(JavaScriptCallback callback) {
this.evalJavaScriptCallback = callback;
}

public void callbackFromService(long name, String foo) {
mainHandler.post(
() -> {
this.evalJavaScriptCallback.onStringResult(
"window.H5vccPlatformService.callback_from_android(" + name + ",'" + foo + "');");
});
}

@SuppressWarnings("unused")
CobaltService openCobaltService(long nativeService, String serviceName) {
if (cobaltServices.get(serviceName) != null) {
Expand All @@ -194,7 +215,7 @@ CobaltService openCobaltService(long nativeService, String serviceName) {
}
CobaltService service = factory.createCobaltService(nativeService);
if (service != null) {
//service.receiveStarboardBridge(this);
service.setCallback(this::callbackFromService);
cobaltServices.put(serviceName, service);
}
return service;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,73 @@
package dev.cobalt.coat;

import static dev.cobalt.util.Log.TAG;
import dev.cobalt.util.Log;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.content.Context;
import android.util.Base64;
import android.webkit.JavascriptInterface;
import dev.cobalt.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* Native call bridge
*/
/** Native call bridge */
public class WebAppInterface {
Context mContext;
StarboardBridge bridge;
Context mContext;
StarboardBridge bridge;

// Instantiate the interface and set the context
WebAppInterface(Context c, StarboardBridge b) {
mContext = c;
bridge = b;
}
// Instantiate the interface and set the context
WebAppInterface(Context c, StarboardBridge b) {
mContext = c;
bridge = b;
}

@JavascriptInterface
public boolean has_platform_service(String servicename) {
return bridge.hasCobaltService(servicename);
}
@JavascriptInterface
public boolean has_platform_service(String servicename) {
return bridge.hasCobaltService(servicename);
}

@JavascriptInterface
public void open_platform_service(String servicename) {
bridge.openCobaltService(1, servicename);
}
@JavascriptInterface
public void open_platform_service(long number, String servicename) {
bridge.openCobaltService(number, servicename);
}

@JavascriptInterface
public void close_platform_service(String servicename) {
bridge.closeCobaltService(servicename);
}
@JavascriptInterface
public void platform_service_send(String servicename, String base64Data) {
byte[] data = Base64.decode(base64Data, Base64.DEFAULT);
bridge.sendToCobaltService(servicename, data);
}
@JavascriptInterface
public void close_platform_service(String servicename) {
bridge.closeCobaltService(servicename);
}

@JavascriptInterface
public String getSystemProperty(String propertyName, String defaultValue) {
return System.getProperty(propertyName, defaultValue);
}
@JavascriptInterface
public void platform_service_send(String servicename, String base64Data) {
byte[] data = Base64.decode(base64Data, Base64.DEFAULT);
bridge.sendToCobaltService(servicename, data);
}

@JavascriptInterface
public String getRestrictedSystemProperty(String propName, String defaultValue) {
try {
Process process = Runtime.getRuntime().exec("getprop " + propName);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
@JavascriptInterface
public String getSystemProperty(String propertyName, String defaultValue) {
return System.getProperty(propertyName, defaultValue);
}

return bufferedReader.readLine();
} catch (IOException e) {
return defaultValue;
}
}
@JavascriptInterface
public String getRestrictedSystemProperty(String propName, String defaultValue) {
try {
Process process = Runtime.getRuntime().exec("getprop " + propName);
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(process.getInputStream()));

@JavascriptInterface
public String getAdvertisingId() {
Log.i(TAG, "getAdvertisingId:" + bridge.getAdvertisingId());
return bridge.getAdvertisingId();
return bufferedReader.readLine();
} catch (IOException e) {
return defaultValue;
}
}

@JavascriptInterface
public boolean getLimitAdTracking() {
return bridge.getLimitAdTracking();
}
@JavascriptInterface
public String getAdvertisingId() {
Log.i(TAG, "getAdvertisingId:" + bridge.getAdvertisingId());
return bridge.getAdvertisingId();
}

@JavascriptInterface
public boolean getLimitAdTracking() {
return bridge.getLimitAdTracking();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
public class AccountManager extends CobaltService {
// The application uses this identifier to open the service.
protected static final String SERVICE_NAME = "com.google.youtube.tv.accountmanager";
protected static final String SEQ_ID = "seqId";
protected static final String ACTION = "action";

private final Executor backgroundExecutor;
private long nativeService = 0;
Expand Down Expand Up @@ -60,7 +62,16 @@ public ResponseToClient receiveFromClient(byte[] data) {

public ActionResponse handleAction(String request) {
ActionResponse actionResponse = new ActionResponse();
actionResponse.message += "false";
try {
JSONObject json = new JSONObject(request);
actionResponse.seqId = json.getString(SEQ_ID);
actionResponse.action = json.getString(ACTION);
} catch (JSONException e) {
actionResponse.error = "Failed to retrieve field value from request:" + e.getMessage();
Log.w(TAG, actionResponse.error);
return actionResponse;
}
actionResponse.message = "false";
return actionResponse;
}

Expand Down

0 comments on commit a52146c

Please sign in to comment.