Compare commits

...

52 Commits

Author SHA1 Message Date
topjohnwu
c840a30c30 Bump version 2018-02-13 06:16:24 +08:00
topjohnwu
ae5277a898 Fix multiusers conflicting 2018-02-13 06:05:20 +08:00
topjohnwu
bffa837825 Fix repackaging 2018-02-13 03:27:27 +08:00
topjohnwu
b9e7d0faea Add option to restore Magisk Manager after repackage 2018-02-13 03:22:41 +08:00
topjohnwu
860b08d9ed Add version code to downloaded upgrades 2018-02-13 01:22:43 +08:00
topjohnwu
691dc1d49e Update to libsu 1.1.0 with su I/O 2018-02-12 23:07:35 +08:00
topjohnwu
9d6886d367 Do not allow backups 2018-02-12 03:18:57 +08:00
Taras Korzhak
9589b68f5a Updated UK translation 2018-02-12 03:11:00 +08:00
Albert I
28d88af1af Update Indonesian translations
* Translate new strings
* Improve translation of several strings

Signed-off-by: Albert I <krascgq@outlook.co.id>
2018-02-12 03:10:44 +08:00
Vv2233Bb
8b5acd1849 Update for springs-lt 2018-02-12 03:10:32 +08:00
topjohnwu
33dc63a7fd Fix filenames 2018-02-12 03:09:38 +08:00
topjohnwu
d0a86385b7 Update console messages 2018-02-09 05:38:02 +08:00
topjohnwu
50a49e2c8c Prevent crashes on non rooted devices 2018-02-01 04:42:59 +08:00
topjohnwu
c60adb113e Fix strings 2018-01-31 23:11:31 +08:00
Vv2233Bb
aee015e8f6 Lithuanian translation update 2018-01-31 04:05:03 +08:00
Killer7Mod
bf6af29205 update translation to portuguese-BR 2018-01-31 04:04:48 +08:00
Primokorn
329905d472 Update FR strings.xml 2018-01-31 04:04:36 +08:00
Fatih Fırıncı
00d450d262 Update strings.xml 2018-01-31 04:04:20 +08:00
Jonas Schubert
2365d1bd20 Update german strings 2018-01-31 04:04:04 +08:00
linar10
5b385c18e5 Update strings.xml 2018-01-31 04:03:41 +08:00
Madis
98c0434ec0 Estonian updates 2018-01-31 04:03:23 +08:00
Oliver Cervera
f318d0a3bc Italian - Add fingerprint authentication
Italian translation update
* Add fingerprint authentication
2018-01-31 04:03:03 +08:00
AndroPlus
27f5b410c0 Update Japanese translation 2018-01-31 04:02:48 +08:00
topjohnwu
3f55be9676 Update the method to handle global su db 2018-01-31 04:00:11 +08:00
topjohnwu
b05d2d3a2d Rename module 2018-01-27 08:34:12 +08:00
topjohnwu
19af5f9e0b Remove JNI; use native Java zipadjust 2018-01-27 08:23:02 +08:00
topjohnwu
f37f330670 Update with latest :crypto 2018-01-27 00:17:43 +08:00
topjohnwu
40082d4571 Update to libsu 1.0.0 2018-01-25 18:43:30 +08:00
topjohnwu
00d655f346 Update proguard to minimize APK size 2018-01-23 05:04:59 +08:00
topjohnwu
821726e7c0 Switch to libsu 2018-01-21 06:07:24 +08:00
dark-basic #DarkBasic BasicHD
759e905c3c Update strings.xml
New Lines Added.
2018-01-13 05:58:07 +08:00
topjohnwu
8bf7e42913 Bump version 2018-01-13 05:53:11 +08:00
topjohnwu
0dcd073554 Fix crashes on Lollipop 2018-01-13 05:49:47 +08:00
YumeMichi
2fe35d578d Check fm before using it
* Prevent NPE on devices without fingerprint.
2018-01-13 04:53:19 +08:00
topjohnwu
8d139e156e Adjust proguard settings to prevent crash 2018-01-12 03:33:50 +08:00
topjohnwu
7c2849356a Bump version 2018-01-12 01:57:31 +08:00
topjohnwu
0025ffd1c0 Update Trad. Chinese translation 2018-01-12 01:57:09 +08:00
topjohnwu
2ef7146642 Add fingerprint authentication 2018-01-12 01:53:49 +08:00
Grammatopoulos Apostolos
1b27e69e40 Greek translation updates 2018-01-11 21:04:29 +08:00
topjohnwu
8e7b757efd Fix dtbo detection 2018-01-10 20:41:55 +08:00
Michael Cerne
1ab543cea1 Minor language changes 2018-01-10 19:13:04 +08:00
Vv2233Bb
a3f86903e4 Lithuanian translation 2018-01-10 19:12:30 +08:00
Mevlüt TOPÇU
c239c305ab Update strings.xml 2018-01-10 19:04:26 +08:00
topjohnwu
2e02af994e Bump version 2018-01-02 00:25:08 +08:00
topjohnwu
836d9afe17 Update scripts 2018-01-01 16:46:08 +08:00
topjohnwu
007a352742 Update Trad. Chinese translations 2018-01-01 16:45:50 +08:00
vvb2060
e526e5659e Update zh-rCN translation 2018-01-01 16:39:15 +08:00
Rikka
4a5227c7bf Fix bug in SuDatabaseHelper 2018-01-01 01:11:45 +08:00
AndroPlus-org
c2c151ec4c Update Japanese translation 2018-01-01 01:09:56 +08:00
Jonas Schubert
452096e7e4 Added missing german translations 2018-01-01 01:09:21 +08:00
linar10
50c2a9859e Update strings.xml 2018-01-01 01:09:02 +08:00
Oliver Cervera
677b667307 Add sorting repo by update time
Add translation for new repo strings
2018-01-01 01:08:52 +08:00
62 changed files with 1376 additions and 1528 deletions

View File

@@ -8,12 +8,8 @@ android {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion 27
versionCode 84
versionName "5.5.2"
ndk {
moduleName 'zipadjust'
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
versionCode 100
versionName "5.6.0"
javaCompileOptions {
annotationProcessorOptions {
argument('butterknife.debuggable', 'false')
@@ -36,11 +32,6 @@ android {
preDexLibraries true
javaMaxHeapSize "2g"
}
externalNativeBuild {
cmake {
path 'src/main/jni/CMakeLists.txt'
}
}
lintOptions {
disable 'MissingTranslation'
}
@@ -54,7 +45,8 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':crypto')
implementation project(':utils')
implementation 'com.github.topjohnwu:libsu:1.1.0'
implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.android.support:cardview-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'

7
proguard-rules.pro vendored
View File

@@ -20,5 +20,10 @@
-keepnames class ** { *; }
# BouncyCastle
-keep class org.bouncycastle.jcajce.provider.** { *; }
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; }
-keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; }
-keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; }
-dontwarn javax.naming.**
# Gson
-keepattributes Signature

View File

@@ -9,10 +9,11 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application
android:name=".MagiskManager"
android:allowBackup="true"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"

View File

@@ -1,4 +1,5 @@
### v5.5.2
- Support sorting online repos with last update
- Fix issue that advanced installation settings won't stick
- Prevent sudb crashing Magisk Manager
### v5.6.0
- Remove JNI requirement, Magisk Manager is now pure Java
- Update the method of handling su database, may fix the issue that root requests won't save
- Add the option to restore Magisk Manager after repackaging with random package name
- Massive under-the-hood optimizations

View File

@@ -16,9 +16,9 @@ import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.FlashZip;
import com.topjohnwu.magisk.asyncs.InstallMagisk;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.container.CallbackList;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell;
import java.io.File;
import java.io.FileWriter;
@@ -49,7 +49,7 @@ public class FlashActivity extends Activity {
@OnClick(R.id.reboot)
void reboot() {
Shell.su_raw("/system/bin/reboot");
Shell.Async.su("/system/bin/reboot");
}
@OnClick(R.id.save_logs)
@@ -96,10 +96,10 @@ public class FlashActivity extends Activity {
reboot.setVisibility(View.GONE);
logs = new ArrayList<>();
List<String> console = new CallbackList<String>() {
CallbackList<String> console = new CallbackList<String>(new ArrayList<>()) {
@Override
public synchronized void onAddElement(String e) {
logs.add(e);
public void onAddElement(String s) {
logs.add(s);
flashLogs.setText(TextUtils.join("\n", this));
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
}

View File

@@ -22,10 +22,10 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.ShowUI;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import butterknife.BindColor;
import butterknife.BindView;

View File

@@ -21,8 +21,9 @@ import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell;
import java.io.File;
import java.io.FileWriter;
@@ -113,12 +114,18 @@ public class MagiskLogFragment extends Fragment {
mode = (int) params[0];
switch (mode) {
case 0:
StringBuildingList logList = new StringBuildingList();
Shell.su(logList, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
return logList.getCharSequence();
StringBuilder builder = new StringBuilder();
CallbackList<String> logs = new CallbackList<String>() {
@Override
public void onAddElement(String s) {
builder.append(s).append('\n');
}
};
Shell.Sync.su(logs, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
return builder;
case 1:
Shell.su_raw("echo -n > " + Const.MAGISK_LOG);
Shell.Async.su("echo -n > " + Const.MAGISK_LOG);
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
return "";
@@ -138,8 +145,16 @@ public class MagiskLogFragment extends Fragment {
}
try (FileWriter out = new FileWriter(targetFile)) {
FileWritingList fileWritingList = new FileWritingList(out);
Shell.su(fileWritingList, "cat " + Const.MAGISK_LOG);
CallbackList<String> list = new CallbackList<String>() {
@Override
public void onAddElement(String s) {
try {
out.write(s);
out.write("\n");
} catch (IOException ignored) {}
}
};
Shell.Sync.su(list, "cat " + Const.MAGISK_LOG);
} catch (IOException e) {
e.printStackTrace();
return false;
@@ -187,41 +202,4 @@ public class MagiskLogFragment extends Fragment {
exec(2);
}
}
private static class StringBuildingList extends Shell.AbstractList<String> {
StringBuilder builder;
StringBuildingList() {
builder = new StringBuilder();
}
@Override
public boolean add(String s) {
builder.append(s).append("\n");
return true;
}
public CharSequence getCharSequence() {
return builder;
}
}
private static class FileWritingList extends Shell.AbstractList<String> {
private FileWriter writer;
FileWritingList(FileWriter out) {
writer = out;
}
@Override
public boolean add(String s) {
try {
writer.write(s + "\n");
} catch (IOException ignored) {}
return true;
}
}
}

View File

@@ -1,6 +1,5 @@
package com.topjohnwu.magisk;
import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -8,22 +7,28 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.BusyBox;
import com.topjohnwu.superuser.Shell;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class MagiskManager extends Application {
public class MagiskManager extends Shell.ContainerApp {
// Global weak reference to self
private static WeakReference<MagiskManager> weakSelf;
@@ -62,8 +67,6 @@ public class MagiskManager extends Application {
public boolean magiskHide;
public boolean isDarkTheme;
public boolean updateNotification;
public boolean suReauth;
public int suRequestTimeout;
public int suLogTimeout = 14;
public int suAccessState;
@@ -74,14 +77,12 @@ public class MagiskManager extends Application {
public String localeConfig;
public int updateChannel;
public String bootFormat;
public String customChannelUrl;
public int repoOrder;
// Global resources
public SharedPreferences prefs;
public SuDatabaseHelper suDB;
public RepoDatabaseHelper repoDB;
public Shell shell;
public Runnable permissionGrantCallback = null;
private static Handler mHandler = new Handler();
@@ -93,6 +94,24 @@ public class MagiskManager extends Application {
@Override
public void onCreate() {
super.onCreate();
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
Shell.verboseLogging(BuildConfig.DEBUG);
BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH);
Shell.setInitializer(new Shell.Initializer() {
@Override
public void onRootShellInit(@NonNull Shell shell) {
try (InputStream in = MagiskManager.get().getAssets().open(Const.UTIL_FUNCTIONS)) {
shell.loadInputStream(null, null, in);
} catch (IOException e) {
e.printStackTrace();
}
shell.run(null, null,
"mount_partitions",
"run_migrations");
}
});
prefs = PreferenceManager.getDefaultSharedPreferences(this);
// Handle duplicate package
@@ -106,7 +125,15 @@ public class MagiskManager extends Application {
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
}
suDB = SuDatabaseHelper.getSuDB(false);
suDB = SuDatabaseHelper.getInstance(this);
String pkg = suDB.getStrings(Const.Key.SU_REQUESTER, Const.ORIG_PKG_NAME);
if (getPackageName().equals(Const.ORIG_PKG_NAME) && !pkg.equals(Const.ORIG_PKG_NAME)) {
suDB.setStrings(Const.Key.SU_REQUESTER, null);
Utils.uninstallPkg(pkg);
suDB = SuDatabaseHelper.getInstance(this);
}
repoDB = new RepoDatabaseHelper(this);
defaultLocale = Locale.getDefault();
setLocale();
@@ -135,17 +162,14 @@ public class MagiskManager extends Application {
suRequestTimeout = Utils.getPrefsInt(prefs, Const.Key.SU_REQUEST_TIMEOUT, Const.Value.timeoutList[2]);
suResponseType = Utils.getPrefsInt(prefs, Const.Key.SU_AUTO_RESPONSE, Const.Value.SU_PROMPT);
suNotificationType = Utils.getPrefsInt(prefs, Const.Key.SU_NOTIFICATION, Const.Value.NOTIFICATION_TOAST);
suReauth = prefs.getBoolean(Const.Key.SU_REAUTH, false);
suAccessState = suDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB);
multiuserMode = suDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY);
suNamespaceMode = suDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER);
// config
isDarkTheme = prefs.getBoolean(Const.Key.DARK_THEME, false);
updateNotification = prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true);
updateChannel = Utils.getPrefsInt(prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL);
bootFormat = prefs.getString(Const.Key.BOOT_FORMAT, ".img");
customChannelUrl = prefs.getString(Const.Key.CUSTOM_CHANNEL, "");
repoOrder = prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_NAME);
}
@@ -153,10 +177,8 @@ public class MagiskManager extends Application {
prefs.edit()
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
.putBoolean(Const.Key.UPDATE_NOTIFICATION, updateNotification)
.putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE()))
.putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE))
.putBoolean(Const.Key.SU_REAUTH, suReauth)
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE().exists())
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
@@ -171,7 +193,7 @@ public class MagiskManager extends Application {
.apply();
}
public static void toast(String msg, int duration) {
public static void toast(CharSequence msg, int duration) {
mHandler.post(() -> Toast.makeText(weakSelf.get(), msg, duration).show());
}
@@ -180,69 +202,22 @@ public class MagiskManager extends Application {
}
public void loadMagiskInfo() {
List<String> ret;
ret = Shell.sh("magisk -v");
if (!Utils.isValidShellResponse(ret)) {
ret = Shell.sh("getprop magisk.version");
if (Utils.isValidShellResponse(ret)) {
try {
magiskVersionString = ret.get(0);
magiskVersionCode = (int) Double.parseDouble(ret.get(0)) * 10;
} catch (NumberFormatException ignored) {}
}
} else {
magiskVersionString = ret.get(0).split(":")[0];
ret = Shell.sh("magisk -V");
try {
magiskVersionCode = Integer.parseInt(ret.get(0));
} catch (NumberFormatException ignored) {}
}
if (magiskVersionCode > 1435) {
ret = Shell.su("resetprop -p " + Const.MAGISKHIDE_PROP);
} else {
ret = Shell.sh("getprop " + Const.MAGISKHIDE_PROP);
}
try {
magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0;
} catch (NumberFormatException e) {
magiskHide = true;
}
magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
magiskHide = s == null || Integer.parseInt(s) != 0;
} catch (Exception ignored) {}
ret = Shell.su("echo \"$BOOTIMAGE\"");
if (Utils.isValidShellResponse(ret))
bootBlock = ret.get(0);
if (suDB != null && !SuDatabaseHelper.verified) {
suDB.close();
suDB = SuDatabaseHelper.getSuDB(true);
}
bootBlock = Utils.cmd("echo \"$BOOTIMAGE\"");
}
public void getDefaultInstallFlags() {
List<String> ret;
ret = Shell.su("echo \"$DTBOIMAGE\"");
if (Utils.isValidShellResponse(ret))
keepVerity = true;
keepVerity = Boolean.parseBoolean(Utils.cmd("getvar KEEPVERITY; echo $KEEPVERITY")) ||
Utils.cmd("echo \"$DTBOIMAGE\"") != null;
ret = Shell.su(
"getvar KEEPVERITY",
"echo $KEEPVERITY");
try {
if (Utils.isValidShellResponse(ret))
keepVerity = Boolean.parseBoolean(ret.get(0));
} catch (NumberFormatException ignored) {}
ret = Shell.sh("getprop ro.crypto.state");
if (Utils.isValidShellResponse(ret) && ret.get(0).equals("encrypted"))
keepEnc = true;
ret = Shell.su(
"getvar KEEPFORCEENCRYPT",
"echo $KEEPFORCEENCRYPT");
try {
if (Utils.isValidShellResponse(ret))
keepEnc = Boolean.parseBoolean(ret.get(0));
} catch (NumberFormatException ignored) {}
keepEnc = Boolean.parseBoolean(Utils.cmd("getvar KEEPFORCEENCRYPT; echo $KEEPFORCEENCRYPT")) ||
TextUtils.equals("encrypted", Utils.cmd("getprop ro.crypto.state"));
}
public void setPermissionGrantCallback(Runnable callback) {

View File

@@ -19,9 +19,9 @@ import android.view.View;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -20,9 +20,9 @@ import com.topjohnwu.magisk.asyncs.LoadModules;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
import java.util.List;
@@ -113,16 +113,16 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.reboot:
Shell.su_raw("/system/bin/reboot");
Shell.Async.su("/system/bin/reboot");
return true;
case R.id.reboot_recovery:
Shell.su_raw("/system/bin/reboot recovery");
Shell.Async.su("/system/bin/reboot recovery");
return true;
case R.id.reboot_bootloader:
Shell.su_raw("/system/bin/reboot bootloader");
Shell.Async.su("/system/bin/reboot bootloader");
return true;
case R.id.reboot_download:
Shell.su_raw("/system/bin/reboot download");
Shell.Async.su("/system/bin/reboot download");
return true;
default:
return false;

View File

@@ -1,6 +1,7 @@
package com.topjohnwu.magisk;
import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
@@ -21,11 +22,14 @@ import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.asyncs.HideManager;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.io.IOException;
import java.util.Locale;
import butterknife.BindView;
@@ -97,6 +101,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
Preference hideManager = findPreference("hide");
Preference restoreManager = findPreference("restore");
findPreference("clear").setOnPreferenceClickListener((pref) -> {
prefs.edit().remove(Const.Key.ETAG_KEY).apply();
mm.repoDB.clearRepo();
@@ -112,13 +117,14 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
multiuserMode = (ListPreference) findPreference(Const.Key.SU_MULTIUSER_MODE);
namespaceMode = (ListPreference) findPreference(Const.Key.SU_MNT_NS);
SwitchPreference reauth = (SwitchPreference) findPreference(Const.Key.SU_REAUTH);
SwitchPreference fingerprint = (SwitchPreference) findPreference(Const.Key.SU_FINGERPRINT);
updateChannel.setOnPreferenceChangeListener((pref, o) -> {
mm.updateChannel = Integer.parseInt((String) o);
if (mm.updateChannel == Const.Value.CUSTOM_CHANNEL) {
View v = LayoutInflater.from(getActivity()).inflate(R.layout.custom_channel_dialog, null);
EditText url = v.findViewById(R.id.custom_url);
url.setText(mm.customChannelUrl);
url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
new AlertDialog.Builder(getActivity())
.setTitle(R.string.settings_update_custom)
.setView(v)
@@ -144,6 +150,43 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
reauth.setSummary(R.string.android_o_not_support);
}
// Remove fingerprint option if not possible
if (!FingerprintHelper.canUseFingerprint()) {
suCategory.removePreference(fingerprint);
}
if (mm.magiskVersionCode >= 1440) {
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
hideManager.setOnPreferenceClickListener((pref) -> {
Utils.runWithPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE,
() -> new HideManager(getActivity()).exec());
return true;
});
generalCatagory.removePreference(restoreManager);
} else {
if (Utils.checkNetworkStatus()) {
restoreManager.setOnPreferenceClickListener((pref) -> {
Utils.runWithPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> {
Intent intent = new Intent(mm, ManagerUpdate.class);
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
intent.putExtra(Const.Key.INTENT_SET_FILENAME,
Utils.fmt("MagiskManager-v%s(%d).apk",
mm.remoteManagerVersionString, mm.remoteManagerVersionCode));
mm.sendBroadcast(intent);
});
return true;
});
} else {
generalCatagory.removePreference(restoreManager);
}
generalCatagory.removePreference(hideManager);
}
} else {
generalCatagory.removePreference(restoreManager);
generalCatagory.removePreference(hideManager);
}
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME) && mm.magiskVersionCode >= 1440) {
hideManager.setOnPreferenceClickListener((pref) -> {
Utils.runWithPermission(getActivity(),
@@ -151,6 +194,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
() -> new HideManager(getActivity()).exec());
return true;
});
generalCatagory.removePreference(restoreManager);
} else {
generalCatagory.removePreference(hideManager);
}
@@ -216,26 +260,28 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
break;
case Const.Key.COREONLY:
if (prefs.getBoolean(key, false)) {
Utils.createFile(Const.MAGISK_DISABLE_FILE);
try {
Const.MAGISK_DISABLE_FILE.createNewFile();
} catch (IOException ignored) {}
} else {
Utils.removeItem(Const.MAGISK_DISABLE_FILE);
Const.MAGISK_DISABLE_FILE.delete();
}
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
break;
case Const.Key.MAGISKHIDE:
if (prefs.getBoolean(key, false)) {
Shell.su_raw("magiskhide --enable");
Shell.Async.su("magiskhide --enable");
} else {
Shell.su_raw("magiskhide --disable");
Shell.Async.su("magiskhide --disable");
}
break;
case Const.Key.HOSTS:
if (prefs.getBoolean(key, false)) {
Shell.su_raw(
Shell.Async.su(
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(),
"mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts");
} else {
Shell.su_raw(
Shell.Async.su(
"umount -l /system/etc/hosts",
"rm -f " + Const.MAGISK_HOST_FILE());
}

View File

@@ -17,8 +17,8 @@ import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class SplashActivity extends Activity {

View File

@@ -18,9 +18,9 @@ import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
import java.util.Collections;
@@ -81,10 +81,10 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
holder.checkBox.setChecked(mHideList.contains(info.packageName));
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
if (isChecked) {
Shell.su_raw("magiskhide --add " + info.packageName);
Shell.Async.su("magiskhide --add " + info.packageName);
mHideList.add(info.packageName);
} else {
Shell.su_raw("magiskhide --rm " + info.packageName);
Shell.Async.su("magiskhide --rm " + info.packageName);
mHideList.remove(info.packageName);
}
});
@@ -155,7 +155,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
}
Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
.compareTo(b.loadLabel(pm).toString().toLowerCase()));
mHideList = Shell.su("magiskhide --ls");
mHideList = Shell.Sync.su("magiskhide --ls");
return null;
}

View File

@@ -14,7 +14,7 @@ import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.superuser.Shell;
import java.util.List;

View File

@@ -4,9 +4,9 @@ import android.app.Activity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -32,13 +32,13 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
}
private void dlSnet() throws IOException {
Shell.sh("rm -rf " + dexPath.getParent());
Shell.Sync.sh("rm -rf " + dexPath.getParent());
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
dexPath.getParentFile().mkdir();
try (
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
InputStream in = new BufferedInputStream(conn.getInputStream())) {
Utils.inToOut(in, out);
ShellUtils.pump(in, out);
}
conn.disconnect();
}

View File

@@ -33,7 +33,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
jsonStr = WebService.getString(Const.Url.BETA_URL);
break;
case Const.Value.CUSTOM_CHANNEL:
jsonStr = WebService.getString(mm.customChannelUrl);
jsonStr = WebService.getString(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
break;
}
try {
@@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void v) {
MagiskManager mm = MagiskManager.get();
if (showNotification && mm.updateNotification) {
if (showNotification && mm.prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true)) {
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
ShowUI.managerUpdateNotification();
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {

View File

@@ -8,9 +8,10 @@ import android.view.View;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -38,8 +39,8 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
private boolean unzipAndCheck() throws Exception {
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script"));
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script"));
return s != null && s.contains("#MAGISK");
}
@Override
@@ -55,7 +56,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
) {
if (in == null) throw new FileNotFoundException();
InputStream buf= new BufferedInputStream(in);
Utils.inToOut(buf, out);
ShellUtils.pump(buf, out);
} catch (FileNotFoundException e) {
console.add("! Invalid Uri");
throw e;
@@ -65,7 +66,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
}
if (!unzipAndCheck()) return 0;
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
Shell.getShell().run(console, logs,
Shell.Sync.su(console, logs,
"cd " + mCachedFile.getParent(),
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
);
@@ -85,7 +86,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
@Override
protected void onPostExecute(Integer result) {
FlashActivity activity = (FlashActivity) getActivity();
Shell.su_raw(
Shell.Async.su(
"rm -rf " + mCachedFile.getParent(),
"rm -rf " + Const.TMP_FOLDER_PATH
);

View File

@@ -4,18 +4,18 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.widget.Toast;
import com.topjohnwu.crypto.JarMap;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.utils.JarMap;
import java.io.File;
import java.io.FileInputStream;
import java.security.SecureRandom;
import java.util.List;
import java.util.jar.JarEntry;
public class HideManager extends ParallelTask<Void, Void, Boolean> {
@@ -123,20 +123,20 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
apk.getOutputStream(je).write(xml);
// Sign the APK
ZipUtils.signZip(apk, repack, false);
ZipUtils.signZip(apk, repack);
} catch (Exception e) {
e.printStackTrace();
return false;
}
// Install the application
List<String> ret = Shell.su(Utils.fmt("pm install %s >/dev/null && echo true || echo false", repack));
repack.delete();
if (!Utils.isValidShellResponse(ret) || !Boolean.parseBoolean(ret.get(0)))
if (!ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack))
return false;
repack.delete();
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
mm.suDB.flush();
Utils.dumpPrefs();
Utils.uninstallPkg(Const.ORIG_PKG_NAME);

View File

@@ -1,20 +1,22 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import com.topjohnwu.crypto.SignBoot;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.container.TarEntry;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import com.topjohnwu.superuser.io.SuFileInputStream;
import com.topjohnwu.utils.SignBoot;
import org.kamranzafar.jtar.TarInputStream;
import org.kamranzafar.jtar.TarOutputStream;
@@ -28,7 +30,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -70,7 +71,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
mm.createDeviceProtectedStorageContext() :
mm).getFilesDir().getParent()
, "install");
Shell.sh_raw("rm -rf " + install);
Shell.Sync.sh("rm -rf " + install);
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
String arch;
@@ -102,17 +103,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
console.add("! Cannot unzip zip");
throw e;
}
Shell.sh("chmod 755 " + install + "/*");
Shell.Sync.sh("chmod 755 " + install + "/*");
File boot = new File(install, "boot.img");
boolean highCompression = false;
switch (mode) {
case PATCH_MODE:
console.add("- Use boot image: " + boot);
// Copy boot image to local
try (
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
OutputStream out = new FileOutputStream(boot)
try (InputStream in = mm.getContentResolver().openInputStream(mBootImg);
OutputStream out = new FileOutputStream(boot)
) {
InputStream source;
if (in == null) throw new FileNotFoundException();
@@ -130,7 +129,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
// Direct copy raw image
source = new BufferedInputStream(in);
}
Utils.inToOut(source, out);
ShellUtils.pump(source, out);
} catch (FileNotFoundException e) {
console.add("! Invalid Uri");
throw e;
@@ -140,21 +139,16 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
}
break;
case DIRECT_MODE:
console.add("- Use boot image: " + mBootLocation);
console.add("- Patch boot/ramdisk image: " + mBootLocation);
if (mm.remoteMagiskVersionCode >= 1463) {
List<String> ret = new ArrayList<>();
Shell.getShell().run(ret, logs,
install + "/magiskboot --parse " + mBootLocation,
"echo $?"
);
if (Utils.isValidShellResponse(ret)) {
highCompression = Integer.parseInt(ret.get(ret.size() - 1)) == 2;
if (highCompression)
console.add("! Insufficient boot partition size detected");
}
highCompression = Integer.parseInt(Utils.cmd(Utils.fmt(
"%s/magiskboot --parse %s; echo $?",
install, mBootLocation))) == 2;
if (highCompression)
console.add("! Insufficient boot partition size detected");
}
if (boot.createNewFile()) {
Shell.su("cat " + mBootLocation + " > " + boot);
Shell.Sync.su("cat " + mBootLocation + " > " + boot);
} else {
console.add("! Dump boot image failed");
return false;
@@ -168,22 +162,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
try (InputStream in = new FileInputStream(boot)) {
isSigned = SignBoot.verifySignature(in, null);
if (isSigned) {
console.add("- Signed boot image detected");
console.add("- Boot image is signed with AVB 1.0");
}
} catch (Exception e) {
console.add("! Unable to check signature");
throw e;
}
// Force non-root shell
Shell shell;
if (Shell.rootAccess())
shell = new Shell("sh");
else
shell = Shell.getShell();
// Patch boot image
shell.run(console, logs,
Shell.Sync.sh(console, logs,
"cd " + install,
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
@@ -192,27 +179,22 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
return false;
shell.run(null, null,
"mv -f new-boot.img ../",
Shell.Sync.sh("mv -f new-boot.img ../",
"mv bin/busybox busybox",
"rm -rf bin *.img update-binary",
"cd /");
File patched_boot = new File(install.getParent(), "new-boot.img");
SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
if (isSigned) {
console.add("- Signing boot image");
console.add("- Signing boot image with test keys");
File signed = new File(install.getParent(), "signed.img");
AssetManager assets = mm.getAssets();
try (
InputStream in = new FileInputStream(patched_boot);
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed));
InputStream keyIn = assets.open(Const.PRIVATE_KEY_NAME);
InputStream certIn = assets.open(Const.PUBLIC_KEY_NAME)
try (InputStream in = new SuFileInputStream(patched_boot);
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
) {
SignBoot.doSignature("/boot", in, out, keyIn, certIn);
SignBoot.doSignature("/boot", in, out, null, null);
}
shell.run_raw(false, false, "mv -f " + signed + " " + patched_boot);
Shell.Sync.sh("mv -f " + signed + " " + patched_boot);
}
switch (mode) {
@@ -230,8 +212,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
out = new BufferedOutputStream(new FileOutputStream(dest));
break;
}
try (InputStream in = new BufferedInputStream(new FileInputStream(patched_boot))) {
Utils.inToOut(in, out);
try (InputStream in = new SuFileInputStream(patched_boot)) {
ShellUtils.pump(in, out);
out.close();
}
console.add("");
@@ -242,7 +224,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
break;
case DIRECT_MODE:
String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
Shell.getShell().run(console, logs,
Shell.Sync.su(console, logs,
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),

View File

@@ -4,7 +4,7 @@ import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.container.ValueSortedMap;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.superuser.Shell;
import java.util.List;
@@ -12,7 +12,7 @@ public class LoadModules extends ParallelTask<Void, Void, Void> {
private List<String> getModList() {
String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found";
return Shell.su(command);
return Shell.Sync.su(command);
}
@Override

View File

@@ -6,8 +6,8 @@ import android.webkit.WebView;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.superuser.ShellUtils;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
@@ -44,7 +44,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
md = WebService.getString(mUrl);
} else {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Utils.inToOut(is, out);
ShellUtils.pump(is, out);
md = out.toString();
is.close();
} catch (IOException e) {
@@ -57,7 +57,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
InputStream in = mm.getAssets().open(mm.isDarkTheme ? "dark.css" : "light.css");
ByteArrayOutputStream out = new ByteArrayOutputStream()
) {
Utils.inToOut(in, out);
ShellUtils.pump(in, out);
css = out.toString();
} catch (IOException e) {
e.printStackTrace();

View File

@@ -13,10 +13,11 @@ import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -68,7 +69,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
continue;
}
out.putNextEntry(new JarEntry(path));
Utils.inToOut(in, out);
ShellUtils.pump(in, out);
}
}
}
@@ -107,7 +108,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
) {
Utils.inToOut(in, out);
ShellUtils.pump(in, out);
in.close();
}
conn.disconnect();
@@ -120,14 +121,8 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
// First remove top folder in Github source zip, temp1 -> temp2
removeTopFolder(temp1, temp2);
// Then sign the zip for the first time, temp2 -> temp1
ZipUtils.signZip(temp2, temp1, false);
// Adjust the zip to prevent unzip issues, temp1 -> temp2
ZipUtils.zipAdjust(temp1.getPath(), temp2.getPath());
// Finally, sign the whole zip file again, temp2 -> target
ZipUtils.signZip(temp2, mFile, true);
// Then sign the zip
ZipUtils.signZip(temp2, mFile);
// Delete temp files
temp1.delete();

View File

@@ -4,29 +4,24 @@ import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import java.util.List;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
String sha1;
List<String> ret = Utils.readFile("/.backup/.sha1");
if (Utils.isValidShellResponse(ret)) {
sha1 = ret.get(0);
} else {
ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1");
if (!Utils.isValidShellResponse(ret))
sha1 = Utils.cmd("cat /.backup/.sha1");
if (sha1 == null) {
sha1 = Utils.cmd("cat /init.magisk.rc | grep STOCKSHA1");
if (sha1 == null)
return false;
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
sha1 = sha1.substring(sha1.indexOf('=') + 1);
}
ret = Shell.su("restore_imgs " + sha1 + " && echo true || echo false");
return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1));
return ShellUtils.fastCmdResult(Shell.getShell(), "restore_imgs " + sha1);
}
@Override

View File

@@ -1,22 +0,0 @@
package com.topjohnwu.magisk.container;
import android.os.Handler;
import java.util.ArrayList;
public abstract class CallbackList<E> extends ArrayList<E> {
private Handler handler;
protected CallbackList() {
handler = new Handler();
}
public abstract void onAddElement(E e);
public synchronized boolean add(E e) {
boolean ret = super.add(e);
handler.post(() -> onAddElement(e));
return ret;
}
}

View File

@@ -1,21 +1,24 @@
package com.topjohnwu.magisk.container;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.io.SuFile;
import java.io.IOException;
public class Module extends BaseModule {
private String mRemoveFile, mDisableFile, mUpdateFile;
private SuFile mRemoveFile, mDisableFile, mUpdateFile;
private boolean mEnable, mRemove, mUpdated;
public Module(String path) {
try {
parseProps(Utils.readFile(path + "/module.prop"));
parseProps(Shell.Sync.su("cat " + path + "/module.prop"));
} catch (NumberFormatException ignored) {}
mRemoveFile = path + "/remove";
mDisableFile = path + "/disable";
mUpdateFile = path + "/update";
mRemoveFile = new SuFile(path + "/remove", true);
mDisableFile = new SuFile(path + "/disable", true);
mUpdateFile = new SuFile(path + "/update", true);
if (getId() == null) {
int sep = path.lastIndexOf('/');
@@ -26,19 +29,21 @@ public class Module extends BaseModule {
setName(getId());
}
mEnable = !Utils.itemExist(mDisableFile);
mRemove = Utils.itemExist(mRemoveFile);
mUpdated = Utils.itemExist(mUpdateFile);
mEnable = !mDisableFile.exists();
mRemove = mRemoveFile.exists();
mUpdated = mUpdateFile.exists();
}
public void createDisableFile() {
mEnable = false;
Utils.createFile(mDisableFile);
try {
mDisableFile.createNewFile();
} catch (IOException ignored) {}
}
public void removeDisableFile() {
mEnable = true;
Utils.removeItem(mDisableFile);
mDisableFile.delete();
}
public boolean isEnabled() {
@@ -47,12 +52,14 @@ public class Module extends BaseModule {
public void createRemoveFile() {
mRemove = true;
Utils.createFile(mRemoveFile);
try {
mRemoveFile.createNewFile();
} catch (IOException ignored) {}
}
public void deleteRemoveFile() {
mRemove = false;
Utils.removeItem(mRemoveFile);
mRemoveFile.delete();
}
public boolean willBeRemoved() {

View File

@@ -5,8 +5,8 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.os.Process;
import android.text.TextUtils;
import android.widget.Toast;
@@ -15,8 +15,8 @@ import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.io.File;
import java.text.DateFormat;
@@ -25,142 +25,104 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
public class SuDatabaseHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "su.db";
public static boolean verified = false;
public class SuDatabaseHelper {
private static final int DATABASE_VER = 5;
private static final String POLICY_TABLE = "policies";
private static final String LOG_TABLE = "logs";
private static final String SETTINGS_TABLE = "settings";
private static final String STRINGS_TABLE = "strings";
private static final File GLOBAL_DB = new File("/data/adb/magisk.db");
private Context mContext;
private PackageManager pm;
private SQLiteDatabase mDb;
private File DB_FILE;
private static void unmntDB() {
Shell.su(Utils.fmt("umount -l /data/user*/*/%s/*/*.db", MagiskManager.get().getPackageName()));
}
private static Context initDB(boolean verify) {
Context context, de = null;
MagiskManager ce = MagiskManager.get();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
de = ce.createDeviceProtectedStorageContext();
File ceDB = Utils.getDB(ce, DB_NAME);
if (ceDB.exists()) {
context = ce;
} else {
context = de;
}
} else {
context = ce;
}
File db = Utils.getDB(context, DB_NAME);
if (!verify) {
if (db.exists() && db.length() == 0) {
ce.loadMagiskInfo();
// Continue verification
} else {
return context;
}
}
// Encryption storage
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (ce.magiskVersionCode < 1410) {
if (context == de) {
unmntDB();
ce.moveDatabaseFrom(de, DB_NAME);
context = ce;
}
} else {
if (context == ce) {
unmntDB();
de.moveDatabaseFrom(ce, DB_NAME);
context = de;
}
}
}
// Context might be updated
db = Utils.getDB(context, DB_NAME);
if (!Shell.rootAccess())
return context;
// Verify the global db matches the local with the same inode
if (ce.magiskVersionCode >= 1450 && ce.magiskVersionCode < 1460) {
// v14.5 global su db
File OLD_GLOBAL_DB = new File(context.getFilesDir().getParentFile().getParentFile(), "magisk.db");
verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db));
if (!verified) {
context.deleteDatabase(DB_NAME);
db.getParentFile().mkdirs();
Shell.su(Utils.fmt("magisk --clone-attr %s %s; chmod 600 %s; ln %s %s",
context.getFilesDir(), OLD_GLOBAL_DB, OLD_GLOBAL_DB, OLD_GLOBAL_DB, db));
verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db));
}
} else if (ce.magiskVersionCode >= 1464) {
// New global su db
Shell.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent()));
if (!Utils.itemExist(GLOBAL_DB)) {
context.openOrCreateDatabase(DB_NAME, 0, null).close();
Shell.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db));
}
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
if (!verified) {
context.deleteDatabase(DB_NAME);
Utils.javaCreateFile(db);
Shell.su(Utils.fmt(
"chown 0.0 %s; chmod 666 %s; chcon u:object_r:su_file:s0 %s;" +
"mount -o bind %s %s",
GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, db));
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
}
}
return context;
}
public static SuDatabaseHelper getSuDB(boolean verify) {
public static SuDatabaseHelper getInstance(MagiskManager mm) {
try {
return new SuDatabaseHelper(initDB(verify));
} catch(Exception e) {
// Try to catch runtime exceptions and remove all db for retry
unmntDB();
Shell.su(Utils.fmt("rm -rf /data/user*/*/magisk.db /data/adb/magisk.db /data/user*/*/%s/databases"),
MagiskManager.get().getPackageName());
e.printStackTrace();
return new SuDatabaseHelper(initDB(false));
return new SuDatabaseHelper(mm);
} catch (Exception e) {
// Let's cleanup everything and try again
cleanup("*");
return new SuDatabaseHelper(mm);
}
}
private SuDatabaseHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VER);
mContext = context;
pm = context.getPackageManager();
mDb = getWritableDatabase();
cleanup();
public static void cleanup() {
cleanup(String.valueOf(Const.USER_ID));
}
if (context.getPackageName().equals(Const.ORIG_PKG_NAME)) {
String pkg = getStrings(Const.Key.SU_REQUESTER, null);
if (pkg != null) {
Utils.uninstallPkg(pkg);
setStrings(Const.Key.SU_REQUESTER, null);
public static void cleanup(String s) {
Shell.Sync.su(
"umount -l /data/user*/*/*/databases/su.db",
"umount -l /sbin/.core/db-" + s + "/magisk.db",
"rm -rf /sbin/.core/db-" + s);
}
private SuDatabaseHelper(MagiskManager mm) {
pm = mm.getPackageManager();
mDb = openDatabase(mm);
int version = mDb.getVersion();
if (version < DATABASE_VER) {
onUpgrade(mDb, version);
} else if (version > DATABASE_VER) {
onDowngrade(mDb);
}
mDb.setVersion(DATABASE_VER);
clearOutdated();
}
private SQLiteDatabase openDatabase(MagiskManager mm) {
String GLOBAL_DB = "/data/adb/magisk.db";
DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? mm.createDeviceProtectedStorageContext() : mm;
if (!DB_FILE.exists()) {
if (!Shell.rootAccess()) {
// We don't want the app to crash, create a db and return
DB_FILE = mm.getDatabasePath("su.db");
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
}
mm.loadMagiskInfo();
// Cleanup
cleanup();
if (mm.magiskVersionCode < 1410) {
// Super old legacy mode
DB_FILE = mm.getDatabasePath("su.db");
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else if (mm.magiskVersionCode < 1450) {
// Legacy mode with FBE aware
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
de.moveDatabaseFrom(mm, "su.db");
}
DB_FILE = de.getDatabasePath("su.db");
return de.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else {
mm.deleteDatabase("su.db");
de.deleteDatabase("su.db");
if (mm.magiskVersionCode < 1460) {
// v14.5 global DB location
GLOBAL_DB = new File(de.getFilesDir().getParentFile().getParentFile(),
"magisk.db").getPath();
// We need some additional policies on old versions
Shell.Sync.su("magiskpolicy --live 'create su_file' 'allow * su_file file *'");
}
// Touch global DB and setup db in tmpfs
Shell.Sync.su(Utils.fmt("touch %s; mkdir -p %s; touch %s; touch %s-journal;" +
"mount -o bind %s %s;" +
"chcon u:object_r:su_file:s0 %s/*; chown %d.%d %s;" +
"chmod 666 %s/*; chmod 700 %s;",
GLOBAL_DB, DB_FILE.getParent(), DB_FILE, DB_FILE,
GLOBAL_DB, DB_FILE,
DB_FILE.getParent(), Process.myUid(), Process.myUid(), DB_FILE.getParent(),
DB_FILE.getParent(), DB_FILE.getParent()
));
}
}
// Not using legacy mode, open the mounted global DB
return SQLiteDatabase.openOrCreateDatabase(DB_FILE, null);
}
@Override
public void onCreate(SQLiteDatabase db) {
onUpgrade(db, 0, DATABASE_VER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
public void onUpgrade(SQLiteDatabase db, int oldVersion) {
try {
if (oldVersion == 0) {
createTables(db);
@@ -196,23 +158,18 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
}
} catch (Exception e) {
e.printStackTrace();
onDowngrade(db, DATABASE_VER, 0);
onDowngrade(db);
}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Remove everything, we do not support downgrade
public void onDowngrade(SQLiteDatabase db) {
MagiskManager.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG);
// Remove everything, we do not support downgrade
db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + SETTINGS_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + STRINGS_TABLE);
onUpgrade(db, 0, DATABASE_VER);
}
public File getDbFile() {
return mContext.getDatabasePath(DB_NAME);
onUpgrade(db, 0);
}
private void createTables(SQLiteDatabase db) {
@@ -235,7 +192,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
"(key TEXT, value INT, PRIMARY KEY(key))");
}
public void cleanup() {
public void clearOutdated() {
// Clear outdated policies
mDb.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
// Clear outdated logs
@@ -363,4 +320,9 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
}
return value;
}
public void flush() {
mDb.close();
mDb = SQLiteDatabase.openOrCreateDatabase(DB_FILE, null);
}
}

View File

@@ -40,7 +40,7 @@ public class ManagerUpdate extends BroadcastReceiver {
}
},
intent.getStringExtra(Const.Key.INTENT_SET_LINK),
Utils.fmt("MagiskManager-v%s.apk", intent.getStringExtra(Const.Key.INTENT_SET_VERSION))
intent.getStringExtra(Const.Key.INTENT_SET_FILENAME)
);
}
}

View File

@@ -5,8 +5,9 @@ import android.content.Context;
import android.content.Intent;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class PackageReceiver extends BroadcastReceiver {
@Override
@@ -18,13 +19,13 @@ public class PackageReceiver extends BroadcastReceiver {
switch (intent.getAction()) {
case Intent.ACTION_PACKAGE_REPLACED:
// This will only work pre-O
if (mm.suReauth) {
if (mm.prefs.getBoolean(Const.Key.SU_REAUTH, false)) {
mm.suDB.deletePolicy(pkg);
}
break;
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
mm.suDB.deletePolicy(pkg);
Shell.su_raw("magiskhide --rm " + pkg);
Shell.Async.su("magiskhide --rm " + pkg);
break;
}
}

View File

@@ -4,11 +4,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.superuser.Shell;
public class RebootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Shell.su_raw("/system/bin/reboot");
Shell.Async.su("/system/bin/reboot");
}
}

View File

@@ -8,8 +8,8 @@ import android.support.v4.app.NotificationCompat;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class OnBootIntentService extends IntentService {
@@ -41,6 +41,7 @@ public class OnBootIntentService extends IntentService {
* */
MagiskManager mm = Utils.getMagiskManager(this);
mm.loadMagiskInfo();
mm.getDefaultInstallFlags();
if (Shell.rootAccess()) {
Utils.patchDTBO();
}

View File

@@ -3,12 +3,14 @@ package com.topjohnwu.magisk.superuser;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.FileObserver;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
@@ -23,6 +25,7 @@ import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Utils;
import java.io.DataInputStream;
@@ -40,6 +43,8 @@ public class RequestActivity extends Activity {
@BindView(R.id.package_name) TextView packageNameView;
@BindView(R.id.grant_btn) Button grant_btn;
@BindView(R.id.deny_btn) Button deny_btn;
@BindView(R.id.fingerprint) ImageView fingerprintImg;
@BindView(R.id.warning) TextView warning;
private String socketPath;
private LocalSocket socket;
@@ -49,6 +54,7 @@ public class RequestActivity extends Activity {
private boolean hasTimeout;
private Policy policy;
private CountDownTimer timer;
private FingerprintHelper fingerprintHelper;
@Override
public int getDarkTheme() {
@@ -62,7 +68,7 @@ public class RequestActivity extends Activity {
pm = getPackageManager();
mm = Utils.getMagiskManager(this);
mm.suDB.cleanup();
mm.suDB.clearOutdated();
Intent intent = getIntent();
socketPath = intent.getStringExtra("socket");
@@ -80,6 +86,15 @@ public class RequestActivity extends Activity {
new SocketManager(this).exec();
}
@Override
public void finish() {
if (timer != null)
timer.cancel();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
super.finish();
}
private boolean cancelTimeout() {
timer.cancel();
deny_btn.setText(getString(R.string.deny));
@@ -128,11 +143,49 @@ public class RequestActivity extends Activity {
}
};
grant_btn.setOnClickListener(v -> {
handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
boolean useFingerprint = mm.prefs.getBoolean(Const.Key.SU_FINGERPRINT, false) && FingerprintHelper.canUseFingerprint();
if (useFingerprint) {
try {
fingerprintHelper = new FingerprintHelper() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
warning.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
warning.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
handleAction(Policy.ALLOW);
}
@Override
public void onAuthenticationFailed() {
warning.setText(R.string.auth_fail);
}
};
fingerprintHelper.startAuth();
} catch (Exception e) {
e.printStackTrace();
useFingerprint = false;
}
}
if (!useFingerprint) {
grant_btn.setOnClickListener(v -> {
handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
}
grant_btn.setVisibility(useFingerprint ? View.GONE : View.VISIBLE);
fingerprintImg.setVisibility(useFingerprint ? View.VISIBLE : View.GONE);
deny_btn.setOnClickListener(v -> {
handleAction(Policy.DENY);
timer.cancel();
@@ -151,8 +204,9 @@ public class RequestActivity extends Activity {
public void onBackPressed() {
if (policy != null) {
handleAction(Policy.DENY);
} else {
finish();
}
finish();
}
void handleAction() {

View File

@@ -2,12 +2,10 @@ package com.topjohnwu.magisk.utils;
import android.support.annotation.Keep;
import com.topjohnwu.crypto.SignBoot;
import com.topjohnwu.utils.SignBoot;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class BootSigner {
@@ -15,30 +13,23 @@ public class BootSigner {
public static void main(String[] args) throws Exception {
if (args.length > 0 && "-verify".equals(args[0])) {
String certPath = "";
if (args.length >= 3 && "-certificate".equals(args[1])) {
/* args[2] is the path to a public key certificate */
certPath = args[2];
if (args.length >= 2) {
/* args[1] is the path to a public key certificate */
certPath = args[1];
}
/* args[1] is the path to a signed boot image */
boolean signed = SignBoot.verifySignature(System.in,
certPath.isEmpty() ? null : new FileInputStream(certPath));
System.exit(signed ? 0 : 1);
} else if (args.length > 0 && "-sign".equals(args[0])) {
InputStream keyIn, certIn;
if (args.length >= 3) {
keyIn = new FileInputStream(args[1]);
certIn = new FileInputStream(args[2]);
} else {
/* Use internal test keys */
JarFile apk = new JarFile(System.getProperty("java.class.path"));
JarEntry keyEntry = apk.getJarEntry("assets/" + Const.PRIVATE_KEY_NAME);
JarEntry sigEntry = apk.getJarEntry("assets/" + Const.PUBLIC_KEY_NAME);
InputStream cert = null;
InputStream key = null;
keyIn = apk.getInputStream(keyEntry);
certIn = apk.getInputStream(sigEntry);
if (args.length >= 3) {
cert = new FileInputStream(args[1]);
key = new FileInputStream(args[2]);
}
boolean success = SignBoot.doSignature("/boot", System.in, System.out, keyIn, certIn);
boolean success = SignBoot.doSignature("/boot", System.in, System.out, cert, key);
System.exit(success ? 0 : 1);
} else {
System.err.println(
@@ -48,8 +39,8 @@ public class BootSigner {
"Actions:\n" +
" -verify [x509.pem]\n" +
" verify image, cert is optional\n" +
" -sign [pk8] [x509.pem]\n" +
" sign image, key and cert are optional\n"
" -sign [x509.pem] [pk8]\n" +
" sign image, cert and key pair is optional\n"
);
}
}

View File

@@ -4,6 +4,7 @@ import android.os.Environment;
import android.os.Process;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.superuser.io.SuFile;
import java.io.File;
import java.util.Arrays;
@@ -17,14 +18,16 @@ public class Const {
public static final String MAGISKHIDE_PROP = "persist.magisk.hide";
// APK content
public static final String PUBLIC_KEY_NAME = "public.certificate.x509.pem";
public static final String PRIVATE_KEY_NAME = "private.key.pk8";
public static final String UNINSTALLER = "magisk_uninstaller.sh";
public static final String UTIL_FUNCTIONS= "util_functions.sh";
public static final String ANDROID_MANIFEST = "AndroidManifest.xml";
public static final String SU_KEYSTORE_KEY = "su_key";
// Paths
public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk";
private static SuFile MAGISK_PATH = null;
public static final SuFile MAGISK_DISABLE_FILE = new SuFile("/cache/.disable_magisk", true);
public static final String BUSYBOX_PATH = "/sbin/.core/busybox";
public static final String TMP_FOLDER_PATH = "/dev/tmp";
public static final String MAGISK_LOG = "/cache/magisk.log";
public static final File EXTERNAL_PATH = new File(Environment.getExternalStorageDirectory(), "MagiskManager");
@@ -35,26 +38,23 @@ public class Const {
public static final int SNET_VER = 7;
public static final int MIN_MODULE_VER = 1400;
public static String BUSYBOX_PATH() {
if (Utils.itemExist("/sbin/.core/busybox/busybox")) {
return "/sbin/.core/busybox";
} else {
return "/dev/magisk/bin";
public synchronized static SuFile MAGISK_PATH() {
SuFile file;
if (MAGISK_PATH == null) {
file = new SuFile("/sbin/.core/img", true);
if (file.exists()) {
MAGISK_PATH = file;
} else if ((file = new SuFile("/dev/magisk/img", true)).exists()) {
MAGISK_PATH = file;
} else {
MAGISK_PATH = new SuFile("/magisk", true);
}
}
return MAGISK_PATH;
}
public static String MAGISK_PATH() {
if (Utils.itemExist("/sbin/.core/img")) {
return "/sbin/.core/img";
} else if (Utils.itemExist("/dev/magisk/img")) {
return "/dev/magisk/img";
} else {
return "/magisk";
}
}
public static String MAGISK_HOST_FILE() {
return MAGISK_PATH() + "/.core/hosts";
public static SuFile MAGISK_HOST_FILE() {
return new SuFile(MAGISK_PATH() + "/.core/hosts");
}
/* A list of apps that should not be shown as hide-able */
@@ -109,10 +109,11 @@ public class Const {
public static final String SU_AUTO_RESPONSE = "su_auto_response";
public static final String SU_NOTIFICATION = "su_notification";
public static final String SU_REAUTH = "su_reauth";
public static final String SU_FINGERPRINT = "su_fingerprint";
// intents
public static final String OPEN_SECTION = "section";
public static final String INTENT_SET_VERSION = "version";
public static final String INTENT_SET_FILENAME = "filename";
public static final String INTENT_SET_LINK = "link";
public static final String INTENT_PERM = "perm_dialog";
public static final String FLASH_ACTION = "action";

View File

@@ -0,0 +1,112 @@
package com.topjohnwu.magisk.utils;
import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import com.topjohnwu.magisk.MagiskManager;
import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@TargetApi(Build.VERSION_CODES.M)
public abstract class FingerprintHelper {
private FingerprintManager manager;
private Cipher cipher;
private CancellationSignal cancel;
public static boolean canUseFingerprint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
return false;
MagiskManager mm = MagiskManager.get();
KeyguardManager km = mm.getSystemService(KeyguardManager.class);
FingerprintManager fm = mm.getSystemService(FingerprintManager.class);
return km.isKeyguardSecure() && fm != null && fm.isHardwareDetected() && fm.hasEnrolledFingerprints();
}
protected FingerprintHelper() throws Exception {
MagiskManager mm = MagiskManager.get();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
manager = mm.getSystemService(FingerprintManager.class);
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(Const.SU_KEYSTORE_KEY, null);
if (key == null) {
key = generateKey();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (KeyPermanentlyInvalidatedException e) {
// Only happens on Marshmallow
key = generateKey();
cipher.init(Cipher.ENCRYPT_MODE, key);
}
}
public abstract void onAuthenticationError(int errorCode, CharSequence errString);
public abstract void onAuthenticationHelp(int helpCode, CharSequence helpString);
public abstract void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result);
public abstract void onAuthenticationFailed();
public void startAuth() {
cancel = new CancellationSignal();
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
manager.authenticate(cryptoObject, cancel, 0, new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
FingerprintHelper.this.onAuthenticationError(errorCode, errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
FingerprintHelper.this.onAuthenticationHelp(helpCode, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
FingerprintHelper.this.onAuthenticationSucceeded(result);
}
@Override
public void onAuthenticationFailed() {
FingerprintHelper.this.onAuthenticationFailed();
}
}, null);
}
public void cancel() {
if (cancel != null)
cancel.cancel();
}
private SecretKey generateKey() throws Exception {
KeyGenerator keygen = KeyGenerator
.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
Const.SU_KEYSTORE_KEY,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setInvalidatedByBiometricEnrollment(false);
}
keygen.init(builder.build());
return keygen.generateKey();
}
}

View File

@@ -1,210 +0,0 @@
package com.topjohnwu.magisk.utils;
import android.text.TextUtils;
import com.topjohnwu.magisk.MagiskManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Modified by topjohnwu, based on Chainfire's libsuperuser
*/
public class Shell {
// -2 = not initialized; -1 = no shell; 0 = non root shell; 1 = root shell
public static int status = -2;
private final Process process;
private final OutputStream STDIN;
private final InputStream STDOUT;
private final InputStream STDERR;
private static void testRootShell(Shell shell) throws IOException {
shell.STDIN.write(("id\n").getBytes("UTF-8"));
shell.STDIN.flush();
String s = new BufferedReader(new InputStreamReader(shell.STDOUT)).readLine();
if (TextUtils.isEmpty(s) || !s.contains("uid=0")) {
shell.STDIN.close();
shell.STDIN.close();
throw new IOException();
}
}
public Shell(String command) throws IOException {
process = Runtime.getRuntime().exec(command);
STDIN = process.getOutputStream();
STDOUT = process.getInputStream();
STDERR = process.getErrorStream();
}
public static Shell getShell() {
MagiskManager mm = MagiskManager.get();
boolean needNewShell = mm.shell == null;
if (!needNewShell) {
try {
mm.shell.process.exitValue();
// The process is dead
needNewShell = true;
} catch (IllegalThreadStateException ignored) {
// This should be the expected result
}
}
if (needNewShell) {
status = 1;
try {
mm.shell = new Shell("su --mount-master");
testRootShell(mm.shell);
} catch (IOException e) {
// Mount master not implemented
try {
mm.shell = new Shell("su");
testRootShell(mm.shell);
} catch (IOException e1) {
// No root exists
status = 0;
try {
mm.shell = new Shell("sh");
} catch (IOException e2) {
status = -1;
return null;
}
}
}
if (rootAccess()) {
// Load utility shell scripts
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
mm.shell.loadInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
// Root shell initialization
String bbpath = Const.BUSYBOX_PATH();
mm.shell.run_raw(false, false,
"export PATH=" + bbpath + ":$PATH",
"mount_partitions",
"find_boot_image",
"find_dtbo_image",
"migrate_boot_backup");
}
}
return mm.shell;
}
public static boolean rootAccess() {
if (status == -2) getShell();
return status > 0;
}
public void run(Collection<String> output, Collection<String> error, String... commands) {
StreamGobbler out, err;
synchronized (process) {
try {
out = new StreamGobbler(STDOUT, output);
err = new StreamGobbler(STDERR, error);
out.start();
err.start();
run_raw(output != null, error != null, commands);
STDIN.write("echo \'-shell-done-\'\necho \'-shell-done-\' >&2\n".getBytes("UTF-8"));
STDIN.flush();
try {
out.join();
err.join();
} catch (InterruptedException ignored) {}
} catch (IOException e) {
e.printStackTrace();
process.destroy();
}
}
}
public void run_raw(boolean stdout, boolean stderr, String... commands) {
String suffix = "\n";
if (!stderr) suffix = " 2>/dev/null" + suffix;
if (!stdout) suffix = " >/dev/null" + suffix;
synchronized (process) {
try {
for (String command : commands) {
Logger.shell(true, command);
STDIN.write((command + suffix).getBytes("UTF-8"));
STDIN.flush();
}
} catch (IOException e) {
e.printStackTrace();
process.destroy();
}
}
}
public void loadInputStream(InputStream in) {
synchronized (process) {
try {
Utils.inToOut(in, STDIN);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static List<String> sh(String... commands) {
List<String> res = new ArrayList<>();
sh(res, commands);
return res;
}
public static void sh(Collection<String> output, String... commands) {
Shell shell = getShell();
if (shell == null)
return;
shell.run(output, null, commands);
}
public static void sh_raw(String... commands) {
Shell shell = getShell();
if (shell == null)
return;
shell.run_raw(false, false, commands);
}
public static List<String> su(String... commands) {
if (!rootAccess()) return sh();
return sh(commands);
}
public static void su(Collection<String> output, String... commands) {
if (!rootAccess()) return;
sh(output, commands);
}
public static void su_raw(String... commands) {
if (!rootAccess()) return;
sh_raw(commands);
}
public static abstract class AbstractList<E> extends java.util.AbstractList<E> {
@Override
public abstract boolean add(E e);
@Override
public E get(int i) {
return null;
}
@Override
public int size() {
return 0;
}
}
}

View File

@@ -22,6 +22,8 @@ import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.receivers.RebootReceiver;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -57,10 +59,12 @@ public class ShowUI {
public static void managerUpdateNotification() {
MagiskManager mm = MagiskManager.get();
String filename = Utils.fmt("MagiskManager-v%s(%d).apk",
mm.remoteManagerVersionString, mm.remoteManagerVersionCode);
Intent intent = new Intent(mm, ManagerUpdate.class);
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
intent.putExtra(Const.Key.INTENT_SET_VERSION, mm.remoteManagerVersionString);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -98,7 +102,8 @@ public class ShowUI {
public static void magiskInstallDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
String filename = Utils.fmt("Magisk-v%s.zip", mm.remoteMagiskVersionString);
String filename = Utils.fmt("Magisk-v%s(%d).zip",
mm.remoteMagiskVersionString, mm.remoteMagiskVersionCode);
new AlertDialogBuilder(activity)
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.magisk)))
.setMessage(mm.getString(R.string.repo_install_msg, filename))
@@ -110,11 +115,11 @@ public class ShowUI {
if (Shell.rootAccess()) {
options.add(mm.getString(R.string.direct_install));
}
List<String> res = Shell.su("echo $SLOT");
if (Utils.isValidShellResponse(res)) {
String s = Utils.cmd("echo $SLOT");
if (s != null) {
options.add(mm.getString(R.string.install_second_slot));
}
char[] slot = Utils.isValidShellResponse(res) ? res.get(0).toCharArray() : null;
char[] slot = s == null ? null : s.toCharArray();
new AlertDialog.Builder(activity)
.setTitle(R.string.select_method)
.setItems(
@@ -184,13 +189,12 @@ public class ShowUI {
if (slot[1] == 'a') slot[1] = 'b';
else slot[1] = 'a';
// Then find the boot image again
List<String> ret = Shell.su(
"SLOT=" + String.valueOf(slot),
"find_boot_image",
boot = Utils.cmd(
"SLOT=" + String.valueOf(slot) +
"; find_boot_image;" +
"echo \"$BOOTIMAGE\""
);
boot = Utils.isValidShellResponse(ret) ? ret.get(ret.size() - 1) : null;
Shell.su_raw("mount_partitions");
Shell.Async.su("mount_partitions");
if (boot == null)
return;
receiver = new DownloadReceiver() {
@@ -205,12 +209,7 @@ public class ShowUI {
};
default:
}
Utils.dlAndReceive(
activity,
receiver,
mm.magiskLink,
filename
);
Utils.dlAndReceive(activity, receiver, mm.magiskLink, filename);
}
).show();
})
@@ -227,16 +226,17 @@ public class ShowUI {
public static void managerInstallDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
String filename = Utils.fmt("MagiskManager-v%s(%d).apk",
mm.remoteManagerVersionString, mm.remoteManagerVersionCode);
new AlertDialogBuilder(activity)
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.app_name)))
.setMessage(mm.getString(R.string.repo_install_msg,
Utils.fmt("MagiskManager-v%s.apk", mm.remoteManagerVersionString)))
.setMessage(mm.getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (d, i) -> {
Utils.runWithPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> {
Intent intent = new Intent(mm, ManagerUpdate.class);
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
intent.putExtra(Const.Key.INTENT_SET_VERSION, mm.remoteManagerVersionString);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
mm.sendBroadcast(intent);
});
})
@@ -252,20 +252,20 @@ public class ShowUI {
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
ByteArrayOutputStream uninstaller = new ByteArrayOutputStream();
try (InputStream in = mm.getAssets().open(Const.UNINSTALLER)) {
Utils.inToOut(in, uninstaller);
ShellUtils.pump(in, uninstaller);
} catch (IOException e) {
e.printStackTrace();
return;
}
ByteArrayOutputStream utils = new ByteArrayOutputStream();
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
Utils.inToOut(in, utils);
ShellUtils.pump(in, utils);
} catch (IOException e) {
e.printStackTrace();
return;
}
Shell.su(
Shell.Sync.su(
Utils.fmt("echo '%s' > /cache/%s", uninstaller.toString().replace("'", "'\\''"), Const.UNINSTALLER),
Utils.fmt("echo '%s' > %s/%s", utils.toString().replace("'", "'\\''"),
mm.magiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk", Const.UTIL_FUNCTIONS)

View File

@@ -1,63 +0,0 @@
package com.topjohnwu.magisk.utils;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Collections;
/**
* Modified by topjohnwu, based on Chainfire's libsuperuser
*/
public class StreamGobbler extends Thread {
private BufferedReader reader;
private Collection<String> writer;
/**
* <p>StreamGobbler constructor</p>
*
* <p>We use this class because sh STDOUT and STDERR should be read as quickly as
* possible to prevent a deadlock from occurring, or Process.waitFor() never
* returning (as the buffer is full, pausing the native process)</p>
*
* @param in InputStream to read from
* @param out {@literal List<String>} to write to, or null
*/
public StreamGobbler(InputStream in, Collection<String> out) {
try {
while (in.available() != 0) {
in.skip(in.available());
}
} catch (IOException ignored) {}
reader = new BufferedReader(new InputStreamReader(in));
writer = out == null ? null : Collections.synchronizedCollection(out);
}
@Override
public void run() {
// keep reading the InputStream until it ends (or an error occurs)
try {
String line;
while ((line = reader.readLine()) != null) {
if (TextUtils.equals(line, "-shell-done-"))
return;
if (writer != null) writer.add(line);
Logger.shell(false, line);
}
} catch (IOException e) {
// reader probably closed, expected exit condition
}
// make sure our stream is closed and resources will be freed
try {
reader.close();
} catch (IOException e) {
// read already closed
}
}
}

View File

@@ -19,7 +19,6 @@ import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.Toast;
import com.google.gson.Gson;
@@ -28,12 +27,13 @@ import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.SplashActivity;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -45,41 +45,13 @@ public class Utils {
public static boolean isDownloading = false;
public static boolean itemExist(Object path) {
List<String> ret = Shell.su(fmt("[ -e %s ] && echo true || echo false", path));
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
}
public static void createFile(Object path) {
Shell.su_raw(fmt("mkdir -p `dirname '%s'` 2>/dev/null; touch '%s' 2>/dev/null", path, path));
}
public static boolean javaCreateFile(File path) {
path.getParentFile().mkdirs();
try {
path.createNewFile();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static void removeItem(Object path) {
Shell.su_raw(fmt("rm -rf %s 2>/dev/null", path));
}
public static List<String> readFile(Object path) {
return Shell.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path));
}
public static String checkInode(Object path) {
List<String> ret = Shell.su(fmt("ls -i %s", path));
return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : path.toString();
public static String cmd(String cmd) {
return ShellUtils.fastCmd(Shell.getShell(), cmd);
}
public static void uninstallPkg(String pkg) {
Shell.su(fmt("umount -l /data/user*/*/%s/*/*.db 2>/dev/null; pm uninstall %s", pkg, pkg));
SuDatabaseHelper.cleanup();
Shell.Sync.su("pm uninstall " + pkg);
}
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
@@ -110,18 +82,8 @@ public class Utils {
public static String getLegalFilename(CharSequence filename) {
return filename.toString().replace(" ", "_").replace("'", "").replace("\"", "")
.replace("$", "").replace("`", "").replace("(", "").replace(")", "")
.replace("#", "").replace("@", "").replace("*", "");
}
public static boolean isValidShellResponse(List<String> list) {
if (list != null && list.size() != 0) {
// Check if all empty
for (String res : list) {
if (!TextUtils.isEmpty(res)) return true;
}
}
return false;
.replace("$", "").replace("`", "").replace("*", "").replace("/", "_")
.replace("#", "").replace("@", "").replace("\\", "_");
}
public static int getPrefsInt(SharedPreferences prefs, String key, int def) {
@@ -226,14 +188,6 @@ public class Utils {
}
}
public static File getDB(String dbName) {
return getDB(MagiskManager.get(), dbName);
}
public static File getDB(Context context, String dbName) {
return new File(context.getFilesDir().getParent() + "/databases", dbName);
}
public static AssetManager getAssets(String apk) {
try {
AssetManager asset = AssetManager.class.newInstance();
@@ -245,22 +199,10 @@ public class Utils {
}
}
public static int inToOut(InputStream in, OutputStream out) throws IOException {
int read, total = 0;
byte buffer[] = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
total += read;
}
out.flush();
return total;
}
public static void patchDTBO() {
MagiskManager mm = MagiskManager.get();
if (mm.magiskVersionCode >= 1446 && !mm.keepVerity) {
List<String> ret = Shell.su("patch_dtbo_image && echo true || echo false");
if (Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1))) {
if (ShellUtils.fastCmdResult(Shell.getShell(), "patch_dtbo_image")) {
ShowUI.dtboPatchedNotification();
}
}
@@ -277,13 +219,13 @@ public class Utils {
Map<String, ?> prefs = MagiskManager.get().prefs.getAll();
prefs.remove("App Restrictions");
String json = gson.toJson(prefs, new TypeToken<Map<String, ?>>(){}.getType());
Shell.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS));
Shell.Sync.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS));
}
public static void loadPrefs() {
String config = fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS);
List<String> ret = readFile(config);
if (isValidShellResponse(ret)) {
SuFile config = new SuFile(fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS), true);
List<String> ret = Shell.Sync.su("cat " + config);
if (ShellUtils.isValidOutput(ret)) {
SharedPreferences.Editor editor = MagiskManager.get().prefs.edit();
String json = ret.get(0);
Gson gson = new Gson();
@@ -302,7 +244,7 @@ public class Utils {
editor.remove(Const.Key.ETAG_KEY);
editor.apply();
MagiskManager.get().loadConfig();
removeItem(config);
config.delete();
}
}

View File

@@ -1,27 +1,21 @@
package com.topjohnwu.magisk.utils;
import android.content.res.AssetManager;
import com.topjohnwu.crypto.JarMap;
import com.topjohnwu.crypto.SignAPK;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.utils.JarMap;
import com.topjohnwu.utils.SignAPK;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipUtils {
static {
System.loadLibrary("zipadjust");
}
public native static void zipAdjust(String filenameIn, String filenameOut);
public static void unzip(File zip, File folder, String path, boolean junkPath) throws Exception {
InputStream in = new BufferedInputStream(new FileInputStream(zip));
unzip(in, folder, path, junkPath);
@@ -30,9 +24,9 @@ public class ZipUtils {
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception {
try {
JarInputStream zipfile = new JarInputStream(zip);
JarEntry entry;
while ((entry = zipfile.getNextJarEntry()) != null) {
ZipInputStream zipfile = new ZipInputStream(zip);
ZipEntry entry;
while ((entry = zipfile.getNextEntry()) != null) {
if (!entry.getName().startsWith(path) || entry.isDirectory()){
// Ignore directories, only create files
continue;
@@ -46,7 +40,7 @@ public class ZipUtils {
File dest = new File(folder, name);
dest.getParentFile().mkdirs();
try (FileOutputStream out = new FileOutputStream(dest)) {
Utils.inToOut(zipfile, out);
ShellUtils.pump(zipfile, out);
}
}
} catch(Exception e) {
@@ -55,18 +49,25 @@ public class ZipUtils {
}
}
public static void signZip(InputStream is, File output, boolean minSign) throws Exception {
signZip(new JarMap(is, false), output, minSign);
public static void signZip(InputStream is, File output) throws Exception {
try (JarMap map = new JarMap(is, false)) {
signZip(map, output);
}
}
public static void signZip(File input, File output, boolean minSign) throws Exception {
signZip(new JarMap(input, false), output, minSign);
public static void signZip(File input, File output) throws Exception {
try (JarMap map = new JarMap(input, false)) {
signZip(map, output);
}
}
public static void signZip(JarMap input, File output, boolean minSign) throws Exception {
AssetManager assets = MagiskManager.get().getAssets();
SignAPK.signZip(
assets.open(Const.PUBLIC_KEY_NAME), assets.open(Const.PRIVATE_KEY_NAME),
input, output, minSign);
public static void signZip(JarMap input, File output) throws Exception {
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output))) {
signZip(input, out);
}
}
}
public static void signZip(JarMap input, OutputStream output) throws Exception {
SignAPK.signZip(null, null, input, output);
}
}

View File

@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.6)
add_library(zipadjust SHARED
jni_glue.c
zipadjust.c)
find_library(libz z)
find_library(liblog log)
target_link_libraries(zipadjust ${libz} ${liblog})

View File

@@ -1,19 +0,0 @@
//
// Java entry point
//
#include <jni.h>
#include "zipadjust.h"
JNIEXPORT void JNICALL
Java_com_topjohnwu_magisk_utils_ZipUtils_zipAdjust(JNIEnv *env, jclass type, jstring filenameIn_,
jstring filenameOut_) {
const char *filenameIn = (*env)->GetStringUTFChars(env, filenameIn_, 0);
const char *filenameOut = (*env)->GetStringUTFChars(env, filenameOut_, 0);
// TODO
zipadjust(filenameIn, filenameOut, 0);
(*env)->ReleaseStringUTFChars(env, filenameIn_, filenameIn);
(*env)->ReleaseStringUTFChars(env, filenameOut_, filenameOut);
}

View File

@@ -1,297 +0,0 @@
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <zlib.h>
#include <unistd.h>
#include "zipadjust.h"
#ifndef O_BINARY
#define O_BINARY 0
#define O_TEXT 0
#endif
#pragma pack(1)
struct local_header_struct {
uint32_t signature;
uint16_t extract_version;
uint16_t flags;
uint16_t compression_method;
uint16_t last_modified_time;
uint16_t last_modified_date;
uint32_t crc32;
uint32_t size_compressed;
uint32_t size_uncompressed;
uint16_t length_filename;
uint16_t length_extra;
// filename
// extra
};
typedef struct local_header_struct local_header_t;
#pragma pack(1)
struct data_descriptor_struct {
uint32_t signature;
uint32_t crc32;
uint32_t size_compressed;
uint32_t size_uncompressed;
};
typedef struct data_descriptor_struct data_descriptor_t;
#pragma pack(1)
struct central_header_struct {
uint32_t signature;
uint16_t version_made;
uint16_t version_needed;
uint16_t flags;
uint16_t compression_method;
uint16_t last_modified_time;
uint16_t last_modified_date;
uint32_t crc32;
uint32_t size_compressed;
uint32_t size_uncompressed;
uint16_t length_filename;
uint16_t length_extra;
uint16_t length_comment;
uint16_t disk_start;
uint16_t attr_internal;
uint32_t attr_external;
uint32_t offset;
// filename
// extra
// comment
};
typedef struct central_header_struct central_header_t;
#pragma pack(1)
struct central_footer_struct {
uint32_t signature;
uint16_t disk_number;
uint16_t disk_number_central_directory;
uint16_t central_directory_entries_this_disk;
uint16_t central_directory_entries_total;
uint32_t central_directory_size;
uint32_t central_directory_offset;
uint16_t length_comment;
// comment
};
typedef struct central_footer_struct central_footer_t;
#define MAGIC_LOCAL_HEADER 0x04034b50
#define MAGIC_DATA_DESCRIPTOR 0x08074b50
#define MAGIC_CENTRAL_HEADER 0x02014b50
#define MAGIC_CENTRAL_FOOTER 0x06054b50
static int xerror(char* message) {
LOGE("%s\n", message);
return 0;
}
static int xseekread(int fd, off_t offset, void* buf, size_t bytes) {
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) return xerror("Seek failed");
if (read(fd, buf, bytes) != bytes) return xerror("Read failed");
return 1;
}
static int xseekwrite(int fd, off_t offset, void* buf, size_t bytes) {
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) return xerror("Seek failed");
if (write(fd, buf, bytes) != bytes) return xerror("Write failed");
return 1;
}
static int xfilecopy(int fdIn, int fdOut, off_t offsetIn, off_t offsetOut, size_t bytes) {
if ((offsetIn != (off_t)-1) && (lseek(fdIn, offsetIn, SEEK_SET) == (off_t)-1)) return xerror("Seek failed");
if ((offsetOut != (off_t)-1) && (lseek(fdOut, offsetOut, SEEK_SET) == (off_t)-1)) return xerror("Seek failed");
int CHUNK = 256 * 1024;
void* buf = malloc(CHUNK);
if (buf == NULL) return xerror("malloc failed");
size_t left = bytes;
while (left > 0) {
size_t wanted = (left < CHUNK) ? left : CHUNK;
size_t r = read(fdIn, buf, wanted);
if (r <= 0) return xerror("Read failed");
if (write(fdOut, buf, r) != r) return xerror("Write failed");
left -= r;
}
free(buf);
return 1;
}
static int xdecompress(int fdIn, int fdOut, off_t offsetIn, off_t offsetOut, size_t bytes) {
if ((offsetIn != (off_t)-1) && (lseek(fdIn, offsetIn, SEEK_SET) == (off_t)-1)) return xerror("Seek failed");
if ((offsetOut != (off_t)-1) && (lseek(fdOut, offsetOut, SEEK_SET) == (off_t)-1)) return xerror("Seek failed");
int CHUNK = 256 * 1024;
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15);
if (ret != Z_OK) return xerror("ret != Z_OK");
do {
strm.avail_in = read(fdIn, in, CHUNK);
if (strm.avail_in == 0) break;
strm.next_in = in;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR) return xerror("Stream error");
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return xerror("DICT/DATA/MEM error");
}
have = CHUNK - strm.avail_out;
if (write(fdOut, out, have) != have) {
(void)inflateEnd(&strm);
return xerror("Write failed");
}
} while (strm.avail_out == 0);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? 1 : 0;
}
int zipadjust(const char* filenameIn, const char* filenameOut, int decompress) {
int ok = 0;
int fin = open(filenameIn, O_RDONLY | O_BINARY);
if (fin > 0) {
unsigned int size = lseek(fin, 0, SEEK_END);
lseek(fin, 0, SEEK_SET);
LOGD("%d bytes\n", size);
char filename[1024];
central_footer_t central_footer;
uint32_t central_directory_in_position = 0;
uint32_t central_directory_in_size = 0;
uint32_t central_directory_out_size = 0;
int i;
for (i = size - 4; i >= 0; i--) {
uint32_t magic = 0;
if (!xseekread(fin, i, &magic, sizeof(uint32_t))) return 0;
if (magic == MAGIC_CENTRAL_FOOTER) {
LOGD("central footer @ %08X\n", i);
if (!xseekread(fin, i, &central_footer, sizeof(central_footer_t))) return 0;
central_header_t central_header;
if (!xseekread(fin, central_footer.central_directory_offset, &central_header, sizeof(central_header_t))) return 0;
if ( central_header.signature == MAGIC_CENTRAL_HEADER ) {
central_directory_in_position = central_footer.central_directory_offset;
central_directory_in_size = size - central_footer.central_directory_offset;
LOGD("central header @ %08X (%d)\n", central_footer.central_directory_offset, central_footer.central_directory_size);
break;
}
}
}
if (central_directory_in_position == 0) return 0;
unsigned char* central_directory_in = (unsigned char*)malloc(central_directory_in_size);
unsigned char* central_directory_out = (unsigned char*)malloc(central_directory_in_size);
if (!xseekread(fin, central_directory_in_position, central_directory_in, central_directory_in_size)) return 0;
memset(central_directory_out, 0, central_directory_in_size);
unlink(filenameOut);
int fout = open(filenameOut, O_CREAT | O_WRONLY | O_BINARY, 0644);
if (fout > 0) {
uintptr_t central_directory_in_index = 0;
uintptr_t central_directory_out_index = 0;
central_header_t* central_header = NULL;
uint32_t out_index = 0;
while (1) {
central_header = (central_header_t*)&central_directory_in[central_directory_in_index];
if (central_header->signature != MAGIC_CENTRAL_HEADER) break;
filename[central_header->length_filename] = (char)0;
memcpy(filename, &central_directory_in[central_directory_in_index + sizeof(central_header_t)], central_header->length_filename);
LOGD("%s (%d --> %d) [%08X] (%d)\n", filename, central_header->size_uncompressed, central_header->size_compressed, central_header->crc32, central_header->length_extra + central_header->length_comment);
local_header_t local_header;
if (!xseekread(fin, central_header->offset, &local_header, sizeof(local_header_t))) return 0;
// save and update to next index before we clobber the data
uint16_t compression_method_old = central_header->compression_method;
uint32_t size_compressed_old = central_header->size_compressed;
uint32_t offset_old = central_header->offset;
uint32_t length_extra_old = central_header->length_extra;
central_directory_in_index += sizeof(central_header_t) + central_header->length_filename + central_header->length_extra + central_header->length_comment;
// copying, rewriting, and correcting local and central headers so all the information matches, and no data descriptors are necessary
central_header->offset = out_index;
central_header->flags = central_header->flags & !8;
if (decompress && (compression_method_old == 8)) {
central_header->compression_method = 0;
central_header->size_compressed = central_header->size_uncompressed;
}
central_header->length_extra = 0;
central_header->length_comment = 0;
local_header.compression_method = central_header->compression_method;
local_header.flags = central_header->flags;
local_header.crc32 = central_header->crc32;
local_header.size_uncompressed = central_header->size_uncompressed;
local_header.size_compressed = central_header->size_compressed;
local_header.length_extra = 0;
if (!xseekwrite(fout, out_index, &local_header, sizeof(local_header_t))) return 0;
out_index += sizeof(local_header_t);
if (!xseekwrite(fout, out_index, &filename[0], central_header->length_filename)) return 0;
out_index += central_header->length_filename;
if (decompress && (compression_method_old == 8)) {
if (!xdecompress(fin, fout, offset_old + sizeof(local_header_t) + central_header->length_filename + length_extra_old, out_index, size_compressed_old)) return 0;
} else {
if (!xfilecopy(fin, fout, offset_old + sizeof(local_header_t) + central_header->length_filename + length_extra_old, out_index, size_compressed_old)) return 0;
}
out_index += local_header.size_compressed;
memcpy(&central_directory_out[central_directory_out_index], central_header, sizeof(central_header_t) + central_header->length_filename);
central_directory_out_index += sizeof(central_header_t) + central_header->length_filename;
}
central_directory_out_size = central_directory_out_index;
central_footer.central_directory_size = central_directory_out_size;
central_footer.central_directory_offset = out_index;
central_footer.length_comment = 0;
if (!xseekwrite(fout, out_index, central_directory_out, central_directory_out_size)) return 0;
out_index += central_directory_out_size;
if (!xseekwrite(fout, out_index, &central_footer, sizeof(central_footer_t))) return 0;
LOGD("central header @ %08X (%d)\n", central_footer.central_directory_offset, central_footer.central_directory_size);
LOGD("central footer @ %08X\n", out_index);
close(fout);
ok = 1;
}
free(central_directory_in);
free(central_directory_out);
close(fin);
}
return ok;
}

View File

@@ -1,13 +0,0 @@
#ifndef MAGISKMANAGER_ZIPADJUST_H_H
#define MAGISKMANAGER_ZIPADJUST_H_H
#include <android/log.h>
int zipadjust(const char* filenameIn, const char* filenameOut, int decompress);
#define LOG_TAG "zipadjust"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif //MAGISKMANAGER_ZIPADJUST_H_H

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M17.81,4.47c-0.08,0 -0.16,-0.02 -0.23,-0.06C15.66,3.42 14,3 12.01,3c-1.98,0 -3.86,0.47 -5.57,1.41 -0.24,0.13 -0.54,0.04 -0.68,-0.2 -0.13,-0.24 -0.04,-0.55 0.2,-0.68C7.82,2.52 9.86,2 12.01,2c2.13,0 3.99,0.47 6.03,1.52 0.25,0.13 0.34,0.43 0.21,0.67 -0.09,0.18 -0.26,0.28 -0.44,0.28zM3.5,9.72c-0.1,0 -0.2,-0.03 -0.29,-0.09 -0.23,-0.16 -0.28,-0.47 -0.12,-0.7 0.99,-1.4 2.25,-2.5 3.75,-3.27C9.98,4.04 14,4.03 17.15,5.65c1.5,0.77 2.76,1.86 3.75,3.25 0.16,0.22 0.11,0.54 -0.12,0.7 -0.23,0.16 -0.54,0.11 -0.7,-0.12 -0.9,-1.26 -2.04,-2.25 -3.39,-2.94 -2.87,-1.47 -6.54,-1.47 -9.4,0.01 -1.36,0.7 -2.5,1.7 -3.4,2.96 -0.08,0.14 -0.23,0.21 -0.39,0.21zM9.75,21.79c-0.13,0 -0.26,-0.05 -0.35,-0.15 -0.87,-0.87 -1.34,-1.43 -2.01,-2.64 -0.69,-1.23 -1.05,-2.73 -1.05,-4.34 0,-2.97 2.54,-5.39 5.66,-5.39s5.66,2.42 5.66,5.39c0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0,-2.42 -2.09,-4.39 -4.66,-4.39 -2.57,0 -4.66,1.97 -4.66,4.39 0,1.44 0.32,2.77 0.93,3.85 0.64,1.15 1.08,1.64 1.85,2.42 0.19,0.2 0.19,0.51 0,0.71 -0.11,0.1 -0.24,0.15 -0.37,0.15zM16.92,19.94c-1.19,0 -2.24,-0.3 -3.1,-0.89 -1.49,-1.01 -2.38,-2.65 -2.38,-4.39 0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0,1.41 0.72,2.74 1.94,3.56 0.71,0.48 1.54,0.71 2.54,0.71 0.24,0 0.64,-0.03 1.04,-0.1 0.27,-0.05 0.53,0.13 0.58,0.41 0.05,0.27 -0.13,0.53 -0.41,0.58 -0.57,0.11 -1.07,0.12 -1.21,0.12zM14.91,22c-0.04,0 -0.09,-0.01 -0.13,-0.02 -1.59,-0.44 -2.63,-1.03 -3.72,-2.1 -1.4,-1.39 -2.17,-3.24 -2.17,-5.22 0,-1.62 1.38,-2.94 3.08,-2.94 1.7,0 3.08,1.32 3.08,2.94 0,1.07 0.93,1.94 2.08,1.94s2.08,-0.87 2.08,-1.94c0,-3.77 -3.25,-6.83 -7.25,-6.83 -2.84,0 -5.44,1.58 -6.61,4.03 -0.39,0.81 -0.59,1.76 -0.59,2.8 0,0.78 0.07,2.01 0.67,3.61 0.1,0.26 -0.03,0.55 -0.29,0.64 -0.26,0.1 -0.55,-0.04 -0.64,-0.29 -0.49,-1.31 -0.73,-2.61 -0.73,-3.96 0,-1.2 0.23,-2.29 0.68,-3.24 1.33,-2.79 4.28,-4.6 7.51,-4.6 4.55,0 8.25,3.51 8.25,7.83 0,1.62 -1.38,2.94 -3.08,2.94s-3.08,-1.32 -3.08,-2.94c0,-1.07 -0.93,-1.94 -2.08,-1.94s-2.08,0.87 -2.08,1.94c0,1.71 0.66,3.31 1.87,4.51 0.95,0.94 1.86,1.46 3.27,1.85 0.27,0.07 0.42,0.35 0.35,0.61 -0.05,0.23 -0.26,0.38 -0.47,0.38z"/>
</vector>

View File

@@ -101,18 +101,27 @@
<Button
style="?android:buttonBarButtonStyle"
android:text="@string/deny_with_str"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/deny_btn"
android:layout_weight="1" />
<Button
style="?android:buttonBarButtonStyle"
android:text="@string/grant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/grant_btn"
android:layout_weight="1" />
style="?android:buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/grant" />
<ImageView
android:id="@+id/fingerprint"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="7dp"
android:tint="?attr/colorAccent"
android:src="@drawable/ic_fingerprint" />
</LinearLayout>
</LinearLayout>

View File

@@ -53,6 +53,10 @@
<string name="update_available">Aktualisierung verfügbar</string>
<string name="installed">Installiert</string>
<string name="not_installed">Nicht installiert</string>
<string name="updated_on">Zuletzt aktualisiert: %1$s</string>
<string name="sorting_order">Sortierung</string>
<string name="sort_by_name">Nach Namen sortiert</string>
<string name="sort_by_update">Nach Aktualisierung sortiert</string>
<!--Log Fragment-->
<string name="menuSaveLog">Protokoll speichern</string>
@@ -162,6 +166,8 @@
<string name="request_timeout_summary">%1$s Sekunden</string>
<string name="settings_su_reauth_title">Nach Aktualisierung erneut authentifizieren</string>
<string name="settings_su_reauth_summary">Superuser-Zugriff nach App-Aktualisierung erneut abfragen</string>
<string name="settings_su_fingerprint_title">Aktiviere Authentifizierung durch Fingerabdruck</string>
<string name="settings_su_fingerprint_summary">Fingerabdrucksensor benutzen um Superuser-Anfragen zu erlauben</string>
<string name="multiuser_mode">Mehrbenutzermodus</string>
<string name="settings_owner_only">Nur der Gerätebesitzer</string>
@@ -179,6 +185,7 @@
<string name="global_summary">Alle Root-Sitzungen benutzen den global angelegten Namensraum</string>
<string name="requester_summary">Root-Sitzungen erben den Namensraum des Abfragenden</string>
<string name="isolate_summary">Jede Root-Sitzung hat ihren isolierten Namensraum</string>
<string name="android_o_not_support">Android 8.0+ wird nicht unterstützt</string>
<!--Superuser-->
<string name="su_request_title">Superuser-Anfrage</string>
@@ -207,6 +214,7 @@
<string name="su_revoke_msg">Möchtest du die Rechte für %1$s entziehen?</string>
<string name="toast">Popup</string>
<string name="none">Keine</string>
<string name="auth_fail">Authentifizierung fehlgeschlagen</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -1,219 +1,215 @@
<resources>
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Λήψεις</string>
<string name="superuser">Υπερχρήστης</string>
<string name="log">Αρχείο Καταγραφής</string>
<string name="settings">Ρυθμίσεις</string>
<string name="install">Εγκατάσταση</string>
<!--Status Fragment-->
<string name="magisk_version_error">Το Magisk δεν είναι εγκατεστημένο</string>
<string name="checking_for_updates">Έλεγχος για ενημερώσεις…</string>
<string name="magisk_update_available">Το Magisk v%1$s είναι διαθέσιμο!</string>
<string name="invalid_update_channel">Λανθασμένο κανάλι ενημέρωσης</string>
<string name="safetyNet_check_text">Πατήστε για έλεγχο του SafetyNet</string>
<string name="checking_safetyNet_status">Έλεγχος κατάστασης SafetyNet…</string>
<string name="safetyNet_check_success">Ο Έλεγχος του SafetyNet Ήταν Επιτυχής</string>
<string name="safetyNet_api_error">Σφάλμα του SafetyNet API</string>
<string name="safetyNet_network_loss">Αδυναμία σύνδεσης στο δίκτυο</string>
<string name="safetyNet_service_disconnected">Η υπηρεσία τερματίστηκε</string>
<string name="safetyNet_res_invalid">Η απόκριση είναι άκυρη</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Προηγμένες ρυθμίσεις</string>
<string name="keep_force_encryption">Διατήρηση επιβεβλημένης κρυπτογράφησης</string>
<string name="keep_dm_verity">Διατήρηση AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Εγκατεστημένη έκδοση: %1$s</string>
<string name="install_magisk_title">Τελευταία έκδοση: %1$s</string>
<string name="uninstall">Απεγκατάσταση</string>
<string name="uninstall_magisk_title">Απεγκατάσταση Magisk</string>
<string name="uninstall_magisk_msg">Όλα τα modules θα απενεργοποιηθούν/αφαιρεθούν. Το root θα αφαιρεθεί και ενδέχεται να κρυπτογραφηθούν τα δεδομένα σας, εάν δεν είναι κρυπτογραφημένα</string>
<string name="update">Ενημέρωση %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Δεν δόθηκαν πληροφορίες)</string>
<string name="no_modules_found">Δεν βρέθηκαν modules</string>
<string name="update_file_created">Η ενότητα θα ενημερωθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_created">Η ενότητα θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_deleted">Η ενότητα δεν θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_created">Η ενότητα θα απενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_removed">Η ενότητα θα ενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="author">Δημιουργήθηκε από τον/την %1$s</string>
<string name="reboot_recovery">Επανεκκίνηση στο Recovery</string>
<string name="reboot_bootloader">Επανεκκίνηση στο Bootloader</string>
<string name="reboot_download">Επανεκκίνηση για λήψη</string>
<!--Repo Fragment-->
<string name="update_available">Διαθέσιμη Ενημέρωση</string>
<string name="installed">Εγκαταστάθηκε</string>
<string name="not_installed">Μη εγκατεστημένη</string>
<!--Log Fragment-->
<string name="menuSaveLog">"Αποθήκευση καταγραφής "</string>
<string name="menuReload">Επαναφόρτωση</string>
<string name="menuClearLog">Εκκαθάριση αρχείου καταγραφής τώρα</string>
<string name="logs_cleared">Το αρχείο καταγραφής εκκαθαρίστηκε επιτυχώς</string>
<string name="log_is_empty">Το αρχείο καταγραφής είναι κενό</string>
<string name="logs_save_failed">Αποτυχία αποθήκευσης αρχείου καταγραφής στην κάρτα SD:</string>
<!--About Activity-->
<string name="about">Περί</string>
<string name="app_changelog">Καταγραφή αλλαγών εφαρμογής</string>
<string name="translators">JpegXguy, GreatApo</string>
<string name="app_version">Έκδοση εφαρμογής</string>
<string name="app_source_code">Πηγαίος κώδικας</string>
<string name="donation">Δωρεά</string>
<string name="app_translators">Μεταφραστές εφαρμογής</string>
<string name="support_thread">Σύνδεσμος υποστήριξης</string>
<!--Toasts, Dialogs-->
<string name="permissionNotGranted">Η λειτουργία αυτή δεν θα δουλέψει χωρίς την άδεια εγγραφής στον εξωτερικό χώρο αποθηκεύσης.</string>
<string name="no_thanks">Όχι ευχαριστώ</string>
<string name="yes">Ναι</string>
<string name="ok">OK</string>
<string name="close">Κλείσιμο</string>
<string name="repo_install_title">Εγκατάσταση %1$s</string>
<string name="repo_install_msg">Θέλετε να εγκαταστήσετε το %1$s τώρα;</string>
<string name="download">Λήψη</string>
<string name="download_file_error">Σφάλμα στη λήψη του αρχείου</string>
<string name="reboot">Επανεκκίνηση</string>
<string name="downloading_toast">Κατέβασμα %1$s</string>
<string name="magisk_update_title">Νέα Ενημέρωση Magisk Διαθέσιμη!</string>
<string name="settings_reboot_toast">Επανεκκίνηση για εφαρμογή ρυθμίσεων</string>
<string name="release_notes">Σημειώσεις έκδοσης</string>
<string name="repo_cache_cleared">Η Repo cache καθαρίστηκε</string>
<string name="safetyNet_hide_notice">Αυτή η εφαρμογή χρησιμοποιεί SafetyNet\nΉδη διαχειρίζεται από το MagiskHide από προεπιλογή</string>
<string name="process_error">Σφάλμα διαδικασίας</string>
<string name="internal_storage">Το zip είναι αποθηκευμένο σε:\n[Εσωτερική μνήμη]%1$s</string>
<string name="zip_download_title">Γίνεται λήψη</string>
<string name="zip_download_msg">Λήψη αρχείου zip (%1$d%%) …</string>
<string name="zip_process_title">Γίνεται επεξεργασία</string>
<string name="zip_process_msg">Επεξεργασία αρχείου zip …</string>
<string name="manager_update_title">Νέα Ενημέρωση Magisk Manager Διαθέσιμη!</string>
<string name="manager_download_install">Πιέστε για λήψη και εγκατάσταση</string>
<string name="dtbo_patched_title">Έγινε patch στο DTBO!</string>
<string name="dtbo_patched_reboot">Το Magisk Manager έκανε patch το dtbo.img, παρακαλώ κάντε επανεκκίνηση</string>
<string name="magisk_updates">Ενημερώσεις Magisk</string>
<string name="flashing">Γίνεται flash</string>
<string name="hide_manager_toast">Κρύβοντας το Magisk Manager…</string>
<string name="hide_manager_toast2">Αυτό μπορεί να πάρει λίγη ώρα…</string>
<string name="hide_manager_fail_toast">Η απόκρυψη του Magisk Manager απέτυχε</string>
<string name="download_zip_only">Λήψη Zip Μόνο</string>
<string name="patch_boot_file">Εφαρμογή Patch στο Αρχείο Εικόνας Boot</string>
<string name="direct_install">Απευθείας Εγκατάσταση (Προτείνεται)</string>
<string name="install_second_slot">Εγκατάσταση σε Second Slot (Μετά από ΟΤΑ)</string>
<string name="select_method">Επιλογή Μεθόδου</string>
<string name="no_boot_file_patch_support">Αυτή η Magisk έκδοση δεν υποστηρίζει patch του boot image αρχείου</string>
<string name="boot_file_patch_msg">Επιλογή stock boot image dump σε μορφή .img ή .img.tar</string>
<string name="complete_uninstall">Πλήρης απεγκατάσταση</string>
<string name="restore_done">Η ανάκτηση έγινε!</string>
<string name="restore_fail">Δεν υπάρχει αντίγραφο ασφαλείας!</string>
<string name="uninstall_toast">Απεγκατάσταση του Magisk Manager σε 5 δευτερόλεπτα, παρακαλώ επανεκκινήστε χειροκίνητα αμέσως μετά</string>
<string name="proprietary_title">Λήψη Ιδιόκτητου Κώδικα</string>
<string name="proprietary_notice">Το Magisk Manager είναι FOSS οπότε δεν περιέχει της Google τον ιδιόκτητο κώδικα του SafetyNet API.\n\nΕπιτρέπετε στο Magisk Manager να κατεβάσει μια επέκταση (περιέχει το GoogleApiClient) για ελέγχους του SafetyNet?</string>
<string name="su_db_corrupt">Η βάση δεδομένων SU είναι κατεστραμμένη, θα αναδημιουργηθεί νέα</string>
<!--Settings Activity -->
<string name="settings_general_category">Γενικά</string>
<string name="settings_dark_theme_title">Σκούρο θέμα</string>
<string name="settings_dark_theme_summary">Ενεργοποίηση σκούρου θέματος</string>
<string name="settings_notification_title">Ειδοποίηση Ενημέρωσης</string>
<string name="settings_notification_summary">Εμφάνιση ειδοποιήσεων ενημέρωσης όταν είναι διαθέσιμη νέα έκδοση</string>
<string name="settings_clear_cache_title">Εκκαθάριση προσωρινής μνήμης αποθετηρίων</string>
<string name="settings_clear_cache_summary">Καθαρίζει τις κρυφές πληροφορίες για απευθείας συνδεδεμένα αποθετήρια, αναγκάζει την εφαρμογή να κάνει ανανέωση σε απευθείας σύνδεση</string>
<string name="settings_hide_manager_title">Απόκρυψη του Magisk Manager</string>
<string name="settings_hide_manager_summary">Ανασυγκρότηση του Magisk Manager με τυχαίο όνομα πακέτου</string>
<string name="language">Γλώσσα</string>
<string name="system_default">(Προεπιλογή Συστήματος)</string>
<string name="settings_update">Ρυθμίσεις Ενημερώσεων</string>
<string name="settings_update_channel_title">Κανάλι Ενημερώσεων</string>
<string name="settings_update_stable">Σταθερό</string>
<string name="settings_update_beta">Δοκιμαστικό</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Εισαγωγή ενός custom URL</string>
<string name="settings_boot_format_title">Μορφή Τροποποιημένης Εικόνας Boot</string>
<string name="settings_boot_format_summary">Επιλέξτε τη μορφή της εξαγόμενης εικόνας boot μετά το patch.\nΕπιλέξτε .img για flash μέσω λειτουργίας fastboot/download· επιλέξτε .img.tar για flash μέσω ODIN.</string>
<string name="settings_core_only_title">Magisk Λειτουργία Πυρήνα Μόνο</string>
<string name="settings_core_only_summary">Ενεργοποίηση μόνο των λειτουργιών πυρήνα, καμία από τις ενότητες δεν θα ενεργοποιηθεί. Τα MagiskSU, MagiskHide, και systemless hosts θα παραμείνουν ενεργά</string>
<string name="settings_magiskhide_summary">Κρύβει το Magisk από διάφορες ανιχνεύσεις</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Υποστήριξη Systemless hosts για εφαρμογές Adblock</string>
<string name="settings_su_app_adb">Εφαρμογές και ADB</string>
<string name="settings_su_app">Εφαρμογές μόνο</string>
<string name="settings_su_adb">ADB μόνο</string>
<string name="settings_su_disable">Απενεργοποιημένο</string>
<string name="settings_su_request_10">10 δευτερόλεπτα</string>
<string name="settings_su_request_20">20 δευτερόλεπτα</string>
<string name="settings_su_request_30">30 δευτερόλεπτα</string>
<string name="settings_su_request_60">60 δευτερόλεπτα</string>
<string name="superuser_access">Πρόσβαση Υπερχρήστη</string>
<string name="auto_response">Αυτόματη Απόκριση</string>
<string name="request_timeout">Χρονικό όριο Αιτήματος</string>
<string name="superuser_notification">Ειδοποίηση Υπερχρήστη</string>
<string name="request_timeout_summary">%1$s δευτερόλεπτα</string>
<string name="settings_su_reauth_title">Επαναπιστοποίηση μετά από αναβάθμιση</string>
<string name="settings_su_reauth_summary">Επαναπιστοποίηση αδειών υπερχρήστη μετά την αναβάθμιση μίας εφαρμογής</string>
<string name="multiuser_mode">Λειτουργία Πολλών Χρηστών</string>
<string name="settings_owner_only">Μόνο Ιδιοκτήτης Συσκευής</string>
<string name="settings_owner_manage">Διαχειριζόμενη από τον Ιδιοκτήτη</string>
<string name="settings_user_independent">Ανεξάρτητη από τον χρήστη</string>
<string name="owner_only_summary">Μόνο ο ιδιοκτήτης έχει πρόσβαση root</string>
<string name="owner_manage_summary">Μόνο ο ιδιοκτήτης μπορεί να διαχειριστεί την πρόσβαση root και να δεχτεί προτροπές αίτημάτων</string>
<string name="user_indepenent_summary">Κάθε χρήστης έχει τους δικούς του ξεχωριστούς κανόνες root</string>
<string name="multiuser_hint_owner_request">Ένα αίτημα έχει σταλεί στον ιδιοκτήτη της συσκευής. Παρακαλώ αλλάξτε σε ιδιοκτήτη και δώστε την άδεια</string>
<string name="mount_namespace_mode">Λειτουργία προσάρτησης χώρου ονομάτων</string>
<string name="settings_ns_global">Καθολικός Χώρος Ονομάτων</string>
<string name="settings_ns_requester">Κληρονόμησε Χώρο Ονομάτων</string>
<string name="settings_ns_isolate">Απομονωμένος Χώρος Ονομάτων</string>
<string name="global_summary">Όλες οι συνεδρίες root χρησιμοποιούν τον καθολικό χώρο oνομάτων προσάρτησης</string>
<string name="requester_summary">Οι συνεδρίες root θα κληρονομούν το χώρο ονομάτων του αιτούντα τους</string>
<string name="isolate_summary">Κάθε συνεδρία root θα έχει το δικό της απομονωμένο χώρο ονομάτων</string>
<string name="android_o_not_support">Δεν υποστηρίζεται Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Αίτημα υπερχρήστη</string>
<string name="deny_with_str">Άρνηση%1$s</string>
<string name="deny">Άρνηση</string>
<string name="prompt">Προτροπή</string>
<string name="grant">Αποδοχή</string>
<string name="su_warning">Δίνει πλήρη πρόσβαση στη συσκευή σας.\nΑρνηθείτε αν δεν είστε σίγουρος/η!</string>
<string name="forever">Πάντα</string>
<string name="once">Μία φορά</string>
<string name="tenmin">10 λεπτά</string>
<string name="twentymin">20 λεπτά</string>
<string name="thirtymin">30 λεπτά</string>
<string name="sixtymin">60 λεπτά</string>
<string name="su_allow_toast">Παραχωρήθηκαν δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_deny_toast">Απορρίφθηκαν τα δικαιώματα υπερχρήστη του %1$s</string>
<string name="no_apps_found">Δεν βρέθηκαν εφαρμογές</string>
<string name="su_snack_grant">Παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_deny">Δεν παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_notif_on">Οι ειδοποιήσεις του %1$s είναι ενεργοποιημένες</string>
<string name="su_snack_notif_off">Οι ειδοποιήσεις του %1$s είναι απενεργοποιημένες</string>
<string name="su_snack_log_on">Η καταγραφή του %1$s είναι ενεργοποιημένη</string>
<string name="su_snack_log_off">Η καταγραφή του %1$s είναι απενεργοποιημένη</string>
<string name="su_snack_revoke">Τα δικαιώματα του %1$s ανακαλούνται</string>
<string name="su_revoke_title">Ανάκληση;</string>
<string name="su_revoke_msg">Επιβεβαίωση για ανάκληση δικαιωμάτων %1$s;</string>
<string name="toast">Αναδυόμενο παράθυρο</string>
<string name="none">Κανένα</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID Στόχος:\u0020</string>
<string name="command">Εντολή:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Λήψεις</string>
<string name="superuser">Υπερχρήστης</string>
<string name="log">Αρχείο Καταγραφής</string>
<string name="settings">Ρυθμίσεις</string>
<string name="install">Εγκατάσταση</string>
<!--Status Fragment-->
<string name="magisk_version_error">Το Magisk δεν είναι εγκατεστημένο</string>
<string name="checking_for_updates">Έλεγχος για ενημερώσεις…</string>
<string name="magisk_update_available">Το Magisk v%1$s είναι διαθέσιμο!</string>
<string name="invalid_update_channel">Λανθασμένο κανάλι ενημέρωσης</string>
<string name="safetyNet_check_text">Πατήστε για έλεγχο του SafetyNet</string>
<string name="checking_safetyNet_status">Έλεγχος κατάστασης SafetyNet…</string>
<string name="safetyNet_check_success">Ο Έλεγχος του SafetyNet Ήταν Επιτυχής</string>
<string name="safetyNet_api_error">Σφάλμα του SafetyNet API</string>
<string name="safetyNet_network_loss">Αδυναμία σύνδεσης στο δίκτυο</string>
<string name="safetyNet_service_disconnected">Η υπηρεσία τερματίστηκε</string>
<string name="safetyNet_res_invalid">Η απόκριση είναι άκυρη</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Προηγμένες ρυθμίσεις</string>
<string name="keep_force_encryption">Διατήρηση επιβεβλημένης κρυπτογράφησης</string>
<string name="keep_dm_verity">Διατήρηση dm-verity</string>
<string name="current_magisk_title">Εγκατεστημένη έκδοση: %1$s</string>
<string name="install_magisk_title">Τελευταία έκδοση: %1$s</string>
<string name="uninstall">Απεγκατάσταση</string>
<string name="uninstall_magisk_title">Απεγκατάσταση Magisk</string>
<string name="uninstall_magisk_msg">Όλα τα modules θα απενεργοποιηθούν/αφαιρεθούν. Το root θα αφαιρεθεί και ενδέχεται να κρυπτογραφηθούν τα δεδομένα σας, εάν δεν είναι κρυπτογραφημένα</string>
<string name="update">Ενημέρωση %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Δεν δόθηκαν πληροφορίες)</string>
<string name="no_modules_found">Δεν βρέθηκαν modules</string>
<string name="update_file_created">Η ενότητα θα ενημερωθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_created">Η ενότητα θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_deleted">Η ενότητα δεν θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_created">Η ενότητα θα απενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_removed">Η ενότητα θα ενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="author">Δημιουργήθηκε από τον/την %1$s</string>
<string name="reboot_recovery">Επανεκκίνηση στο Recovery</string>
<string name="reboot_bootloader">Επανεκκίνηση στο Bootloader</string>
<string name="reboot_download">Επανεκκίνηση για λήψη</string>
<!--Repo Fragment-->
<string name="update_available">Διαθέσιμη Ενημέρωση</string>
<string name="installed">Εγκαταστάθηκε</string>
<string name="not_installed">Μη εγκατεστημένη</string>
<string name="updated_on">Αναβαθμίστηκε στις: %1$s</string>
<string name="sorting_order">Ταξινόμηση κατά</string>
<string name="sort_by_name">Ταξινόμηση κατά όνομα</string>
<string name="sort_by_update">Ταξινόμηση κατά τελευταία αναβάθμιση</string>
<!--Log Fragment-->
<string name="menuSaveLog">"Αποθήκευση καταγραφής "</string>
<string name="menuReload">Επαναφόρτωση</string>
<string name="menuClearLog">Εκκαθάριση αρχείου καταγραφής τώρα</string>
<string name="logs_cleared">Το αρχείο καταγραφής εκκαθαρίστηκε επιτυχώς</string>
<string name="log_is_empty">Το αρχείο καταγραφής είναι κενό</string>
<string name="logs_save_failed">Αποτυχία αποθήκευσης αρχείου καταγραφής στην κάρτα SD:</string>
<!--About Activity-->
<string name="about">Περί</string>
<string name="app_changelog">Καταγραφή αλλαγών εφαρμογής</string>
<string name="translators">GreatApo, JpegXguy</string>
<string name="app_version">Έκδοση εφαρμογής</string>
<string name="app_source_code">Πηγαίος κώδικας</string>
<string name="donation">Δωρεά</string>
<string name="app_translators">Μεταφραστές εφαρμογής</string>
<string name="support_thread">Σύνδεσμος υποστήριξης</string>
<!--Toasts, Dialogs-->
<string name="permissionNotGranted">Η λειτουργία αυτή δεν θα δουλέψει χωρίς την άδεια εγγραφής στον εξωτερικό χώρο αποθηκεύσης.</string>
<string name="no_thanks">Όχι ευχαριστώ</string>
<string name="yes">Ναι</string>
<string name="ok">OK</string>
<string name="close">Κλείσιμο</string>
<string name="repo_install_title">Εγκατάσταση %1$s</string>
<string name="repo_install_msg">Θέλετε να εγκαταστήσετε το %1$s τώρα;</string>
<string name="download">Λήψη</string>
<string name="download_file_error">Σφάλμα στη λήψη του αρχείου</string>
<string name="reboot">Επανεκκίνηση</string>
<string name="downloading_toast">Κατέβασμα %1$s</string>
<string name="magisk_update_title">Νέα Ενημέρωση Magisk Διαθέσιμη!</string>
<string name="settings_reboot_toast">Επανεκκίνηση για εφαρμογή ρυθμίσεων</string>
<string name="release_notes">Σημειώσεις έκδοσης</string>
<string name="repo_cache_cleared">Η Repo cache καθαρίστηκε</string>
<string name="safetyNet_hide_notice">Αυτή η εφαρμογή χρησιμοποιεί SafetyNet\nΉδη διαχειρίζεται από το MagiskHide από προεπιλογή</string>
<string name="process_error">Σφάλμα διαδικασίας</string>
<string name="internal_storage">Το zip είναι αποθηκευμένο σε:\n[Εσωτερική μνήμη]%1$s</string>
<string name="zip_download_title">Γίνεται λήψη</string>
<string name="zip_download_msg">Λήψη αρχείου zip (%1$d%%)</string>
<string name="zip_process_title">Γίνεται επεξεργασία</string>
<string name="zip_process_msg">Επεξεργασία αρχείου zip …</string>
<string name="manager_update_title">Νέα Ενημέρωση Magisk Manager Διαθέσιμη!</string>
<string name="manager_download_install">Πιέστε για λήψη και εγκατάσταση</string>
<string name="dtbo_patched_title">Έγινε patch στο DTBO!</string>
<string name="dtbo_patched_reboot">Το Magisk Manager έκανε patch το dtbo.img, παρακαλώ κάντε επανεκκίνηση</string>
<string name="magisk_updates">Ενημερώσεις Magisk</string>
<string name="flashing">Γίνεται flash</string>
<string name="hide_manager_toast">Κρύβοντας το Magisk Manager…</string>
<string name="hide_manager_toast2">Αυτό μπορεί να πάρει λίγη ώρα…</string>
<string name="hide_manager_fail_toast">Η απόκρυψη του Magisk Manager απέτυχε…</string>
<string name="download_zip_only">Λήψη Zip Μόνο</string>
<string name="patch_boot_file">Εφαρμογή Patch στο Αρχείο Εικόνας Boot</string>
<string name="direct_install">Απευθείας Εγκατάσταση (Προτείνεται)</string>
<string name="install_second_slot">Εγκατάσταση σε Second Slot (Μετά από ΟΤΑ)</string>
<string name="select_method">Επιλογή Μεθόδου</string>
<string name="no_boot_file_patch_support">Αυτή η Magisk έκδοση δεν υποστηρίζει patch του boot image αρχείου</string>
<string name="boot_file_patch_msg">Επιλογή stock boot image dump σε μορφή .img ή .img.tar</string>
<string name="complete_uninstall">Πλήρης απεγκατάσταση</string>
<string name="restore_done">Η ανάκτηση έγινε!</string>
<string name="restore_fail">Δεν υπάρχει αντίγραφο ασφαλείας!</string>
<string name="uninstall_toast">Απεγκατάσταση του Magisk Manager σε 5 δευτερόλεπτα, παρακαλώ επανεκκινήστε χειροκίνητα αμέσως μετά</string>
<string name="proprietary_title">Λήψη Ιδιόκτητου Κώδικα</string>
<string name="proprietary_notice">Το Magisk Manager είναι FOSS οπότε δεν περιέχει της Google τον ιδιόκτητο κώδικα του SafetyNet API.\n\nΕπιτρέπετε στο Magisk Manager να κατεβάσει μια επέκταση (περιέχει το GoogleApiClient) για ελέγχους του SafetyNet?</string>
<string name="su_db_corrupt">Η βάση δεδομένων SU είναι κατεστραμμένη, θα αναδημιουργηθεί νέα</string>
<!--Settings Activity -->
<string name="settings_general_category">Γενικά</string>
<string name="settings_dark_theme_title">Σκούρο θέμα</string>
<string name="settings_dark_theme_summary">Ενεργοποίηση σκούρου θέματος</string>
<string name="settings_notification_title">Ειδοποίηση Ενημέρωσης</string>
<string name="settings_notification_summary">Εμφάνιση ειδοποιήσεων ενημέρωσης όταν είναι διαθέσιμη νέα έκδοση</string>
<string name="settings_clear_cache_title">Εκκαθάριση προσωρινής μνήμης αποθετηρίων</string>
<string name="settings_clear_cache_summary">Καθαρίζει τις κρυφές πληροφορίες για απευθείας συνδεδεμένα αποθετήρια, αναγκάζει την εφαρμογή να κάνει ανανέωση σε απευθείας σύνδεση</string>
<string name="settings_hide_manager_title">Απόκρυψη του Magisk Manager</string>
<string name="settings_hide_manager_summary">Ανασυγκρότηση του Magisk Manager με τυχαίο όνομα πακέτου</string>
<string name="language">Γλώσσα</string>
<string name="system_default">(Προεπιλογή Συστήματος)</string>
<string name="settings_update">Ρυθμίσεις Ενημερώσεων</string>
<string name="settings_update_channel_title">Κανάλι Ενημερώσεων</string>
<string name="settings_update_stable">Σταθερό</string>
<string name="settings_update_beta">Δοκιμαστικό</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Εισαγωγή ενός custom URL</string>
<string name="settings_boot_format_title">Μορφή Τροποποιημένης Εικόνας Boot</string>
<string name="settings_boot_format_summary">Επιλέξτε τη μορφή της εξαγόμενης εικόνας boot μετά το patch.\nΕπιλέξτε .img για flash μέσω λειτουργίας fastboot/download· επιλέξτε .img.tar για flash μέσω ODIN.</string>
<string name="settings_core_only_title">Magisk Λειτουργία Πυρήνα Μόνο</string>
<string name="settings_core_only_summary">Ενεργοποίηση μόνο των λειτουργιών πυρήνα, καμία από τις ενότητες δεν θα ενεργοποιηθεί. Τα MagiskSU, MagiskHide, και systemless hosts θα παραμείνουν ενεργά</string>
<string name="settings_magiskhide_summary">Κρύβει το Magisk από διάφορες ανιχνεύσεις</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Υποστήριξη Systemless hosts για εφαρμογές Adblock</string>
<string name="settings_su_app_adb">Εφαρμογές και ADB</string>
<string name="settings_su_app">Εφαρμογές μόνο</string>
<string name="settings_su_adb">ADB μόνο</string>
<string name="settings_su_disable">Απενεργοποιημένο</string>
<string name="settings_su_request_10">10 δευτερόλεπτα</string>
<string name="settings_su_request_20">20 δευτερόλεπτα</string>
<string name="settings_su_request_30">30 δευτερόλεπτα</string>
<string name="settings_su_request_60">60 δευτερόλεπτα</string>
<string name="superuser_access">Πρόσβαση Υπερχρήστη</string>
<string name="auto_response">Αυτόματη Απόκριση</string>
<string name="request_timeout">Χρονικό όριο Αιτήματος</string>
<string name="superuser_notification">Ειδοποίηση Υπερχρήστη</string>
<string name="request_timeout_summary">%1$s δευτερόλεπτα</string>
<string name="settings_su_reauth_title">Επαναπιστοποίηση μετά από αναβάθμιση</string>
<string name="settings_su_reauth_summary">Επαναπιστοποίηση αδειών υπερχρήστη μετά την αναβάθμιση μίας εφαρμογής</string>
<string name="multiuser_mode">Λειτουργία Πολλών Χρηστών</string>
<string name="settings_owner_only">Μόνο Ιδιοκτήτης Συσκευής</string>
<string name="settings_owner_manage">Διαχειριζόμενη από τον Ιδιοκτήτη</string>
<string name="settings_user_independent">Ανεξάρτητη από τον χρήστη</string>
<string name="owner_only_summary">Μόνο ο ιδιοκτήτης έχει πρόσβαση root</string>
<string name="owner_manage_summary">Μόνο ο ιδιοκτήτης μπορεί να διαχειριστεί την πρόσβαση root και να δεχτεί προτροπές αίτημάτων</string>
<string name="user_indepenent_summary">Κάθε χρήστης έχει τους δικούς του ξεχωριστούς κανόνες root</string>
<string name="multiuser_hint_owner_request">Ένα αίτημα έχει σταλεί στον ιδιοκτήτη της συσκευής. Παρακαλώ αλλάξτε σε ιδιοκτήτη και δώστε την άδεια</string>
<string name="mount_namespace_mode">Λειτουργία προσάρτησης χώρου ονομάτων</string>
<string name="settings_ns_global">Καθολικός Χώρος Ονομάτων</string>
<string name="settings_ns_requester">Κληρονόμησε Χώρο Ονομάτων</string>
<string name="settings_ns_isolate">Απομονωμένος Χώρος Ονομάτων</string>
<string name="global_summary">Όλες οι συνεδρίες root χρησιμοποιούν τον καθολικό χώρο oνομάτων προσάρτησης</string>
<string name="requester_summary">Οι συνεδρίες root θα κληρονομούν το χώρο ονομάτων του αιτούντα τους</string>
<string name="isolate_summary">Κάθε συνεδρία root θα έχει το δικό της απομονωμένο χώρο ονομάτων</string>
<string name="android_o_not_support">Δεν υποστηρίζεται Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Αίτημα υπερχρήστη</string>
<string name="deny_with_str">Άρνηση%1$s</string>
<string name="deny">Άρνηση</string>
<string name="prompt">Προτροπή</string>
<string name="grant">Αποδοχή</string>
<string name="su_warning">Δίνει πλήρη πρόσβαση στη συσκευή σας.\nΑρνηθείτε αν δεν είστε σίγουρος/η!</string>
<string name="forever">Πάντα</string>
<string name="once">Μία φορά</string>
<string name="tenmin">10 λεπτά</string>
<string name="twentymin">20 λεπτά</string>
<string name="thirtymin">30 λεπτά</string>
<string name="sixtymin">60 λεπτά</string>
<string name="su_allow_toast">Παραχωρήθηκαν δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_deny_toast">Απορρίφθηκαν τα δικαιώματα υπερχρήστη του %1$s</string>
<string name="no_apps_found">Δεν βρέθηκαν εφαρμογές</string>
<string name="su_snack_grant">Παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_deny">Δεν παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_notif_on">Οι ειδοποιήσεις του %1$s είναι ενεργοποιημένες</string>
<string name="su_snack_notif_off">Οι ειδοποιήσεις του %1$s είναι απενεργοποιημένες</string>
<string name="su_snack_log_on">Η καταγραφή του %1$s είναι ενεργοποιημένη</string>
<string name="su_snack_log_off">Η καταγραφή του %1$s είναι απενεργοποιημένη</string>
<string name="su_snack_revoke">Τα δικαιώματα του %1$s ανακαλούνται</string>
<string name="su_revoke_title">Ανάκληση;</string>
<string name="su_revoke_msg">Επιβεβαίωση για ανάκληση δικαιωμάτων %1$s;</string>
<string name="toast">Αναδυόμενο παράθυρο</string>
<string name="none">Κανένα</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID Στόχος:\u0020</string>
<string name="command">Εντολή:\u0020</string>
</resources>

View File

@@ -163,7 +163,10 @@
<string name="request_timeout_summary">%1$s segundos</string>
<string name="settings_su_reauth_title">Re-autenticación</string>
<string name="settings_su_reauth_summary">Pedir permisos de superusuario nuevamente si una aplicación es actualizada o reinstalada</string>
<string name="settings_su_fingerprint_title">Habilitar la autenticación de huellas digitales</string>
<string name="settings_su_fingerprint_summary">Utilice el escáner de huellas digitales para permitir las solicitudes de superusuario</string>
<string name="multiuser_mode">Modo MultiUsuario</string>
<string name="settings_owner_only">Sólo Administrador del Dispositivo</string>
<string name="settings_owner_manage">Administrador del Dispositivo</string>
@@ -209,6 +212,7 @@
<string name="su_revoke_msg">¿Confirmar para revocar derechos de %1$s?</string>
<string name="toast">Aviso</string>
<string name="none">Nada</string>
<string name="auth_fail">Autenticación fallida</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -50,6 +50,10 @@
<string name="update_available">Uuendus saadaval</string>
<string name="installed">Installitud</string>
<string name="not_installed">Pole installitud</string>
<string name="updated_on">Uuendatud: %1$s</string>
<string name="sorting_order">Sorteerimisjärjekord</string>
<string name="sort_by_name">Sorteeri nime järgi</string>
<string name="sort_by_update">Sorteeri viimase uuenduse järgi</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salvesta logi</string>
@@ -85,9 +89,11 @@
<string name="settings_reboot_toast">Taaskäivita seadete rakendamiseks</string>
<string name="release_notes">Väljalaskemärkmed</string>
<string name="repo_cache_cleared">Hoidla vahemälu tühjendatud</string>
<string name="safetyNet_hide_notice">See rakendus kasutab SafetyNet\'i\nJuba vaikimisi hallatud MagiskHide poolt</string>
<string name="safetyNet_hide_notice">See rakendus kasutab SafetyNet\'i\n
Juba vaikimisi hallatud MagiskHide poolt</string>
<string name="process_error">Protsessi viga</string>
<string name="internal_storage">ZIP on salvestatud:\n[Sisemälu]%1$s</string>
<string name="internal_storage">ZIP on salvestatud:\n
[Sisemälu]%1$s</string>
<string name="zip_download_title">Laadin alla</string>
<string name="zip_download_msg">Laadin ZIP-faili alla (%1$d%%)...</string>
<string name="zip_process_title">Töötlen</string>
@@ -95,11 +101,11 @@
<string name="manager_update_title">Magisk Manager\'ile on uuendus saadaval!</string>
<string name="manager_download_install">Vajuta allalaadimiseks ja installimiseks</string>
<string name="dtbo_patched_title">DTBO sai paigatud!</string>
<string name="dtbo_patched_reboot">Magisk Manager on paiganud dtbo.img, palun taaskäivita</string>
<string name="dtbo_patched_reboot">Magisk Manager on paiganud dtbo.img, palun taaskäivita</string>
<string name="magisk_updates">Magisk\'i uuendused</string>
<string name="flashing">Välgutamine</string>
<string name="hide_manager_toast">Peidan Magisk Manager\'i...</string>
<string name="hide_manager_toast2">See võib aega võtta...</string>
<string name="hide_manager_toast2">See võib aega võtta...</string>
<string name="hide_manager_fail_toast">Magisk Manager\'i peitmine ebaõnnestus...</string>
<string name="download_zip_only">Laadi ainult ZIP alla</string>
<string name="patch_boot_file">Paika käivituspildi fail</string>
@@ -115,9 +121,11 @@
<string name="restore_fail">Originaalne varundus puudub!</string>
<string name="uninstall_toast">Eemaldan Magisk Manager\'i 5 sekundi pärast, palun tee peale seda käsitsi taaskäivitus</string>
<string name="proprietary_title">Laadi alla suletud koodi</string>
<string name="proprietary_notice">Magisk Manager on vaba ja avatud lähtekoodiga, seega ei sisalda Google\'i suletud SafetyNet\'i API koodi.\n\nKas lubad Magisk Manager\'il SafetyNet\'i kontrollide jaoks laadida alla laiendus (sisaldab GoogleApiClient\'i)?</string>
<string name="su_db_corrupt">Superkasutaja andmebaas on korrumpteerunud, loon uue andmebaasi</string>
<string name="proprietary_notice">Magisk Manager on vaba ja avatud lähtekoodiga, mis ei sisalda Google\'i suletud SafetyNet\'i API koodi.\n
\n
Kas lubad Magisk Manager\'il SafetyNet\'i kontrollide jaoks laadida alla laiendus (sisaldab GoogleApiClient\'i)?</string>
<string name="su_db_corrupt">Superkasutaja andmebaas on korrumpteerunud, loon uue andmebaasi</string>
<!--Settings Activity -->
<string name="settings_general_category">Üldine</string>
<string name="settings_dark_theme_title">Tume teema</string>
@@ -127,20 +135,20 @@
<string name="settings_clear_cache_title">Tühjenda hoidla vahemälu</string>
<string name="settings_clear_cache_summary">Tühjenda võrgus olevate hoidlate vahemälus olev teave, sunnib rakendust võrgust värskendama</string>
<string name="settings_hide_manager_title">Peida Magisk Manager</string>
<string name="settings_hide_manager_summary">Taaspaki Magisk Manager juhusliku nimega</string>
<string name="settings_hide_manager_summary">Taaspaki Magisk Manager juhusliku nimega</string>
<string name="language">Keel</string>
<string name="system_default">(Süsteemi vaikesäte)</string>
<string name="settings_update">Uuenda seadeid</string>
<string name="settings_update_channel_title">Uuenduste kanal</string>
<string name="settings_update_stable">Stabiilne</string>
<string name="settings_update_beta">Beeta</string>
<string name="settings_update_custom">Kohandatud</string>
<string name="settings_update_custom_msg">Sisesta kohandatud URL</string>
<string name="settings_update_custom">Kohandatud</string>
<string name="settings_update_custom_msg">Sisesta kohandatud URL</string>
<string name="settings_boot_format_title">Paigatud käivitusväljundi vorming</string>
<string name="settings_boot_format_summary">Vali väljutatava paigatud käivituspildi vorming.\nVali .img, mida välgutada fastboot/allalaadimisrežiimi kaudu; vali .img.tar, mida välgutada ODIN\'i kaudu.</string>
<string name="settings_boot_format_summary">Vali väljutatava paigatud käivituspildi vorming.\n
Vali .img, mida välgutada fastboot/allalaadimisrežiimi kaudu; vali .img.tar, mida välgutada ODIN\'i kaudu.</string>
<string name="settings_core_only_title">Magisk\'i ainult tuuma režiim</string>
<string name="settings_core_only_summary">Luba ainult põhifunktsioonid, kõiki mooduleid ei laadita. MagiskSU, MagiskHide ja süsteemivaba hosts siiski lubatakse</string>
<string name="settings_core_only_summary">Luba ainult põhifunktsioonid. MagiskSU, MagiskHide ja süsteemivaba hosts siiski lubatakse, ent mooduleid ei laadita.</string>
<string name="settings_magiskhide_summary">Peida Magisk erinevate tuvastuste eest</string>
<string name="settings_hosts_title">Süsteemivaba hosts</string>
<string name="settings_hosts_summary">Süsteemivaba hosts-tugi reklaamiblokeerijatest rakendustele</string>
@@ -160,6 +168,8 @@
<string name="request_timeout_summary">%1$s sekundit</string>
<string name="settings_su_reauth_title">Taas-autendi peale uuendust</string>
<string name="settings_su_reauth_summary">Taas-autendi superkasutaja õigused peale rakenduse uuendust</string>
<string name="settings_su_fingerprint_title">Luba sõrmejäljega autentimine</string>
<string name="settings_su_fingerprint_summary">Kasuta sõrmejäljelugejat superkasutaja taotluste lubamiseks</string>
<string name="multiuser_mode">Mitmikkasutaja režiim</string>
<string name="settings_owner_only">Ainult seadme omanik</string>
@@ -168,7 +178,7 @@
<string name="owner_only_summary">Ainult omanikul on juurkasutaja õigused</string>
<string name="owner_manage_summary">Ainult omanik saab hallata juurkasutaja ligipääsu ja saada taotlusküsimusi</string>
<string name="user_indepenent_summary">Igal kasutajal on oma isiklikud juurkasutaja reeglid</string>
<string name="multiuser_hint_owner_request">Taotlus on saadetud seadme omanikule. Palun lülitu omanikule ja anna luba</string>
<string name="multiuser_hint_owner_request">Taotlus on saadetud seadme omanikule. Palun lülitu omanikule ja anna vajalikud load</string>
<string name="mount_namespace_mode">Nimeruumi monteerimisrežiim</string>
<string name="settings_ns_global">Globaalne nimeruum</string>
@@ -185,7 +195,8 @@
<string name="deny">Keela</string>
<string name="prompt">Küsi</string>
<string name="grant">Luba</string>
<string name="su_warning">Annab täieliku ligipääsu sinu seadmele.\nKeela, kui sa pole kindel!</string>
<string name="su_warning">Annab täieliku ligipääsu sinu seadmele.\n
Keela, kui sa pole kindel!</string>
<string name="forever">Igavesti</string>
<string name="once">Üks kord</string>
<string name="tenmin">10 min</string>
@@ -195,17 +206,18 @@
<string name="su_allow_toast">Rakendusele %1$s anti superkasutaja õigused</string>
<string name="su_deny_toast">Rakendusel %1$s keelati superkasutaja õigused</string>
<string name="no_apps_found">Rakendusi ei leitud</string>
<string name="su_snack_grant">Rakenduse %1$s superkasutaja õigused on antud</string>
<string name="su_snack_deny">Rakenduse %1$s superkasutaja õigused on keelatud</string>
<string name="su_snack_notif_on">Rakenduse %1$s teated on lubatud</string>
<string name="su_snack_notif_off">Rakenduse %1$s teated on keelatud</string>
<string name="su_snack_log_on">Rakenduse %1$s logimine on lubatud</string>
<string name="su_snack_log_off">Rakenduse %1$s logimine on keelatud</string>
<string name="su_snack_grant">Superkasutaja õigused antud rakendusele %1$s</string>
<string name="su_snack_deny">Superkasutaja õigused keelatud rakendusele %1$s</string>
<string name="su_snack_notif_on">Teated lubatud rakendusele %1$s</string>
<string name="su_snack_notif_off">Teated keelatud rakendusele %1$s</string>
<string name="su_snack_log_on">Logimine lubatud rakendusele %1$s</string>
<string name="su_snack_log_off">Logimine keelatud rakendusele %1$s</string>
<string name="su_snack_revoke">Rakenduse %1$s õigused on eemaldatud</string>
<string name="su_revoke_title">Eemaldad?</string>
<string name="su_revoke_msg">Kinnitad rakenduse %1$s õiguste eemaldamise?</string>
<string name="toast">Hüpik</string>
<string name="none">Puudub</string>
<string name="auth_fail">Autentimine ebaõnnestus</string>
<!--Superuser logs-->
<string name="pid">PID:\\u0020</string>

View File

@@ -143,6 +143,7 @@
<string name="settings_boot_format_summary">Sélectionner le format de l\'image boot patchée finale.\nChoisir .img pour flasher via fastboot/mode download ; choisir .img.tar pour flasher via ODIN.</string>
<string name="settings_su_reauth_title">Ré-authentifier après mise à jour</string>
<string name="settings_su_reauth_summary">Ré-authentifier les permissions superuser après les mises à jour d\'une application</string>
<string name="settings_su_fingerprint_title">Activer l\'authentification par empreinte</string>
<string name="multiuser_mode">Mode multi-utilisateurs</string>
<string name="settings_owner_only">Appareil du propriétaire uniquement</string>
<string name="settings_owner_manage">Appareil du propriétaire géré</string>
@@ -164,7 +165,7 @@
<string name="deny">Refuser</string>
<string name="prompt">Demander</string>
<string name="grant">Accepter</string>
<string name="su_warning">Accepter un accès complet à votre appareil.\nRefuser si vous n\'êtes pas sûr!</string>
<string name="su_warning">Accepter un accès complet à votre appareil.\nRefuser si vous n\'êtes pas sûr !</string>
<string name="forever">Toujours</string>
<string name="once">Une fois</string>
<string name="tenmin">10 min</string>
@@ -173,7 +174,7 @@
<string name="sixtymin">60 min</string>
<string name="su_allow_toast">%1$s a obtenu les droits Superuser</string>
<string name="su_deny_toast">%1$s n\'a pas obtenu les droits Superuser</string>
<string name="no_apps_found">Aucun application trouvée</string>
<string name="no_apps_found">Aucune application trouvée</string>
<string name="su_snack_grant">Les droits Superuser de %1$s sont accordés</string>
<string name="su_snack_deny">Les droits Superuser de %1$s sont refusés</string>
<string name="su_snack_notif_on">Les notifications pour %1$s sont activées</string>

View File

@@ -24,8 +24,8 @@
<!--Install Fragment-->
<string name="advanced_settings_title">Pengaturan Lanjutan</string>
<string name="keep_force_encryption">Biarkan enkripsi paksa</string>
<string name="keep_dm_verity">Biarkan AVB 2.0/dm-verity</string>
<string name="keep_force_encryption">Pertahankan enkripsi paksa</string>
<string name="keep_dm_verity">Pertahankan AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versi yang Terpasang: %1$s</string>
<string name="install_magisk_title">Versi Terbaru: %1$s</string>
<string name="uninstall">Copot</string>
@@ -42,11 +42,18 @@
<string name="disable_file_created">Modul akan dinonaktifkan pada reboot berikutnya</string>
<string name="disable_file_removed">Modul akan diaktifkan pada reboot berikutnya</string>
<string name="author">Dibuat oleh %1$s</string>
<string name="reboot_recovery">Reboot ke Recovery</string>
<string name="reboot_bootloader">Reboot ke Bootloader</string>
<string name="reboot_download">Reboot ke Download</string>
<!--Repo Fragment-->
<string name="update_available">Pembaruan Tersedia</string>
<string name="installed">Terpasang</string>
<string name="not_installed">Tidak Terpasang</string>
<string name="updated_on">Diperbarui pada: %1$s</string>
<string name="sorting_order">Urutkan Susunan</string>
<string name="sort_by_name">Urut berdasarkan nama</string>
<string name="sort_by_update">Urut berdasarkan pembaruan terakhir</string>
<!--Log Fragment-->
<string name="menuSaveLog">Simpan log</string>
@@ -58,12 +65,12 @@
<!--About Activity-->
<string name="about">Tentang</string>
<string name="app_changelog">Log pembaruan apl</string>
<string name="app_changelog">Log pembaruan</string>
<string name="translators"><![CDATA[<a href="https://github.com/krasCGQ">Albert I (krasCGQ)</a>]]></string>
<string name="app_version">Versi apl</string>
<string name="app_version">Versi</string>
<string name="app_source_code">Kode sumber</string>
<string name="donation">Donasi</string>
<string name="app_translators">Penerjemah apl</string>
<string name="app_translators">Penerjemah</string>
<string name="support_thread">Thread dukungan</string>
<!--Toasts, Dialogs-->
@@ -100,17 +107,19 @@
<string name="hide_manager_fail_toast">Kesalahan menyembunyikan Magisk Manager…</string>
<string name="download_zip_only">Unduh Zip Saja</string>
<string name="patch_boot_file">Tambal File Boot Image</string>
<string name="direct_install">Pasang Langsung (Rekomendasikan)</string>
<string name="direct_install">Pasang Langsung (Direkomendasikan)</string>
<string name="install_second_slot">Pasang ke Slot Kedua (Setelah OTA)</string>
<string name="select_method">Pilih Metode</string>
<string name="no_boot_file_patch_support">Versi target Magisk tidak mendukung penambalan file boot image</string>
<string name="boot_file_patch_msg">Pilih stock boot image dump dalam format .img atau .img.tar</string>
<string name="restore_img">Pulihkan Image</string>
<string name="uninstall_app">Copot Apl</string>
<string name="complete_uninstall">Copot Total</string>
<string name="restore_done">Pemulihan selesai!</string>
<string name="restore_fail">Cadangan stock tidak ada!</string>
<string name="uninstall_toast">Mencopot Magisk Manager dalam 5 detik, silahkan reboot secara manual setelahnya</string>
<string name="proprietary_title">Unduh Kode Proprieter</string>
<string name="proprietary_notice">Magisk Manager adalah aplikasi FOSS sehingga tidak menyertakan kode API proprieter Google SafetyNet.\n\nApakah Anda mengizinkan Magisk Manager untuk mengunduh sebuah ekstensi (berisi GoogleApiClient) untuk pemeriksaan SafetyNet?</string>
<string name="proprietary_notice">Magisk Manager adalah aplikasi FOSS, yang tidak menyertakan kode API proprieter Google SafetyNet.\n\nApakah Anda mengizinkan Magisk Manager untuk mengunduh sebuah ekstensi (berisi GoogleApiClient) untuk pemeriksaan SafetyNet?</string>
<string name="su_db_corrupt">Database SU rusak, akan membuat db baru</string>
<!--Settings Activity -->
@@ -134,7 +143,7 @@
<string name="settings_boot_format_title">Format Keluaran Boot yang Ditambal</string>
<string name="settings_boot_format_summary">Pilih format keluaran boot image yang ditambal.\nPilih .img untuk flash melalui mode recovery/download; pilih .img.tar untuk flash melalui ODIN.</string>
<string name="settings_core_only_title">Magisk Mode Inti Saja</string>
<string name="settings_core_only_summary">Aktifkan fitur inti saja, semua modul tidak akan dimuat. MagiskSU, MagiskHide, dan host tanpa sistem akan tetap diaktifkan</string>
<string name="settings_core_only_summary">Aktifkan fitur inti saja. MagiskSU, MagiskHide, dan host tanpa sistem akan tetap diaktifkan</string>
<string name="settings_magiskhide_summary">Sembunyikan Magisk dari berbagai pendeteksian</string>
<string name="settings_hosts_title">Host tanpa sistem</string>
<string name="settings_hosts_summary">Dukungan host tanpa sistem untuk apl pemblokir iklan</string>
@@ -154,6 +163,8 @@
<string name="request_timeout_summary">%1$s detik</string>
<string name="settings_su_reauth_title">Otentikasi ulang setelah pembaruan</string>
<string name="settings_su_reauth_summary">Otentikasi ulang izin superuser setelah pembaruan sebuah aplikasi</string>
<string name="settings_su_fingerprint_title">Aktifkan Otentikasi Sidik Jari</string>
<string name="settings_su_fingerprint_summary">Gunakan pemindai sidik jari untuk mengizinkan permintaan superuser</string>
<string name="multiuser_mode">Mode Multipengguna</string>
<string name="settings_owner_only">Pemilik Perangkat Saja</string>
@@ -162,7 +173,7 @@
<string name="owner_only_summary">Hanya pemilik yang memiliki akses root</string>
<string name="owner_manage_summary">Hanya pemilik yang dapat mengelola akses root dan menerima permintaan</string>
<string name="user_indepenent_summary">Setiap pengguna memiliki aturan root tersendiri</string>
<string name="multiuser_hint_owner_request">Permintaan telah dikirim kepada pemilik perangkat. Silakan beralih ke pemilik dan berikan izin</string>
<string name="multiuser_hint_owner_request">Permintaan telah dikirim kepada pemilik perangkat. Silakan beralih ke pemilik dan berikan izin yang diperlukan</string>
<string name="mount_namespace_mode">Mode Mount Ruang Nama</string>
<string name="settings_ns_global">Ruang Nama Global</string>
@@ -171,6 +182,7 @@
<string name="global_summary">Semua sesi root menggunakan mount ruang nama global</string>
<string name="requester_summary">Sesi root akan mewarisi ruang nama pemintanya</string>
<string name="isolate_summary">Setiap sesi root akan memiliki ruang nama tersendiri</string>
<string name="android_o_not_support">Tidak mendukung Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Permintaan Superuser</string>
@@ -199,6 +211,7 @@
<string name="su_revoke_msg">Konfirmasi untuk mencabut akses %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Tidak ada</string>
<string name="auth_fail">Otentikasi Gagal</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -50,6 +50,10 @@
<string name="update_available">Aggiornamento disponibile</string>
<string name="installed">Installato</string>
<string name="not_installed">Non installato</string>
<string name="updated_on">Aggiornato il: %1$s</string>
<string name="sorting_order">Ordinamento</string>
<string name="sort_by_name">Ordina per nome</string>
<string name="sort_by_update">Ordina per ultimo aggiornamento</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salva registro eventi</string>
@@ -159,6 +163,8 @@
<string name="request_timeout_summary">%1$s secondi</string>
<string name="settings_su_reauth_title">Ri-autentica dopo aggiornamento</string>
<string name="settings_su_reauth_summary">Ri-autentica i permessi Superuser dopo un aggiornamento dell\'app</string>
<string name="settings_su_fingerprint_title">Abilita autenticazione impronta</string>
<string name="settings_su_fingerprint_summary">Utilizza il sensore di impronte per accettare le richieste Superuser</string>
<string name="multiuser_mode">Modalità multiutente</string>
<string name="settings_owner_only">Solo proprietario del dispositivo</string>
@@ -205,6 +211,7 @@
<string name="su_revoke_msg">Confermi la revoca dei diritti di %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Nessuno</string>
<string name="auth_fail">Autenticatione fallita</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -10,12 +10,17 @@
<string name="install">インストール</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk がインストールされていません</string>
<string name="magisk_version_error">Magiskがインストールされていません</string>
<string name="checking_for_updates">更新を確認中...</string>
<string name="magisk_update_available">Magisk v%1$s が利用可能です!</string>
<string name="invalid_update_channel">不正な更新チャンネルです</string>
<string name="safetyNet_check_text">タップしてSafetyNetチェックを開始</string>
<string name="checking_safetyNet_status">SafetyNet Statusをチェック中…</string>
<string name="checking_safetyNet_status">SafetyNetの状態をチェック中…</string>
<string name="safetyNet_check_success">SafetyNetチェック成功</string>
<string name="safetyNet_api_error">SafetyNet APIエラー</string>
<string name="safetyNet_network_loss">ネットワーク接続がありません</string>
<string name="safetyNet_service_disconnected">サービスが終了されました</string>
<string name="safetyNet_res_invalid">応答が不正です</string>
<!--Install Fragment-->
<string name="advanced_settings_title">高度な設定</string>
@@ -24,7 +29,9 @@
<string name="current_magisk_title">インストール済: %1$s</string>
<string name="install_magisk_title">最新: %1$s</string>
<string name="uninstall">アンインストール</string>
<string name="uninstall_magisk_title">Magiskアンインストールします</string>
<string name="uninstall_magisk_title">Magiskアンインストール</string>
<string name="uninstall_magisk_msg">すべてのモジュールが無効化/削除されます。Rootも無効化され、ストレージが暗号化されていない場合、暗号化される場合があります</string>
<string name="update">%1$sの更新</string>
<!--Module Fragment-->
<string name="no_info_provided">(情報がありません)</string>
@@ -34,25 +41,32 @@
<string name="remove_file_deleted">次の再起動時にモジュールを削除しない</string>
<string name="disable_file_created">次の再起動時にモジュールを無効にする</string>
<string name="disable_file_removed">次の再起動時にモジュールを有効にする</string>
<string name="author">者: %1$s</string>
<string name="author">開発者: %1$s</string>
<string name="reboot_recovery">リカバリへ再起動</string>
<string name="reboot_bootloader">Bootloaderへ再起動</string>
<string name="reboot_download">Downloadへ再起動</string>
<!--Repo Fragment-->
<string name="update_available">利用可能な更新</string>
<string name="update_available">更新あり</string>
<string name="installed">インストール済</string>
<string name="not_installed">未インストール</string>
<string name="updated_on">更新日: %1$s</string>
<string name="sorting_order">並び順</string>
<string name="sort_by_name">名前順</string>
<string name="sort_by_update">最終更新日順</string>
<!--Log Fragment-->
<string name="menuSaveLog">ログ保存</string>
<string name="menuReload">リロード</string>
<string name="menuClearLog">ログ消去する</string>
<string name="logs_cleared">ログは正常にクリアされました</string>
<string name="menuSaveLog">ログ保存</string>
<string name="menuReload">再読み込み</string>
<string name="menuClearLog">ログ消去</string>
<string name="logs_cleared">ログを消去しました</string>
<string name="log_is_empty">ログは空です</string>
<string name="logs_save_failed">SDカードにログを書き込むことができません:</string>
<string name="logs_save_failed">SDカードにログを書き込ません:</string>
<!--About Activity-->
<string name="about">このアプリについて</string>
<string name="app_changelog">アプリの更新履歴</string>
<string name="translators">神楽坂桜Sakura_Sa233#Twitter/ hota (@lindwurm)</string>
<string name="translators">神楽坂桜Sakura_Sa233#Twitter/ hota (@lindwurm) / AndroPlus (@AndroPlus_org)</string>
<string name="app_version">アプリのバージョン</string>
<string name="app_source_code">ソースコード</string>
<string name="donation">寄付</string>
@@ -60,7 +74,7 @@
<string name="support_thread">サポートスレッド</string>
<!--Toasts, Dialogs-->
<string name="permissionNotGranted">この機能は外部ストレージへの書き込み権限がないと動しません</string>
<string name="permissionNotGranted">この機能は外部ストレージへの書き込み権限がないと動しません</string>
<string name="no_thanks">いいえ</string>
<string name="yes">はい</string>
<string name="ok">OK</string>
@@ -70,31 +84,69 @@
<string name="download">ダウンロード</string>
<string name="download_file_error">ダウンロード中にエラーが発生しました</string>
<string name="reboot">再起動</string>
<string name="zip_process_msg">zipファイルの処理中…</string>
<string name="downloading_toast">%1$s をダウンロード中</string>
<string name="magisk_update_title">新しいMagiskの更新が利用可能です</string>
<string name="settings_reboot_toast">再起動して設定を適用する</string>
<string name="release_notes">リリースノート</string>
<string name="release_notes">更新履歴</string>
<string name="repo_cache_cleared">リポジトリキャッシュを消去しました</string>
<string name="safetyNet_hide_notice">このアプリはSafetyNetを使用しています。\n既定ではMagiskHideで既に処理されています</string>
<string name="process_error">プロセスエラー</string>
<string name="internal_storage">zipは:\n[Internal Storage]%1$sに保存されます</string>
<string name="internal_storage">ZIPは\n[内部ストレージ]%1$sに保存されます</string>
<string name="zip_download_title">ダウンロード中</string>
<string name="zip_download_msg">ZIPファイルのダウンロード中 (%1$d%%) …</string>
<string name="zip_process_title">処理</string>
<string name="zip_process_msg">ZIPファイルの処理中…</string>
<string name="manager_update_title">Magisk Managerの更新があります</string>
<string name="manager_download_install">タップでダウンロードしてインストールします</string>
<string name="dtbo_patched_title">DTBOをパッチしました</string>
<string name="dtbo_patched_reboot">Magisk Managerはdtbo.imgをパッチしました。再起動してください</string>
<string name="magisk_updates">Magiskの更新</string>
<string name="flashing">書き込み中</string>
<string name="hide_manager_toast">Magisk Managerを隠しています…</string>
<string name="hide_manager_toast2">しばらくお待ちください…</string>
<string name="hide_manager_fail_toast">Magisk Managerを隠せませんでした…</string>
<string name="download_zip_only">ZIPのみダウンロード</string>
<string name="patch_boot_file">Bootイメージのパッチ</string>
<string name="direct_install">直接インストール (推奨)</string>
<string name="install_second_slot">第2スロットへインストール (OTA後)</string>
<string name="select_method">方法の選択</string>
<string name="no_boot_file_patch_support">指定されたMagiskバージョンはBootイメージのパッチに対応していません</string>
<string name="boot_file_patch_msg">StockのBootイメージ (.img または .img.tar形式) を選択してください</string>
<string name="complete_uninstall">完全にアンインストール</string>
<string name="restore_img">イメージのリストア</string>
<string name="uninstall_app">アプリのアンインストール</string>
<string name="restore_done">リストア完了!</string>
<string name="restore_fail">Stockのバックアップがありません</string>
<string name="uninstall_toast">5秒以内にMagisk Managerをアンインストールします。手動で再起動してください</string>
<string name="proprietary_title">プロプライエタリコードのダウンロード</string>
<string name="proprietary_notice">Magisk ManagerはFOSSのため、GoogleのプロプライエタリなSafetyNet APIコードを含んでいません。\n\nMagisk ManagerがSafetyNetチェックのための拡張機能 (GoogleApiClientを含む) をダウンロードすることを許可しますか?</string>
<string name="su_db_corrupt">SUデータベースが壊れています。DBを再生成します</string>
<!--Settings Activity -->
<string name="settings_general_category">一般</string>
<string name="settings_dark_theme_title">ダークテーマ</string>
<string name="settings_dark_theme_summary">ダークテーマを有効にする</string>
<string name="settings_dark_theme_summary">ダークテーマを有効化します</string>
<string name="settings_notification_title">更新通知</string>
<string name="settings_notification_summary">新しいバージョンが利用可能になったときに通知す</string>
<string name="settings_notification_summary">新しいバージョンがあるときに通知しま</string>
<string name="settings_clear_cache_title">キャッシュを消去</string>
<string name="settings_clear_cache_summary">オンラインリポジトリのキャッシュされた情報をクリアし、アプリをオンラインで更新す</string>
<string name="settings_clear_cache_summary">オンラインリポジトリのキャッシュされた情報を消去し、アプリをオンラインで更新しま</string>
<string name="settings_hide_manager_title">Magisk Managerを隠す</string>
<string name="settings_hide_manager_summary">Magisk Managerをランダムなパッケージ名で再パックします</string>
<string name="language">Language</string>
<string name="system_default">(システム標準)</string>
<string name="settings_update">更新設定</string>
<string name="settings_update_channel_title">更新チャンネル</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">カスタム</string>
<string name="settings_update_custom_msg">カスタムURLを入力</string>
<string name="settings_boot_format_title">パッチしたBootの出力形式</string>
<string name="settings_boot_format_summary">パッチしたBootイメージの出力形式を選択してください。\nfastboot/download modeでインストールするには .img を、ODINでインストールするには .img.tar を選択してください</string>
<string name="settings_core_only_title">Magisk コアモード</string>
<string name="settings_core_only_summary">コア機能のみを有効にすると、すべてのモジュールがロードされなくなります。 MagiskSU、MagiskHide、systemless hostsは引き続き有効になります</string>
<string name="settings_magiskhide_summary">さまざまな検出からMagiskを隠す</string>
<string name="settings_core_only_summary">コア機能のみを有効にします。すべてのモジュールが読み込まれなくなります。 MagiskSU、MagiskHide、systemless hostsは引き続き有効になります</string>
<string name="settings_magiskhide_summary">さまざまな検出からMagiskを隠しま</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">AdblockのためのSystemless hostsサポート</string>
<string name="settings_hosts_summary">広告ブロックアプリのためのSystemless hostsサポートを有効化します</string>
<string name="settings_su_app_adb">アプリとADB</string>
<string name="settings_su_app">アプリのみ</string>
@@ -105,10 +157,32 @@
<string name="settings_su_request_30">30秒</string>
<string name="settings_su_request_60">60秒</string>
<string name="superuser_access">スーパーユーザーアクセス</string>
<string name="auto_response">自動</string>
<string name="auto_response">自動応</string>
<string name="request_timeout">リクエストタイムアウト</string>
<string name="superuser_notification">スーパーユーザー通知</string>
<string name="request_timeout_summary">%1$s秒</string>
<string name="settings_su_reauth_title">アップグレード後の再認証</string>
<string name="settings_su_reauth_summary">アプリのアップグレード後にスーパーユーザー権限を再認証します</string>
<string name="settings_su_fingerprint_title">指紋認証の有効化</string>
<string name="settings_su_fingerprint_summary">スーパーユーザー権限のリクエストの許可に指紋認証を使います</string>
<string name="multiuser_mode">マルチユーザーモード</string>
<string name="settings_owner_only">端末の管理者のみ</string>
<string name="settings_owner_manage">端末の管理者が管理</string>
<string name="settings_user_independent">ユーザー毎</string>
<string name="owner_only_summary">端末の管理者のみスーパーユーザー権限を利用できます</string>
<string name="owner_manage_summary">端末の管理者のみがスーパーユーザー権限を管理し、リクエストを受け付けられます</string>
<string name="user_indepenent_summary">ユーザー毎にそれぞれスーパーユーザー権限を設定できます</string>
<string name="multiuser_hint_owner_request">端末の管理者にリクエストを送信しました。管理者に切り替えて権限を許可してください</string>
<string name="mount_namespace_mode">名前空間のマウントモード</string>
<string name="settings_ns_global">グローバル名前空間</string>
<string name="settings_ns_requester">継承された名前空間</string>
<string name="settings_ns_isolate">分離された名前空間</string>
<string name="global_summary">すべてのrootセッションがグローバル名前空間を使用します</string>
<string name="requester_summary">rootセッションはリクエスト者の名前空間を継承します</string>
<string name="isolate_summary">rootセッション毎に分離された名前空間を使用します</string>
<string name="android_o_not_support">Android 8.0以降では対応していません</string>
<!--Superuser-->
<string name="su_request_title">スーパーユーザーリクエスト</string>
@@ -134,9 +208,10 @@
<string name="su_snack_log_off">%1$s のログは無効です</string>
<string name="su_snack_revoke">%1$s の権限は取り消されました</string>
<string name="su_revoke_title">確認</string>
<string name="su_revoke_msg">%1$s の権限を取り消すことを承認しますか?</string>
<string name="su_revoke_msg">%1$s の権限を取り消しますか?</string>
<string name="toast">トースト通知</string>
<string name="none">なし</string>
<string name="auth_fail">認証に失敗しました</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -0,0 +1,221 @@
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moduliai</string>
<string name="downloads">Atsisiuntimai</string>
<string name="superuser">Super Naudotojas</string>
<string name="log">Surašyti (Log)</string>
<string name="settings">Nustatymai</string>
<string name="install">Instaliuoti</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk yra neinstaliuotas</string>
<string name="checking_for_updates">Ieškoma atnaujinimų…</string>
<string name="magisk_update_available">Magisk v%1$s yra galima!</string>
<string name="invalid_update_channel">Neteisingas atnaujinimų nustatymas</string>
<string name="safetyNet_check_text">Paspauskite SafetyNet paieškai</string>
<string name="checking_safetyNet_status">Ieškomas SafetyNet statusas…</string>
<string name="safetyNet_check_success">SafetyNet Paieška sėkminga</string>
<string name="safetyNet_api_error">SafetyNet API Klaida</string>
<string name="safetyNet_network_loss">Nėra prieigos prie interneto</string>
<string name="safetyNet_service_disconnected">Paslauga atjungta</string>
<string name="safetyNet_res_invalid">Gautas neteisingas atsakas</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Išplėstiniai nustatymai</string>
<string name="keep_force_encryption">Palikti priverstinį šifravimą</string>
<string name="keep_dm_verity">Palikti dm-verity</string>
<string name="current_magisk_title">Instaliuota versija: %1$s</string>
<string name="install_magisk_title">Naujausia versija: %1$s</string>
<string name="uninstall">Ištrinti</string>
<string name="uninstall_magisk_title">Ištrinti Magisk</string>
<string name="uninstall_magisk_msg">Visi moduliai bus išjungti/panaikinti. Roo bus panaikintas ir duomenys bus potencialiai užšifruoti, jeigu jie nėra užšifruoti.</string>
<string name="update">Atnaujinti %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nėra informacijos)</string>
<string name="no_modules_found">Modulių nesurasta</string>
<string name="update_file_created">Perkrovus sistemą modulis bus atnaulintas</string>
<string name="remove_file_created">Perkrovus sistemą modulis bus panaikintas</string>
<string name="remove_file_deleted">Perkrovus sistemą modulis nebus panaikintas</string>
<string name="disable_file_created">Perkrovus sistemą modulis bus išjungtas, bet ne panaikintas</string>
<string name="disable_file_removed">Perkrovus sistemą modulis bus įjungtas</string>
<string name="author">Sukūrė %1$s</string>
<string name="reboot_recovery">Perkrauti į Recovery</string>
<string name="reboot_bootloader">Perkrauti į Bootloader</string>
<string name="reboot_download">Perkraukite, į Download režimą</string>
<!--Repo Fragment-->
<string name="update_available">Galimas atnaujinimas</string>
<string name="installed">Instaliuota</string>
<string name="not_installed">Ne instaliuota</string>
<string name="updated_on">Atnaujinta: %1$s</string>
<string name="sorting_order">Išdėliojimo tvarka</string>
<string name="sort_by_name">Išdėlioti pagal pavadinimą</string>
<string name="sort_by_update">Išdėlioti pagal paskutinį atnaujinimą</string>
<!--Log Fragment-->
<string name="menuSaveLog">Išsauguti surašymus (log)</string>
<string name="menuReload">Iš naujo</string>
<string name="menuClearLog">Išvalyti surašymus (log)</string>
<string name="logs_cleared">Surašymas (log) sėkmingai užrašytas</string>
<string name="log_is_empty">Surašymas yra tuščias</string>
<string name="logs_save_failed">Nesugebėjome įrašyti surašymų į SD kortelę:</string>
<!--About Activity-->
<string name="about">Apie</string>
<string name="app_changelog">Pakeitimų sąrašas</string>
<string name="translators">Vv2233Bb</string>
<string name="app_version">Versija</string>
<string name="app_source_code">Prisidėkite</string>
<string name="donation">Auka</string>
<string name="app_translators">Vertėjai</string>
<string name="support_thread">Mūsų XDA puslapis</string>
<!--Toasts, Dialogs-->
<string name="permissionNotGranted">Ši įpatybė neveiks be prieigos prie saugyklos.</string>
<string name="no_thanks">Ačiū, nereikia</string>
<string name="yes">Taip</string>
<string name="ok">Gerai</string>
<string name="close">Uždaryti</string>
<string name="repo_install_title">Instaliuoti %1$s</string>
<string name="repo_install_msg">Ar jūs norite dabar instaliuoti %1$s?</string>
<string name="download">Atsisiųsti</string>
<string name="download_file_error">Atsisiunčiant failą įvyko klaida</string>
<string name="reboot">Perkrauti</string>
<string name="downloading_toast">Atsisiunčiamas %1$s</string>
<string name="magisk_update_title">Naujas Magisk atnaujinimas egzistuoja!</string>
<string name="settings_reboot_toast">Nustatymų įgalinimui prašome perkrauti telefoną</string>
<string name="release_notes">Šios versijos naujos įpatybės</string>
<string name="repo_cache_cleared">Repo failai išvalyti</string>
<string name="safetyNet_hide_notice">Ši programėlė naudoja SafetyNet\nMagiskHide tai automatiškai sutvarko</string>
<string name="process_error">Proceso klaida</string>
<string name="internal_storage">Zip failas yra saugomas:\n[Internal Storage]%1$s</string>
<string name="zip_download_title">Atsisiunčiama</string>
<string name="zip_download_msg">Atsiunčiamas zip failas(%1$d%%) …</string>
<string name="zip_process_title">Vyksta procesas</string>
<string name="zip_process_msg">Zip failas apdorojamas…</string>
<string name="manager_update_title">Atsirado naujas Magisk Manager atnaujinimas!</string>
<string name="manager_download_install">Paspauskite, kad atsisiųstumėte ir instaliuotumėte</string>
<string name="dtbo_patched_title">DTBO buvo ištaisytas!</string>
<string name="dtbo_patched_reboot">Magisk Manager ištaisė dtbo.img, prašome perkrauti telefoną</string>
<string name="magisk_updates">Magisk Atnaujinimai</string>
<string name="flashing">Instaliuojama</string>
<string name="hide_manager_toast">Magisk Manager paslėpiamas…</string>
<string name="hide_manager_toast2">Tai užtruks sekundėlę…</string>
<string name="hide_manager_fail_toast">Magisk Manager paslėpimas žlugo…</string>
<string name="download_zip_only">Atsisiųsti zip failą</string>
<string name="patch_boot_file">Ištaisyti boot failą</string>
<string name="direct_install">Tiesioginis atsisiuntimas (Rekomenduojamas)</string>
<string name="install_second_slot">Instaliuoti į antrą vietą (Po OTA)</string>
<string name="select_method">Pasirinkite metodą</string>
<string name="no_boot_file_patch_support">Pasirinkta Magisk versija nepalaiko pakeitimų boot faile.</string>
<string name="boot_file_patch_msg">Pasirinkti boot failą .img ar .img.tar formate.</string>
<string name="complete_uninstall">Pilnas pašalinimas</string>
<string name="restore_img">Atstatyti boot failą.</string>
<string name="uninstall_app">Ištrinti programėlę</string>
<string name="restore_done">Atstatymas įvykdytas!</string>
<string name="restore_fail">Gamyklinis atstatymo failas neegzistuoja!</string>
<string name="uninstall_toast">Magisk Manager bus pašalintas po 5 sekundžių, pašalinus perkraukite telefoną.</string>
<string name="proprietary_title">Atsisiųsti patentuotą kodą</string>
<string name="proprietary_notice">Magisk Manager yra FOSS todėl neturi Google patentuoto SafetyNet API kodo.\n\nAr jūs leidžiate Magisk Manager atsisiųsti papildinį (turintį GoogleApiClient) SafetyNet paieškai?</string>
<string name="su_db_corrupt">SU duomenų bazė yra sugadinta, perkursime naują duomenų bazę</string>
<!--Settings Activity -->
<string name="settings_general_category">Pagrininiai</string>
<string name="settings_dark_theme_title">Tamsi tema</string>
<string name="settings_dark_theme_summary">Įjungti tamsią temą</string>
<string name="settings_notification_title">Pranešimai atsiradus atnaujinimui</string>
<string name="settings_notification_summary">Parodyti pranešmus atsiradus naujai versijai</string>
<string name="settings_clear_cache_title">Išvalyti nereikalingus saugyklos failus</string>
<string name="settings_clear_cache_summary">Išvalyti patalpintą informaciją talpykloms internete, priverčia perkrauti inerneto jungtį</string>
<string name="settings_hide_manager_title">Paslėpti Magisk Manager</string>
<string name="settings_hide_manager_summary">Perpakuoti Magisk Manager su atsitiktiniu pakuotės pavadinimu</string>
<string name="language">Kalba</string>
<string name="system_default">(Sistemos)</string>
<string name="settings_update">Atnaujinimų nustatymai</string>
<string name="settings_update_channel_title">Atnaujinimų tipai</string>
<string name="settings_update_stable">Stabilūs</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Pasirinktiniai</string>
<string name="settings_update_custom_msg">Įvesti pasirinktinį URL</string>
<string name="settings_boot_format_title">Boot failo formatas</string>
<string name="settings_boot_format_summary">Pasirinkite boot failo formatą.\nPasirinkite .img įdiegimui per fastboot/download; Pasirinkite .img.tar įdiegimui per ODIN.</string>
<string name="settings_core_only_title">Magisk Pagrindinis režimas</string>
<string name="settings_core_only_summary">Įgalintos bus tik pagrindines funkcijos, visi moduliai bus išjungti. MagiskSU, Magisk Hide ir Sistemos pedejėjai liks įgalinti</string>
<string name="settings_magiskhide_summary">Paslėpti Magisk nuo įvairių susekimų</string>
<string name="settings_hosts_title">Sistemos padejėjai</string>
<string name="settings_hosts_summary">Sistemų padejėjų įgalinimas Adblock programėlėms</string>
<string name="settings_su_app_adb">Programėlėms ir ADB</string>
<string name="settings_su_app">Tik programėlėms</string>
<string name="settings_su_adb">Tik ADB</string>
<string name="settings_su_disable">Išjungta</string>
<string name="settings_su_request_10">10 sekundžių</string>
<string name="settings_su_request_20">20 sekundžių</string>
<string name="settings_su_request_30">30 sekundžių</string>
<string name="settings_su_request_60">60 sekundžių</string>
<string name="superuser_access">Supervartotojo prieiga</string>
<string name="auto_response">Automatinis atsakymas</string>
<string name="request_timeout">Prašymo laikas baigėsi</string>
<string name="superuser_notification">Supervartotojo pranešimai</string>
<string name="request_timeout_summary">%1$s sekundžių</string>
<string name="settings_su_reauth_title">Pakartotinai patvirtinti po atnaujinimo</string>
<string name="settings_su_reauth_summary">Pakartotinai patvirtinti supervartotojo leidimus po programėlės atnaujinimo</string>
<string name="settings_su_fingerprint_title">Įgalinti patvirtinimą piršto antspaudu</string>
<string name="settings_su_fingerprint_summary">Naudoti piršto antspaudą supervartotojo leidimo prašymų atsakymui</string>
<string name="multiuser_mode">Daugialypio vartotojo režimas</string>
<string name="settings_owner_only">Tik įrenginio savininkas</string>
<string name="settings_owner_manage">Įrenginio savininko valdomas</string>
<string name="settings_user_independent">Visų</string>
<string name="owner_only_summary">Tik įrenginio savininkas turi root prieigą</string>
<string name="owner_manage_summary">Tik įrenginio savinkas gali tvarkyti root prieigą ir gauti lenteles prašančias root prieigos</string>
<string name="user_indepenent_summary">Kiekvienas vartotojas turi savo atskiras root taisykles</string>
<string name="multiuser_hint_owner_request">Prašymas buvo nusiųstas savininkui. Prašome tapti savininku ir suteikite leidimą.</string>
<string name="mount_namespace_mode">Root sesijos vardų srities režimas</string>
<string name="settings_ns_global">Globali vardų sritis</string>
<string name="settings_ns_requester">Paveldima vardų sritis</string>
<string name="settings_ns_isolate">Izoliuota vardų sritis</string>
<string name="global_summary">Visos root sesijos naudoja globalią vardų sritį</string>
<string name="requester_summary">Root sesijos paveldi jos išprašytojo/s vardų sritį</string>
<string name="isolate_summary">Kiekviena root sesija turi savo izoliuotą vardų sritį</string>
<string name="android_o_not_support">Negalima įrenginiams naudojantiems Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Supervartotojo prašymas</string>
<string name="deny_with_str">Atmesti%1$s</string>
<string name="deny">Atmesti</string>
<string name="prompt">Klausti</string>
<string name="grant">Suteikti(a)</string>
<string name="su_warning">Suteikia pilną prieigą prie jūsų įrenginio\nAtmeskite jei neesate tikri dėl programėlės šaltinio!</string>
<string name="forever">Visados</string>
<string name="once">Vieną kartą</string>
<string name="tenmin">10 min</string>
<string name="twentymin">20 min</string>
<string name="thirtymin">30 min</string>
<string name="sixtymin">60 min</string>
<string name="su_allow_toast">%1$s gavo Supervartotojo teises</string>
<string name="su_deny_toast">%1$s negavo Supervartotojo teisių</string>
<string name="no_apps_found">Nėra surastų programėlių</string>
<string name="su_snack_grant">Supervartotojo teisių buvo %1$s suteikta</string>
<string name="su_snack_deny">Supervartotojo teisių buvo %1$s atmesta</string>
<string name="su_snack_notif_on">Buvo įjungta %1$s pranešimų</string>
<string name="su_snack_notif_off">Buvo išjungta %1$s pranešimų</string>
<string name="su_snack_log_on">%1$s surašymų buvo įjungta</string>
<string name="su_snack_log_off">%1$s surašymų buvo išjungta</string>
<string name="su_snack_revoke">%1$s teisių atšaukta</string>
<string name="su_revoke_title">Atšaukti?</string>
<string name="su_revoke_msg">Atšaukti %1$s teisių?</string>
<string name="toast">Išmesti</string>
<string name="none">Nėra</string>
<string name="auth_fail">Patvirtinimas žlugo</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Target UID:\u0020</string>
<string name="command">Komanda:\u0020</string>
</resources>

View File

@@ -27,7 +27,7 @@
<!--Install Fragment-->
<string name="advanced_settings_title">Zaawansowane Ustawienia</string>
<string name="keep_force_encryption">Zachowaj Szyfrowanie</string>
<string name="keep_force_encryption">Zachowaj force encryption</string>
<string name="keep_dm_verity">Zachowaj AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Zainstalowana Wersja: %1$s</string>
<string name="install_magisk_title">Ostatnia Wersja: %1$s</string>
@@ -53,6 +53,10 @@
<string name="update_available">Aktualizacja jest dostępna</string>
<string name="installed">Zainstalowany</string>
<string name="not_installed">Nie zainstalowany</string>
<string name="updated_on">Zaktualizowano: %1$s</string>
<string name="sorting_order">Kolejność Sortowania</string>
<string name="sort_by_name">Sortuj po nazwie</string>
<string name="sort_by_update">Sortuj po ostatniej aktualizacji</string>
<!--Log Fragment-->
<string name="menuSaveLog">Zapisz log</string>
@@ -112,7 +116,9 @@
<string name="no_boot_file_patch_support">Wersja docelowa programu Magisk nie obsługuje ładowania pliku boot image</string>
<string name="boot_file_patch_msg">Wybierz stock boot image w formacie .img lub .img.tar</string>
<string name="complete_uninstall">Odinstalowywanie Zakończone</string>
<string name="restore_done">Przywracanie zakończone!</string>
<string name="restore_img">Przywróć Obraz</string>
<string name="uninstall_app">Odinstaluj Aplikację</string>
<string name="restore_done">Przywracanie zakończone!</string>
<string name="restore_fail">Stock backup nie istnieje!</string>
<string name="uninstall_toast">Odinstalowanie Magisk Manager w ciągu 5 sekund, proszę następnie ręcznie ponownie uruchomić urządzenie</string>
<string name="proprietary_title">Pobierz Kod</string>
@@ -160,8 +166,10 @@
<string name="request_timeout_summary">%1$s sekund</string>
<string name="settings_su_reauth_title">Ponowienie uwierzytelnienia po aktualizacji</string>
<string name="settings_su_reauth_summary">Ponowne uwierzytelnianie uprawnienia superużytkownika po aktualizacji aplikacji</string>
<string name="settings_su_fingerprint_title">Włącz Uwierzytelnienie Odciskiem Palca</string>
<string name="settings_su_fingerprint_summary">Użyj skanera linii papilarnych, aby zezwolić na żądania supersu</string>
<string name="multiuser_mode">Tryb Multiusera</string>
<string name="multiuser_mode">Tryb Multiusera</string>
<string name="settings_owner_only">Tylko Właściciel Urządzenia</string>
<string name="settings_owner_manage">Zarządzanie Właścicielami Urządzenia</string>
<string name="settings_user_independent">Niezależny Użytkownik</string>
@@ -206,6 +214,7 @@
<string name="su_revoke_msg">Potwierdzasz odwołanie uprawnień %1$s?</string>
<string name="toast">Powiadomienie</string>
<string name="none">Brak</string>
<string name="auth_fail">Uwierzytelnienie Nieudane</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -45,12 +45,19 @@
<string name="disable_file_created">Módulo será desativado na próxima reinicialização</string>
<string name="disable_file_removed">Módulo será ativado na próxima reinicialização</string>
<string name="author">Criado por %1$s</string>
<string name="reboot_recovery">Reiniciar no Recovery</string>
<string name="reboot_bootloader">Reiniciar no Bootloader</string>
<string name="reboot_download">Reiniciar no Download</string>
<!--Repo Fragment-->
<string name="update_available">Atualização disponível</string>
<string name="installed">Instalado</string>
<string name="not_installed">Não Instalado</string>
<string name="updated_on">Atualizado em: %1$s</string>
<string name="sorting_order">Ordem de classificação</string>
<string name="sort_by_name">Classificar por nome</string>
<string name="sort_by_update">Classificar por última atualização</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salvar registro</string>
<string name="menuReload">Recarregar</string>
@@ -94,23 +101,29 @@
<string name="zip_process_msg">Processando arquivo zip …</string>
<string name="manager_update_title">Nova atualização do Magisk Manager disponível!</string>
<string name="manager_download_install">Pressione para baixar e instalar</string>
<string name="dtbo_patched_title">Patch no DTBO instalado!</string>
<string name="dtbo_patched_reboot">Magisk Manager instalou um patch no dtbo.img, por favor reinicie</string>
<string name="magisk_updates">Atualizações do Magisk</string>
<string name="flashing">Flasheando</string>
<string name="hide_manager_toast">Ocultando Magisk Manager…</string>
<string name="hide_manager_toast2">Isso pode demorar um pouco…</string>
<string name="hide_manager_fail_toast">Falha ao ocultar o Magisk Manager…</string>
<string name="download_zip_only">Baixar somente o zip</string>
<string name="patch_boot_file">Arquivo Patch Boot Image</string>
<string name="patch_boot_file">Patchear um arquivo Boot Image</string>
<string name="direct_install">Instalação Direta (Recomendado)</string>
<string name="install_second_slot">Instalação no segundo Slot (Depois do OTA)</string>
<string name="select_method">Selecionar Método</string>
<string name="no_boot_file_patch_support">Versão do Magisk escolhida não suporta arquivo de patch boot image</string>
<string name="boot_file_patch_msg">Selecione a stock boot image despejada(dump) no formato .img ou img.tar</string>
<string name="complete_uninstall">Desinstalação Completa</string>
<string name="restore_img">Restaurar Images</string>
<string name="uninstall_app">Desinstalar App</string>
<string name="restore_done">Restauração Completa!</string>
<string name="restore_fail">backup da Stock não existe!</string>
<string name="uninstall_toast">Desinstalando o Magisk Manager em 5 segundos, por favor reinicie manualmente depois</string>
<string name="proprietary_title">Baixar Código do Proprietário</string>
<string name="proprietary_notice">Magisk Manager é FOSS então não contém o código proprietário da API SafetyNet do Google.\n\nVocê permite que o Magisk Manager baixe uma extensão (contém o GoogleApiClient) para verificações SafetyNet?</string>
<string name="su_db_corrupt">O Banco de dados do SU está corrompido, criará novo db</string>
<!--Settings Fragment -->
<string name="settings_general_category">Geral</string>
@@ -121,15 +134,17 @@
<string name="settings_clear_cache_title">Limpar Repo Cache</string>
<string name="settings_clear_cache_summary">Limpe as informações armazenadas em cache para repos. online, forçando o aplicativo a atualizar online</string>
<string name="settings_hide_manager_title">Ocultar Magisk Manager</string>
<string name="settings_hide_manager_summary">Criar um Magisk Manager com o nome do pacote aleatório</string>
<string name="language">Linguagem</string>
<string name="system_default">(Padrão do Sistema)</string>
<string name="settings_update">Atualizar Configurações</string>
<string name="settings_update_channel_title">Canal de atualizações</string>
<string name="settings_update_stable">Estável</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_boot_format_title">Formato de Saida do Boot Patcheado</string>
<string name="settings_boot_format_summary">Selecione o formato de saida do Boot Image Patcheado.\nSelecione .img para flashear através do fastboot/modo de download; Selecione .img.tar para flashear com o ODIN.</string>
<string name="settings_update_custom">personalizado</string>
<string name="settings_update_custom_msg">Insira um URL personalizado</string>
<string name="settings_boot_format_title">Formato de Saida do Boot com patch instalado</string>
<string name="settings_boot_format_summary">Selecione o formato de saida do Boot Image com patch instalado.\nSelecione .img para flashear através do fastboot/modo de download; Selecione .img.tar para flashear com o ODIN.</string>
<string name="settings_core_only_title">Magisk modo somente Core</string>
<string name="settings_core_only_summary">Ativar somente recursos principais, todos os módulos não serão carregados. MagiskSU, MagiskHide, e systemless hosts ainda estará ativado</string>
<string name="settings_magiskhide_summary">Ocultar Magisk de várias detecções</string>
@@ -151,6 +166,8 @@
<string name="request_timeout_summary">%1$s segundos</string>
<string name="settings_su_reauth_title">Re-autenticar após a atualização</string>
<string name="settings_su_reauth_summary">Re-autenticar permissões de superusuário após as atualizações de um aplicativo</string>
<string name="settings_su_fingerprint_title">Ativar autenticação de impressão digital</string>
<string name="settings_su_fingerprint_summary">Use o scanner de impressão digital para permitir solicitações de superusuário</string>
<string name="multiuser_mode">Modo Multiusuário</string>
<string name="settings_owner_only">Apenas Proprietário do Dispositivo</string>
@@ -168,7 +185,8 @@
<string name="global_summary">Todas as sessões raiz usam o namespace de montagem global</string>
<string name="requester_summary">As sessões de raiz herdarão o namespace do seu solicitante</string>
<string name="isolate_summary">Cada sessão raiz terá seu próprio namespace isolado</string>
<string name="android_o_not_support">Não suporta Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Solicitação de superusuário</string>
<string name="deny_with_str">Negar%1$s</string>
@@ -196,7 +214,8 @@
<string name="su_revoke_msg">Revogar os diretos do %1$s, Confirmar?</string>
<string name="toast">Notificação(Toast)</string>
<string name="none">Nenhum</string>
<string name="auth_fail">Falha na autenticação</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Alvo UID:\u0020</string>

View File

@@ -12,11 +12,11 @@
<string name="magisk_version_error">Magisk yüklü değil</string>
<string name="checking_for_updates">Güncelleştirmeler denetleniyor…</string>
<string name="magisk_update_available">Magisk v%1$s mevcut!</string>
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</string>
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</string>
<string name="safetyNet_check_text">SafetyNet kontrolünü başlatmak için dokunun</string>
<string name="checking_safetyNet_status">SafetyNet durumu kontrol ediliyor…</string>
<string name="safetyNet_check_success">SafetyNet Kontrolü Başarılı</string>
<string name="safetyNet_api_error">SafetyNet API Hatası</string>
<string name="safetyNet_api_error">SafetyNet API Hatası</string>
<string name="safetyNet_network_loss">Ağ bağlantısı kullanılamıyor</string>
<string name="safetyNet_service_disconnected">Hizmet sonlandırıldı</string>
<string name="safetyNet_res_invalid">Yanıt geçersiz</string>
@@ -24,7 +24,7 @@
<!--Install Fragment-->
<string name="advanced_settings_title">Gelişmiş Ayarlar</string>
<string name="keep_force_encryption">Şifrelemeyi zorlamayı sürdür</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity \'yi koru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'yi koru</string>
<string name="current_magisk_title">Yüklü Sürüm: %1$s</string>
<string name="install_magisk_title">Yeni Sürüm: %1$s</string>
<string name="uninstall">Kaldır</string>
@@ -49,6 +49,10 @@
<string name="update_available">Güncelleme Mevcut</string>
<string name="installed">Yüklenmiş</string>
<string name="not_installed">Yüklenmemiş</string>
<string name="updated_on">Güncelleme: %1$s</string>
<string name="sorting_order">Sıralama Düzeni</string>
<string name="sort_by_name">İsme göre sırala</string>
<string name="sort_by_update">Son güncellemeye göre sırala</string>
<!--Log Fragment-->
<string name="menuSaveLog">Günlüğü kaydet</string>
@@ -93,27 +97,29 @@
<string name="zip_process_msg">Zip dosyası işleniyor …</string>
<string name="manager_update_title">Yeni Magisk Manager Güncellemesi Mevcut!</string>
<string name="manager_download_install">İndirmek ve yüklemek için dokunun</string>
<string name="dtbo_patched_title">DTBO yamalandı!</string>
<string name="dtbo_patched_reboot">Magisk Manager dtbo.img\'yi yamaladı, lütfen yeniden başlatın</string>
<string name="dtbo_patched_title">DTBO yamalandı!</string>
<string name="dtbo_patched_reboot">Magisk Manager dtbo.img\'yi yamaladı, lütfen yeniden başlatın</string>
<string name="magisk_updates">Magisk Güncellemeleri</string>
<string name="flashing">Yükleniyor</string>
<string name="hide_manager_toast">Magisk Manager Gizleniyor…</string>
<string name="hide_manager_toast2">Bu biraz zaman alabilir…</string>
<string name="hide_manager_toast2">Bu biraz zaman alabilir…</string>
<string name="hide_manager_fail_toast">Magisk Manager\'ı Gizleme başarısız oldu…</string>
<string name="download_zip_only">Yalnızca Zip Dosyasını İndir</string>
<string name="patch_boot_file">Önyükleme İmaj Dosyasını Yamala</string>
<string name="direct_install">Doğrudan Yükle (Önerilen)</string>
<string name="install_second_slot">İkinci Yuvaya Yükle (OTA\'dan sonra)</string>
<string name="install_second_slot">İkinci Yuvaya Yükle (OTA\'dan sonra)</string>
<string name="select_method">Yöntem Seçin</string>
<string name="no_boot_file_patch_support">Hedef Magisk sürümü önyükleme imaj dosyasını yamalamayı desteklemiyor</string>
<string name="boot_file_patch_msg">.img veya .img.tar formatında stok önyükleme imajını seçin</string>
<string name="complete_uninstall">Tamamen Kaldır</string>
<string name="restore_img">Önyükleme İmajını Geri Yükle</string>
<string name="uninstall_app">Uygulamayı Kaldır</string>
<string name="restore_done">Yenileme tamamlandı!</string>
<string name="restore_fail">Stok önyükleme yedeği yok!</string>
<string name="uninstall_toast">Magisk Manager\'ı 5 saniye içinde kaldırdıktan sonra lütfen daha sonra elle yeniden başlatın</string>
<string name="proprietary_title">Tescil Kodunu İndirin</string>
<string name="proprietary_notice">Magisk Yöneticisi, FOSS olduğundan Google\'ın tescilli olduğu SafetyNet API kodunu içermez.\n\nMagisk Manager\'ın SafetyNet kontrolü için bir uzantıyı (GoogleApiClient içeriyor) indirmesine izin veriyor musunuz?</string>
<string name="su_db_corrupt">SU veritabanı bozuk, yeni db oluşturacak</string>
<string name="uninstall_toast">Magisk Manager\'ı 5 saniye içinde kaldırdıktan sonra lütfen daha sonra elle yeniden başlatın</string>
<string name="proprietary_title">Tescil Kodunu İndirin</string>
<string name="proprietary_notice">Magisk Yöneticisi, FOSS olduğundan Google\'ın tescilli olduğu SafetyNet API kodunu içermez.\n\nMagisk Manager\'ın SafetyNet kontrolü için bir uzantıyı (GoogleApiClient içeriyor) indirmesine izin veriyor musunuz?</string>
<string name="su_db_corrupt">SU veritabanı bozuk, yeni db oluşturacak</string>
<!--Settings Activity -->
<string name="settings_general_category">Genel</string>
@@ -124,15 +130,15 @@
<string name="settings_clear_cache_title">Repo Önbelleğini Temizle</string>
<string name="settings_clear_cache_summary">Çevrimiçi repolar için önbellek bilgilerini temizle, uygulamayı çevrimiçi yenilemeye zorla</string>
<string name="settings_hide_manager_title">Magisk Manager\'ı Gizle</string>
<string name="settings_hide_manager_summary">Rastgele seçilen bir paket adı ile Magisk Manager yeniden paketlenecek</string>
<string name="settings_hide_manager_summary">Rastgele seçilen bir paket adı ile Magisk Manager yeniden paketlenecek</string>
<string name="language">Dil</string>
<string name="system_default">(Sistem Varsayılanı)</string>
<string name="settings_update">Güncelleme Ayarları</string>
<string name="settings_update_channel_title">Güncelleme Kanalı</string>
<string name="settings_update_stable">Kararlı</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Özel</string>
<string name="settings_update_custom_msg">Özel bir URL ekleyin</string>
<string name="settings_update_custom">Özel</string>
<string name="settings_update_custom_msg">Özel bir URL ekleyin</string>
<string name="settings_boot_format_title">Yamalı Önyükleme Formatı</string>
<string name="settings_boot_format_summary">Yamalı önyükleme imaj dosyasının formatını seçin\nFastboot/indirme modunda yüklemek için .img seçeneğini seçin; ODIN ile yüklemek için .img.tar\'ı seçin.</string>
<string name="settings_core_only_title">Magisk Sadece Çekirdek Modu</string>
@@ -154,8 +160,10 @@
<string name="request_timeout">İstek Zaman Aşımı</string>
<string name="superuser_notification">Yetkili Kullanıcı Bildirimi</string>
<string name="request_timeout_summary">%1$s saniye</string>
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrulaması yapın</string>
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrulama</string>
<string name="settings_su_reauth_summary">Uygulama yükseltmeleri sonrasında yetkili kullanıcı izinlerini yeniden doğrulama</string>
<string name="settings_su_fingerprint_title">Parmak İzi Kimlik Doğrulamayı Etkinleştir</string>
<string name="settings_su_fingerprint_summary">Yetkili kullanıcı isteklerine izin vermek için parmak izi tarayıcısını kullan</string>
<string name="multiuser_mode">Çok Kullanıcılı Mod</string>
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</string>
@@ -202,6 +210,7 @@
<string name="su_revoke_msg">%1$s hakları geri alınsın mı?</string>
<string name="toast">Pencere</string>
<string name="none">Hiçbiri</string>
<string name="auth_fail">Kimlik Doğrulama Başarısız</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -10,12 +10,12 @@
<!--Status Fragment-->
<string name="magisk_version_error">Magisk не встановлено</string>
<string name="checking_for_updates">Перевірка оновлень…</string>
<string name="magisk_update_available">Доступно Magisk v%1$s!</string>
<string name="invalid_update_channel">Неправильний канал оновлень</string>
<string name="safetyNet_check_text">Перевірити статус SafetyNet</string>
<string name="checking_safetyNet_status">Перевірка статусу SafetyNet…</string>
<string name="safetyNet_check_success">Перевірку SafetyNet завершено</string>
<string name="safetyNet_check_success">Результат перевірки SafetyNet</string>
<string name="safetyNet_api_error">Помилка в API SafetyNet</string>
<string name="safetyNet_network_loss">Підключення до інтернету втрачено</string>
<string name="safetyNet_service_disconnected">Службу зупинено</string>
@@ -41,11 +41,18 @@
<string name="disable_file_created">Модуль вимкнеться при перезавантаженні</string>
<string name="disable_file_removed">Модуль увімкнеться при перезавантаженні</string>
<string name="author">Автор: %1$s</string>
<string name="reboot_recovery">Перезавантаження в Recovery</string>
<string name="reboot_bootloader">Перезавантаження в Bootloader</string>
<string name="reboot_download">Перезавантаження в Download</string>
<!--Repo Fragment-->
<string name="update_available">Доступне оновлення</string>
<string name="installed">Встановлено</string>
<string name="not_installed">Не встановлено</string>
<string name="updated_on">Оновлено: %1$s</string>
<string name="sorting_order">Порядок сортування</string>
<string name="sort_by_name">Сортувати за ім'ям</string>
<string name="sort_by_update">Сортувати за оновленням</string>
<!--Log Fragment-->
<string name="menuSaveLog">Зберегти логи</string>
@@ -90,6 +97,8 @@
<string name="zip_process_msg">Опрацювання архіву …</string>
<string name="manager_update_title">Доступне оновлення Magisk Manager!</string>
<string name="manager_download_install">Натисніть, щоб завантажити і встановити</string>
<string name="dtbo_patched_title">DTBO пропатчено!</string>
<string name="dtbo_patched_reboot">Magisk Manager пропатчив dtbo.img, будь ласка, перезавантажте пристрій</string>
<string name="magisk_updates">Оновлення Magisk</string>
<string name="flashing">Прошивання</string>
<string name="hide_manager_toast">Приховування Magisk Manager…</string>
@@ -103,11 +112,14 @@
<string name="no_boot_file_patch_support">Цільова версія Magisk не підтримує пропатчування boot образу</string>
<string name="boot_file_patch_msg">Виберіть оригінальний дамп boot образу в форматі .img чи .img.tar</string>
<string name="complete_uninstall">Видалення виконано</string>
<string name="restore_img">Відновити образ</string>
<string name="uninstall_app">Видалити додаток</string>
<string name="restore_done">Відновлення завершено!</string>
<string name="restore_fail">Немає резервної копії оригінального boot образу</string>
<string name="uninstall_toast">Видалення Менеджера Magisk протягом 5 секунд, потім, будь ласка, вручну перезавантажте</string>
<string name="uninstall_toast">Видалення Magisk Manager протягом 5 секунд, потім, будь ласка, вручну перезавантажте пристрій</string>
<string name="proprietary_title">Завантажити пропрієтарний код</string>
<string name="proprietary_notice">Менеджер Magisk - це безкоштовний додаток з відкритим вихідним кодом, тому він не містить пропрієтарний код API SafetyNet від компанії Google.\n\nДозволити Менеджеру Magisk завантажити розширення (яке містить GoogleApiClient) для перевірки SafetyNet?</string>
<string name="proprietary_notice">Magisk Manager — це безкоштовний додаток з відкритим вихідним кодом, тому він не містить пропрієтарний код API SafetyNet від компанії Google.\n\nДозволити Magisk Manager завантажити розширення (яке містить GoogleApiClient) для перевірки SafetyNet?</string>
<string name="su_db_corrupt">База даних SU пошкоджена, буде створено нову БД</string>
<!--Settings Activity -->
<string name="settings_general_category">Основні</string>
@@ -118,13 +130,15 @@
<string name="settings_clear_cache_title">Очищення кешу</string>
<string name="settings_clear_cache_summary">Очистити збережену інформацію про мережеві репозиторії, змушуючи програму примусово оновлюватися через Інтернет</string>
<string name="settings_hide_manager_title">Приховати Magisk Manager</string>
<string name="settings_hide_manager_summary">Перезібрати Менеджер Magisk з випадковим іменем пакету</string>
<string name="settings_hide_manager_summary">Перезібрати Magisk Manager з випадковим іменем пакету</string>
<string name="language">Мова</string>
<string name="system_default">Стандартна (системна)</string>
<string name="settings_update">Оновити налаштування</string>
<string name="settings_update_channel_title">Канал оновлення</string>
<string name="settings_update_stable">Стабільний реліз</string>
<string name="settings_update_beta">Бета реліз</string>
<string name="settings_update_custom">Власний</string>
<string name="settings_update_custom_msg">Вставте власний URL</string>
<string name="settings_boot_format_title">Формат пропатченого образу</string>
<string name="settings_boot_format_summary">Виберіть формат вихідного пропатченого boot образу.\n.img - для прошивання через fastboot/download режим;\n.img.tar - для прошивання через ODIN.</string>
<string name="settings_core_only_title">Режим ядра Magisk</string>
@@ -148,6 +162,8 @@
<string name="request_timeout_summary">%1$s сек.</string>
<string name="settings_su_reauth_title">Повторна автентифікація</string>
<string name="settings_su_reauth_summary">Перевидача прав суперкористувача після оновлення програм</string>
<string name="settings_su_fingerprint_title">Увімкнути автентифікацію за відбитком</string>
<string name="settings_su_fingerprint_summary">Використовувати сканер відбитків пальців, щоб надавати дозвіл суперкористувача</string>
<string name="multiuser_mode">Багатокористувацький режим</string>
<string name="settings_owner_only">Тільки власник</string>
@@ -165,6 +181,7 @@
<string name="global_summary">Всі сеанси Суперкористувача використовують глобальний простір імен</string>
<string name="requester_summary">Сеанси Суперкористувача наслідують простір імен запитувача</string>
<string name="isolate_summary">Кожнен сеанс Суперкористувача має власний ізольований простір імен</string>
<string name="android_o_not_support">Не підтримує Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Запит прав Суперкористувача</string>
@@ -193,6 +210,7 @@
<string name="su_revoke_msg">Підтвердити відкликання прав для %1$s?</string>
<string name="toast">Спливаюче сповіщення</string>
<string name="none">Нічого</string>
<string name="auth_fail">Помилка автентифікації</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -50,6 +50,10 @@
<string name="update_available">可更新</string>
<string name="installed">已安装</string>
<string name="not_installed">未安装</string>
<string name="updated_on">更新于: %1$s</string>
<string name="sorting_order">排序方式</string>
<string name="sort_by_name">按名称排序</string>
<string name="sort_by_update">按更新时间排序</string>
<!--Log Fragment-->
<string name="menuSaveLog">保存日志</string>

View File

@@ -210,5 +210,12 @@
<string name="android_o_not_support">不支援 Android 8.0+</string>
<string name="uninstall_app">解除安裝應用程式</string>
<string name="restore_img">還原原廠映像檔</string>
<string name="updated_on">更新於:%1$s</string>
<string name="sorting_order">排序方式</string>
<string name="sort_by_name">按名稱排序</string>
<string name="sort_by_update">按更新時間排序</string>
<string name="settings_su_fingerprint_title">啟用指紋認證</string>
<string name="settings_su_fingerprint_summary">用指紋辨識來允許超級用戶權限</string>
<string name="auth_fail">認證失敗</string>
</resources>

View File

@@ -110,7 +110,7 @@
<string name="hide_manager_fail_toast">Hide Magisk Manager failed…</string>
<string name="download_zip_only">Download Zip Only</string>
<string name="patch_boot_file">Patch Boot Image File</string>
<string name="direct_install">Direct Install (Recommend)</string>
<string name="direct_install">Direct Install (Recommended)</string>
<string name="install_second_slot">Install to Second Slot (After OTA)</string>
<string name="select_method">Select Method</string>
<string name="no_boot_file_patch_support">Target Magisk version doesn\'t support boot image file patching</string>
@@ -122,7 +122,7 @@
<string name="restore_fail">Stock backup does not exist!</string>
<string name="uninstall_toast">Uninstalling Magisk Manager in 5 seconds, please manually reboot afterwards</string>
<string name="proprietary_title">Download Proprietary Code</string>
<string name="proprietary_notice">Magisk Manager is FOSS so doesn\'t contain Google\'s proprietary SafetyNet API code.\n\nDo you allow Magisk Manager to download an extension (contains GoogleApiClient) for SafetyNet checks?</string>
<string name="proprietary_notice">Magisk Manager is FOSS, which doesn\'t contain Google\'s proprietary SafetyNet API code.\n\nDo you allow Magisk Manager to download an extension (contains GoogleApiClient) for SafetyNet checks?</string>
<string name="su_db_corrupt">SU database is corrupted, will recreate new db</string>
<!--Settings Activity -->
@@ -135,6 +135,8 @@
<string name="settings_clear_cache_summary">Clear the cached information for online repos, forces the app to refresh online</string>
<string name="settings_hide_manager_title">Hide Magisk Manager</string>
<string name="settings_hide_manager_summary">Repackage Magisk Manager with random package name</string>
<string name="settings_restore_manager_title">Restore Magisk Manager</string>
<string name="settings_restore_manager_summary">Restore Magisk Manager with original package</string>
<string name="language">Language</string>
<string name="system_default">(System Default)</string>
<string name="settings_update">Update Settings</string>
@@ -146,7 +148,7 @@
<string name="settings_boot_format_title">Patched Boot Output Format</string>
<string name="settings_boot_format_summary">Select the format of the output patched boot image.\nChoose .img to flash through fastboot/download mode; choose .img.tar to flash with ODIN.</string>
<string name="settings_core_only_title">Magisk Core Only Mode</string>
<string name="settings_core_only_summary">Enable only core features, all modules will not be loaded. MagiskSU, MagiskHide, and systemless hosts will still be enabled</string>
<string name="settings_core_only_summary">Enable only core features. MagiskSU, MagiskHide and systemless hosts will still be enabled, but no modules will be loaded.</string>
<string name="settings_magiskhide_summary">Hide Magisk from various detections</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Systemless hosts support for Adblock apps</string>
@@ -166,6 +168,8 @@
<string name="request_timeout_summary">%1$s seconds</string>
<string name="settings_su_reauth_title">Re-authenticate after upgrade</string>
<string name="settings_su_reauth_summary">Re-authenticate superuser permissions after an application upgrades</string>
<string name="settings_su_fingerprint_title">Enable Fingerprint Authentication</string>
<string name="settings_su_fingerprint_summary">Use fingerprint scanner to allow superuser requests</string>
<string name="multiuser_mode">Multiuser Mode</string>
<string name="settings_owner_only">Device Owner Only</string>
@@ -174,7 +178,7 @@
<string name="owner_only_summary">Only owner has root access</string>
<string name="owner_manage_summary">Only owner can manage root access and receive request prompts</string>
<string name="user_indepenent_summary">Each user has its own separate root rules</string>
<string name="multiuser_hint_owner_request">A request has been sent to the device owner. Please switch to the owner and grant the permission</string>
<string name="multiuser_hint_owner_request">A request has been sent to the device owner. Please switch to the owner and grant the permissions required</string>
<string name="mount_namespace_mode">Mount Namespace Mode</string>
<string name="settings_ns_global">Global Namespace</string>
@@ -183,7 +187,7 @@
<string name="global_summary">All root sessions use the global mount namespace</string>
<string name="requester_summary">Root sessions will inherit its requester\'s namespace</string>
<string name="isolate_summary">Each root session will have its own isolated namespace</string>
<string name="android_o_not_support">Does not support on Android 8.0+</string>
<string name="android_o_not_support">Does not support Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Superuser Request</string>
@@ -212,6 +216,7 @@
<string name="su_revoke_msg">Confirm to revoke %1$s rights?</string>
<string name="toast">Toast</string>
<string name="none">None</string>
<string name="auth_fail">Authentication Failed</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>

View File

@@ -20,6 +20,11 @@
android:title="@string/settings_hide_manager_title"
android:summary="@string/settings_hide_manager_summary" />
<Preference
android:key="restore"
android:summary="@string/settings_restore_manager_summary"
android:title="@string/settings_restore_manager_title" />
</PreferenceCategory>
<PreferenceCategory
@@ -107,6 +112,11 @@
android:entries="@array/su_notification"
android:entryValues="@array/value_array" />
<SwitchPreference
android:key="su_fingerprint"
android:title="@string/settings_su_fingerprint_title"
android:summary="@string/settings_su_fingerprint_summary"/>
<SwitchPreference
android:key="su_reauth"
android:title="@string/settings_su_reauth_title"