Skip to content
This repository was archived by the owner on May 4, 2023. It is now read-only.

Commit 0349ce1

Browse files
committed
Implement Androidacy mega fix.
1 parent 4ba30cf commit 0349ce1

File tree

2 files changed

+67
-13
lines changed

2 files changed

+67
-13
lines changed

app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.webkit.ValueCallback;
1414
import android.webkit.WebChromeClient;
1515
import android.webkit.WebResourceRequest;
16+
import android.webkit.WebResourceResponse;
1617
import android.webkit.WebSettings;
1718
import android.webkit.WebView;
1819
import android.widget.TextView;
@@ -38,13 +39,14 @@
3839
import org.json.JSONException;
3940
import org.json.JSONObject;
4041

42+
import java.io.ByteArrayInputStream;
4143
import java.io.IOException;
4244
import java.util.HashMap;
4345

4446
/**
4547
* Per Androidacy repo implementation agreement, no request of this WebView shall be modified.
4648
*/
47-
public class AndroidacyActivity extends FoxActivity {
49+
public final class AndroidacyActivity extends FoxActivity {
4850
private static final String TAG = "AndroidacyActivity";
4951

5052
static {
@@ -147,6 +149,19 @@ public boolean shouldOverrideUrlLoading(
147149
return false;
148150
}
149151

152+
@Nullable
153+
@Override
154+
public WebResourceResponse shouldInterceptRequest(
155+
WebView view, WebResourceRequest request) {
156+
if (AndroidacyActivity.this.megaIntercept(
157+
this.pageUrl, request.getUrl().toString())) {
158+
// Block request as Androidacy doesn't allow duplicate requests
159+
return new WebResourceResponse("text/plain", "UTF-8",
160+
new ByteArrayInputStream(new byte[0]));
161+
}
162+
return null;
163+
}
164+
150165
@Override
151166
public void onPageStarted(WebView view, String url, Bitmap favicon) {
152167
this.pageUrl = url;
@@ -224,18 +239,12 @@ public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
224239
AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI;
225240
if (androidacyWebAPI != null) {
226241
if (!androidacyWebAPI.downloadMode) {
242+
// Native module popup may cause download after consumed action
227243
if (androidacyWebAPI.consumedAction)
228-
return; // Native module popup may cause download after consumed action
229-
int lenPrefix = 0;
230-
// Workaround WebView/Chromium bug
231-
for (String prefix : new String[]{
232-
"https://api.androidacy.com/magisk/download/",
233-
"https://staging-api.androidacy.com/magisk/download/"
234-
}) { // Make both staging and non staging act the same
235-
if (downloadUrl.startsWith(prefix)) lenPrefix = prefix.length();
236-
}
237-
if (lenPrefix != 0) {
238-
final String moduleId = downloadUrl.substring(lenPrefix);
244+
return;
245+
// Workaround Androidacy bug
246+
final String moduleId = moduleIdOfUrl(downloadUrl);
247+
if (moduleId != null) {
239248
webView.evaluateJavascript("document.querySelector(" +
240249
"\"#download-form input[name=_token]\").value",
241250
result -> new Thread("Androidacy popup workaround thread") {
@@ -253,6 +262,8 @@ public void run() {
253262
if (downloadUrl.equals(realUrl)) {
254263
Log.e(TAG, "Failed to resolve URL from " +
255264
downloadUrl);
265+
AndroidacyActivity.this.megaIntercept(
266+
webView.getUrl(), downloadUrl);
256267
return;
257268
}
258269
Log.i(TAG, "Got url: " + realUrl);
@@ -264,7 +275,8 @@ public void run() {
264275
}
265276
}.start());
266277
return;
267-
}
278+
} else if (this.megaIntercept(webView.getUrl(), downloadUrl))
279+
return;
268280
}
269281
androidacyWebAPI.consumedAction = true;
270282
androidacyWebAPI.downloadMode = false;
@@ -313,4 +325,44 @@ protected void onResume() {
313325
this.androidacyWebAPI.consumedAction = false;
314326
}
315327
}
328+
329+
private String moduleIdOfUrl(String url) {
330+
for (String prefix : new String[]{
331+
"https://api.androidacy.com/magisk/download/",
332+
"https://staging-api.androidacy.com/magisk/download/",
333+
"https://api.androidacy.com/magisk/readme/",
334+
"https://staging-api.androidacy.com/magisk/readme/",
335+
"https://api.androidacy.com/magisk/info/",
336+
"https://staging-api.androidacy.com/magisk/info/"
337+
}) { // Make both staging and non staging act the same
338+
int i = url.indexOf('?', prefix.length()); if (i == -1) i = url.length();
339+
if (url.startsWith(prefix)) return url.substring(prefix.length(), i);
340+
}
341+
return null;
342+
}
343+
344+
private boolean isFileUrl(String url) {
345+
for (String prefix : new String[]{
346+
"https://api.androidacy.com/magisk/file/",
347+
"https://staging-api.androidacy.com/magisk/file/"
348+
}) { // Make both staging and non staging act the same
349+
if (url.startsWith(prefix)) return true;
350+
}
351+
return false;
352+
}
353+
354+
private boolean megaIntercept(String pageUrl, String fileUrl) {
355+
if (pageUrl == null || fileUrl == null) return false;
356+
if (this.isFileUrl(fileUrl)) {
357+
Log.d(TAG, "megaIntercept(" +
358+
AndroidacyUtil.hideToken(pageUrl) + ", " +
359+
AndroidacyUtil.hideToken(fileUrl) + ")");
360+
}
361+
final AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI;
362+
final String moduleId = this.moduleIdOfUrl(pageUrl);
363+
if (moduleId == null || !this.isFileUrl(fileUrl)) return false;
364+
androidacyWebAPI.openNativeModuleDialogRaw(fileUrl,
365+
moduleId, "", androidacyWebAPI.canInstall());
366+
return true;
367+
}
316368
}

app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public static String hideToken(@NonNull String url) {
2929
int i = url.lastIndexOf("token=");
3030
if (i == -1) return url;
3131
int i2 = url.indexOf('&', i);
32+
int i3 = url.indexOf(' ', i);
33+
if (i3 != -1 && i3 < i2) i2 = i3;
3234
if (i2 == -1) {
3335
return url.substring(0, i + 6) +
3436
"<token>";

0 commit comments

Comments
 (0)