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

Commit 6a608ff

Browse files
committed
Release 0.0.3
- Improved non standard file picker response handling. (Should fix install module from storage on some devices, and notifying the user that their file manager is weird) - Handle file picker returning http/https urls for files. - Improved search icon padding for rounded corner phones - Fixed card background being invisible on light theme - Make install terminal light when light theme is on - Added a switch to force the terminal to be always dark (to restore old behavior, default is false)
1 parent 1bc08e6 commit 6a608ff

17 files changed

+157
-32
lines changed

app/build.gradle

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

1616
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1717
}

app/proguard-rules.pro

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646
int d(java.lang.String, java.lang.String);
4747
int d(java.lang.String, java.lang.String, java.lang.Throwable);
4848
}
49+
-assumenosideeffects class androidx.loader.app.LoaderManager {
50+
static void enableDebugLogging(boolean);
51+
}
52+
-assumevalues class androidx.loader.app.LoaderManagerImpl {
53+
static boolean DEBUG return false;
54+
}
4955

5056
# This is just some proguard rules testes, might do a separate lib after
5157
# Made to help optimise the libraries and not the app directly

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

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

3+
import android.annotation.SuppressLint;
34
import android.app.Application;
45
import android.content.Intent;
56
import android.content.SharedPreferences;
@@ -70,6 +71,10 @@ public static boolean isShowIncompatibleModules() {
7071
return getSharedPreferences().getBoolean("pref_show_incompatible", false);
7172
}
7273

74+
public static boolean isForceDarkTerminal() {
75+
return getSharedPreferences().getBoolean("pref_force_dark_terminal", false);
76+
}
77+
7378
public static boolean hasGottenRootAccess() {
7479
return getSharedPreferences().getBoolean("has_root_access", false);
7580
}
@@ -118,6 +123,23 @@ public int getManagerThemeResId() {
118123
return managerThemeResId;
119124
}
120125

126+
@SuppressLint("NonConstantResourceId")
127+
public boolean isLightTheme() {
128+
switch (this.managerThemeResId) {
129+
case R.style.Theme_MagiskModuleManager:
130+
return (this.getResources().getConfiguration().uiMode
131+
& Configuration.UI_MODE_NIGHT_MASK)
132+
!= Configuration.UI_MODE_NIGHT_YES;
133+
case R.style.Theme_MagiskModuleManager_Light:
134+
return true;
135+
case R.style.Theme_MagiskModuleManager_Dark:
136+
return false;
137+
default:
138+
throw new IllegalStateException("Non manager theme!");
139+
}
140+
}
141+
142+
121143
@Override
122144
public void onCreate() {
123145
INSTANCE = this;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.annotation.SuppressLint;
44
import android.content.res.Resources;
5+
import android.graphics.Color;
56
import android.graphics.Typeface;
67
import android.graphics.drawable.Drawable;
78
import android.util.TypedValue;
@@ -11,6 +12,8 @@
1112
import android.widget.ImageButton;
1213
import android.widget.TextView;
1314

15+
import androidx.annotation.ColorInt;
16+
import androidx.annotation.ColorRes;
1417
import androidx.annotation.NonNull;
1518
import androidx.cardview.widget.CardView;
1619
import androidx.recyclerview.widget.RecyclerView;
@@ -250,7 +253,10 @@ public boolean update(ModuleHolder moduleHolder) {
250253
Resources.Theme theme = this.cardView.getContext().getTheme();
251254
TypedValue value = new TypedValue();
252255
theme.resolveAttribute(backgroundAttr, value, true);
253-
this.cardView.setCardBackgroundColor(value.data);
256+
@ColorInt int color = value.data;
257+
// Fix card background being invisible on light theme
258+
if (color == Color.WHITE) color = 0xFFF8F8F8;
259+
this.cardView.setCardBackgroundColor(color);
254260
} else {
255261
this.cardView.setBackground(null);
256262
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ public boolean shouldRemove() {
5656
CompatActivity compatActivity = CompatActivity.getCompatActivity(v);
5757
final File module = new File(compatActivity.getCacheDir(),
5858
"installer" + File.separator + "module.zip");
59-
IntentHelper.openFileTo(compatActivity, module, (d, s) -> {
60-
if (s) {
59+
IntentHelper.openFileTo(compatActivity, module, (d, u, s) -> {
60+
if (s == IntentHelper.RESPONSE_FILE) {
6161
try {
6262
boolean needPatch;
6363
try (ZipFile zipFile = new ZipFile(d)) {
@@ -86,6 +86,10 @@ public boolean shouldRemove() {
8686
Toast.makeText(compatActivity,
8787
R.string.invalid_format, Toast.LENGTH_SHORT).show();
8888
}
89+
} else if (s == IntentHelper.RESPONSE_URL) {
90+
IntentHelper.openInstaller(compatActivity, u.toString(),
91+
compatActivity.getString(
92+
R.string.remote_install_title), null);
8993
}
9094
});
9195
}, true) {

app/src/main/java/com/fox2code/mmm/installer/InstallerActivity.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import android.content.Intent;
44
import android.content.pm.PackageManager;
5+
import android.graphics.Color;
6+
import android.graphics.drawable.ColorDrawable;
57
import android.os.Bundle;
68
import android.util.Log;
79
import android.view.KeyEvent;
@@ -40,9 +42,9 @@ protected void onCreate(Bundle savedInstanceState) {
4042
this.moduleCache = new File(this.getCacheDir(), "installer");
4143
if (!this.moduleCache.exists() && !this.moduleCache.mkdirs())
4244
Log.e(TAG, "Failed to mkdir module cache dir!");
45+
super.onCreate(savedInstanceState);
4346
this.setDisplayHomeAsUpEnabled(false);
4447
this.setOnBackPressedCallback(DISABLE_BACK_BUTTON);
45-
super.onCreate(savedInstanceState);
4648
final Intent intent = this.getIntent();
4749
final String target;
4850
final String name;
@@ -64,8 +66,21 @@ protected void onCreate(Bundle savedInstanceState) {
6466
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
6567
setTitle(name);
6668
setContentView(R.layout.installer);
69+
int background;
70+
int foreground;
71+
if (MainApplication.getINSTANCE().isLightTheme() &&
72+
!MainApplication.isForceDarkTerminal()) {
73+
background = Color.WHITE;
74+
foreground = Color.BLACK;
75+
} else {
76+
background = Color.BLACK;
77+
foreground = Color.WHITE;
78+
}
79+
findViewById(R.id.install_horizontal_scroller)
80+
.setBackground(new ColorDrawable(background));
6781
this.progressIndicator = findViewById(R.id.progress_bar);
68-
this.installerTerminal = new InstallerTerminal(findViewById(R.id.install_terminal));
82+
this.installerTerminal = new InstallerTerminal(
83+
findViewById(R.id.install_terminal), foreground);
6984
this.progressIndicator.setVisibility(View.GONE);
7085
this.progressIndicator.setIndeterminate(true);
7186
if (urlMode) {

app/src/main/java/com/fox2code/mmm/installer/InstallerTerminal.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ public class InstallerTerminal extends RecyclerView.Adapter<InstallerTerminal.Te
1616
private final RecyclerView recyclerView;
1717
private final ArrayList<String> terminal;
1818
private final Object lock = new Object();
19+
private final int foreground;
1920

20-
public InstallerTerminal(RecyclerView recyclerView) {
21+
public InstallerTerminal(RecyclerView recyclerView,int foreground) {
2122
recyclerView.setLayoutManager(
2223
new LinearLayoutManager(recyclerView.getContext()));
2324
this.recyclerView = recyclerView;
25+
this.foreground = foreground;
2426
this.terminal = new ArrayList<>();
25-
this.recyclerView.setBackground(
26-
new ColorDrawable(Color.BLACK));
2727
this.recyclerView.setAdapter(this);
2828
}
2929

3030
@NonNull
3131
@Override
3232
public TextViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
33-
return new TextViewHolder(new TextView(parent.getContext()));
33+
return new TextViewHolder(new TextView(parent.getContext()), this.foreground);
3434
}
3535

3636
@Override
@@ -116,11 +116,11 @@ public void scrollDown() {
116116
public static class TextViewHolder extends RecyclerView.ViewHolder {
117117
private final TextView textView;
118118

119-
public TextViewHolder(@NonNull TextView itemView) {
119+
public TextViewHolder(@NonNull TextView itemView,int foreground) {
120120
super(itemView);
121121
this.textView = itemView;
122122
itemView.setTypeface(Typeface.MONOSPACE);
123-
itemView.setTextColor(Color.WHITE);
123+
itemView.setTextColor(foreground);
124124
itemView.setTextSize(12);
125125
itemView.setLines(1);
126126
itemView.setText(" ");

app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import androidx.annotation.StyleRes;
66
import androidx.fragment.app.FragmentTransaction;
7+
import androidx.preference.ListPreference;
78
import androidx.preference.Preference;
89
import androidx.preference.PreferenceFragmentCompat;
910

@@ -14,6 +15,7 @@
1415
import com.fox2code.mmm.repo.RepoManager;
1516
import com.fox2code.mmm.utils.IntentHelper;
1617
import com.mikepenz.aboutlibraries.LibsBuilder;
18+
import com.topjohnwu.superuser.internal.UiThreadHandler;
1719

1820
public class SettingsActivity extends CompatActivity {
1921
@Override
@@ -37,7 +39,9 @@ public static class SettingsFragment extends PreferenceFragmentCompat
3739
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
3840
getPreferenceManager().setSharedPreferencesName("mmm");
3941
setPreferencesFromResource(R.xml.root_preferences, rootKey);
40-
findPreference("pref_theme").setOnPreferenceChangeListener((preference, newValue) -> {
42+
ListPreference themePreference = findPreference("pref_theme");
43+
themePreference.setSummaryProvider(p -> themePreference.getEntry());
44+
themePreference.setOnPreferenceChangeListener((preference, newValue) -> {
4145
@StyleRes int themeResId;
4246
switch (String.valueOf(newValue)) {
4347
default:
@@ -55,6 +59,9 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
5559
CompatActivity.getCompatActivity(this).setThemeRecreate(themeResId);
5660
return true;
5761
});
62+
if ("dark".equals(themePreference.getValue())) {
63+
findPreference("pref_force_dark_terminal").setEnabled(false);
64+
}
5865

5966
setRepoNameResolution("pref_repo_main", RepoManager.MAGISK_REPO,
6067
"Magisk Modules Repo (Official)", RepoManager.MAGISK_REPO_HOMEPAGE);

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

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
package com.fox2code.mmm.utils;
22

3+
import android.annotation.SuppressLint;
34
import android.app.Activity;
45
import android.content.ActivityNotFoundException;
56
import android.content.ComponentName;
7+
import android.content.ContentResolver;
68
import android.content.Context;
79
import android.content.ContextWrapper;
810
import android.content.Intent;
911
import android.net.Uri;
1012
import android.os.Bundle;
13+
import android.os.Environment;
1114
import android.util.Log;
1215
import android.widget.Toast;
1316

1417
import androidx.core.app.ActivityOptionsCompat;
1518

1619
import com.fox2code.mmm.Constants;
1720
import com.fox2code.mmm.MainApplication;
21+
import com.fox2code.mmm.R;
1822
import com.fox2code.mmm.compat.CompatActivity;
1923
import com.fox2code.mmm.installer.InstallerActivity;
2024
import com.fox2code.mmm.markdown.MarkdownActivity;
25+
import com.topjohnwu.superuser.io.SuFileInputStream;
2126

2227
import java.io.File;
28+
import java.io.FileInputStream;
2329
import java.io.FileOutputStream;
30+
import java.io.IOException;
2431
import java.io.InputStream;
2532
import java.io.OutputStream;
2633

@@ -144,50 +151,78 @@ public static Activity getActivity(Context context) {
144151
return (Activity) context;
145152
}
146153

154+
public static final int RESPONSE_ERROR = 0;
155+
public static final int RESPONSE_FILE = 1;
156+
public static final int RESPONSE_URL = 2;
157+
158+
@SuppressLint("SdCardPath")
147159
public static void openFileTo(CompatActivity compatActivity, File destination,
148-
OnFileReceivedCallback callback) {
160+
OnFileReceivedCallback callback) {
149161
Intent intent = new Intent(Intent.ACTION_GET_CONTENT).setType("application/zip");
150162
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
151-
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
163+
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
164+
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, false);
152165
intent.addCategory(Intent.CATEGORY_OPENABLE);
153166
Bundle param = ActivityOptionsCompat.makeCustomAnimation(compatActivity,
154167
android.R.anim.fade_in, android.R.anim.fade_out).toBundle();
155168
compatActivity.startActivityForResult(intent, param, (result, data) -> {
156-
String name = destination.getName();
157-
if (data == null || result != Activity.RESULT_OK) {
158-
callback.onReceived(destination, false);
169+
Uri uri = data == null ? null : data.getData();
170+
if (uri == null || (result == Activity.RESULT_CANCELED && !((
171+
ContentResolver.SCHEME_FILE.equals(uri.getScheme())
172+
&& uri.getPath() != null &&
173+
(uri.getPath().startsWith("/sdcard/") ||
174+
uri.getPath().startsWith("/data/"))
175+
) || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())))) {
176+
callback.onReceived(destination, null, RESPONSE_ERROR);
159177
return;
160178
}
161-
Uri uri = data.getData();
162-
if (uri == null || "http".equals(uri.getScheme()) ||
179+
Log.d("IntentHelper", "FilePicker returned " + uri.toString());
180+
if ("http".equals(uri.getScheme()) ||
163181
"https".equals(uri.getScheme())) {
164-
callback.onReceived(destination, false);
182+
callback.onReceived(destination, uri, RESPONSE_URL);
165183
return;
166184
}
185+
if (ContentResolver.SCHEME_FILE.equals(uri.getScheme()) ||
186+
(result != Activity.RESULT_OK && result != Activity.RESULT_FIRST_USER)) {
187+
Toast.makeText(compatActivity,
188+
R.string.file_picker_wierd,
189+
Toast.LENGTH_SHORT).show();
190+
}
167191
InputStream inputStream = null;
168192
OutputStream outputStream = null;
169193
boolean success = false;
170194
try {
171-
inputStream = compatActivity.getContentResolver()
172-
.openInputStream(uri);
195+
if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
196+
String path = uri.getPath();
197+
if (path.startsWith("/sdcard/")) { // Fix file paths
198+
path = Environment.getExternalStorageDirectory()
199+
.getAbsolutePath() + path.substring(7);
200+
}
201+
inputStream = SuFileInputStream.open(
202+
new File(path).getAbsoluteFile());
203+
} else {
204+
inputStream = compatActivity.getContentResolver()
205+
.openInputStream(uri);
206+
}
173207
outputStream = new FileOutputStream(destination);
174208
Files.copy(inputStream, outputStream);
175-
String newName = uri.getLastPathSegment();
176-
if (newName.endsWith(".zip")) name = newName;
177209
success = true;
178210
} catch (Exception e) {
179211
Log.e("IntentHelper", "fail copy", e);
212+
Toast.makeText(compatActivity,
213+
R.string.file_picker_failure,
214+
Toast.LENGTH_SHORT).show();
180215
} finally {
181216
Files.closeSilently(inputStream);
182217
Files.closeSilently(outputStream);
183218
if (!success && destination.exists() && !destination.delete())
184219
Log.e("IntentHelper", "Failed to delete artefact!");
185220
}
186-
callback.onReceived(destination, success);
221+
callback.onReceived(destination, uri, success ? RESPONSE_FILE : RESPONSE_ERROR);
187222
});
188223
}
189224

190225
public interface OnFileReceivedCallback {
191-
void onReceived(File target,boolean success);
226+
void onReceived(File target,Uri uri,int response);
192227
}
193228
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal"
7+
android:autoMirrored="true">
8+
<path
9+
android:fillColor="@android:color/white"
10+
android:pathData="M3,13h2v-2L3,11v2zM3,17h2v-2L3,15v2zM3,9h2L5,7L3,7v2zM7,13h14v-2L7,11v2zM7,17h14v-2L7,15v2zM7,7v2h14L21,7L7,7z"/>
11+
</vector>

0 commit comments

Comments
 (0)