Release 0.2.9, Implement text wrap #10 and fix #37

pull/40/head 0.2.9
Fox2Code 2 years ago
parent b81509dd32
commit 1bbb16908a

@ -81,6 +81,7 @@ Variables:
- `MMM_EXT_SUPPORT` declared if extensions are supported
- `MMM_USER_LANGUAGE` the current user selected language
- `MMM_APP_VERSION` display version of the app (Ex: `x.y.z`)
- `MMM_TEXT_WRAP` is set to `1` if text wrapping is enabled
Note:
The current behavior with unknown command is to ignore them,

@ -10,8 +10,8 @@ android {
applicationId "com.fox2code.mmm"
minSdk 21
targetSdk 32
versionCode 19
versionName "0.2.8"
versionCode 20
versionName "0.2.9"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

@ -0,0 +1,24 @@
#!/sbin/sh
# This script is only used to test debug builds
umask 022
API=$(getprop ro.build.version.sdk)
OUTFD=$2
ZIPFILE=$3
MODPATH="${ZIPFILE%/*}"
ui_print() { echo "$1"; }
abort() {
ui_print "$1"
[ -f $MODPATH/customize.sh ] && rm -f $MODPATH/customize.sh
exit 1
}
ui_print "! Using rootless installer test script"
unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2
[ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh
ui_print "- Done"

@ -13,6 +13,7 @@ public class Constants {
public static final String EXTRA_INSTALL_CONFIG = "extra_install_config";
public static final String EXTRA_INSTALL_NO_PATCH = "extra_install_no_patch";
public static final String EXTRA_INSTALL_NO_EXTENSIONS = "extra_install_no_extensions";
public static final String EXTRA_INSTALL_TEST_ROOTLESS = "extra_install_test_rootless";
public static final String EXTRA_MARKDOWN_URL = "extra_markdown_url";
public static final String EXTRA_MARKDOWN_TITLE = "extra_markdown_title";
public static final String EXTRA_MARKDOWN_CONFIG = "extra_markdown_config";

@ -102,6 +102,10 @@ public class MainApplication extends Application implements CompatActivity.Appli
return getSharedPreferences().getBoolean("pref_force_dark_terminal", false);
}
public static boolean isTextWrapEnabled() {
return getSharedPreferences().getBoolean("pref_wrap_text", false);
}
public static boolean isDeveloper() {
return BuildConfig.DEBUG ||
getSharedPreferences().getBoolean("developer", false);

@ -21,6 +21,7 @@ import java.util.zip.ZipFile;
interface NotificationTypeCst {
String TAG = "NotificationType";
boolean ROOTLESS_TEST = true;
}
public enum NotificationType implements NotificationTypeCst {
@ -88,7 +89,9 @@ public enum NotificationType implements NotificationTypeCst {
} else {
IntentHelper.openInstaller(compatActivity, d.getAbsolutePath(),
compatActivity.getString(
R.string.local_install_title), null);
R.string.local_install_title), null, false,
BuildConfig.DEBUG && // Use debug mode if no root
InstallerInitializer.peekMagiskPath() == null);
}
} catch (IOException ignored) {
if (d.exists() && !d.delete())
@ -99,14 +102,17 @@ public enum NotificationType implements NotificationTypeCst {
} else if (s == IntentHelper.RESPONSE_URL) {
IntentHelper.openInstaller(compatActivity, u.toString(),
compatActivity.getString(
R.string.remote_install_title), null);
R.string.remote_install_title), null, false,
BuildConfig.DEBUG && // Use debug mode if no root
InstallerInitializer.peekMagiskPath() == null);
}
});
}, true) {
@Override
public boolean shouldRemove() {
return MainApplication.isShowcaseMode() ||
InstallerInitializer.peekMagiskPath() == null;
return (!(ROOTLESS_TEST && BuildConfig.DEBUG)) &&
(MainApplication.isShowcaseMode() ||
InstallerInitializer.peekMagiskPath() == null);
}
};

@ -12,6 +12,8 @@ import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.fox2code.mmm.ActionButtonType;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants;
@ -39,6 +41,7 @@ public class InstallerActivity extends CompatActivity {
public InstallerTerminal installerTerminal;
private File moduleCache;
private File toDelete;
private boolean textWrap;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -53,6 +56,7 @@ public class InstallerActivity extends CompatActivity {
final String name;
final boolean noPatch;
final boolean noExtensions;
final boolean rootless;
// Should we allow 3rd part app to install modules?
if (Constants.INTENT_INSTALL_INTERNAL.equals(intent.getAction())) {
if (!MainApplication.checkSecret(intent)) {
@ -65,6 +69,8 @@ public class InstallerActivity extends CompatActivity {
noPatch = intent.getBooleanExtra(Constants.EXTRA_INSTALL_NO_PATCH, false);
noExtensions = intent.getBooleanExtra(// Allow intent to disable extensions
Constants.EXTRA_INSTALL_NO_EXTENSIONS, false);
rootless = intent.getBooleanExtra(// For debug only
Constants.EXTRA_INSTALL_TEST_ROOTLESS, false);
} else {
Toast.makeText(this, "Unknown intent!", Toast.LENGTH_SHORT).show();
this.forceBackPressed();
@ -74,7 +80,9 @@ public class InstallerActivity extends CompatActivity {
boolean urlMode = target.startsWith("http://") || target.startsWith("https://");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setTitle(name);
setContentView(R.layout.installer);
setContentView((this.textWrap =
MainApplication.isTextWrapEnabled()) ?
R.layout.installer_wrap :R.layout.installer);
int background;
int foreground;
if (MainApplication.getINSTANCE().isLightTheme() &&
@ -85,11 +93,13 @@ public class InstallerActivity extends CompatActivity {
background = Color.BLACK;
foreground = Color.WHITE;
}
findViewById(R.id.install_horizontal_scroller)
.setBackground(new ColorDrawable(background));
View horizontalScroller = findViewById(R.id.install_horizontal_scroller);
RecyclerView installTerminal;
this.progressIndicator = findViewById(R.id.progress_bar);
this.installerTerminal = new InstallerTerminal(
findViewById(R.id.install_terminal), foreground);
installTerminal = findViewById(R.id.install_terminal), foreground);
(horizontalScroller != null ? horizontalScroller : installTerminal)
.setBackground(new ColorDrawable(background));
this.progressIndicator.setVisibility(View.GONE);
this.progressIndicator.setIndeterminate(true);
if (urlMode) {
@ -134,7 +144,7 @@ public class InstallerActivity extends CompatActivity {
this.runOnUiThread(() -> {
this.installerTerminal.addLine("- Installing " + name);
});
this.doInstall(moduleCache, noExtensions);
this.doInstall(moduleCache, noExtensions, rootless);
} catch (IOException e) {
Log.e(TAG, "Failed to download module zip", e);
this.setInstallStateFinished(false,
@ -144,19 +154,32 @@ public class InstallerActivity extends CompatActivity {
} else {
this.installerTerminal.addLine("- Installing " + name);
new Thread(() -> this.doInstall(
this.toDelete = new File(target), noExtensions),
this.toDelete = new File(target), noExtensions, rootless),
"Install Thread").start();
}
}
private void doInstall(File file,boolean noExtensions) {
private void doInstall(File file,boolean noExtensions,boolean rootless) {
Log.i(TAG, "Installing: " + moduleCache.getName());
InstallerController installerController = new InstallerController(
this.progressIndicator, this.installerTerminal,
file.getAbsoluteFile(), noExtensions);
InstallerMonitor installerMonitor;
Shell.Job installJob;
if (MainApplication.isUsingMagiskCommand() || noExtensions) {
if (rootless) { // rootless is only used for debugging
File installScript = this.extractInstallScript("module_installer_test.sh");
if (installScript == null) {
this.setInstallStateFinished(false,
"! Failed to extract test install script", "");
return;
}
installerMonitor = new InstallerMonitor(installScript);
installJob = Shell.sh("export MMM_EXT_SUPPORT=1",
"cd \"" + this.moduleCache.getAbsolutePath() + "\"",
"sh \"" + installScript.getAbsolutePath() + "\"" +
" /dev/null 1 \"" + file.getAbsolutePath() + "\"")
.to(installerController, installerMonitor);
} else if (MainApplication.isUsingMagiskCommand() || noExtensions) {
installerMonitor = new InstallerMonitor(new File(InstallerInitializer
.peekMagiskPath().equals("/sbin") ? "/sbin/magisk" : "/system/bin/magisk"));
if (noExtensions) {
@ -170,12 +193,13 @@ public class InstallerActivity extends CompatActivity {
"en-US" : Resources.getSystem()
.getConfiguration().locale.toLanguageTag()),
"export MMM_APP_VERSION=" + BuildConfig.VERSION_NAME,
"export MMM_TEXT_WRAP=" + (this.textWrap ? "1" : "0"),
"cd \"" + this.moduleCache.getAbsolutePath() + "\"",
"magisk --install-module \"" + file.getAbsolutePath() + "\"")
.to(installerController, installerMonitor);
}
} else {
File installScript = this.extractCompatScript();
File installScript = this.extractInstallScript("module_installer_compat.sh");
if (installScript == null) {
this.setInstallStateFinished(false,
"! Failed to extract module install script", "");
@ -187,6 +211,7 @@ public class InstallerActivity extends CompatActivity {
"en-US" : Resources.getSystem()
.getConfiguration().locale.toLanguageTag()),
"export MMM_APP_VERSION=" + BuildConfig.VERSION_NAME,
"export MMM_TEXT_WRAP=" + (this.textWrap ? "1" : "0"),
"cd \"" + this.moduleCache.getAbsolutePath() + "\"",
"sh \"" + installScript.getAbsolutePath() + "\"" +
" /dev/null 1 \"" + file.getAbsolutePath() + "\"")
@ -370,16 +395,16 @@ public class InstallerActivity extends CompatActivity {
private static boolean didExtract = false;
private File extractCompatScript() {
File compatInstallScript = new File(this.moduleCache, "module_installer_compat.sh");
private File extractInstallScript(String script) {
File compatInstallScript = new File(this.moduleCache, script);
if (!compatInstallScript.exists() || compatInstallScript.length() == 0 || !didExtract) {
try {
Files.write(compatInstallScript, Files.readAllBytes(
this.getAssets().open("module_installer_compat.sh")));
this.getAssets().open(script)));
didExtract = true;
} catch (IOException e) {
compatInstallScript.delete();
Log.e(TAG, "Failed to extract module_installer_compat.sh", e);
Log.e(TAG, "Failed to extract " + script, e);
return null;
}
}

@ -16,6 +16,7 @@ import android.widget.Toast;
import androidx.core.app.ActivityOptionsCompat;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
@ -88,6 +89,11 @@ public class IntentHelper {
}
public static void openInstaller(Context context, String url, String title, String config) {
openInstaller(context, url, title, config, false, false);
}
public static void openInstaller(Context context, String url, String title, String config,
boolean noPatch,boolean testDebug) {
try {
Intent intent = new Intent(context, InstallerActivity.class);
intent.setAction(Constants.INTENT_INSTALL_INTERNAL);
@ -96,6 +102,10 @@ public class IntentHelper {
intent.putExtra(Constants.EXTRA_INSTALL_NAME, title);
if (config != null && !config.isEmpty())
intent.putExtra(Constants.EXTRA_INSTALL_CONFIG, config);
if (noPatch)
intent.putExtra(Constants.EXTRA_INSTALL_NO_PATCH, true);
if (testDebug && BuildConfig.DEBUG)
intent.putExtra(Constants.EXTRA_INSTALL_TEST_ROOTLESS, true);
startActivity(context, intent, true);
} catch (ActivityNotFoundException e) {
Toast.makeText(context,
@ -158,6 +168,12 @@ public class IntentHelper {
@SuppressLint("SdCardPath")
public static void openFileTo(CompatActivity compatActivity, File destination,
OnFileReceivedCallback callback) {
File destinationFolder;
if (destination == null || (destinationFolder = destination.getParentFile()) == null ||
(!destinationFolder.isDirectory() && !destinationFolder.mkdirs())) {
callback.onReceived(destination, null, RESPONSE_ERROR);
return;
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT).setType("application/zip");
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M19,7v4H5.83l3.58,-3.59L8,6l-6,6 6,6 1.41,-1.41L5.83,13H21V7z"/>
</vector>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/install_terminal"
android:background="@null"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:indeterminate="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -75,8 +75,8 @@
禁用 Fox\'s Mmm 扩展, 这可以防止模块使用
终端扩展, 如果模块滥用 Fox\'s Mmm 的扩展, 这会有用
</string>
<string name="warp_text_pref">文字换行</string>
<string name="warp_text_desc">
<string name="wrap_text_pref">文字换行</string>
<string name="wrap_text_desc">
将文本换行至新行,而不是将所有文本放在同一行
</string>
<string name="repo_enabled">启用仓库</string>

@ -75,9 +75,10 @@
Disable Fox\'s Mmm extensions, this prevent modules from using
terminal extensions, useful if a module misuse Fox\'s Mmm extensions.
</string>
<string name="warp_text_pref">Warp text</string>
<string name="warp_text_desc">
Warp text to new line instead of putting all text on the same line
<string name="wrap_text_pref">Wrap text</string>
<string name="wrap_text_desc">
Wrap text to a new line instead of putting
all text on the same line when installing a module
</string>
<string name="repo_enabled">Repo enabled</string>
<string name="repo_disabled">Repo disabled</string>

@ -34,6 +34,14 @@
app:summary="@string/showcase_mode_desc"
app:singleLineTitle="false" />
<SwitchPreferenceCompat
app:defaultValue="false"
app:key="pref_wrap_text"
app:icon="@drawable/ic_baseline_keyboard_return_24"
app:title="@string/wrap_text_pref"
app:summary="@string/wrap_text_desc"
app:singleLineTitle="false" />
<SwitchPreferenceCompat
app:defaultValue="false"
app:key="pref_show_incompatible"

Loading…
Cancel
Save