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

Commit 6dc32f7

Browse files
committed
0.2.4 Release
1 parent 8bda2e1 commit 6dc32f7

File tree

3 files changed

+109
-12
lines changed

3 files changed

+109
-12
lines changed

app/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ android {
1010
applicationId "com.fox2code.mmm"
1111
minSdk 21
1212
targetSdk 31
13-
versionCode 13
14-
versionName "0.2.3"
13+
versionCode 14
14+
versionName "0.2.4"
1515

1616
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1717
}
@@ -50,8 +50,8 @@ configurations {
5050
dependencies {
5151
// UI
5252
implementation 'androidx.appcompat:appcompat:1.4.0'
53-
implementation 'androidx.emoji2:emoji2:1.0.0'
54-
implementation 'androidx.emoji2:emoji2-views-helper:1.0.0'
53+
implementation 'androidx.emoji2:emoji2:1.0.1'
54+
implementation 'androidx.emoji2:emoji2-views-helper:1.0.1'
5555
implementation 'androidx.preference:preference:1.1.1'
5656
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
5757
implementation 'androidx.recyclerview:recyclerview:1.2.1'

app/src/main/java/com/fox2code/mmm/MainApplication.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ public class MainApplication extends Application implements CompatActivity.Appli
6464
secret = new Random().nextInt();
6565
}
6666

67+
public MainApplication() {
68+
if (INSTANCE != null)
69+
throw new IllegalStateException("Duplicate application instance!");
70+
INSTANCE = this;
71+
}
72+
6773
public static Shell build(String... command) {
6874
return shellBuilder.build(command);
6975
}
@@ -167,7 +173,7 @@ public Markwon getMarkwon() {
167173
.usePlugin(SyntaxHighlightPlugin.create(
168174
new Prism4j(new Prism4jGrammarLocator()), new Prism4jSwitchTheme()))
169175
.usePlugin(ImagesPlugin.create().addSchemeHandler(
170-
OkHttpNetworkSchemeHandler.create(Http.getHttpclientWithCache()))).build();
176+
OkHttpNetworkSchemeHandler.create(Http.getHttpClientWithCache()))).build();
171177
return this.markwon = markwon;
172178
}
173179

@@ -243,7 +249,6 @@ public boolean isLightTheme() {
243249

244250
@Override
245251
public void onCreate() {
246-
INSTANCE = this;
247252
super.onCreate();
248253
SharedPreferences sharedPreferences = MainApplication.getSharedPreferences();
249254
// We are only one process so it's ok to do this

app/src/main/java/com/fox2code/mmm/utils/Http.java

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.fox2code.mmm.utils;
22

3+
import android.content.Context;
4+
import android.content.SharedPreferences;
35
import android.util.Log;
46

57
import androidx.annotation.NonNull;
@@ -13,9 +15,11 @@
1315
import java.net.InetAddress;
1416
import java.net.Proxy;
1517
import java.net.UnknownHostException;
18+
import java.util.ArrayList;
1619
import java.util.Arrays;
1720
import java.util.Collections;
1821
import java.util.HashMap;
22+
import java.util.HashSet;
1923
import java.util.Iterator;
2024
import java.util.List;
2125
import java.util.Objects;
@@ -34,6 +38,7 @@
3438
import okhttp3.dnsoverhttps.DnsOverHttps;
3539

3640
public class Http {
41+
private static final String TAG = "Http";
3742
private static final OkHttpClient httpClient;
3843
private static final OkHttpClient httpClientWithCache;
3944

@@ -70,28 +75,34 @@ public class Http {
7075
Objects.requireNonNull(HttpUrl.parse("https://cloudflare-dns.com/dns-query")))
7176
.bootstrapDnsHosts(cloudflareBootstrap).resolvePrivateAddresses(true).build();
7277
} catch (UnknownHostException|RuntimeException e) {
73-
Log.e("Http", "Failed to init DoH", e);
78+
Log.e(TAG, "Failed to init DoH", e);
7479
}
7580
httpclientBuilder.cookieJar(CookieJar.NO_COOKIES);
76-
httpclientBuilder.dns(dns);
77-
httpClient = httpclientBuilder.build();
7881
MainApplication mainApplication = MainApplication.getINSTANCE();
7982
if (mainApplication != null) {
83+
httpclientBuilder.dns(new FallBackDNS(mainApplication, dns, "github.com",
84+
"api.github.com", "raw.githubusercontent.com", "camo.githubusercontent.com",
85+
"user-images.githubusercontent.com", "cdn.jsdelivr.net", "img.shields.io",
86+
"magisk-modules-repo.github.io", "www.androidacy.com"));
87+
httpClient = httpclientBuilder.build();
8088
httpclientBuilder.cache(new Cache(
8189
new File(mainApplication.getCacheDir(), "http_cache"),
8290
2L * 1024L * 1024L)); // 2Mib of cache
8391
httpclientBuilder.cookieJar(new CDNCookieJar());
8492
httpClientWithCache = httpclientBuilder.build();
93+
Log.i(TAG, "Initialized Http successfully!");
8594
} else {
86-
httpClientWithCache = httpClient;
95+
httpclientBuilder.dns(dns);
96+
httpClientWithCache = httpClient = httpclientBuilder.build();
97+
Log.e(TAG, "Initialized Http too soon!");
8798
}
8899
}
89100

90-
public static OkHttpClient getHttpclientNoCache() {
101+
public static OkHttpClient getHttpClient() {
91102
return httpClient;
92103
}
93104

94-
public static OkHttpClient getHttpclientWithCache() {
105+
public static OkHttpClient getHttpClientWithCache() {
95106
return httpClientWithCache;
96107
}
97108

@@ -207,4 +218,85 @@ public void saveFromResponse(@NonNull HttpUrl httpUrl, @NonNull List<Cookie> coo
207218
public interface ProgressListener {
208219
void onUpdate(int downloaded,int total, boolean done);
209220
}
221+
222+
/**
223+
* FallBackDNS store successful DNS request to return them later
224+
* can help make the app to work later when the current DNS system
225+
* isn't functional or available.
226+
*
227+
* Note: DNS Cache is stored in user data.
228+
* */
229+
private static class FallBackDNS implements Dns {
230+
private final Dns parent;
231+
private final SharedPreferences sharedPreferences;
232+
private final HashSet<String> fallbacks;
233+
private final HashMap<String, List<InetAddress>> fallbackCache;
234+
235+
public FallBackDNS(Context context, Dns parent, String... fallbacks) {
236+
this.sharedPreferences = context.getSharedPreferences(
237+
"mmm_dns", Context.MODE_PRIVATE);
238+
this.parent = parent;
239+
this.fallbacks = new HashSet<>(Arrays.asList(fallbacks));
240+
this.fallbackCache = new HashMap<>();
241+
}
242+
243+
@NonNull
244+
@Override
245+
public List<InetAddress> lookup(@NonNull String s) throws UnknownHostException {
246+
if (this.fallbacks.contains(s)) {
247+
List<InetAddress> addresses = this.fallbackCache.get(s);
248+
if (addresses != null)
249+
return addresses;
250+
try {
251+
addresses = this.parent.lookup(s);
252+
if (addresses.isEmpty() || addresses.get(0).isLoopbackAddress())
253+
throw new UnknownHostException(s);
254+
this.fallbackCache.put(s, addresses);
255+
this.sharedPreferences.edit().putString(
256+
s.replace('.', '_'), toString(addresses)).apply();
257+
} catch (UnknownHostException e) {
258+
String key = this.sharedPreferences.getString(
259+
s.replace('.', '_'), "");
260+
if (!key.isEmpty()) try {
261+
addresses = fromString(key);
262+
this.fallbackCache.put(s, addresses);
263+
return addresses;
264+
} catch (UnknownHostException e2) {
265+
this.sharedPreferences.edit().remove(
266+
s.replace('.', '_')).apply();
267+
}
268+
throw e;
269+
}
270+
271+
return addresses;
272+
} else {
273+
return this.parent.lookup(s);
274+
}
275+
}
276+
277+
@NonNull
278+
private static String toString(@NonNull List<InetAddress> inetAddresses) {
279+
if (inetAddresses.isEmpty()) return "";
280+
Iterator<InetAddress> inetAddressIterator = inetAddresses.iterator();
281+
StringBuilder stringBuilder = new StringBuilder();
282+
while (true) {
283+
stringBuilder.append(inetAddressIterator.next().getHostAddress());
284+
if (!inetAddressIterator.hasNext())
285+
return stringBuilder.toString();
286+
stringBuilder.append("|");
287+
}
288+
}
289+
290+
@NonNull
291+
private static List<InetAddress> fromString(@NonNull String string)
292+
throws UnknownHostException {
293+
if (string.isEmpty()) return Collections.emptyList();
294+
String[] strings = string.split("\\|");
295+
ArrayList<InetAddress> inetAddresses = new ArrayList<>(strings.length);
296+
for (String address : strings) {
297+
inetAddresses.add(InetAddress.getByName(address));
298+
}
299+
return inetAddresses;
300+
}
301+
}
210302
}

0 commit comments

Comments
 (0)