diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java index 9bd4884..5a6a0d8 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java @@ -13,6 +13,7 @@ import android.webkit.ConsoleMessage; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.TextView; @@ -38,13 +39,14 @@ import com.fox2code.mmm.utils.IntentHelper; import org.json.JSONException; import org.json.JSONObject; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashMap; /** * Per Androidacy repo implementation agreement, no request of this WebView shall be modified. */ -public class AndroidacyActivity extends FoxActivity { +public final class AndroidacyActivity extends FoxActivity { private static final String TAG = "AndroidacyActivity"; static { @@ -147,6 +149,19 @@ public class AndroidacyActivity extends FoxActivity { return false; } + @Nullable + @Override + public WebResourceResponse shouldInterceptRequest( + WebView view, WebResourceRequest request) { + if (AndroidacyActivity.this.megaIntercept( + this.pageUrl, request.getUrl().toString())) { + // Block request as Androidacy doesn't allow duplicate requests + return new WebResourceResponse("text/plain", "UTF-8", + new ByteArrayInputStream(new byte[0])); + } + return null; + } + @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { this.pageUrl = url; @@ -224,18 +239,12 @@ public class AndroidacyActivity extends FoxActivity { AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI; if (androidacyWebAPI != null) { if (!androidacyWebAPI.downloadMode) { + // Native module popup may cause download after consumed action if (androidacyWebAPI.consumedAction) - return; // Native module popup may cause download after consumed action - int lenPrefix = 0; - // Workaround WebView/Chromium bug - for (String prefix : new String[]{ - "https://api.androidacy.com/magisk/download/", - "https://staging-api.androidacy.com/magisk/download/" - }) { // Make both staging and non staging act the same - if (downloadUrl.startsWith(prefix)) lenPrefix = prefix.length(); - } - if (lenPrefix != 0) { - final String moduleId = downloadUrl.substring(lenPrefix); + return; + // Workaround Androidacy bug + final String moduleId = moduleIdOfUrl(downloadUrl); + if (moduleId != null) { webView.evaluateJavascript("document.querySelector(" + "\"#download-form input[name=_token]\").value", result -> new Thread("Androidacy popup workaround thread") { @@ -253,6 +262,8 @@ public class AndroidacyActivity extends FoxActivity { if (downloadUrl.equals(realUrl)) { Log.e(TAG, "Failed to resolve URL from " + downloadUrl); + AndroidacyActivity.this.megaIntercept( + webView.getUrl(), downloadUrl); return; } Log.i(TAG, "Got url: " + realUrl); @@ -264,7 +275,8 @@ public class AndroidacyActivity extends FoxActivity { } }.start()); return; - } + } else if (this.megaIntercept(webView.getUrl(), downloadUrl)) + return; } androidacyWebAPI.consumedAction = true; androidacyWebAPI.downloadMode = false; @@ -313,4 +325,44 @@ public class AndroidacyActivity extends FoxActivity { this.androidacyWebAPI.consumedAction = false; } } + + private String moduleIdOfUrl(String url) { + for (String prefix : new String[]{ + "https://api.androidacy.com/magisk/download/", + "https://staging-api.androidacy.com/magisk/download/", + "https://api.androidacy.com/magisk/readme/", + "https://staging-api.androidacy.com/magisk/readme/", + "https://api.androidacy.com/magisk/info/", + "https://staging-api.androidacy.com/magisk/info/" + }) { // Make both staging and non staging act the same + int i = url.indexOf('?', prefix.length()); if (i == -1) i = url.length(); + if (url.startsWith(prefix)) return url.substring(prefix.length(), i); + } + return null; + } + + private boolean isFileUrl(String url) { + for (String prefix : new String[]{ + "https://api.androidacy.com/magisk/file/", + "https://staging-api.androidacy.com/magisk/file/" + }) { // Make both staging and non staging act the same + if (url.startsWith(prefix)) return true; + } + return false; + } + + private boolean megaIntercept(String pageUrl, String fileUrl) { + if (pageUrl == null || fileUrl == null) return false; + if (this.isFileUrl(fileUrl)) { + Log.d(TAG, "megaIntercept(" + + AndroidacyUtil.hideToken(pageUrl) + ", " + + AndroidacyUtil.hideToken(fileUrl) + ")"); + } + final AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI; + final String moduleId = this.moduleIdOfUrl(pageUrl); + if (moduleId == null || !this.isFileUrl(fileUrl)) return false; + androidacyWebAPI.openNativeModuleDialogRaw(fileUrl, + moduleId, "", androidacyWebAPI.canInstall()); + return true; + } } diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java index e940dc7..a96228f 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java @@ -29,6 +29,8 @@ public class AndroidacyUtil { int i = url.lastIndexOf("token="); if (i == -1) return url; int i2 = url.indexOf('&', i); + int i3 = url.indexOf(' ', i); + if (i3 != -1 && i3 < i2) i2 = i3; if (i2 == -1) { return url.substring(0, i + 6) + "";