From 495e1cc3e648ee801027751fffabef9385fd4814 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Sun, 27 Feb 2022 00:52:56 +0100 Subject: [PATCH 01/15] Fixing android layout for older android devices, fix debug builds. --- app/build.gradle | 1 - app/src/main/AndroidManifest.xml | 1 + .../java/com/fox2code/mmm/MainActivity.java | 43 +++++++++++-------- .../fox2code/mmm/compat/CompatActivity.java | 41 ++++++++++++++++-- .../mmm/markdown/MarkdownActivity.java | 8 +++- app/src/main/res/layout/activity_main.xml | 13 ++++-- app/src/main/res/layout/markdown_view.xml | 4 +- app/src/main/res/layout/module_entry.xml | 4 +- 8 files changed, 83 insertions(+), 32 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ee5bd64..1661b02 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,7 +35,6 @@ android { lint { disable 'MissingTranslation' } - namespace 'com.fox2code.mmm' } aboutLibraries { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3ce948e..d143063 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 2b9558b..2bd3ce3 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.widget.SearchView; import androidx.cardview.widget.CardView; import androidx.core.content.ContextCompat; +import androidx.core.graphics.ColorUtils; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -22,6 +23,7 @@ import android.view.inputmethod.EditorInfo; import android.widget.TextView; import com.fox2code.mmm.compat.CompatActivity; +import com.fox2code.mmm.compat.CompatDisplay; import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.manager.LocalModuleInfo; import com.fox2code.mmm.manager.ModuleManager; @@ -32,6 +34,7 @@ import com.fox2code.mmm.utils.IntentHelper; import com.google.android.material.progressindicator.LinearProgressIndicator; import eightbitlab.com.blurview.BlurView; +import eightbitlab.com.blurview.BlurViewFacade; import eightbitlab.com.blurview.RenderScriptBlur; public class MainActivity extends CompatActivity implements SwipeRefreshLayout.OnRefreshListener, @@ -72,10 +75,8 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O setContentView(R.layout.activity_main); this.setTitle(R.string.app_name); this.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, - WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, + WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); setActionBarBackground(null); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes(); @@ -106,7 +107,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O this.actionBarBlur.setupWith(this.moduleList).setFrameClearDrawable( this.getWindow().getDecorView().getBackground()) .setBlurAlgorithm(new RenderScriptBlur(this)) - .setBlurRadius(5F).setBlurAutoUpdate(true) + .setBlurRadius(4F).setBlurAutoUpdate(true) .setHasFixedTransformationMatrix(true); this.updateBlurState(); this.moduleList.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -116,6 +117,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O MainActivity.this.searchView.clearFocus(); } }); + this.searchView.setMinimumHeight(CompatDisplay.dpToPixel(16)); this.searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_FULLSCREEN); this.searchView.setOnQueryTextListener(this); @@ -238,32 +240,37 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O this.swipeRefreshLayout.setProgressViewOffset(false, swipeRefreshLayoutOrigStartOffset + combinedBarsHeight, swipeRefreshLayoutOrigEndOffset + combinedBarsHeight); - this.moduleViewListBuilder.setHeaderPx(actionBarHeight); + this.moduleViewListBuilder.setHeaderPx( + actionBarHeight + CompatDisplay.dpToPixel(4)); this.moduleViewListBuilder.setFooterPx( bottomInset + this.searchCard.getHeight()); this.moduleViewListBuilder.updateInsets(); this.actionBarBlur.invalidate(); this.overScrollInsetTop = combinedBarsHeight; this.overScrollInsetBottom = bottomInset; + Log.d(TAG, "( " + bottomInset + ", " + + this.searchCard.getHeight() + ")"); } private void updateBlurState() { + boolean isLightMode = this.isLightTheme(); + int colorBackground; + try { + colorBackground = this.getColorCompat( + android.R.attr.windowBackground); + } catch (Resources.NotFoundException e) { + colorBackground = this.getColorCompat(isLightMode ? + R.color.white : R.color.black); + } if (MainApplication.isBlurEnabled()) { this.actionBarBlur.setBlurEnabled(true); - int transparent = this.getColorCompat(R.color.transparent); - this.actionBarBackground.setColor(transparent); + this.actionBarBackground.setColor(ColorUtils + .setAlphaComponent(colorBackground, 0x02)); + this.actionBarBackground.setColor(Color.TRANSPARENT); } else { this.actionBarBlur.setBlurEnabled(false); - boolean isLightMode = this.isLightTheme(); - int colorOpaque; - try { - colorOpaque = this.getColorCompat( - android.R.attr.windowBackground); - } catch (Resources.NotFoundException e) { - colorOpaque = this.getColorCompat(isLightMode ? - R.color.white : R.color.black); - } - this.actionBarBackground.setColor(colorOpaque); + this.actionBarBlur.setOverlayColor(Color.TRANSPARENT); + this.actionBarBackground.setColor(colorBackground); } } 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 9c3e547..a7031b8 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java @@ -12,9 +12,13 @@ import android.os.Build; import android.os.Bundle; import android.util.Log; import android.util.TypedValue; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.ViewConfiguration; +import android.view.WindowManager; import androidx.annotation.AttrRes; import androidx.annotation.CallSuper; @@ -65,8 +69,10 @@ public class CompatActivity extends AppCompatActivity { private MenuItem.OnMenuItemClickListener menuClickListener; private CharSequence menuContentDescription; @StyleRes private int setThemeDynamic = 0; + private boolean onCreateCalledOnce = false; private boolean onCreateCalled = false; private boolean isRefreshUi = false; + private boolean hasHardwareNavBar; private int drawableResId; private MenuItem menuItem; // CompatConfigHelper @@ -82,6 +88,9 @@ public class CompatActivity extends AppCompatActivity { if (!this.onCreateCalled) { this.getLayoutInflater().setFactory2(new LayoutInflaterFactory(this.getDelegate()) .addOnViewCreatedListener(WindowInsetsHelper.Companion.getLISTENER())); + this.hasHardwareNavBar = ViewConfiguration.get(this).hasPermanentMenuKey() || + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + this.onCreateCalledOnce = true; } Application application = this.getApplication(); if (application instanceof ApplicationCallbacks) { @@ -114,7 +123,7 @@ public class CompatActivity extends AppCompatActivity { @CallSuper public void refreshUI() { // Avoid recursive calls - if (this.isRefreshUi) return; + if (this.isRefreshUi || !this.onCreateCalled) return; Application application = this.getApplication(); if (application instanceof ApplicationCallbacks) { this.isRefreshUi = true; @@ -196,6 +205,22 @@ public class CompatActivity extends AppCompatActivity { } } + public View getActionBarView() { + androidx.appcompat.app.ActionBar compatActionBar; + try { + compatActionBar = this.getSupportActionBar(); + } catch (Exception e) { + Log.e(TAG, "Failed to call getSupportActionBar", e); + compatActionBar = null; // Allow fallback to builtin actionBar. + } + if (compatActionBar != null) { + return compatActionBar.getCustomView(); + } else { + android.app.ActionBar actionBar = this.getActionBar(); + return actionBar != null ? actionBar.getCustomView() : null; + } + } + @Dimension @Px public int getActionBarHeight() { androidx.appcompat.app.ActionBar compatActionBar; @@ -242,21 +267,31 @@ public class CompatActivity extends AppCompatActivity { return height; } - public int getNavigationBarHeight() { // How to improve this? + public int getNavigationBarHeight() { int height = WindowInsetsCompat.CONSUMED.getInsets( WindowInsetsCompat.Type.navigationBars()).bottom; if (height == 0) { // Fallback to system resources int id = Resources.getSystem().getIdentifier( "config_showNavigationBar", "bool", "android"); - if (id > 0 && Resources.getSystem().getBoolean(id)) { + Log.d(TAG, "Nav 1: " + id); + if ((id > 0 && Resources.getSystem().getBoolean(id)) + || !this.hasHardwareNavBar()) { id = Resources.getSystem().getIdentifier( "navigation_bar_height", "dimen", "android"); + Log.d(TAG, "Nav 2: " + id); if (id > 0) return Resources.getSystem().getDimensionPixelSize(id); } } return height; } + public boolean hasHardwareNavBar() { + // If onCreate has not been called yet, cached value is not valid + return this.onCreateCalledOnce ? this.hasHardwareNavBar : + ViewConfiguration.get(this).hasPermanentMenuKey() || + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + } + public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, MenuItem.OnMenuItemClickListener menuClickListener) { this.setActionBarExtraMenuButton(drawableResId, diff --git a/app/src/main/java/com/fox2code/mmm/markdown/MarkdownActivity.java b/app/src/main/java/com/fox2code/mmm/markdown/MarkdownActivity.java index cdd3c80..933b7ca 100644 --- a/app/src/main/java/com/fox2code/mmm/markdown/MarkdownActivity.java +++ b/app/src/main/java/com/fox2code/mmm/markdown/MarkdownActivity.java @@ -18,6 +18,7 @@ import com.fox2code.mmm.R; import com.fox2code.mmm.compat.CompatActivity; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.IntentHelper; +import com.topjohnwu.superuser.internal.UiThreadHandler; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -64,8 +65,11 @@ public class MarkdownActivity extends CompatActivity { } Log.i(TAG, "Url for markdown " + url); setContentView(R.layout.markdown_view); - ViewGroup markdownBackground = findViewById(R.id.markdownBackground); - TextView textView = findViewById(R.id.markdownView); + final ViewGroup markdownBackground = findViewById(R.id.markdownBackground); + final TextView textView = findViewById(R.id.markdownView); + final TextView footer = findViewById(R.id.markdownFooter); + UiThreadHandler.handler.postDelayed(() -> // Fix footer height + footer.setMinHeight(this.getNavigationBarHeight()), 1L); new Thread(() -> { try { Log.d(TAG, "Downloading"); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2002bd0..4fdbda6 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -57,16 +57,21 @@ android:gravity="right" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:fitsSystemWindowsInsets="bottom" + app:layout_fitsSystemWindowsInsets="bottom" tools:ignore="RtlHardcoded"> - + @@ -75,7 +80,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/markdown_view.xml b/app/src/main/res/layout/markdown_view.xml index 5e31dc4..a7616e7 100644 --- a/app/src/main/res/layout/markdown_view.xml +++ b/app/src/main/res/layout/markdown_view.xml @@ -7,7 +7,7 @@ android:background="@color/black" android:id="@+id/markdownBackground" app:fitsSystemWindowsInsets="top|left|right"> - - + \ No newline at end of file diff --git a/app/src/main/res/layout/module_entry.xml b/app/src/main/res/layout/module_entry.xml index f66c17c..43e2ad6 100644 --- a/app/src/main/res/layout/module_entry.xml +++ b/app/src/main/res/layout/module_entry.xml @@ -10,7 +10,7 @@ android:layout_marginBottom="2dp" android:gravity="center_vertical" android:background="@null"> - - + From e8053c1a505b07bbe5b876fad8a235732efd4566 Mon Sep 17 00:00:00 2001 From: RadiatedExodus <30568955+RealEthanPlayzDev@users.noreply.github.com> Date: Tue, 1 Mar 2022 10:57:14 +0700 Subject: [PATCH 02/15] ID - Translate strings.xml to Indonesian --- app/src/main/res/values-id/strings.xml | 96 ++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 app/src/main/res/values-id/strings.xml diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml new file mode 100644 index 0000000..3815c05 --- /dev/null +++ b/app/src/main/res/values-id/strings.xml @@ -0,0 +1,96 @@ + + Fox\'s Magisk Module Manager + Fox\'s Mmm + Tidak dapat mengakses root atau Magisk + Memuat… + Dapat diperbarui + Terpasang + Repo Online + Aplikasi berada dalam mode lockdown + Tidak dapat mengunduh file. + Modul membutuhkan waktu yang terlalu lama untuk melakukan boot, pertimbangkanglah untuk mematikan beberapa modul + Tidak dapat terhubung dengan internet + SettingsActivity + Tersedia pembaruan aplikasi + Perbarui + Tidak dapat menemukan deskripsi. + Unduh modul + Instal modul + Perbarui modul + Changelog + Situs + Dukungan + Donasi + Kirim sebuah modul + Membutuhkan Android 6.0+ + + + Pembaruan terakhir: + Repo: + oleh + Diunduh: + Bintang: + + + + Kelola repo + Mode lockdown + Mode lockdown mencegah manager dari melakukan tindakan terhadap modul + Peraturan + Info + Perlihatkan lisensi + Lisensi + Tampilkan modul tidak kompatibel + Tampilkan modul yang tidak kompatibel dengan perangkat anda berdasarkan metadata mereka + Versi Magisk usang! + Repos + Repository yang menampung modul Magisk + Sebuah alternatif Magisk-Modules-Repo dengan restriksi lebih ringan. + Hapus file modul? + Simpan file + Hapus file + Tidak dapat menghapus file modul + Tema + Mode tema + Id modul: + Instal modul dari penyimpanan + Modul yang diseleksi mempunyai format yang tidak valid + Instal lokal + Kode sumber + Modul bawaan Magisk + Modul bawaan Substratum + Paksa mode gelap pada terminal + Pemilih file anda sekarang gagal memberikan akses kepada file. + Instal jarak jauh + Pemilih file anda mengembalikan tanggapan yang tidak standar. + Gunakan perintah instal modul magisk + + Waktu diuji ini menyebabkan masalah kepada alat diagnosis kesalahan instal modul, + jadi saya menyembunyikan opsi ini dibelakan mode pengembang, aktifkan pada risiko anda sendiri! + + Mode pengembang aktif + Paksa Bahasa Inggris + Nonaktifkan filter modul qualitas rendah + + Beberapa modul tidak menyatakan metadata mereka dengan benar,menyebabkan glitch visual, + dan/atau mengindikasikan modul qualitas rendah, nonaktifkan pada risiko anda sendiri! + + DNS melalui HTTPS + + Mungkin dapat memperbaiki masalah koneksi didalam beberapa kasus. + (Tidak berlaku untuk WebView) + + Nonaktifkan ekstensi + + Nonaktifkan ekstensi Fox\'s Mmm, ini mencegah modul dari menggunakan + ekstensi terminal, berguna jika sebuah modul menyalahgunakan ekstensi Fox\'s Mmm. + + Wrap teks + + Wrap teks ke sebuah garis baru daripada menaruh + semua teks pada garis yang sama pada saat menginstal sebuah modul + + Aktifkan blur + Repo diaktifkan + Repo dinonaktifkan + From 0d782e76ae7ed4730059b5ec6dccbf1d8c4c86ac Mon Sep 17 00:00:00 2001 From: RadiatedExodus <30568955+RealEthanPlayzDev@users.noreply.github.com> Date: Tue, 1 Mar 2022 10:59:00 +0700 Subject: [PATCH 03/15] ID - Translate arrays.xml to Indonesian --- app/src/main/res/values-id/arrays.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/src/main/res/values-id/arrays.xml diff --git a/app/src/main/res/values-id/arrays.xml b/app/src/main/res/values-id/arrays.xml new file mode 100644 index 0000000..d1e9488 --- /dev/null +++ b/app/src/main/res/values-id/arrays.xml @@ -0,0 +1,7 @@ + + + Sistem + Gelap + Terang + + From 4cd3fcbcdd9571385d2fe3ab5974ea1e8e032c27 Mon Sep 17 00:00:00 2001 From: Jia-Bin Date: Wed, 2 Mar 2022 04:38:27 +0800 Subject: [PATCH 04/15] Update Traditional Chinese Not sure what function "Theme mode" is, need to see the actual effect to be translated --- app/src/main/res/values-zh-rTW/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 7f19e4f..922e789 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -22,6 +22,7 @@ 支援 捐贈 提交一個模組 + 要求 Android 6.0 以上版本 最後更新: @@ -50,6 +51,7 @@ 刪除安裝檔 刪除安裝檔失敗 主題 + Theme mode 模組 ID: 從本機安裝 所選模組的格式無效或檔案損毀 @@ -88,6 +90,7 @@ 將文字換行至新行, 而不是將所有文字放在同一行。 + 啟用模糊 啟用倉庫 禁用倉庫 - + \ No newline at end of file From f9e9559e9370d281e26f6550b0de25d1af3e086a Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Wed, 2 Mar 2022 19:06:04 +0100 Subject: [PATCH 05/15] Fix detecting software navbar height on emulator. --- app/build.gradle | 3 +++ .../com/fox2code/mmm/compat/CompatActivity.java | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1661b02..479c4eb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,6 +74,9 @@ dependencies { annotationProcessor "io.noties:prism4j-bundler:2.0.0" implementation "com.caverock:androidsvg:1.4" + // Utils for compat + compileOnly "org.robolectric:android-all:11-robolectric-6757853" + // Test testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' 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 a7031b8..0df73eb 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java @@ -10,6 +10,7 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.os.SystemProperties; import android.util.Log; import android.util.TypedValue; import android.view.KeyCharacterMap; @@ -88,8 +89,7 @@ public class CompatActivity extends AppCompatActivity { if (!this.onCreateCalled) { this.getLayoutInflater().setFactory2(new LayoutInflaterFactory(this.getDelegate()) .addOnViewCreatedListener(WindowInsetsHelper.Companion.getLISTENER())); - this.hasHardwareNavBar = ViewConfiguration.get(this).hasPermanentMenuKey() || - KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + this.hasHardwareNavBar = this.hasHardwareNavBar0(); this.onCreateCalledOnce = true; } Application application = this.getApplication(); @@ -104,6 +104,7 @@ public class CompatActivity extends AppCompatActivity { @Override protected void onResume() { + this.hasHardwareNavBar = this.hasHardwareNavBar0(); super.onResume(); this.refreshUI(); } @@ -287,9 +288,13 @@ public class CompatActivity extends AppCompatActivity { public boolean hasHardwareNavBar() { // If onCreate has not been called yet, cached value is not valid - return this.onCreateCalledOnce ? this.hasHardwareNavBar : - ViewConfiguration.get(this).hasPermanentMenuKey() || - KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + return this.onCreateCalledOnce ? this.hasHardwareNavBar : this.hasHardwareNavBar0(); + } + + private boolean hasHardwareNavBar0() { + return (ViewConfiguration.get(this).hasPermanentMenuKey() || + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)) && + !"0".equals(SystemProperties.get("qemu.hw.mainkeys")); } public void setActionBarExtraMenuButton(@DrawableRes int drawableResId, From 4ce22b29388a89240524634ff1a408b6fc3e686e Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Wed, 2 Mar 2022 19:33:46 +0100 Subject: [PATCH 06/15] Make error messages about magisk or root redirect to Magisk GitHub --- .../java/com/fox2code/mmm/NotificationType.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/NotificationType.java b/app/src/main/java/com/fox2code/mmm/NotificationType.java index 71fc825..06b4330 100644 --- a/app/src/main/java/com/fox2code/mmm/NotificationType.java +++ b/app/src/main/java/com/fox2code/mmm/NotificationType.java @@ -31,13 +31,17 @@ public enum NotificationType implements NotificationTypeCst { return !MainApplication.isShowcaseMode(); } }, - NO_ROOT(R.string.fail_root_magisk, R.drawable.ic_baseline_numbers_24) { + NO_ROOT(R.string.fail_root_magisk, R.drawable.ic_baseline_numbers_24, v -> { + IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk"); + }) { @Override public boolean shouldRemove() { return InstallerInitializer.peekMagiskPath() != null; } }, - MAGISK_OUTDATED(R.string.magisk_outdated, R.drawable.ic_baseline_update_24) { + MAGISK_OUTDATED(R.string.magisk_outdated, R.drawable.ic_baseline_update_24, v -> { + IntentHelper.openUrl(v.getContext(), "https://github.com/topjohnwu/Magisk"); + }) { @Override public boolean shouldRemove() { return InstallerInitializer.peekMagiskPath() == null || @@ -128,7 +132,11 @@ public enum NotificationType implements NotificationTypeCst { public final boolean special; NotificationType(@StringRes int textId, int iconId) { - this(textId, iconId, R.attr.colorError, R.attr.colorOnPrimary); //R.attr.colorOnError); + this(textId, iconId, R.attr.colorError, R.attr.colorOnPrimary); + } + + NotificationType(@StringRes int textId, int iconId, View.OnClickListener onClickListener) { + this(textId, iconId, R.attr.colorError, R.attr.colorOnPrimary, onClickListener); } NotificationType(@StringRes int textId, int iconId, int backgroundAttr, int foregroundAttr) { From 97cd87c13e052b19d5c377186000026e37467a02 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Wed, 2 Mar 2022 22:20:41 +0100 Subject: [PATCH 07/15] Add compat flags for modules, fix Androidacy code typo. --- .../com/fox2code/mmm/AppUpdateManager.java | 92 +++++++++++++++++++ .../java/com/fox2code/mmm/MainActivity.java | 2 + .../fox2code/mmm/ModuleViewListBuilder.java | 9 +- .../mmm/androidacy/AndroidacyActivity.java | 4 +- .../mmm/installer/InstallerActivity.java | 53 ++++++++--- .../com/fox2code/mmm/utils/PropUtils.java | 23 ++++- 6 files changed, 165 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/AppUpdateManager.java b/app/src/main/java/com/fox2code/mmm/AppUpdateManager.java index 1050811..9ce29e7 100644 --- a/app/src/main/java/com/fox2code/mmm/AppUpdateManager.java +++ b/app/src/main/java/com/fox2code/mmm/AppUpdateManager.java @@ -2,25 +2,42 @@ package com.fox2code.mmm; import android.util.Log; +import com.fox2code.mmm.utils.Files; import com.fox2code.mmm.utils.Http; import org.json.JSONArray; import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.HashMap; // See https://docs.github.com/en/rest/reference/repos#releases public class AppUpdateManager { + public static int FLAG_COMPAT_LOW_QUALITY = 0x01; + public static int FLAG_COMPAT_NO_EXT = 0x02; + public static int FLAG_COMPAT_MAGISK_CMD = 0x04; + public static int FLAG_COMPAT_NEED_32BIT = 0x08; private static final String TAG = "AppUpdateManager"; private static final AppUpdateManager INSTANCE = new AppUpdateManager(); private static final String RELEASES_API_URL = "https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/releases"; + private static final String COMPAT_API_URL = + "https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/releases"; public static AppUpdateManager getAppUpdateManager() { return INSTANCE; } + private final HashMap compatDataId = new HashMap<>(); private final Object updateLock = new Object(); + private final File compatFile; private String latestRelease; private String latestPreRelease; private long lastChecked; @@ -28,12 +45,20 @@ public class AppUpdateManager { private boolean lastCheckSuccess; private AppUpdateManager() { + this.compatFile = new File(MainApplication.getINSTANCE().getFilesDir(), "compat.txt"); this.latestRelease = MainApplication.getBootSharedPreferences() .getString("updater_latest_release", BuildConfig.VERSION_NAME); this.latestPreRelease = MainApplication.getBootSharedPreferences() .getString("updater_latest_pre_release", BuildConfig.VERSION_NAME); this.lastChecked = 0; this.preReleaseNewer = true; + if (this.compatFile.isFile()) { + try { + this.parseCompatibilityFlags(new FileInputStream(this.compatFile)); + } catch (IOException e) { + e.printStackTrace(); + } + } } // Return true if should show a notification @@ -95,6 +120,31 @@ public class AppUpdateManager { return this.peekShouldUpdate(); } + public void checkUpdateCompat() { + if (this.compatFile.exists()) { + long lastUpdate = this.compatFile.lastModified(); + if (lastUpdate <= System.currentTimeMillis() && + lastUpdate + 600_000L > System.currentTimeMillis()) { + return; // Skip update + } + } + try { + JSONObject object = new JSONObject(new String(Http.doHttpGet( + COMPAT_API_URL, false), StandardCharsets.UTF_8)); + if (object.isNull("body")) { + compatDataId.clear(); + Files.write(compatFile, new byte[0]); + return; + } + byte[] rawData = object.getString("body") + .getBytes(StandardCharsets.UTF_8); + this.parseCompatibilityFlags(new ByteArrayInputStream(rawData)); + Files.write(compatFile, rawData); + } catch (Exception e) { + Log.e("AppUpdateManager", "Failed to update compat list", e); + } + } + public boolean peekShouldUpdate() { return !(BuildConfig.VERSION_NAME.equals(this.latestRelease) || (this.preReleaseNewer && @@ -109,4 +159,46 @@ public class AppUpdateManager { public boolean isLastCheckSuccess() { return lastCheckSuccess; } + + private void parseCompatibilityFlags(InputStream inputStream) throws IOException { + compatDataId.clear(); + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line; + while ((line = bufferedReader.readLine()) != null) { + line = line.trim(); + if (line.isEmpty() || line.startsWith("#")) continue; + int i = line.indexOf('/'); + if (i == -1) continue; + int value = 0; + for (String arg : line.substring(i + 1).split(",")) { + switch (arg) { + default: + break; + case "lowQuality": + value |= FLAG_COMPAT_LOW_QUALITY; + break; + case "noExt": + value |= FLAG_COMPAT_NO_EXT; + break; + case "magiskCmd": + value |= FLAG_COMPAT_MAGISK_CMD; + break; + case "need32bit": + value |= FLAG_COMPAT_NEED_32BIT; + break; + } + } + compatDataId.put(line.substring(0, i), value); + } + } + + public int getCompatibilityFlags(String moduleId) { + Integer compatFlags = compatDataId.get(moduleId); + return compatFlags == null ? 0 : compatFlags; + } + + public static int getFlagsForModule(String moduleId) { + return INSTANCE.getCompatibilityFlags(moduleId); + } } diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 2bd3ce3..45750b1 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -179,6 +179,8 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O } else { if (AppUpdateManager.getAppUpdateManager().checkUpdate(true)) moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE); + if (AppUpdateManager.getAppUpdateManager().isLastCheckSuccess()) + AppUpdateManager.getAppUpdateManager().checkUpdateCompat(); if (max != 0) { int current = 0; for (LocalModuleInfo localModuleInfo : diff --git a/app/src/main/java/com/fox2code/mmm/ModuleViewListBuilder.java b/app/src/main/java/com/fox2code/mmm/ModuleViewListBuilder.java index ec074a2..02417ad 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleViewListBuilder.java +++ b/app/src/main/java/com/fox2code/mmm/ModuleViewListBuilder.java @@ -76,6 +76,7 @@ public class ModuleViewListBuilder { RepoManager repoManager = RepoManager.getINSTANCE(); repoManager.runAfterUpdate(() -> { Log.i(TAG, "A2: " + repoManager.getModules().size()); + boolean no32bitSupport = Build.SUPPORTED_32_BIT_ABIS.length == 0; for (RepoModule repoModule : repoManager.getModules().values()) { if (!repoModule.repoData.isEnabled()) continue; ModuleInfo moduleInfo = repoModule.moduleInfo; @@ -84,9 +85,11 @@ public class ModuleViewListBuilder { // Only check Magisk compatibility if root is present (InstallerInitializer.peekMagiskPath() != null && repoModule.moduleInfo.minMagisk > - InstallerInitializer.peekMagiskVersion() - ))) - continue; // Skip adding incompatible modules + InstallerInitializer.peekMagiskVersion())) || + // If 64bit only system, skip 32bit only modules + (no32bitSupport && (AppUpdateManager.getFlagsForModule(repoModule.id) + & AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0) + ) continue; // Skip adding incompatible modules ModuleHolder moduleHolder = this.mappedModuleHolders.get(repoModule.id); if (moduleHolder == null) { this.mappedModuleHolders.put(repoModule.id, 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 c7d905d..6fdb430 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java @@ -81,9 +81,9 @@ public class AndroidacyActivity extends CompatActivity { setActionBarBackground(null); this.setDisplayHomeAsUpEnabled(true); if (title == null || title.isEmpty()) { - this.setTitle(title); - } else { this.setTitle("Androidacy"); + } else { + this.setTitle(title); } if (allowInstall || title == null || title.isEmpty()) { this.hideActionBar(); diff --git a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java index 448c55f..cc21da1 100644 --- a/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java +++ b/app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java @@ -16,6 +16,7 @@ import android.widget.Toast; import androidx.recyclerview.widget.RecyclerView; import com.fox2code.mmm.ActionButtonType; +import com.fox2code.mmm.AppUpdateManager; import com.fox2code.mmm.BuildConfig; import com.fox2code.mmm.Constants; import com.fox2code.mmm.MainApplication; @@ -26,6 +27,7 @@ import com.fox2code.mmm.utils.Files; import com.fox2code.mmm.utils.Hashes; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.IntentHelper; +import com.fox2code.mmm.utils.PropUtils; import com.google.android.material.progressindicator.LinearProgressIndicator; import com.topjohnwu.superuser.CallbackList; import com.topjohnwu.superuser.Shell; @@ -261,23 +263,39 @@ public class InstallerActivity extends CompatActivity { .to(installerController, installerMonitor); } else { String arch32 = "true"; // Do nothing by default + boolean needs32bit = false; + String moduleId = null; + try (ZipFile zipFile = new ZipFile(file)) { + if (zipFile.getEntry( // Check if module hard require 32bit support + "common/addon/Volume-Key-Selector/tools/arm64/keycheck") == null && + zipFile.getEntry( + "common/addon/Volume-Key-Selector/install.sh") != null) { + needs32bit = true; + } + moduleId = PropUtils.readModuleId(zipFile + .getInputStream(zipFile.getEntry("module.prop"))); + } catch (IOException ignored) {} + int compatFlags = AppUpdateManager.getFlagsForModule(moduleId); + if ((compatFlags & AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0) + needs32bit = true; + if ((compatFlags & AppUpdateManager.FLAG_COMPAT_NO_EXT) != 0) + noExtensions = true; + if (moduleId != null && (moduleId.isEmpty() || + moduleId.contains("/") || moduleId.contains("\0") || + (moduleId.startsWith(".") && moduleId.endsWith(".")))) { + this.setInstallStateFinished(false, + "! This module contain a dangerous moduleId", + null); + return; + } if (Build.SUPPORTED_32_BIT_ABIS.length == 0) { - boolean needs32bit = false; - try (ZipFile zipFile = new ZipFile(file)) { - if (zipFile.getEntry( // Check if module hard require 32bit support - "common/addon/Volume-Key-Selector/tools/arm64/keycheck") == null && - zipFile.getEntry( - "common/addon/Volume-Key-Selector/install.sh") != null) { - needs32bit = true; - } - } catch (IOException ignored) {} if (needs32bit) { this.setInstallStateFinished(false, "! This module can't be installed on a 64bit only system", null); return; } - } else { + } else if (needs32bit || (compatFlags & AppUpdateManager.FLAG_COMPAT_NO_EXT) == 0) { // Restore Magisk legacy stuff for retro compatibility if (Build.SUPPORTED_32_BIT_ABIS[0].contains("arm")) arch32 = "export ARCH32=arm"; @@ -288,7 +306,8 @@ public class InstallerActivity extends CompatActivity { File installExecutable; if (InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND && - (noExtensions || MainApplication.isUsingMagiskCommand())) { + ((compatFlags & AppUpdateManager.FLAG_COMPAT_MAGISK_CMD) != 0 || + noExtensions || MainApplication.isUsingMagiskCommand())) { installCommand = "magisk --install-module \"" + file.getAbsolutePath() + "\""; installExecutable = new File(InstallerInitializer.peekMagiskPath() .equals("/sbin") ? "/sbin/magisk" : "/system/bin/magisk"); @@ -296,13 +315,14 @@ public class InstallerActivity extends CompatActivity { installExecutable = this.extractInstallScript("module_installer_compat.sh"); if (installExecutable == null) { this.setInstallStateFinished(false, - "! Failed to extract module install script", ""); + "! Failed to extract module install script", null); return; } installCommand = "sh \"" + installExecutable.getAbsolutePath() + "\"" + " /dev/null 1 \"" + file.getAbsolutePath() + "\""; } installerMonitor = new InstallerMonitor(installExecutable); + if (moduleId != null) installerMonitor.setForCleanUp(moduleId); if (noExtensions) { installJob = Shell.su(arch32, // No Extensions "cd \"" + this.moduleCache.getAbsolutePath() + "\"", @@ -462,6 +482,7 @@ public class InstallerActivity extends CompatActivity { private static final String DEFAULT_ERR = "! Install failed"; private final String installScriptErr; public String lastCommand = ""; + public String forCleanUp; public InstallerMonitor(File installScript) { super(Runnable::run); @@ -476,6 +497,10 @@ public class InstallerActivity extends CompatActivity { this.lastCommand = s; } + public void setForCleanUp(String forCleanUp) { + this.forCleanUp = forCleanUp; + } + private String doCleanUp() { String installScriptErr = this.installScriptErr; // This block is mainly to help fixing customize.sh syntax errors @@ -490,6 +515,10 @@ public class InstallerActivity extends CompatActivity { Log.e(TAG, "Failed to delete failed update"); return "Error: " + installScriptErr.substring(i + 1); } + } else if (this.forCleanUp != null) { + SuFile moduleUpdate = new SuFile("/data/adb/modules_update/" + this.forCleanUp); + if (moduleUpdate.exists() && !moduleUpdate.deleteRecursive()) + Log.e(TAG, "Failed to delete failed update"); } return DEFAULT_ERR; } diff --git a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java index 5a9deed..8b78628 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java +++ b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java @@ -1,7 +1,11 @@ package com.fox2code.mmm.utils; +import static com.fox2code.mmm.AppUpdateManager.FLAG_COMPAT_LOW_QUALITY; +import static com.fox2code.mmm.AppUpdateManager.getFlagsForModule; + import android.os.Build; import android.text.TextUtils; +import android.util.Log; import com.fox2code.mmm.manager.ModuleInfo; import com.topjohnwu.superuser.io.SuFileInputStream; @@ -274,6 +278,22 @@ public class PropUtils { } } + public static String readModuleId(InputStream inputStream) { + String moduleId = null; + try (BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + if (line.startsWith("id=")) { + moduleId = line.substring(3).trim(); + } + } + } catch (IOException e) { + Log.d("PropUtils", "Failed to get moduleId", e); + } + return moduleId; + } + public static void applyFallbacks(ModuleInfo moduleInfo) { if (moduleInfo.support == null || moduleInfo.support.isEmpty()) { moduleInfo.support = moduleSupportsFallbacks.get(moduleInfo.id); @@ -299,7 +319,8 @@ public class PropUtils { || moduleInfo.author == null || !TextUtils.isGraphic(moduleInfo.author) || (description = moduleInfo.description) == null || !TextUtils.isGraphic(description) || description.toLowerCase(Locale.ROOT).equals(moduleInfo.name.toLowerCase(Locale.ROOT)) - || description.length() < Math.min(Math.max(moduleInfo.name.length() + 4, 16), 24); + || description.length() < Math.min(Math.max(moduleInfo.name.length() + 4, 16), 24) + || (getFlagsForModule(moduleInfo.id) & FLAG_COMPAT_LOW_QUALITY) != 0; } private static boolean isInvalidValue(String name) { From 4f02487439e18de19e5b69c96d97c805640207c9 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Wed, 2 Mar 2022 22:30:44 +0100 Subject: [PATCH 08/15] Bring back rounded search view. --- app/src/main/java/com/fox2code/mmm/MainActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 45750b1..cb4a0a8 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -117,6 +117,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O MainActivity.this.searchView.clearFocus(); } }); + this.searchCard.setRadius(this.searchCard.getHeight() / 2F); this.searchView.setMinimumHeight(CompatDisplay.dpToPixel(16)); this.searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_FULLSCREEN); @@ -246,6 +247,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O actionBarHeight + CompatDisplay.dpToPixel(4)); this.moduleViewListBuilder.setFooterPx( bottomInset + this.searchCard.getHeight()); + this.searchCard.setRadius(this.searchCard.getHeight() / 2F); this.moduleViewListBuilder.updateInsets(); this.actionBarBlur.invalidate(); this.overScrollInsetTop = combinedBarsHeight; From c24e068f99921bff716121c68eac34ad6fbcdea1 Mon Sep 17 00:00:00 2001 From: ender-zhao <77391690+ender-zhao@users.noreply.github.com> Date: Thu, 3 Mar 2022 15:19:25 +0800 Subject: [PATCH 09/15] Update strings.xml --- app/src/main/res/values-zh-rCN/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index bf920b3..239ff79 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -22,6 +22,7 @@ 支持 捐赠 提交一个模块 + 需要 Android 6.0+ 最后更新: @@ -50,6 +51,7 @@ 删除文件 无法删除模块文件 主题 + 主题模式 模块ID: 从存储空间安装模块 所选模块的格式无效 @@ -88,6 +90,7 @@ 将文本换行至新行, 而不是将所有文本放在同一行 + 启用模糊 启用仓库 禁用仓库 From 2b435690cb81429e3adf7a42c813afef75a233bd Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Thu, 3 Mar 2022 12:36:06 +0100 Subject: [PATCH 10/15] Update libsu. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 479c4eb..02115a9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { // Utils implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.3' implementation 'com.squareup.okhttp3:okhttp-brotli:4.9.3' - implementation 'com.github.topjohnwu.libsu:io:3.2.1' + implementation 'com.github.topjohnwu.libsu:io:4.0.0' // Markdown implementation "io.noties.markwon:core:4.6.2" From 52d22fe48795db5a31091b341da22b5b02fcf8e7 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Thu, 3 Mar 2022 13:25:43 +0100 Subject: [PATCH 11/15] Fix click not registering when clicking on image icon. --- app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java b/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java index 0b44297..accb39c 100644 --- a/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java +++ b/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java @@ -104,6 +104,7 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter { if (this.initState) return; // Skip if non user From f8183bd2dc9c7e8d97e45292da48895204543ec1 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Thu, 3 Mar 2022 13:59:39 +0100 Subject: [PATCH 12/15] Fix WebView uri handling, and fix top inset. --- app/build.gradle | 2 +- .../java/com/fox2code/mmm/MainActivity.java | 2 +- .../mmm/androidacy/AndroidacyActivity.java | 6 +++--- .../com/fox2code/mmm/utils/IntentHelper.java | 19 ++++++++++++++++--- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 02115a9..0fe31c7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,7 +10,7 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 32 - versionCode 30 + versionCode 31 versionName "0.3.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index cb4a0a8..563b4fc 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -244,7 +244,7 @@ public class MainActivity extends CompatActivity implements SwipeRefreshLayout.O swipeRefreshLayoutOrigStartOffset + combinedBarsHeight, swipeRefreshLayoutOrigEndOffset + combinedBarsHeight); this.moduleViewListBuilder.setHeaderPx( - actionBarHeight + CompatDisplay.dpToPixel(4)); + actionBarHeight + CompatDisplay.dpToPixel(8)); this.moduleViewListBuilder.setFooterPx( bottomInset + this.searchCard.getHeight()); this.searchCard.setRadius(this.searchCard.getHeight() / 2F); 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 6fdb430..8b10024 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java @@ -120,9 +120,9 @@ public class AndroidacyActivity extends CompatActivity { public boolean shouldOverrideUrlLoading( @NonNull WebView view, @NonNull WebResourceRequest request) { // Don't open non Androidacy urls inside WebView - if (request.isForMainFrame() && !(request.getUrl().getScheme().equals("intent") || - AndroidacyUtil.isAndroidacyLink(request.getUrl()))) { - IntentHelper.openUrl(view.getContext(), request.getUrl().toString()); + if (request.isForMainFrame() && + !AndroidacyUtil.isAndroidacyLink(request.getUrl())) { + IntentHelper.openUri(view.getContext(), request.getUrl().toString()); return true; } return false; diff --git a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java index c10d62e..a022b1a 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java +++ b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.java @@ -30,8 +30,21 @@ import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.net.URISyntaxException; public class IntentHelper { + private static final String TAG = "IntentHelper"; + + public static void openUri(Context context, String uri) { + if (uri.startsWith("intent://")) { + try { + startActivity(context, Intent.parseUri(uri, Intent.URI_INTENT_SCHEME), false); + } catch (URISyntaxException | ActivityNotFoundException e) { + Log.e(TAG, "Failed launch of " + uri, e); + } + } else openUrl(context, uri); + } + public static void openUrl(Context context, String url) { openUrl(context, url, false); } @@ -227,7 +240,7 @@ public class IntentHelper { callback.onReceived(destination, null, RESPONSE_ERROR); return; } - Log.d("IntentHelper", "FilePicker returned " + uri); + Log.d(TAG, "FilePicker returned " + uri); if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) { callback.onReceived(destination, uri, RESPONSE_URL); @@ -259,7 +272,7 @@ public class IntentHelper { Files.copy(inputStream, outputStream); success = true; } catch (Exception e) { - Log.e("IntentHelper", "failed copy of " + uri, e); + Log.e(TAG, "failed copy of " + uri, e); Toast.makeText(compatActivity, R.string.file_picker_failure, Toast.LENGTH_SHORT).show(); @@ -267,7 +280,7 @@ public class IntentHelper { Files.closeSilently(inputStream); Files.closeSilently(outputStream); if (!success && destination.exists() && !destination.delete()) - Log.e("IntentHelper", "Failed to delete artefact!"); + Log.e(TAG, "Failed to delete artefact!"); } callback.onReceived(destination, uri, success ? RESPONSE_FILE : RESPONSE_ERROR); }); From 680abcb9901e9e7e4aeb6ba6bff10f8c6bb8a120 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Thu, 3 Mar 2022 14:30:52 +0100 Subject: [PATCH 13/15] Release Candidate 1 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0fe31c7..0f58843 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 32 - versionCode 31 - versionName "0.3.2" + versionCode 32 + versionName "0.4.0-rc1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 6bb2f8dd8cd0e07708a73b6a8c4b7fc489731e49 Mon Sep 17 00:00:00 2001 From: Jia-Bin Date: Thu, 3 Mar 2022 21:49:06 +0800 Subject: [PATCH 14/15] Update strings.xml --- app/src/main/res/values-zh-rTW/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 922e789..56396e8 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -51,7 +51,7 @@ 刪除安裝檔 刪除安裝檔失敗 主題 - Theme mode + 主題模式 模組 ID: 從本機安裝 所選模組的格式無效或檔案損毀 From 5324f5ac2e816a7ffa8fb40dc676b0b554b424c0 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Thu, 3 Mar 2022 15:21:52 +0100 Subject: [PATCH 15/15] 0.4.0 Release Candidate 1 --- app/build.gradle | 4 ++-- .../main/java/android/os/SystemProperties.java | 16 ++++++++++++++++ .../com/fox2code/mmm/compat/CompatActivity.java | 1 - .../fox2code/mmm/settings/SettingsActivity.java | 3 ++- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/android/os/SystemProperties.java diff --git a/app/build.gradle b/app/build.gradle index 0f58843..82ddfc5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,8 +74,8 @@ dependencies { annotationProcessor "io.noties:prism4j-bundler:2.0.0" implementation "com.caverock:androidsvg:1.4" - // Utils for compat - compileOnly "org.robolectric:android-all:11-robolectric-6757853" + // Utils for compat (Needs to be outsourced ASAP) + // compileOnly "org.robolectric:android-all:11-robolectric-6757853" // Test testImplementation 'junit:junit:4.+' diff --git a/app/src/main/java/android/os/SystemProperties.java b/app/src/main/java/android/os/SystemProperties.java new file mode 100644 index 0000000..1017039 --- /dev/null +++ b/app/src/main/java/android/os/SystemProperties.java @@ -0,0 +1,16 @@ +package android.os; + +import androidx.annotation.Keep; + +import com.topjohnwu.superuser.ShellUtils; + +@Keep +public class SystemProperties { + @Keep + public static String get(String key) { + String prop = ShellUtils.fastCmd("getprop " + key).trim(); + if (prop.endsWith("\n")) + prop = prop.substring(0, prop.length() - 1).trim(); + return prop; + } +} 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 0df73eb..7f5dd1d 100644 --- a/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java +++ b/app/src/main/java/com/fox2code/mmm/compat/CompatActivity.java @@ -19,7 +19,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewConfiguration; -import android.view.WindowManager; import androidx.annotation.AttrRes; import androidx.annotation.CallSuper; diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java index 739db08..101f7d5 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -112,7 +112,8 @@ public class SettingsActivity extends CompatActivity { .withLicenseShown(true).withAboutMinimalDesign(false) .withUiListener(new OverScrollManager.LibsOverScroll()); Preference update = findPreference("pref_update"); - update.setVisible(AppUpdateManager.getAppUpdateManager().peekHasUpdate()); + update.setVisible(BuildConfig.DEBUG || + AppUpdateManager.getAppUpdateManager().peekHasUpdate()); update.setOnPreferenceClickListener(p -> { devModeStep = 0; IntentHelper.openUrl(p.getContext(),