Skip to content

Commit

Permalink
Merge pull request #5426 from msupply-foundation/5383-android-12
Browse files Browse the repository at this point in the history
5383 Android - Load Plugins after they've be registered properly
  • Loading branch information
jmbrunskill authored Nov 18, 2024
2 parents a08bb89 + b6939e6 commit 24982c5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 18 deletions.
10 changes: 5 additions & 5 deletions client/packages/android/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ The UI is not bundled within Capacitor, it is served by the server the client co
Before building the Android app, the Rust server library that allows us to run the mSupply server on the mobile device needs to be built.
This requires a couple of steps.

- Install Android Studio
- Install Android Studio (Ladybug at time of writing 15/11/24)
- Install NDK (26.1.10909125 at the time of writing on the 8/4/24)

![omSupply Android NDK](./doc/omSupply_android_ndk.png)

Currently, we support two Android architectures;
Currently, we support only 1 Android architecture (64bit);

| rust target | android ABI |
| ----------------------- | ----------- |
| aarch64-linux-android | arm64-v8a |
| armv7-linux-androideabi | armeabi-v7a |
| ----------------------- | ----------- |


To add the required build targets to Rust run:

```bash
rustup target add aarch64-linux-android && rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
```

Next we have to tell Rust where to find the Android NDK binaries required to link the server library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,24 @@

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;



public class ExtendedWebViewClient extends BridgeWebViewClient {
Bridge bridge;
String jsInject;

public ExtendedWebViewClient(Bridge bridge) {
super(bridge);

this.bridge = bridge;
this.jsInject = this.generatePluginScript();
}

public void loadJsInject() {
if(this.jsInject == null) {
Logger.debug("Generating JS");
this.jsInject = this.generatePluginScript();
}
}

// Have to manually inject Capacitor JS, this typically happens in
Expand All @@ -31,26 +39,35 @@ public ExtendedWebViewClient(Bridge bridge) {
public void onPageStarted(WebView webView, String url, Bitmap favicon) {
if (url.startsWith("data:text")) return;

// Just incase the js hasn't been generated yet, generate it here.
this.loadJsInject();

if(this.jsInject != null) {
Logger.debug("injecting JS");
// .post to run on UI thread
webView.post(() -> webView.evaluateJavascript(this.jsInject, null));
} else {
Logger.error("JS not generated, not injecting");
webView.post(() -> webView.evaluateJavascript("alert('Error unable to load javascript to inject. Please contact mSupply Support for assistance.')", null));
}
}

String generatePluginScript() {
// TODO make sure this is only injected for pages in native bundle
// There is no way to get the full list of plugins from bridge, use 'debug' and
// see what plugins to add
List<PluginHandle> pluginList = Arrays.asList(
bridge.getPlugin("NativeApi"),
bridge.getPlugin("Keyboard"),
bridge.getPlugin("WebView"),
bridge.getPlugin("BarcodeScanner"),
bridge.getPlugin("Preferences"),
bridge.getPlugin("KeepAwake"),
bridge.getPlugin("App"),
bridge.getPlugin("Printer")
);

// This function needs to run after plugins are registered, so can't be part of the constructor as order doesn't appear to be consistent.
List<String> pluginNames = Arrays.asList("NativeApi","Keyboard", "WebView","BarcodeScanner","Preferences", "KeepAwake", "App", "Printer");
List<PluginHandle> pluginList = new ArrayList<>();
for (String pluginName : pluginNames) {
PluginHandle plugin = bridge.getPlugin(pluginName);
if (plugin == null) {
Logger.error("Couldn't find plugin : " + pluginName);
return null;
}
pluginList.add(plugin);
}

try {
// From Bridge.getJSInjector()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ public class NativeApi extends Plugin implements NsdManager.DiscoveryListener {
boolean isResolvingServer;
boolean shouldRestartDiscovery;

CertWebViewClient client;

@Override
public void load() {
super.load();

CertWebViewClient client = new CertWebViewClient(this.getBridge(), this.getContext().getFilesDir(), this);
client = new CertWebViewClient(this.getBridge(), this.getContext().getFilesDir(), this);
bridge.setWebViewClient(client);

serversToResolve = new ArrayDeque<NsdServiceInfo>();
Expand Down Expand Up @@ -111,7 +113,19 @@ private void sleep(int delay) {

@Override
protected void handleOnStart() {
Logger.debug("NativeAPI.handleOnStart()");
WebView webView = this.getBridge().getWebView();

// Normally javascript would be loaded by Capacitor by loading the generated javascript from WEBVIEW_SERVER_URL
// However we'd get an SSL issue with this approach, so we need to generate it ourselves and inject it later.

// NOTE: There have been various timing issues with this javascript injection loading
// We do the actual injection during onPageStarted in ExtendedWebViewClient
// We call it here as well as in ExtendedWebViewClient as this gives more time for it to be generated before the webview loads
// Potentially avoiding issues if it takes too long to generate.
client.loadJsInject();


// this method (handleOnStart) is called when resuming and switching to the app
// the webView url will be DEFAULT_URL only on the initial load
// so this test is a quick check to see if we should be redirecting to the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.openmsupply.client;

import com.getcapacitor.Logger;

public class RemoteServer {
static {
// This will load libremote_server_android, from app/src/main/jniLib/ directory
Expand All @@ -12,6 +14,7 @@ public RemoteServer() {
}

public void start(int port, String filesDir, String cacheDir, String androidId) {
Logger.info("Starting OMS Rust Server");
startServer(port, filesDir, cacheDir, androidId);
}

Expand Down

0 comments on commit 24982c5

Please sign in to comment.