From ba68d7334ae2f51c962ec22463c77213dc499b14 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 26 Jan 2024 11:39:31 -0800 Subject: [PATCH] [Android] Use correct prefix for remapping URLs This needs to support the scheme/hostname prefix on newer versions of Cordova Android. Closes #16. --- src/android/AppScopePlugin.java | 85 ++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/src/android/AppScopePlugin.java b/src/android/AppScopePlugin.java index 972f59a..8c36e33 100644 --- a/src/android/AppScopePlugin.java +++ b/src/android/AppScopePlugin.java @@ -123,38 +123,87 @@ public Uri remapUri(Uri uri) { remapped = "index.html" + remapped; } - String resultURL = "file:///android_asset/www/" + remapped; + String resultURL = getLaunchUrlPrefix() + remapped; + String codePushPrefix = tryFindCodePushPrefix(); + if (codePushPrefix != null) { + resultURL = codePushPrefix + remapped; + } + + LOG.d(TAG, "Result URL is " + resultURL); + return Uri.parse(resultURL); + } + + /** + * Get the default prefix for Cordova web assets. + * + * This needs to determine whether we're serving from a file:/// URL or + * from a scheme/hostname, and return the correct prefix for the remapped + * URL. + */ + private String getLaunchUrlPrefix() { + Integer major = 0; + try { + major = Integer.parseInt(CordovaWebView.CORDOVA_VERSION.split("\\.", 2)[0]); + } catch (Exception e) { + major = 0; + } + + // Before Cordova Android 10, we always use file:/// URLs + if ((major > 0 && major < 10) || preferences.getBoolean("AndroidInsecureFileModeEnabled", false)) { + return "file:///android_asset/www/"; + } else { + String scheme = preferences.getString("scheme", "https").toLowerCase(); + String hostname = preferences.getString("hostname", "localhost").toLowerCase(); + + if (!scheme.contentEquals("http") && !scheme.contentEquals("https")) { + scheme = "https"; + } + + return scheme + "://" + hostname + '/'; + } + } + + /** + * Try to find a CodePush path prefix for the current version. + * + * This conditionally checks if the CodePush plugin is installed and then + * tries to look up the directory for the current CodePush package version, + * so that the right prefix can be used for a remapped URL within the + * CodePush package. + */ + private String tryFindCodePushPrefix() { try { CordovaPlugin codepush = this.webView.getPluginManager().getPlugin("CodePush"); - if (codepush != null) { - Class codepushClass = codepush.getClass(); - Field pkgMgr = codepushClass.getDeclaredField("codePushPackageManager"); - pkgMgr.setAccessible(true); + if (codepush == null) { + return null; + } + + Class codepushClass = codepush.getClass(); + Field pkgMgr = codepushClass.getDeclaredField("codePushPackageManager"); + pkgMgr.setAccessible(true); - Object codePushPackageManager = pkgMgr.get(codepush); + Object codePushPackageManager = pkgMgr.get(codepush); - Class cppmClass = pkgMgr.getType(); + Class cppmClass = pkgMgr.getType(); - Method getCurrentPackageMetadata = cppmClass.getDeclaredMethod("getCurrentPackageMetadata"); + Method getCurrentPackageMetadata = cppmClass.getDeclaredMethod("getCurrentPackageMetadata"); - Object packageMetadata = getCurrentPackageMetadata.invoke(codePushPackageManager); + Object packageMetadata = getCurrentPackageMetadata.invoke(codePushPackageManager); - if (packageMetadata != null) { - Class metadataClass = getCurrentPackageMetadata.getReturnType(); - Field localPathField = metadataClass.getDeclaredField("localPath"); - String localPath = (String)localPathField.get(packageMetadata); + if (packageMetadata != null) { + Class metadataClass = getCurrentPackageMetadata.getReturnType(); + Field localPathField = metadataClass.getDeclaredField("localPath"); + String localPath = (String)localPathField.get(packageMetadata); - if (localPath != null) { - resultURL = "file://" + this.cordova.getActivity().getFilesDir() + localPath + "www/" + remapped; - } + if (localPath != null) { + return "file://" + this.cordova.getActivity().getFilesDir() + localPath + "www/"; } } } catch (Exception e) { LOG.e(TAG, Log.getStackTraceString(e)); } - LOG.d(TAG, "Result URL is " + resultURL); - return Uri.parse(resultURL); + return null; } }