diff --git a/app/build.gradle b/app/build.gradle index 87a752767..8b61374aa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 32 - versionCode 28 - versionName "0.3.0" + versionCode 29 + versionName "0.3.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -20,7 +20,8 @@ android { release { minifyEnabled true shrinkResources true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile( + 'proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix '.debug' diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 96798b5f9..07b443099 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -51,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { this.setActionBarExtraMenuButton(R.drawable.ic_baseline_settings_24, v -> { IntentHelper.startActivity(this, SettingsActivity.class); return true; - }); + }, R.string.pref_category_settings); setContentView(R.layout.activity_main); this.setTitle(R.string.app_name); this.getWindow().setFlags( diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 9b1ee4bd7..11bf3ee51 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -4,6 +4,7 @@ import android.app.Application; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; @@ -25,9 +26,12 @@ import com.topjohnwu.superuser.Shell; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; +import java.util.HashSet; import java.util.Locale; import java.util.Random; +import java.util.Set; import io.noties.markwon.Markwon; import io.noties.markwon.html.HtmlPlugin; @@ -276,7 +280,6 @@ public boolean isLightTheme() { } } - @Override public void onCreate() { super.onCreate(); diff --git a/app/src/main/java/com/fox2code/mmm/ModuleHolder.java b/app/src/main/java/com/fox2code/mmm/ModuleHolder.java index c9194f5b3..2c815678a 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleHolder.java +++ b/app/src/main/java/com/fox2code/mmm/ModuleHolder.java @@ -226,7 +226,11 @@ public int compare(ModuleHolder o1, ModuleHolder o2) { public int compare(ModuleHolder o1, ModuleHolder o2) { int cmp = Integer.compare(o1.filterLevel, o2.filterLevel); if (cmp != 0) return cmp; - return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated); + long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated; + long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated; + cmp = Long.compare(lastUpdated2, lastUpdated1); + if (cmp != 0) return cmp; + return o1.getMainModuleName().compareTo(o2.getMainModuleName()); } }, INSTALLED(R.string.installed, true, true) { @@ -243,7 +247,11 @@ public int compare(ModuleHolder o1, ModuleHolder o2) { public int compare(ModuleHolder o1, ModuleHolder o2) { int cmp = Integer.compare(o1.filterLevel, o2.filterLevel); if (cmp != 0) return cmp; - return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated); + long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated; + long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated; + cmp = Long.compare(lastUpdated2, lastUpdated1); + if (cmp != 0) return cmp; + return o1.getMainModuleName().compareTo(o2.getMainModuleName()); } }, FOOTER(R.string.loading, false, false); 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 5f4108894..8e39a7ea8 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java @@ -3,6 +3,7 @@ import android.annotation.SuppressLint; import android.content.Intent; import android.content.pm.PackageManager; +import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -11,9 +12,11 @@ import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.webkit.WebResourceErrorCompat; import androidx.webkit.WebSettingsCompat; import androidx.webkit.WebViewClientCompat; import androidx.webkit.WebViewFeature; @@ -104,6 +107,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { WebSettingsCompat.FORCE_DARK_OFF : WebSettingsCompat.FORCE_DARK_ON); } this.webView.setWebViewClient(new WebViewClientCompat() { + private String pageUrl; + @Override public boolean shouldOverrideUrlLoading( @NonNull WebView view, @NonNull WebResourceRequest request) { @@ -115,6 +120,33 @@ public boolean shouldOverrideUrlLoading( } return false; } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + this.pageUrl = url; + } + + private void onReceivedError(String url,int errorCode) { + if ((url.startsWith("https://api.androidacy.com/magisk/") || + url.equals(pageUrl)) && (errorCode == 419 || errorCode == 429)) { + Toast.makeText(AndroidacyActivity.this, + "Too many requests!", Toast.LENGTH_LONG).show(); + AndroidacyActivity.this.runOnUiThread(AndroidacyActivity.this::onBackPressed); + } + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + this.onReceivedError(failingUrl, errorCode); + } + + @Override + public void onReceivedError(@NonNull WebView view, @NonNull WebResourceRequest request, + @NonNull WebResourceErrorCompat error) { + if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE)) { + this.onReceivedError(request.getUrl().toString(), error.getErrorCode()); + } + } }); this.webView.setWebChromeClient(new WebChromeClient() { @Override diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java index 28cd3ed56..19d597218 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java @@ -32,12 +32,14 @@ public AndroidacyWebAPI(AndroidacyActivity activity, boolean allowInstall) { @JavascriptInterface public void forceQuit(String error) { Toast.makeText(this.activity, error, Toast.LENGTH_LONG).show(); - this.activity.forceBackPressed(); + this.activity.runOnUiThread( + this.activity::forceBackPressed); } @JavascriptInterface public void cancel() { - this.activity.forceBackPressed(); + this.activity.runOnUiThread( + this.activity::forceBackPressed); } /** diff --git a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java index 09dfc644f..221664b16 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java @@ -6,6 +6,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.res.Resources; +import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.Menu; @@ -17,6 +18,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import androidx.annotation.Px; +import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowInsetsCompat; @@ -50,6 +52,7 @@ public boolean onBackPressed(CompatActivity compatActivity) { private CompatActivity.OnActivityResultCallback onActivityResultCallback; private CompatActivity.OnBackPressedCallback onBackPressedCallback; private MenuItem.OnMenuItemClickListener menuClickListener; + private CharSequence menuContentDescription; @StyleRes private int setThemeDynamic = 0; private boolean onCreateCalled = false; private boolean isRefreshUi = false; @@ -195,11 +198,29 @@ public int getNavigationBarHeight() { // How to improve this? public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, MenuItem.OnMenuItemClickListener menuClickListener) { + this.setActionBarExtraMenuButton(drawableResId, + menuClickListener, null); + } + + public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, + MenuItem.OnMenuItemClickListener menuClickListener, + @StringRes int menuContentDescription) { + this.setActionBarExtraMenuButton(drawableResId, + menuClickListener, this.getString(menuContentDescription)); + } + + public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, + MenuItem.OnMenuItemClickListener menuClickListener, + CharSequence menuContentDescription) { Objects.requireNonNull(menuClickListener); this.drawableResId = drawableResId; this.menuClickListener = menuClickListener; + this.menuContentDescription = menuContentDescription; if (this.menuItem != null) { this.menuItem.setOnMenuItemClickListener(this.menuClickListener); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.menuItem.setContentDescription(this.menuContentDescription); + } this.menuItem.setIcon(this.drawableResId); this.menuItem.setEnabled(true); this.menuItem.setVisible(true); @@ -209,8 +230,12 @@ public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, public void removeActionBarExtraMenuButton() { this.drawableResId = 0; this.menuClickListener = null; + this.menuContentDescription = null; if (this.menuItem != null) { this.menuItem.setOnMenuItemClickListener(null); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.menuItem.setContentDescription(null); + } this.menuItem.setIcon(null); this.menuItem.setEnabled(false); this.menuItem.setVisible(false);