Compare commits

..

101 Commits

Author SHA1 Message Date
topjohnwu
2d5cf8a6fe Push release notes 2020-11-13 04:32:20 -08:00
topjohnwu
290959f74c Fix strings resources 2020-11-13 04:22:06 -08:00
Ilya Kushnir
4d9f58ee72 Update RU strings & tidying up EN 2020-11-13 03:03:35 -08:00
topjohnwu
9241246de6 Only use MediaStore APIs on Android 11+
Fix #3428
2020-11-13 02:53:30 -08:00
Heimen Stoffels
58a5d52b78 Updated Dutch translation 2020-11-13 02:34:49 -08:00
Rom
2906178ac3 Update French translation 2020-11-13 02:34:21 -08:00
topjohnwu
e0afbb647b Minor changes 2020-11-13 02:31:54 -08:00
topjohnwu
50be50cf6a Update dependencies 2020-11-13 00:58:41 -08:00
topjohnwu
77a9d3a5bc Upgrade AGP 2020-11-12 23:29:07 -08:00
topjohnwu
f9c7a4c933 Redirect /data/adb/magisk/busybox
Workaround some stupid Samsung kernel restrictions
2020-11-11 02:26:07 -08:00
topjohnwu
2b759b84b0 Properly reset string 2020-11-09 21:17:21 -08:00
topjohnwu
1e45c63ea5 Scan for zygote periodically
Fix #3417
2020-11-08 03:44:43 -08:00
topjohnwu
b14a260827 Offset pid_set by 1
PID starts at 1, not 0
2020-11-08 02:12:35 -08:00
topjohnwu
ade1597e03 Support hiding apps not installed in main user
Fix #2181, close #1840
2020-11-08 01:53:18 -08:00
topjohnwu
2739d3cb67 Update PayPal link 2020-11-07 15:10:10 -08:00
cheese1
dc5e78e142 Fix German Translation Typo 2020-11-07 14:48:22 -08:00
vvb2060
e9759a5868 Update HideViewModel 2020-11-07 14:47:44 -08:00
AdiityaAndre
e7ab802498 Update Indonesian translation 2020-11-07 14:43:46 -08:00
kubalav
42672c2e27 Update Slovak translation 2020-11-07 14:43:21 -08:00
孟武.尼德霍格.龍
e65d61d313 更新繁體中文字串
更新繁體中文字串
2020-11-07 14:42:48 -08:00
Taras
076da5c7c4 Update Ukrainian translation 2020-11-07 14:42:11 -08:00
vvb2060
9deaf2507c Update zh-rCN translation 2020-11-07 14:41:32 -08:00
kam821
5c114c67de Update Polish translation
- Add missing strings
- Small corrections.
- Changed "Magisk Manager" translation to form which better reflects the original meaning in Polish.
2020-11-07 14:40:56 -08:00
programminghoch10
d904cb0441 Updated german translations 2020-11-07 14:40:02 -08:00
pablomh
bd1dd9d863 Fix ensure_bb by assigning the arguments propery
If we assign the execution output directly it will fail (tested on Android 11):

pdx201:/ # INSTALLER=/data/adb/magisk_install /data/adb/magisk_install/flash_script.sh                                                                          
/data/adb/magisk_install/flash_script.sh[31]: typeset: -o: is not an identifier

Because:

local cmds=$($bb sh -o standalone -c "
	  for arg in \$(tr '\0' '\n' < /proc/$$/cmdline); do
	    if [ -z \"\$cmds\" ]; then
	      # Skip the first argument as we want to change the interpreter
	      cmds=\"sh -o standalone\"
	    else
	      cmds=\"\$cmds '\$arg'\"
	    fi
	  done
	  echo \$cmds")
/system/bin/sh: typeset: -o: is not an identifier

Signed-off-by: Pablo Mendez Hernandez <pablomh@gmail.com>
2020-11-07 14:39:03 -08:00
topjohnwu
afebe734b8 Fix several things regarding scripting 2020-11-07 14:36:13 -08:00
topjohnwu
e21a78164e Properly handle factory resets
Close #3345
2020-11-04 04:50:04 -08:00
topjohnwu
1e0f96d0fd Prefer platform implementation over internal 2020-11-04 04:42:02 -08:00
topjohnwu
bf650332d8 Update nanopb 2020-11-04 01:56:49 -08:00
topjohnwu
f32e0af830 Update resetprop help msg 2020-11-03 01:21:05 -08:00
topjohnwu
4c94f90e5d Templatize function callbacks 2020-11-03 01:16:55 -08:00
topjohnwu
ffb4224640 Don't use reserved symbols 2020-11-03 01:12:33 -08:00
topjohnwu
89fff4830b Mount proper system_root mirror in magiskd 2020-11-03 00:37:08 -08:00
topjohnwu
16e4c67992 Significantly broaden sepolicy.rule compatibility
Previously, Magisk uses persist or cache for storing modules' custom
sepolicy rules. In this commit, we significantly broaden its
compatibility and also prevent mounting errors.

The persist partition is non-standard and also critical for Snapdragon
devices, so we prefer not to use it by default.

We will go through the following logic to find the best suitable
non-volatile, writable location to store and load sepolicy.rule files:

Unencrypted data -> FBE data unencrypted dir -> cache -> metadata -> persist

This should cover almost all possible cases: very old devices have
cache partitions; newer devices will use FBE; latest devices will use
metadata FBE (which guarantees a metadata parition); and finally,
all Snapdragon devices have the persist partition (as a last resort).

Fix #3179
2020-11-02 23:20:38 -08:00
topjohnwu
cf47214ee4 Require Magisk v20.4 for modules
It has been long enough
2020-10-28 05:13:39 -07:00
topjohnwu
0feab753fb Fix coding errors and minor changes 2020-10-28 04:17:34 -07:00
Leorize
d0b6318b90 init/mount: support for dm-verity verified root
This commit adds support for kernel initialized dm-verity on legacy SAR
devices.

Tested on a Pixel 2 XL with a kernel patch to initialize mappings
specified via the `dm=` kernel parameter even when an initramfs is used.
2020-10-27 03:47:50 -07:00
topjohnwu
966e23b846 magiskinit code tidy-up 2020-10-26 20:46:15 -07:00
topjohnwu
5b8a1fc2a7 Minor renames 2020-10-25 21:41:14 -07:00
topjohnwu
02ea3ca525 Headers doesn't always occupy 1 page 2020-10-25 06:25:42 -07:00
topjohnwu
0632b146b8 Add vendor boot image support to magiskboot 2020-10-25 06:09:36 -07:00
topjohnwu
1b0b180761 Fix COMPRESSED macro
Fix #3383
2020-10-25 05:10:19 -07:00
topjohnwu
0d11f73a1d Handle unexpected exceptions
Fix #3276
2020-10-22 03:09:05 -07:00
vvb2060
533cb8eb58 Tapjacking protection 2020-10-22 02:40:47 -07:00
loading
8ac1181e9a Update Hindi translations 2020-10-21 00:43:15 -07:00
Ilya Kushnir
5ca1892eb0 Update RU strings 2020-10-21 00:42:09 -07:00
MASVA
e32db6a0e8 Update croatian language 2020-10-21 00:41:48 -07:00
kubalav
82fff615d6 Update Slovak translation 2020-10-21 00:40:36 -07:00
Rom
24a8f0808d Update French translation 2020-10-21 00:40:08 -07:00
vvb2060
4a7c3c06bc Disable hide/restore when no remote info 2020-10-20 23:56:44 -07:00
vvb2060
da93bbc1fe Fix network 2020-10-20 23:56:21 -07:00
topjohnwu
fa2dbe981e Handle retrofit errors 2020-10-20 03:03:40 -07:00
vvb2060
ce6cceae8b Smaller stub 2020-10-17 06:55:24 -07:00
topjohnwu
7b26e8b818 Update dependencies 2020-10-17 06:46:36 -07:00
topjohnwu
2da5fcb00b ANDROID_HOME is deprecated 2020-10-17 06:42:34 -07:00
topjohnwu
a079966f97 Migrate to AGP 4.1.0 2020-10-17 06:32:49 -07:00
vvb2060
468796c23d Add option to show OS apps 2020-10-17 05:57:43 -07:00
vvb2060
5833aadef5 Silence kotlin warnings 2020-10-17 05:57:35 -07:00
vvb2060
eb261c8026 Fix antlr warning
https://issuetracker.google.com/issues/150106190
2020-10-17 05:57:20 -07:00
vvb2060
a4c48847d1 Cancel vibration to sync with notification channel 2020-10-17 05:56:07 -07:00
vvb2060
43288be091 Prevent dot in the first position 2020-10-17 05:55:58 -07:00
vvb2060
1ad7a6fe93 Update activity display when download fails 2020-10-17 05:54:34 -07:00
topjohnwu
4e0a3f5e72 Fix compile errors 2020-10-17 04:28:20 -07:00
Davy Defaud
d7c33f647d Fix a typo and use the proper Unicode characters
- fix a French typo: raccourcis → raccourci
- French orthotypography: use a thin space before a question mark, and a true (non breaking) hyphen instead of a dash.
2020-10-17 04:18:00 -07:00
topjohnwu
9087207dc0 Minor changes 2020-10-17 04:14:12 -07:00
vvb2060
2760f37e6b Add userspace reboot 2020-10-17 03:54:51 -07:00
Miguel Cruces
3fa3426032 Spanish translations update 2020-10-17 03:54:17 -07:00
topjohnwu
2e4dc91b96 Better stub hiding experience 2020-10-17 03:40:43 -07:00
topjohnwu
aaaaa3d044 Minor refactoring 2020-10-15 00:19:11 -07:00
topjohnwu
1edc4449d5 Update lz4 to v1.9.2
Close #3334
2020-10-15 00:04:48 -07:00
topjohnwu
f3cd4da026 Make lz4_lg an exception of lz4_legacy 2020-10-14 23:45:06 -07:00
vvb2060
872c55207c Add com.android.i18n to apex path 2020-10-12 01:59:41 -07:00
topjohnwu
339ca6d666 Improve magiskboot info logging 2020-10-12 01:55:33 -07:00
topjohnwu
4aeac3b8f4 Support header_version 3 2020-10-12 01:06:42 -07:00
topjohnwu
d625beb7f3 Update --remove-modules implementation 2020-10-11 18:30:03 -07:00
topjohnwu
735b65c50c Update DoH implementation 2020-10-11 15:19:19 -07:00
topjohnwu
efb1eab327 Silence some warnings 2020-10-11 05:47:47 -07:00
topjohnwu
49d4785da0 Fix strings 2020-10-11 05:26:50 -07:00
RoySchutte
28e65ce383 Update strings.xml
I don't know who else is translating Magisk Manager, but I noticed some weird translations. Fixed a couple of them in this update.
2020-10-11 05:24:16 -07:00
Antikruk
c3b6a48373 belarusian 2020-10-11 05:23:51 -07:00
omerakgoz34
a42ebd429b Update Turkish(TR) Translation 2020-10-11 05:22:01 -07:00
MASVA
8f89010752 Update croatian language 2020-10-11 05:20:34 -07:00
GrepItAll
105a18f719 Temporary note about OTA update no longer working
Added temporary note about OTA update no longer working, as this option has been disabled in newer Magisk Manager versions
2020-10-11 05:19:38 -07:00
topjohnwu
eb04ca4c4a Make provider boot aware
Close #3322
2020-10-11 05:19:05 -07:00
topjohnwu
6092d7ca88 Minor cleanups 2020-10-11 05:10:02 -07:00
topjohnwu
66cad101c0 Support new canary links 2020-10-11 03:37:03 -07:00
topjohnwu
0a14f43f9c Refactor class names 2020-10-10 22:40:57 -07:00
topjohnwu
311c1f0dfd Switch to new repo format 2020-10-10 14:31:30 -07:00
topjohnwu
0499588107 Support androidboot.fstab_suffix cmdline flag
Fix #3187
2020-10-08 03:04:12 -07:00
topjohnwu
d4d837a562 Update docs and README 2020-10-08 01:13:00 -07:00
topjohnwu
fbcbb20178 Update app changelog 2020-10-08 01:06:37 -07:00
topjohnwu
0914700fc6 Fix string resources 2020-10-08 00:50:21 -07:00
vvb2060
eeced2fb5b Only care about the main process when not expanded 2020-10-08 00:30:34 -07:00
topjohnwu
6509e3d4f5 Use ProgressDialog when restoring images
Close #3287
2020-10-08 00:27:16 -07:00
AdiityaAndre
317052604b Translation: Update and improve Indonesian strings
* Added new strings
* Decapitalized wording
2020-10-08 00:16:29 -07:00
Wagg13
5538f7168c Update PT-BR translation 2020-10-08 00:15:56 -07:00
vvb2060
dcb9e4cd93 Update zh-rCN translation 2020-10-08 00:15:29 -07:00
topjohnwu
d9382f59bf Fix logical error 2020-10-08 00:14:51 -07:00
topjohnwu
403a0c770a Fix typo 2020-10-07 20:15:23 -07:00
topjohnwu
f0f1cdc501 Disable LoggingInterceptor 2020-10-07 04:01:50 -07:00
topjohnwu
4e272b70ef Download GitHub files through CDN 2020-10-07 04:01:03 -07:00
150 changed files with 3114 additions and 2534 deletions

View File

@@ -15,7 +15,7 @@ Here are some feature highlights:
## Downloads
[![](https://img.shields.io/badge/Magisk%20Manager-v8.0.1-green)](https://github.com/topjohnwu/Magisk/releases/download/manager-v8.0.1/MagiskManager-v8.0.1.apk)
[![](https://img.shields.io/badge/Magisk%20Manager-v8.0.2-green)](https://github.com/topjohnwu/Magisk/releases/download/manager-v8.0.2/MagiskManager-v8.0.2.apk)
[![](https://img.shields.io/badge/Magisk%20Manager-Canary-red)](https://raw.githubusercontent.com/topjohnwu/magisk_files/canary/app-debug.apk)
<br>
[![](https://img.shields.io/badge/Magisk-v20.4-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v20.4)
@@ -56,7 +56,7 @@ For Magisk Manager crashes, record and upload the logcat when the crash occurs.
- macOS: `export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home"`
- Linux: `export PATH="/path/to/androidstudio/jre/bin:$PATH"`
- Windows: Add `C:\Path\To\Android Studio\jre\bin` to environment variable `PATH`
- Set environment variable `ANDROID_HOME` to the Android SDK folder (can be found in Android Studio settings)
- Set environment variable `ANDROID_SDK_ROOT` to the Android SDK folder (can be found in Android Studio settings)
- Run `./build.py ndk` to let the script download and install NDK for you
- Set configurations in `config.prop`. A sample `config.prop.sample` is provided.
- To start building, run `build.py` to see your options. \

View File

@@ -51,11 +51,12 @@ android {
packagingOptions {
exclude("/META-INF/**")
exclude("/androidsupportmultidexversion.txt")
exclude("/org/bouncycastle/**")
exclude("/kotlin/**")
exclude("/kotlinx/**")
exclude("/okhttp3/**")
exclude("/*.txt")
exclude("/*.bin")
}
kotlinOptions {
@@ -123,7 +124,7 @@ dependencies {
implementation("com.squareup.moshi:moshi:${vMoshi}")
kapt("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}")
val vRoom = "2.2.5"
val vRoom = "2.3.0-alpha03"
implementation("androidx.room:room-runtime:${vRoom}")
implementation("androidx.room:room-ktx:${vRoom}")
kapt("androidx.room:room-compiler:${vRoom}")
@@ -133,7 +134,7 @@ dependencies {
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
implementation("androidx.biometric:biometric:1.0.1")
implementation("androidx.constraintlayout:constraintlayout:2.0.1")
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.browser:browser:1.2.0")
implementation("androidx.preference:preference:1.1.1")

View File

@@ -35,12 +35,6 @@
void onResponse(org.json.JSONObject);
}
# Fragments
# TODO: Remove when AGP 4.1 release
# https://issuetracker.google.com/issues/142601969
-keep,allowobfuscation class * extends androidx.fragment.app.Fragment
-keepnames class androidx.navigation.fragment.NavHostFragment
# Strip Timber verbose and debug logging
-assumenosideeffects class timber.log.Timber.Tree {
public void v(**);

View File

@@ -12,12 +12,6 @@
android:supportsRtl="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
tools:ignore="UnusedAttribute">
<provider
android:name="a.p"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
</provider>
</application>
</manifest>

View File

@@ -1,7 +0,0 @@
package a;
import com.topjohnwu.magisk.FileProvider;
public class p extends FileProvider {
/* Stub */
}

View File

@@ -8,7 +8,6 @@ import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns;
@@ -34,8 +33,6 @@ public class FileProvider extends ContentProvider {
private PathStrategy mStrategy;
public static ProviderCallHandler callHandler;
@Override
public boolean onCreate() {
return true;
@@ -131,13 +128,6 @@ public class FileProvider extends ContentProvider {
return file.delete() ? 1 : 0;
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
if (callHandler != null)
return callHandler.call(getContext(), method, arg, extras);
return Bundle.EMPTY;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {

View File

@@ -1,8 +0,0 @@
package com.topjohnwu.magisk;
import android.content.Context;
import android.os.Bundle;
public interface ProviderCallHandler {
Bundle call(Context context, String method, String arg, Bundle extras);
}

View File

@@ -30,6 +30,6 @@ repositories {
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
api("org.bouncycastle:bcprov-jdk15on:1.66")
api("org.bouncycastle:bcpkix-jdk15on:1.66")
api("org.bouncycastle:bcprov-jdk15on:1.67")
api("org.bouncycastle:bcpkix-jdk15on:1.67")
}

View File

@@ -4,11 +4,10 @@
package="com.topjohnwu.magisk">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
android:maxSdkVersion="29" />
<application
android:icon="@drawable/ic_launcher"
@@ -65,6 +64,15 @@
<!-- DownloadService -->
<service android:name="a.j" />
<!-- FileProvider -->
<provider
android:name="a.p"
android:authorities="${applicationId}.provider"
android:directBootAware="true"
android:exported="false"
android:grantUriPermissions="true">
</provider>
<!-- Hardcode GMS version -->
<meta-data
android:name="com.google.android.gms.version"

View File

@@ -2,7 +2,8 @@
package a
import com.topjohnwu.magisk.core.App
import com.topjohnwu.magisk.core.GeneralReceiver
import com.topjohnwu.magisk.core.Provider
import com.topjohnwu.magisk.core.Receiver
import com.topjohnwu.magisk.core.SplashActivity
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.ui.MainActivity
@@ -22,8 +23,10 @@ class e : App {
constructor(o: Any) : super(o)
}
class h : GeneralReceiver()
class h : Receiver()
class j : DownloadService()
class m : SuRequestActivity()
class p : Provider()

View File

@@ -70,6 +70,10 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
ensureInsets()
}
fun setAccessibilityDelegate(delegate: View.AccessibilityDelegate?) {
viewRoot.rootView.accessibilityDelegate = delegate
}
override fun onResume() {
super.onResume()
viewModel.requestRefresh()
@@ -79,7 +83,7 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
return currentFragment?.onKeyEvent(event) == true || super.dispatchKeyEvent(event)
}
override fun onEventDispatched(event: ViewEvent) = when(event) {
override fun onEventDispatched(event: ViewEvent) = when (event) {
is ContextExecutor -> event(this)
is ActivityExecutor -> event(this)
else -> Unit

View File

@@ -9,18 +9,18 @@ import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
import me.tatarka.bindingcollectionadapter2.ItemBinding
import me.tatarka.bindingcollectionadapter2.OnItemBind
inline fun <T : ComparableRvItem<*>> diffListOf(
fun <T : ComparableRvItem<*>> diffListOf(
vararg newItems: T
) = diffListOf(newItems.toList())
inline fun <T : ComparableRvItem<*>> diffListOf(
fun <T : ComparableRvItem<*>> diffListOf(
newItems: List<T>
) = DiffObservableList(object : DiffObservableList.Callback<T> {
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
}).also { it.update(newItems) }
inline fun <T : ComparableRvItem<*>> filterableListOf(
fun <T : ComparableRvItem<*>> filterableListOf(
vararg newItems: T
) = FilterableDiffObservableList(object : DiffObservableList.Callback<T> {
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)

View File

@@ -10,8 +10,6 @@ import androidx.multidex.MultiDex
import androidx.work.WorkManager
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.FileProvider
import com.topjohnwu.magisk.core.su.SuCallbackHandler
import com.topjohnwu.magisk.core.utils.IODispatcherExecutor
import com.topjohnwu.magisk.core.utils.RootInit
import com.topjohnwu.magisk.core.utils.updateConfig
@@ -36,7 +34,6 @@ open class App() : Application() {
.setInitializers(RootInit::class.java)
.setTimeout(2))
Shell.EXECUTOR = IODispatcherExecutor()
FileProvider.callHandler = SuCallbackHandler
// Always log full stack trace with Timber
Timber.plant(Timber.DebugTree())

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk.core
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.util.Xml
@@ -9,19 +10,16 @@ import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.magiskdb.StringDao
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.defaultLocale
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.data.preference.PreferenceModel
import com.topjohnwu.magisk.data.repository.DBConfig
import com.topjohnwu.magisk.di.Protected
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.ui.theme.Theme
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileInputStream
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.IOException
import java.io.InputStream
object Config : PreferenceModel, DBConfig {
@@ -29,6 +27,15 @@ object Config : PreferenceModel, DBConfig {
override val settingsDao: SettingsDao by inject()
override val context: Context by inject(Protected)
@get:SuppressLint("ApplySharedPref")
val prefsFile: File get() {
// Flush prefs to disk
prefs.edit().apply {
remove(Key.ASKED_HOME)
}.commit()
return File("${context.filesDir.parent}/shared_prefs", "${fileName}.xml")
}
object Key {
// db configs
const val ROOT_ACCESS = "root_access"
@@ -43,6 +50,7 @@ object Config : PreferenceModel, DBConfig {
const val SU_AUTO_RESPONSE = "su_auto_response"
const val SU_NOTIFICATION = "su_notification"
const val SU_REAUTH = "su_reauth"
const val SU_TAPJACK = "su_tapjack"
const val CHECK_UPDATES = "check_update"
const val UPDATE_CHANNEL = "update_channel"
const val CUSTOM_CHANNEL = "custom_channel"
@@ -119,7 +127,7 @@ object Config : PreferenceModel, DBConfig {
var repoOrder by preference(Key.REPO_ORDER, Value.ORDER_DATE)
var suDefaultTimeout by preferenceStrInt(Key.SU_REQUEST_TIMEOUT, 10)
var suAutoReponse by preferenceStrInt(Key.SU_AUTO_RESPONSE, Value.SU_PROMPT)
var suAutoResponse by preferenceStrInt(Key.SU_AUTO_RESPONSE, Value.SU_PROMPT)
var suNotification by preferenceStrInt(Key.SU_NOTIFICATION, Value.NOTIFICATION_TOAST)
var updateChannel by preferenceStrInt(Key.UPDATE_CHANNEL, defaultChannel)
@@ -127,8 +135,9 @@ object Config : PreferenceModel, DBConfig {
var darkTheme by preference(Key.DARK_THEME, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
var themeOrdinal by preference(Key.THEME_ORDINAL, Theme.Piplup.ordinal)
var suReAuth by preference(Key.SU_REAUTH, false)
var suTapjack by preference(Key.SU_TAPJACK, true)
var checkUpdate by preference(Key.CHECK_UPDATES, true)
var doh by preference(Key.DOH, defaultLocale.country == "CN")
var doh by preference(Key.DOH, false)
var magiskHide by preference(Key.MAGISKHIDE, true)
var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false)
@@ -150,8 +159,12 @@ object Config : PreferenceModel, DBConfig {
private const val SU_FINGERPRINT = "su_fingerprint"
fun initialize() {
prefs.edit { parsePrefs() }
fun load(pkg: String) {
try {
context.contentResolver.openInputStream(Provider.PREFS_URI(pkg))?.use {
prefs.edit { parsePrefs(it) }
}
} catch (e: IOException) {}
prefs.edit {
// Settings migration
@@ -173,10 +186,8 @@ object Config : PreferenceModel, DBConfig {
}
}
private fun SharedPreferences.Editor.parsePrefs() {
val config = SuFile.open("/data/adb", Const.MANAGER_CONFIGS)
if (config.exists()) runCatching {
val input = SuFileInputStream(config)
private fun SharedPreferences.Editor.parsePrefs(input: InputStream) {
runCatching {
val parser = Xml.newPullParser()
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
parser.setInput(input, "UTF-8")
@@ -220,21 +231,6 @@ object Config : PreferenceModel, DBConfig {
else -> parser.next()
}
}
config.delete()
}
}
fun export() {
// Flush prefs to disk
prefs.edit().apply {
remove(Key.ASKED_HOME)
}.commit()
val context = get<Context>(Protected)
val xml = File(
"${context.filesDir.parent}/shared_prefs",
"${context.packageName}_preferences.xml"
)
Shell.su("cat $xml > /data/adb/${Const.MANAGER_CONFIGS}").exec()
}
}

View File

@@ -18,7 +18,6 @@ object Const {
// Misc
const val ANDROID_MANIFEST = "AndroidManifest.xml"
const val MAGISK_INSTALL_LOG_FILENAME = "magisk_install_log_%s.log"
const val MANAGER_CONFIGS = ".tmp.magisk.config"
val USER_ID = Process.myUid() / 100000
object Version {
@@ -46,7 +45,6 @@ object Const {
}
object Url {
const val ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip"
const val PATREON_URL = "https://www.patreon.com/topjohnwu"
const val SOURCE_CODE_URL = "https://github.com/topjohnwu/Magisk"
@@ -54,14 +52,13 @@ object Const {
const val GITHUB_API_URL = "https://api.github.com/"
const val GITHUB_PAGE_URL = "https://topjohnwu.github.io/magisk_files/"
const val JS_DELIVR_URL = "https://cdn.jsdelivr.net/gh/"
const val OFFICIAL_REPO = "https://magisk-modules-repo.github.io/submission/modules.json"
}
object Key {
// others
const val LINK_KEY = "Link"
const val ETAG_KEY = "ETag"
// intents
const val OPEN_SECTION = "section"
const val HIDDEN_PKG = "hidden_pkg"
}
object Value {

View File

@@ -149,7 +149,7 @@ private object ClassMap {
App::class.java to a.e::class.java,
MainActivity::class.java to a.b::class.java,
SplashActivity::class.java to a.c::class.java,
GeneralReceiver::class.java to a.h::class.java,
Receiver::class.java to a.h::class.java,
DownloadService::class.java to a.j::class.java,
SuRequestActivity::class.java to a.m::class.java
)

View File

@@ -0,0 +1,39 @@
package com.topjohnwu.magisk.core
import android.content.Context
import android.content.pm.ProviderInfo
import android.net.Uri
import android.os.Bundle
import android.os.ParcelFileDescriptor
import android.os.ParcelFileDescriptor.MODE_READ_ONLY
import com.topjohnwu.magisk.FileProvider
import com.topjohnwu.magisk.core.su.SuCallbackHandler
import java.io.File
open class Provider : FileProvider() {
override fun attachInfo(context: Context, info: ProviderInfo?) {
super.attachInfo(context.wrap(), info)
}
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
SuCallbackHandler(context!!, method, extras)
return Bundle.EMPTY
}
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
return when (uri.encodedPath ?: return null) {
"/apk_file" -> ParcelFileDescriptor.open(File(context!!.packageCodePath), MODE_READ_ONLY)
"/prefs_file" -> ParcelFileDescriptor.open(Config.prefsFile, MODE_READ_ONLY)
else -> super.openFile(uri, mode)
}
}
companion object {
fun APK_URI(pkg: String) =
Uri.Builder().scheme("content").authority("$pkg.provider").path("apk_file").build()
fun PREFS_URI(pkg: String) =
Uri.Builder().scheme("content").authority("$pkg.provider").path("prefs_file").build()
}
}

View File

@@ -11,7 +11,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.koin.core.inject
open class GeneralReceiver : BaseReceiver() {
open class Receiver : BaseReceiver() {
private val policyDB: PolicyDao by inject()

View File

@@ -3,9 +3,9 @@ package com.topjohnwu.magisk.core
import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.data.network.GithubRawServices
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.view.Notifications
@@ -29,18 +29,18 @@ open class SplashActivity : Activity() {
}
}
private fun handleRepackage() {
val pkg = Config.suManager
if (Config.suManager.isNotEmpty() && packageName == BuildConfig.APPLICATION_ID) {
Config.suManager = ""
Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec()
}
if (pkg == packageName) {
private fun handleRepackage(pkg: String?) {
if (packageName != APPLICATION_ID) {
runCatching {
// We are the manager, remove com.topjohnwu.magisk as it could be malware
packageManager.getApplicationInfo(BuildConfig.APPLICATION_ID, 0)
Shell.su("(pm uninstall ${BuildConfig.APPLICATION_ID})& >/dev/null 2>&1").exec()
// Hidden, remove com.topjohnwu.magisk if exist as it could be malware
packageManager.getApplicationInfo(APPLICATION_ID, 0)
Shell.su("(pm uninstall $APPLICATION_ID)& >/dev/null 2>&1").exec()
}
} else {
if (Config.suManager.isNotEmpty())
Config.suManager = ""
pkg ?: return
Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec()
}
}
@@ -48,14 +48,16 @@ open class SplashActivity : Activity() {
// Pre-initialize root shell
Shell.getShell()
Config.initialize()
handleRepackage()
val hiddenPackage = intent.getStringExtra(Const.Key.HIDDEN_PKG)
Config.load(hiddenPackage ?: APPLICATION_ID)
handleRepackage(hiddenPackage)
Notifications.setup(this)
UpdateCheckService.schedule(this)
Shortcuts.setupDynamic(this)
// Pre-fetch network stuffs
get<GithubRawServices>()
// Pre-fetch network services
get<NetworkService>()
DONE = true

View File

@@ -1,6 +1,6 @@
package com.topjohnwu.magisk.core.base
import android.Manifest
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
@@ -40,8 +40,8 @@ abstract class BaseActivity : AppCompatActivity() {
fun withPermission(permission: String, builder: PermissionRequestBuilder.() -> Unit) {
val request = PermissionRequestBuilder().apply(builder).build()
if (permission == Manifest.permission.WRITE_EXTERNAL_STORAGE && Build.VERSION.SDK_INT >= 29) {
// We do not need external rw on 29+
if (permission == WRITE_EXTERNAL_STORAGE && Build.VERSION.SDK_INT >= 30) {
// We do not need external rw on 30+
request.onSuccess()
return
}
@@ -52,7 +52,7 @@ abstract class BaseActivity : AppCompatActivity() {
var requestCode: Int
do {
requestCode = Random.nextInt(Const.ID.MAX_ACTIVITY_RESULT + 1, 1 shl 15)
} while (!resultCallbacks.containsKey(requestCode))
} while (resultCallbacks.containsKey(requestCode))
resultCallbacks[requestCode] = { result, _ ->
if (result > 0)
request.onSuccess()
@@ -64,7 +64,7 @@ abstract class BaseActivity : AppCompatActivity() {
}
fun withExternalRW(builder: PermissionRequestBuilder.() -> Unit) {
withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, builder = builder)
withPermission(WRITE_EXTERNAL_STORAGE, builder = builder)
}
override fun onRequestPermissionsResult(

View File

@@ -16,15 +16,6 @@ sealed class Action : Parcelable {
}
sealed class APK : Action() {
@Parcelize
object Upgrade : APK()
@Parcelize
object Restore : APK()
}
@Parcelize
object Download : Action()

View File

@@ -117,7 +117,7 @@ abstract class BaseDownloader : BaseService(), KoinComponent {
fun Subject.notifyID() = hashCode()
private fun notifyFail(subject: Subject) = lastNotify(subject.notifyID()) {
broadcast(-1f, subject)
broadcast(-2f, subject)
it.setContentText(getString(R.string.download_file_error))
.setSmallIcon(android.R.drawable.stat_notify_error)
.setOngoing(false)

View File

@@ -73,10 +73,7 @@ open class DownloadService : BaseDownloader() {
}
private fun Notification.Builder.setIntent(subject: Manager)
= when (subject.action) {
APK.Upgrade -> setContentIntent(APKInstall.installIntent(context, subject.file.toFile()))
else -> setContentIntent(Intent())
}
= setContentIntent(APKInstall.installIntent(context, subject.file.toFile()))
private fun Notification.Builder.setContentIntent(intent: Intent) =
setContentIntent(

View File

@@ -5,20 +5,16 @@ import androidx.core.net.toFile
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Action.APK.Restore
import com.topjohnwu.magisk.core.download.Action.APK.Upgrade
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.tasks.PatchAPK
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.ktx.relaunchApp
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.superuser.Shell
import java.io.File
private fun Context.patch(apk: File) {
val patched = File(apk.parent, "patched.apk")
PatchAPK.patch(this, apk.path, patched.path, packageName, applicationInfo.nonLocalizedLabel)
HideAPK.patch(this, apk.path, patched.path, packageName, applicationInfo.nonLocalizedLabel)
apk.delete()
patched.renameTo(apk)
}
@@ -31,7 +27,7 @@ private fun BaseDownloader.notifyHide(id: Int) {
}
}
private suspend fun BaseDownloader.upgrade(subject: Subject.Manager) {
suspend fun BaseDownloader.handleAPK(subject: Subject.Manager) {
val apk = subject.file.toFile()
val id = subject.notifyID()
if (isRunningAsStub) {
@@ -53,20 +49,3 @@ private suspend fun BaseDownloader.upgrade(subject: Subject.Manager) {
patch(apk)
}
}
private fun BaseDownloader.restore(apk: File, id: Int) {
update(id) {
it.setProgress(0, 0, true)
.setProgress(0, 0, true)
.setContentTitle(getString(R.string.restore_img_msg))
.setContentText("")
}
Config.export()
Shell.su("pm install $apk && pm uninstall $packageName").exec()
}
suspend fun BaseDownloader.handleAPK(subject: Subject.Manager) =
when (subject.action) {
is Upgrade -> upgrade(subject)
is Restore -> restore(subject.file.toFile(), subject.notifyID())
}

View File

@@ -8,7 +8,7 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.model.MagiskJson
import com.topjohnwu.magisk.core.model.ManagerJson
import com.topjohnwu.magisk.core.model.StubJson
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.ktx.cachedFile
import com.topjohnwu.magisk.ktx.get
@@ -26,10 +26,10 @@ sealed class Subject : Parcelable {
@Parcelize
class Module(
val module: Repo,
val module: OnlineModule,
override val action: Action
) : Subject() {
override val url: String get() = module.zipUrl
override val url: String get() = module.zip_url
override val title: String get() = module.downloadFilename
@IgnoredOnParcel
@@ -40,16 +40,12 @@ sealed class Subject : Parcelable {
@Parcelize
class Manager(
override val action: Action.APK,
private val app: ManagerJson = Info.remote.app,
val stub: StubJson = Info.remote.stub
) : Subject() {
override val title: String
get() = "MagiskManager-${app.version}(${app.versionCode})"
override val url: String
get() = app.link
override val action get() = Action.Download
override val title: String get() = "MagiskManager-${app.version}(${app.versionCode})"
override val url: String get() = app.link
@IgnoredOnParcel
override val file by lazy {

View File

@@ -41,3 +41,29 @@ data class StubJson(
val versionCode: Int = -1,
val link: String = ""
) : Parcelable
@JsonClass(generateAdapter = true)
data class ModuleJson(
val id: String,
val last_update: Long,
val prop_url: String,
val zip_url: String,
val notes_url: String
)
@JsonClass(generateAdapter = true)
data class RepoJson(
val name: String,
val last_update: Long,
val modules: List<ModuleJson>
)
@JsonClass(generateAdapter = true)
data class CommitInfo(
val sha: String
)
@JsonClass(generateAdapter = true)
data class BranchInfo(
val commit: CommitInfo
)

View File

@@ -1,41 +0,0 @@
package com.topjohnwu.magisk.core.model.module
abstract class BaseModule : Comparable<BaseModule> {
abstract var id: String
protected set
abstract var name: String
protected set
abstract var author: String
protected set
abstract var version: String
protected set
abstract var versionCode: Int
protected set
abstract var description: String
protected set
@Throws(NumberFormatException::class)
protected fun parseProps(props: List<String>) {
for (line in props) {
val prop = line.split("=".toRegex(), 2).map { it.trim() }
if (prop.size != 2)
continue
val key = prop[0]
val value = prop[1]
if (key.isEmpty() || key[0] == '#')
continue
when (key) {
"id" -> id = value
"name" -> name = value
"version" -> version = value
"versionCode" -> versionCode = value.toInt()
"author" -> author = value
"description" -> description = value
}
}
}
override operator fun compareTo(other: BaseModule) = name.compareTo(other.name, true)
}

View File

@@ -0,0 +1,89 @@
package com.topjohnwu.magisk.core.model.module
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class LocalModule(path: String) : Module() {
override var id: String = ""
override var name: String = ""
override var author: String = ""
override var version: String = ""
override var versionCode: Int = -1
override var description: String = ""
private val removeFile = SuFile(path, "remove")
private val disableFile = SuFile(path, "disable")
private val updateFile = SuFile(path, "update")
private val ruleFile = SuFile(path, "sepolicy.rule")
val updated: Boolean get() = updateFile.exists()
var enable: Boolean
get() = !disableFile.exists()
set(enable) {
val dir = "$PERSIST/$id"
if (enable) {
disableFile.delete()
if (Const.Version.isCanary())
Shell.su("copy_sepolicy_rules").submit()
else
Shell.su("mkdir -p $dir", "cp -af $ruleFile $dir").submit()
} else {
!disableFile.createNewFile()
if (Const.Version.isCanary())
Shell.su("copy_sepolicy_rules").submit()
else
Shell.su("rm -rf $dir").submit()
}
}
var remove: Boolean
get() = removeFile.exists()
set(remove) {
if (remove) {
removeFile.createNewFile()
if (Const.Version.isCanary())
Shell.su("copy_sepolicy_rules").submit()
else
Shell.su("rm -rf $PERSIST/$id").submit()
} else {
!removeFile.delete()
if (Const.Version.isCanary())
Shell.su("copy_sepolicy_rules").submit()
else
Shell.su("cp -af $ruleFile $PERSIST/$id").submit()
}
}
init {
runCatching {
parseProps(Shell.su("dos2unix < $path/module.prop").exec().out)
}
if (id.isEmpty()) {
val sep = path.lastIndexOf('/')
id = path.substring(sep + 1)
}
if (name.isEmpty()) {
name = id
}
}
companion object {
private val PERSIST get() = "${Const.MAGISKTMP}/mirror/persist/magisk"
suspend fun installed() = withContext(Dispatchers.IO) {
SuFile(Const.MAGISK_PATH)
.listFiles { _, name -> name != "lost+found" && name != ".core" }
.orEmpty()
.filter { !it.isFile }
.map { LocalModule("${Const.MAGISK_PATH}/${it.name}") }
.sortedBy { it.name.toLowerCase() }
}
}
}

View File

@@ -1,77 +1,41 @@
package com.topjohnwu.magisk.core.model.module
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
abstract class Module : Comparable<Module> {
abstract var id: String
protected set
abstract var name: String
protected set
abstract var author: String
protected set
abstract var version: String
protected set
abstract var versionCode: Int
protected set
abstract var description: String
protected set
class Module(path: String) : BaseModule() {
override var id: String = ""
override var name: String = ""
override var author: String = ""
override var version: String = ""
override var versionCode: Int = -1
override var description: String = ""
@Throws(NumberFormatException::class)
protected fun parseProps(props: List<String>) {
for (line in props) {
val prop = line.split("=".toRegex(), 2).map { it.trim() }
if (prop.size != 2)
continue
private val removeFile = SuFile(path, "remove")
private val disableFile = SuFile(path, "disable")
private val updateFile = SuFile(path, "update")
private val ruleFile = SuFile(path, "sepolicy.rule")
val key = prop[0]
val value = prop[1]
if (key.isEmpty() || key[0] == '#')
continue
val updated: Boolean get() = updateFile.exists()
var enable: Boolean
get() = !disableFile.exists()
set(enable) {
val dir = "$PERSIST/$id"
if (enable) {
Shell.su("mkdir -p $dir", "cp -af $ruleFile $dir").submit()
disableFile.delete()
} else {
Shell.su("rm -rf $dir").submit()
!disableFile.createNewFile()
when (key) {
"id" -> id = value
"name" -> name = value
"version" -> version = value
"versionCode" -> versionCode = value.toInt()
"author" -> author = value
"description" -> description = value
}
}
var remove: Boolean
get() = removeFile.exists()
set(remove) {
if (remove) {
Shell.su("rm -rf $PERSIST/$id").submit()
removeFile.createNewFile()
} else {
Shell.su("cp -af $ruleFile $PERSIST/$id").submit()
!removeFile.delete()
}
}
init {
runCatching {
parseProps(Shell.su("dos2unix < $path/module.prop").exec().out)
}
if (id.isEmpty()) {
val sep = path.lastIndexOf('/')
id = path.substring(sep + 1)
}
if (name.isEmpty()) {
name = id
}
}
companion object {
private val PERSIST get() = "${Const.MAGISKTMP}/mirror/persist/magisk"
suspend fun installed() = withContext(Dispatchers.IO) {
SuFile(Const.MAGISK_PATH)
.listFiles { _, name -> name != "lost+found" && name != ".core" }
.orEmpty()
.filter { !it.isFile }
.map { Module("${Const.MAGISK_PATH}/${it.name}") }
.sortedBy { it.name.toLowerCase() }
}
}
override operator fun compareTo(other: Module) = name.compareTo(other.name, true)
}

View File

@@ -0,0 +1,66 @@
package com.topjohnwu.magisk.core.model.module
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.topjohnwu.magisk.core.model.ModuleJson
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.legalFilename
import kotlinx.android.parcel.Parcelize
import java.text.DateFormat
import java.util.*
@Entity(tableName = "modules")
@Parcelize
data class OnlineModule(
@PrimaryKey override var id: String,
override var name: String = "",
override var author: String = "",
override var version: String = "",
override var versionCode: Int = -1,
override var description: String = "",
val last_update: Long,
val prop_url: String,
val zip_url: String,
val notes_url: String
) : Module(), Parcelable {
private val svc: NetworkService get() = get()
constructor(info: ModuleJson) : this(
id = info.id,
last_update = info.last_update,
prop_url = info.prop_url,
zip_url = info.zip_url,
notes_url = info.notes_url
)
val lastUpdate get() = Date(last_update)
val lastUpdateString get() = DATE_FORMAT.format(lastUpdate)
val downloadFilename get() = "$name-$version($versionCode).zip".legalFilename()
suspend fun notes() = svc.fetchString(notes_url)
@Throws(IllegalRepoException::class)
suspend fun load() {
try {
val rawProps = svc.fetchString(prop_url)
val props = rawProps.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }
parseProps(props)
} catch (e: Exception) {
throw IllegalRepoException("Repo [$id] parse error:", e)
}
if (versionCode < 0) {
throw IllegalRepoException("Repo [$id] does not contain versionCode")
}
}
class IllegalRepoException(msg: String, cause: Throwable? = null) : Exception(msg, cause)
companion object {
private val DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
}
}

View File

@@ -1,64 +0,0 @@
package com.topjohnwu.magisk.core.model.module
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.legalFilename
import kotlinx.android.parcel.Parcelize
import java.text.DateFormat
import java.util.*
@Entity(tableName = "repos")
@Parcelize
data class Repo(
@PrimaryKey override var id: String,
override var name: String,
override var author: String,
override var version: String,
override var versionCode: Int,
override var description: String,
var last_update: Long
) : BaseModule(), Parcelable {
private val svc: NetworkService get() = get()
val lastUpdate get() = Date(last_update)
val lastUpdateString: String get() = dateFormat.format(lastUpdate)
val downloadFilename: String get() = "$name-$version($versionCode).zip".legalFilename()
suspend fun readme() = svc.fetchReadme(this)
val zipUrl: String get() = Const.Url.ZIP_URL.format(id)
constructor(id: String) : this(id, "", "", "", -1, "", 0)
@Throws(IllegalRepoException::class)
private fun loadProps(props: String) {
props.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }.runCatching {
parseProps(this)
}.onFailure {
throw IllegalRepoException("Repo [$id] parse error: " + it.message)
}
if (versionCode < 0) {
throw IllegalRepoException("Repo [$id] does not contain versionCode")
}
}
@Throws(IllegalRepoException::class)
suspend fun update(lastUpdate: Date? = null) {
lastUpdate?.let { last_update = it.time }
loadProps(svc.fetchMetadata(this))
}
class IllegalRepoException(message: String) : Exception(message)
companion object {
val dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
}
}

View File

@@ -7,14 +7,12 @@ import android.os.Bundle
import android.os.Process
import android.widget.Toast
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.ProviderCallHandler
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.model.su.toLog
import com.topjohnwu.magisk.core.model.su.toPolicy
import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.startActivity
@@ -26,18 +24,13 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import timber.log.Timber
object SuCallbackHandler : ProviderCallHandler {
object SuCallbackHandler {
const val REQUEST = "request"
const val LOG = "log"
const val NOTIFY = "notify"
const val TEST = "test"
override fun call(context: Context, method: String, arg: String?, extras: Bundle?): Bundle? {
invoke(context.wrap(), method, extras)
return Bundle.EMPTY
}
operator fun invoke(context: Context, action: String?, data: Bundle?) {
data ?: return

View File

@@ -36,7 +36,7 @@ class SuRequestHandler(
if (policy.packageName == BuildConfig.APPLICATION_ID)
return false
when (Config.suAutoReponse) {
when (Config.suAutoResponse) {
Config.Value.SU_AUTO_DENY -> {
respond(SuPolicy.DENY, 0)
return false

View File

@@ -1,20 +1,20 @@
package com.topjohnwu.magisk.core.tasks
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION.SDK_INT
import android.widget.Toast
import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.utils.AXML
import com.topjohnwu.magisk.core.utils.Keygen
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.inject
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.signing.JarMap
import com.topjohnwu.signing.SignApk
import com.topjohnwu.superuser.Shell
@@ -28,25 +28,27 @@ import java.io.FileOutputStream
import java.io.IOException
import java.security.SecureRandom
object PatchAPK {
object HideAPK {
private const val ALPHA = "abcdefghijklmnopqrstuvwxyz"
private const val ALPHADOTS = "$ALPHA....."
private const val APP_ID = "com.topjohnwu.magisk"
private const val APP_NAME = "Magisk Manager"
// Some arbitrary limit
const val MAX_LABEL_LENGTH = 32
private fun genPackageName(): CharSequence {
private val svc: NetworkService by inject()
private val Context.APK_URI get() = Provider.APK_URI(packageName)
private val Context.PREFS_URI get() = Provider.PREFS_URI(packageName)
private fun genPackageName(): String {
val random = SecureRandom()
val len = 5 + random.nextInt(15)
val builder = StringBuilder(len)
var next: Char
var prev = 0.toChar()
for (i in 0 until len) {
next = if (prev == '.' || i == len - 1) {
next = if (prev == '.' || prev == 0.toChar() || i == len - 1) {
ALPHA[random.nextInt(ALPHA.length)]
} else {
ALPHADOTS[random.nextInt(ALPHADOTS.length)]
@@ -59,20 +61,20 @@ object PatchAPK {
val idx = random.nextInt(len - 1)
builder[idx] = '.'
}
return builder
return builder.toString()
}
fun patch(
context: Context,
apk: String, out: String,
pkg: CharSequence, label: CharSequence
pkg: String, label: CharSequence
): Boolean {
try {
val jar = JarMap.open(apk)
val je = jar.getJarEntry(Const.ANDROID_MANIFEST)
val xml = AXML(jar.getRawData(je))
if (!xml.findAndPatch(APP_ID to pkg.toString(), APP_NAME to label.toString()))
if (!xml.findAndPatch(APPLICATION_ID to pkg, APP_NAME to label.toString()))
return false
// Write apk changes
@@ -91,7 +93,6 @@ object PatchAPK {
val dlStub = !isRunningAsStub && SDK_INT >= 28 && Const.Version.atLeast_20_2()
val src = if (dlStub) {
val stub = File(context.cacheDir, "stub.apk")
val svc = get<NetworkService>()
try {
svc.fetchFile(Info.remote.stub.link).byteStream().use {
it.writeTo(stub)
@@ -117,23 +118,73 @@ object PatchAPK {
if (!Shell.su("adb_pm_install $repack").exec().isSuccess)
return false
Config.suManager = pkg.toString()
Config.export()
Shell.su("pm uninstall $APP_ID").submit()
context.apply {
val intent = packageManager.getLaunchIntentForPackage(pkg) ?: return false
Config.suManager = pkg
grantUriPermission(pkg, APK_URI, Intent.FLAG_GRANT_READ_URI_PERMISSION)
grantUriPermission(pkg, PREFS_URI, Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
}
return true
}
fun hideManager(context: Context, label: String) {
val progress = Notifications.progress(context, context.getString(R.string.hide_manager_title))
Notifications.mgr.notify(Const.ID.HIDE_MANAGER_NOTIFICATION_ID, progress.build())
@Suppress("DEPRECATION")
fun hide(context: Context, label: String) {
val dialog = ProgressDialog.show(context, context.getString(R.string.hide_manager_title), "", true)
GlobalScope.launch {
val result = withContext(Dispatchers.IO) {
patchAndHide(context, label)
}
if (!result)
if (!result) {
Utils.toast(R.string.hide_manager_fail_toast, Toast.LENGTH_LONG)
Notifications.mgr.cancel(Const.ID.HIDE_MANAGER_NOTIFICATION_ID)
dialog.dismiss()
}
}
}
private suspend fun downloadAndRestore(context: Context): Boolean {
val apk = if (isRunningAsStub) {
DynAPK.current(context)
} else {
File(context.cacheDir, "manager.apk").also { apk ->
try {
svc.fetchFile(Info.remote.app.link).byteStream().use {
it.writeTo(apk)
}
} catch (e: IOException) {
Timber.e(e)
return false
}
}
}
if (!Shell.su("adb_pm_install $apk").exec().isSuccess)
return false
context.apply {
val intent = packageManager.getLaunchIntentForPackage(APPLICATION_ID) ?: return false
Config.suManager = ""
grantUriPermission(APPLICATION_ID, APK_URI, Intent.FLAG_GRANT_READ_URI_PERMISSION)
grantUriPermission(APPLICATION_ID, PREFS_URI, Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.putExtra(Const.Key.HIDDEN_PKG, packageName)
startActivity(intent)
}
return true
}
@Suppress("DEPRECATION")
fun restore(context: Context) {
val dialog = ProgressDialog.show(context, context.getString(R.string.restore_img_msg), "", true)
GlobalScope.launch {
val result = withContext(Dispatchers.IO) {
downloadAndRestore(context)
}
if (!result) {
Utils.toast(R.string.restore_manager_fail_toast, Toast.LENGTH_LONG)
dialog.dismiss()
}
}
}
}

View File

@@ -290,7 +290,7 @@ abstract class MagiskInstallImpl : KoinComponent {
srcBoot = File(installDir, "boot.img").path
}
var isSigned = false
var isSigned: Boolean
try {
SuFileInputStream(srcBoot).use {
isSigned = SignBoot.verifySignature(it, null)

View File

@@ -1,119 +1,42 @@
package com.topjohnwu.magisk.core.tasks
import com.squareup.moshi.JsonClass
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.synchronized
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.net.HttpURLConnection
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.HashSet
class RepoUpdater(
private val svc: NetworkService,
private val repoDB: RepoDao
) {
private fun String.trimEtag() = substring(indexOf('\"'), lastIndexOf('\"') + 1)
private suspend fun forcedReload(cached: MutableSet<String>) = coroutineScope {
cached.forEach {
launch {
val repo = repoDB.getRepo(it)!!
try {
repo.update()
repoDB.addRepo(repo)
} catch (e: Repo.IllegalRepoException) {
Timber.e(e)
}
}
}
}
private suspend fun loadRepos(
repos: List<GithubRepoInfo>,
cached: MutableSet<String>
) = coroutineScope {
repos.forEach {
// Skip submission
if (it.id == "submission")
return@forEach
launch {
val repo = repoDB.getRepo(it.id)?.apply { cached.remove(it.id) } ?: Repo(it.id)
try {
repo.update(it.pushDate)
repoDB.addRepo(repo)
} catch (e: Repo.IllegalRepoException) {
Timber.e(e)
}
}
}
}
private enum class PageResult {
SUCCESS,
CACHED,
ERROR
}
private suspend fun loadPage(
cached: MutableSet<String>,
page: Int = 1,
etag: String = ""
): PageResult = coroutineScope {
runCatching {
val result = svc.fetchRepos(page, etag)
result.run {
if (code() == HttpURLConnection.HTTP_NOT_MODIFIED)
return@coroutineScope PageResult.CACHED
if (!isSuccessful)
return@coroutineScope PageResult.ERROR
if (page == 1)
repoDB.etagKey = headers()[Const.Key.ETAG_KEY].orEmpty().trimEtag()
val repoLoad = async { loadRepos(body()!!, cached) }
val next = if (headers()[Const.Key.LINK_KEY].orEmpty().contains("next")) {
async { loadPage(cached, page + 1) }
} else {
async { PageResult.SUCCESS }
}
repoLoad.await()
return@coroutineScope next.await()
}
}.getOrElse {
Timber.e(it)
PageResult.ERROR
}
}
suspend fun run(forced: Boolean) = withContext(Dispatchers.IO) {
val cached = HashSet(repoDB.repoIDList).synchronized()
when (loadPage(cached, etag = repoDB.etagKey)) {
PageResult.CACHED -> if (forced) forcedReload(cached)
PageResult.SUCCESS -> repoDB.removeRepos(cached)
PageResult.ERROR -> Unit
val cachedMap = HashMap<String, Date>().also { map ->
repoDB.getModuleStubs().forEach { map[it.id] = Date(it.last_update) }
}.synchronized()
svc.fetchRepoInfo()?.let { info ->
coroutineScope {
info.modules.forEach {
launch {
val lastUpdated = cachedMap.remove(it.id)
if (forced || lastUpdated?.before(Date(it.last_update)) != false) {
try {
val repo = OnlineModule(it).apply { load() }
repoDB.addModule(repo)
} catch (e: OnlineModule.IllegalRepoException) {
Timber.e(e)
}
}
}
}
}
repoDB.removeModules(cachedMap.keys)
}
}
}
private val dateFormat: SimpleDateFormat =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
@JsonClass(generateAdapter = true)
data class GithubRepoInfo(
val name: String,
val pushed_at: String
) {
val id get() = name
@Transient
val pushDate = dateFormat.parse(pushed_at)!!
}

View File

@@ -66,8 +66,8 @@ object MediaStoreUtils {
}
private fun queryFile(displayName: String): UriFile? {
if (Build.VERSION.SDK_INT < 29) {
// Before official general purpose MediaStore API exists, fallback to file based I/O
if (Build.VERSION.SDK_INT < 30) {
// Fallback to file based I/O pre Android 11
val parent = File(Environment.getExternalStorageDirectory(), relativePath)
parent.mkdirs()
return LegacyUriFile(File(parent, displayName))

View File

@@ -1,67 +0,0 @@
@file:JvmMultifileClass
package com.topjohnwu.magisk.data.database
import androidx.room.Dao
import androidx.room.Query
import com.topjohnwu.magisk.core.model.module.Repo
interface RepoBase {
fun getRepos(offset: Int, limit: Int = LIMIT): List<Repo>
fun searchRepos(query: String, offset: Int, limit: Int = LIMIT): List<Repo>
@Query("SELECT * FROM repos WHERE id = :id AND versionCode > :versionCode LIMIT 1")
fun getUpdatableRepoById(id: String, versionCode: Int): Repo?
@Query("SELECT * FROM repos WHERE id = :id LIMIT 1")
fun getRepoById(id: String): Repo?
companion object {
const val LIMIT = 10
}
}
@Dao
interface RepoByUpdatedDao : RepoBase {
@Query("SELECT * FROM repos ORDER BY last_update DESC LIMIT :limit OFFSET :offset")
override fun getRepos(offset: Int, limit: Int): List<Repo>
@Query(
"""SELECT *
FROM repos
WHERE
(author LIKE '%' || :query || '%') ||
(name LIKE '%' || :query || '%') ||
(description LIKE '%' || :query || '%')
ORDER BY last_update DESC
LIMIT :limit
OFFSET :offset"""
)
override fun searchRepos(query: String, offset: Int, limit: Int): List<Repo>
}
@Dao
interface RepoByNameDao : RepoBase {
@Query("SELECT * FROM repos ORDER BY name COLLATE NOCASE LIMIT :limit OFFSET :offset")
override fun getRepos(offset: Int, limit: Int): List<Repo>
@Query(
"""SELECT *
FROM repos
WHERE
(author LIKE '%' || :query || '%') ||
(name LIKE '%' || :query || '%') ||
(description LIKE '%' || :query || '%')
ORDER BY name COLLATE NOCASE
LIMIT :limit
OFFSET :offset"""
)
override fun searchRepos(query: String, offset: Int, limit: Int): List<Repo>
}

View File

@@ -2,72 +2,89 @@ package com.topjohnwu.magisk.data.database
import androidx.room.*
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Database(version = 6, entities = [Repo::class, RepoEtag::class], exportSchema = false)
@Database(version = 8, entities = [OnlineModule::class], exportSchema = false)
abstract class RepoDatabase : RoomDatabase() {
abstract fun repoDao() : RepoDao
abstract fun repoByUpdatedDao(): RepoByUpdatedDao
abstract fun repoByNameDao(): RepoByNameDao
}
@Dao
abstract class RepoDao(private val db: RepoDatabase) {
val repoIDList get() = getRepoID().map { it.id }
val repos: List<Repo> get() = when (Config.repoOrder) {
Config.Value.ORDER_NAME -> getReposNameOrder()
else -> getReposDateOrder()
}
var etagKey: String
set(value) = addEtagRaw(RepoEtag(0, value))
get() = etagRaw()?.key.orEmpty()
suspend fun clear() = withContext(Dispatchers.IO) { db.clearAllTables() }
@Query("SELECT * FROM repos ORDER BY last_update DESC")
protected abstract fun getReposDateOrder(): List<Repo>
@Query("SELECT * FROM repos ORDER BY name COLLATE NOCASE")
protected abstract fun getReposNameOrder(): List<Repo>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun addRepo(repo: Repo)
@Query("SELECT * FROM repos WHERE id = :id")
abstract fun getRepo(id: String): Repo?
@Query("SELECT id FROM repos")
protected abstract fun getRepoID(): List<RepoID>
abstract fun addModule(repo: OnlineModule)
@Delete
abstract fun removeRepo(repo: Repo)
abstract fun removeModule(repo: OnlineModule)
@Query("DELETE FROM repos WHERE id = :id")
abstract fun removeRepo(id: String)
@Query("DELETE FROM modules WHERE id = :id")
abstract fun removeModule(id: String)
@Query("DELETE FROM repos WHERE id IN (:idList)")
abstract fun removeRepos(idList: Collection<String>)
@Query("DELETE FROM modules WHERE id IN (:idList)")
abstract fun removeModules(idList: Collection<String>)
@Query("SELECT * FROM etag")
protected abstract fun etagRaw(): RepoEtag?
@Query("SELECT * FROM modules WHERE id = :id")
abstract fun getModule(id: String): OnlineModule?
@Insert(onConflict = OnConflictStrategy.REPLACE)
protected abstract fun addEtagRaw(etag: RepoEtag)
@Query("SELECT id, last_update FROM modules")
abstract fun getModuleStubs(): List<ModuleStub>
fun getModules(offset: Int, limit: Int = LIMIT) = when (Config.repoOrder) {
Config.Value.ORDER_NAME -> getNameOrder(offset, limit)
else -> getDateOrder(offset, limit)
}
fun searchModules(query: String, offset: Int, limit: Int = LIMIT) = when (Config.repoOrder) {
Config.Value.ORDER_NAME -> searchNameOrder(query, offset, limit)
else -> searchDateOrder(query, offset, limit)
}
@Query("SELECT * FROM modules WHERE id = :id AND versionCode > :versionCode LIMIT 1")
abstract fun getUpdatableModule(id: String, versionCode: Int): OnlineModule?
@Query("SELECT * FROM modules ORDER BY last_update DESC LIMIT :limit OFFSET :offset")
protected abstract fun getDateOrder(offset: Int, limit: Int): List<OnlineModule>
@Query("SELECT * FROM modules ORDER BY name COLLATE NOCASE LIMIT :limit OFFSET :offset")
protected abstract fun getNameOrder(offset: Int, limit: Int): List<OnlineModule>
@Query(
"""SELECT *
FROM modules
WHERE
(author LIKE '%' || :query || '%') ||
(name LIKE '%' || :query || '%') ||
(description LIKE '%' || :query || '%')
ORDER BY last_update DESC
LIMIT :limit
OFFSET :offset"""
)
protected abstract fun searchDateOrder(query: String, offset: Int, limit: Int): List<OnlineModule>
@Query(
"""SELECT *
FROM modules
WHERE
(author LIKE '%' || :query || '%') ||
(name LIKE '%' || :query || '%') ||
(description LIKE '%' || :query || '%')
ORDER BY name COLLATE NOCASE
LIMIT :limit
OFFSET :offset"""
)
protected abstract fun searchNameOrder(query: String, offset: Int, limit: Int): List<OnlineModule>
companion object {
const val LIMIT = 10
}
}
data class RepoID(
@PrimaryKey val id: String
data class ModuleStub(
@PrimaryKey val id: String,
val last_update: Long
)
@Entity(tableName = "etag")
data class RepoEtag(
@PrimaryKey val id: Int,
val key: String
)

View File

@@ -1,20 +1,18 @@
package com.topjohnwu.magisk.data.network
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.model.BranchInfo
import com.topjohnwu.magisk.core.model.RepoJson
import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.core.tasks.GithubRepoInfo
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.*
private const val REVISION = "revision"
private const val MODULE = "module"
private const val FILE = "file"
private const val IF_NONE_MATCH = "If-None-Match"
private const val BRANCH = "branch"
private const val REPO = "repo"
private const val MAGISK_FILES = "topjohnwu/magisk_files"
private const val MAGISK_MASTER = "topjohnwu/Magisk/master"
private const val MAGISK_MODULES = "Magisk-Modules-Repo"
const val MAGISK_FILES = "topjohnwu/magisk_files"
const val MAGISK_MAIN = "topjohnwu/Magisk"
interface GithubPageServices {
@@ -34,27 +32,23 @@ interface JSDelivrServices {
@GET("$MAGISK_FILES@{$REVISION}/bootctl")
@Streaming
suspend fun fetchBootctl(@Path(REVISION) revision: String = Const.BOOTCTL_REVISION): ResponseBody
@GET("$MAGISK_FILES@{$REVISION}/canary.json")
suspend fun fetchCanaryUpdate(@Path(REVISION) revision: String): UpdateInfo
@GET("$MAGISK_MAIN@{$REVISION}/scripts/module_installer.sh")
@Streaming
suspend fun fetchInstaller(@Path(REVISION) revision: String): ResponseBody
}
interface GithubRawServices {
@GET("$MAGISK_FILES/canary/debug.json")
suspend fun fetchCanaryUpdate(): UpdateInfo
interface RawServices {
@GET
suspend fun fetchCustomUpdate(@Url url: String): UpdateInfo
@GET("$MAGISK_MASTER/scripts/module_installer.sh")
@Streaming
suspend fun fetchInstaller(): ResponseBody
@GET
suspend fun fetchRepoInfo(@Url url: String): RepoJson
@GET("$MAGISK_MODULES/{$MODULE}/master/{$FILE}")
suspend fun fetchModuleFile(@Path(MODULE) id: String, @Path(FILE) file: String): String
/**
* This method shall be used exclusively for fetching files from urls from previous requests.
* Him, who uses it in a wrong way, shall die in an eternal flame.
* */
@GET
@Streaming
suspend fun fetchFile(@Url url: String): ResponseBody
@@ -66,13 +60,11 @@ interface GithubRawServices {
interface GithubApiServices {
@GET("users/${MAGISK_MODULES}/repos")
@GET("repos/{$REPO}/branches/{$BRANCH}")
@Headers("Accept: application/vnd.github.v3+json")
suspend fun fetchRepos(
@Query("page") page: Int,
@Header(IF_NONE_MATCH) etag: String,
@Query("sort") sort: String = "pushed",
@Query("per_page") count: Int = 100
): Response<List<GithubRepoInfo>>
suspend fun fetchBranch(
@Path(REPO, encoded = true) repo: String,
@Path(BRANCH) branch: String
): BranchInfo
}

View File

@@ -11,16 +11,14 @@ interface PreferenceModel {
val fileName: String
get() = "${context.packageName}_preferences"
val commitPrefs: Boolean
get() = false
val prefs: SharedPreferences
get() = context.getSharedPreferences(fileName, Context.MODE_PRIVATE)
fun preferenceStrInt(
name: String,
default: Int,
writeDefault: Boolean = false,
commit: Boolean = commitPrefs
commit: Boolean = false
) = object: ReadWriteProperty<PreferenceModel, Int> {
val base = StringProperty(name, default.toString(), commit)
override fun getValue(thisRef: PreferenceModel, property: KProperty<*>): Int =
@@ -33,37 +31,37 @@ interface PreferenceModel {
fun preference(
name: String,
default: Boolean,
commit: Boolean = commitPrefs
commit: Boolean = false
) = BooleanProperty(name, default, commit)
fun preference(
name: String,
default: Float,
commit: Boolean = commitPrefs
commit: Boolean = false
) = FloatProperty(name, default, commit)
fun preference(
name: String,
default: Int,
commit: Boolean = commitPrefs
commit: Boolean = false
) = IntProperty(name, default, commit)
fun preference(
name: String,
default: Long,
commit: Boolean = commitPrefs
commit: Boolean = false
) = LongProperty(name, default, commit)
fun preference(
name: String,
default: String,
commit: Boolean = commitPrefs
commit: Boolean = false
) = StringProperty(name, default, commit)
fun preference(
name: String,
default: Set<String>,
commit: Boolean = commitPrefs
commit: Boolean = false
) = StringSetProperty(name, default, commit)
}

View File

@@ -6,23 +6,21 @@ import com.topjohnwu.magisk.core.Config.Value.CANARY_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.CUSTOM_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.DEFAULT_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.STABLE_CHANNEL
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.data.network.GithubApiServices
import com.topjohnwu.magisk.data.network.GithubPageServices
import com.topjohnwu.magisk.data.network.GithubRawServices
import com.topjohnwu.magisk.data.network.JSDelivrServices
import com.topjohnwu.magisk.core.model.*
import com.topjohnwu.magisk.data.network.*
import retrofit2.HttpException
import timber.log.Timber
import java.io.IOException
class NetworkService(
private val pages: GithubPageServices,
private val raw: GithubRawServices,
private val raw: RawServices,
private val jsd: JSDelivrServices,
private val api: GithubApiServices
) {
suspend fun fetchUpdate() = try {
suspend fun fetchUpdate() = safe {
var info = when (Config.updateChannel) {
DEFAULT_CHANNEL, STABLE_CHANNEL -> fetchStableUpdate()
BETA_CHANNEL -> fetchBetaUpdate()
@@ -38,31 +36,62 @@ class NetworkService(
}
Info.remote = info
info
} catch (e: IOException) {
Timber.e(e)
null
} catch (e: HttpException) {
Timber.e(e)
null
}
// UpdateInfo
suspend fun fetchStableUpdate() = pages.fetchStableUpdate()
suspend fun fetchBetaUpdate() = pages.fetchBetaUpdate()
suspend fun fetchCanaryUpdate() = raw.fetchCanaryUpdate()
suspend fun fetchCustomUpdate(url: String) = raw.fetchCustomUpdate(url)
private suspend fun fetchStableUpdate() = pages.fetchStableUpdate()
private suspend fun fetchBetaUpdate() = pages.fetchBetaUpdate()
private suspend fun fetchCustomUpdate(url: String) = raw.fetchCustomUpdate(url)
private suspend fun fetchCanaryUpdate(): UpdateInfo {
val sha = fetchCanaryVersion()
val info = jsd.fetchCanaryUpdate(sha)
// Byte streams
suspend fun fetchSafetynet() = jsd.fetchSafetynet()
suspend fun fetchBootctl() = jsd.fetchBootctl()
suspend fun fetchInstaller() = raw.fetchInstaller()
suspend fun fetchFile(url: String) = raw.fetchFile(url)
fun genCDNUrl(name: String) = "${Const.Url.JS_DELIVR_URL}${MAGISK_FILES}@${sha}/${name}"
fun ManagerJson.updateCopy() = copy(link = genCDNUrl(link), note = genCDNUrl(note))
fun MagiskJson.updateCopy() = copy(link = genCDNUrl(link), note = genCDNUrl(note))
fun StubJson.updateCopy() = copy(link = genCDNUrl(link))
fun UninstallerJson.updateCopy() = copy(link = genCDNUrl(link))
// Strings
suspend fun fetchMetadata(repo: Repo) = raw.fetchModuleFile(repo.id, "module.prop")
suspend fun fetchReadme(repo: Repo) = raw.fetchModuleFile(repo.id, "README.md")
suspend fun fetchString(url: String) = raw.fetchString(url)
return info.copy(
app = info.app.updateCopy(),
magisk = info.magisk.updateCopy(),
stub = info.stub.updateCopy(),
uninstaller = info.uninstaller.updateCopy()
)
}
// API calls
suspend fun fetchRepos(page: Int, etag: String) = api.fetchRepos(page, etag)
private inline fun <T> safe(factory: () -> T): T? {
return try {
factory()
} catch (e: Exception) {
Timber.e(e)
null
}
}
private inline fun <T> wrap(factory: () -> T): T {
return try {
factory()
} catch (e: HttpException) {
throw IOException(e)
}
}
// Modules related
suspend fun fetchRepoInfo(url: String = Const.Url.OFFICIAL_REPO) = safe {
raw.fetchRepoInfo(url)
}
// Fetch files
suspend fun fetchSafetynet() = wrap { jsd.fetchSafetynet() }
suspend fun fetchBootctl() = wrap { jsd.fetchBootctl() }
suspend fun fetchInstaller() = wrap {
val sha = fetchMainVersion()
jsd.fetchInstaller(sha)
}
suspend fun fetchFile(url: String) = wrap { raw.fetchFile(url) }
suspend fun fetchString(url: String) = wrap { raw.fetchString(url) }
private suspend fun fetchCanaryVersion() = api.fetchBranch(MAGISK_FILES, "canary").commit.sha
private suspend fun fetchMainVersion() = api.fetchBranch(MAGISK_MAIN, "master").commit.sha
}

View File

@@ -200,12 +200,12 @@ fun RecyclerView.setDividers(dividerVertical: Drawable?, dividerHorizontal: Draw
}
}
@BindingAdapter("app:icon")
@BindingAdapter("icon")
fun Button.setIconRes(res: Int) {
(this as MaterialButton).setIconResource(res)
}
@BindingAdapter("app:icon")
@BindingAdapter("icon")
fun Button.setIcon(drawable: Drawable) {
(this as MaterialButton).icon = drawable
}

View File

@@ -17,8 +17,6 @@ val databaseModule = module {
single { StringDao() }
single { createRepoDatabase(get()) }
single { get<RepoDatabase>().repoDao() }
single { get<RepoDatabase>().repoByNameDao() }
single { get<RepoDatabase>().repoByUpdatedDao() }
single { createSuLogDatabase(get(Protected)).suLogDao() }
single { RepoUpdater(get(), get()) }
}

View File

@@ -3,13 +3,14 @@ package com.topjohnwu.magisk.di
import android.content.Context
import android.os.Build
import com.squareup.moshi.Moshi
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.data.network.GithubApiServices
import com.topjohnwu.magisk.data.network.GithubPageServices
import com.topjohnwu.magisk.data.network.GithubRawServices
import com.topjohnwu.magisk.data.network.JSDelivrServices
import com.topjohnwu.magisk.data.network.RawServices
import com.topjohnwu.magisk.ktx.precomputedText
import com.topjohnwu.magisk.net.Networking
import com.topjohnwu.magisk.net.NoSSLv3SocketFactory
@@ -31,7 +32,7 @@ import java.net.UnknownHostException
val networkingModule = module {
single { createOkHttpClient(get()) }
single { createRetrofit(get()) }
single { createApiService<GithubRawServices>(get(), Const.Url.GITHUB_RAW_URL) }
single { createApiService<RawServices>(get(), Const.Url.GITHUB_RAW_URL) }
single { createApiService<GithubApiServices>(get(), Const.Url.GITHUB_API_URL) }
single { createApiService<GithubPageServices>(get(), Const.Url.GITHUB_PAGE_URL) }
single { createApiService<JSDelivrServices>(get(), Const.Url.JS_DELIVR_URL) }
@@ -40,8 +41,6 @@ val networkingModule = module {
private class DnsResolver(client: OkHttpClient) : Dns {
private var dohError = false
private val poisonedHosts = listOf("raw.githubusercontent.com")
private val doh by lazy {
DnsOverHttps.Builder().client(client)
.url(HttpUrl.get("https://cloudflare-dns.com/dns-query"))
@@ -61,16 +60,12 @@ private class DnsResolver(client: OkHttpClient) : Dns {
}
override fun lookup(hostname: String): List<InetAddress> {
return if (!dohError && Config.doh && poisonedHosts.contains(hostname)) {
if (Config.doh) {
try {
doh.lookup(hostname)
} catch (e: UnknownHostException) {
dohError = true
Dns.SYSTEM.lookup(hostname)
}
} else {
Dns.SYSTEM.lookup(hostname)
return doh.lookup(hostname)
} catch (e: UnknownHostException) {}
}
return Dns.SYSTEM.lookup(hostname)
}
}
@@ -78,10 +73,11 @@ private class DnsResolver(client: OkHttpClient) : Dns {
fun createOkHttpClient(context: Context): OkHttpClient {
val builder = OkHttpClient.Builder()
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.HEADERS
if (BuildConfig.DEBUG) {
builder.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BASIC
})
}
builder.addInterceptor(httpLoggingInterceptor)
if (!Networking.init(context)) {
Info.hasGMS = false

View File

@@ -20,7 +20,7 @@ val viewModelModules = module {
viewModel { HideViewModel() }
viewModel { HomeViewModel(get()) }
viewModel { LogViewModel(get()) }
viewModel { ModuleViewModel(get(), get(), get()) }
viewModel { ModuleViewModel(get(), get()) }
viewModel { SafetynetViewModel() }
viewModel { SettingsViewModel(get()) }
viewModel { SuperuserViewModel(get(), get()) }

View File

@@ -1,8 +1,11 @@
package com.topjohnwu.magisk.events
import android.os.Build
import android.os.PowerManager
import android.view.ContextThemeWrapper
import android.view.MenuItem
import android.widget.PopupMenu
import androidx.core.content.getSystemService
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.superuser.Shell
@@ -13,6 +16,7 @@ object RebootEvent {
private fun reboot(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_reboot_normal -> systemReboot()
R.id.action_reboot_userspace -> systemReboot("userspace")
R.id.action_reboot_bootloader -> systemReboot("bootloader")
R.id.action_reboot_download -> systemReboot("download")
R.id.action_reboot_edl -> systemReboot("edl")
@@ -25,6 +29,9 @@ object RebootEvent {
fun inflateMenu(activity: BaseActivity): PopupMenu {
val themeWrapper = ContextThemeWrapper(activity, R.style.Foundation_PopupMenu)
val menu = PopupMenu(themeWrapper, activity.findViewById(R.id.action_reboot))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true)
menu.menu.getItem(R.id.action_reboot_userspace).isVisible = true
activity.menuInflater.inflate(R.menu.menu_reboot, menu.menu)
menu.setOnMenuItemClickListener(::reboot)
return menu

View File

@@ -35,11 +35,9 @@ class SnackbarEvent private constructor(
) = Snackbar.make(view, message, length).apply(builder).show()
override fun invoke(activity: BaseUIActivity<*, *>) {
if (activity is BaseUIActivity<*, *>) {
snackbar(activity.snackbarView,
msg.getText(activity.resources).toString(),
length, builder)
}
snackbar(activity.snackbarView,
msg.getText(activity.resources).toString(),
length, builder)
}
}

View File

@@ -4,6 +4,7 @@ import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.view.View
import android.widget.Toast
import androidx.navigation.NavDirections
import com.topjohnwu.magisk.MainDirections
@@ -12,7 +13,7 @@ import com.topjohnwu.magisk.arch.*
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.base.ActivityResultCallback
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MarkDownWindow
import com.topjohnwu.magisk.view.Shortcuts
@@ -22,10 +23,10 @@ class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), Activi
override fun invoke(activity: BaseUIActivity<*, *>) = action(activity)
}
class OpenChangelogEvent(val item: Repo) : ViewEventWithScope(), ContextExecutor {
class OpenReadmeEvent(val item: OnlineModule) : ViewEventWithScope(), ContextExecutor {
override fun invoke(context: Context) {
scope.launch {
MarkDownWindow.show(context, null, item::readme)
MarkDownWindow.show(context, null, item::notes)
}
}
}
@@ -58,9 +59,11 @@ class DieEvent : ViewEvent(), ActivityExecutor {
}
}
class ShowUIEvent : ViewEvent(), ActivityExecutor {
class ShowUIEvent(private val delegate: View.AccessibilityDelegate?)
: ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
activity.setContentView()
activity.setAccessibilityDelegate(delegate)
}
}

View File

@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.events.dialog
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Action
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.ktx.res
@@ -16,7 +15,7 @@ class ManagerInstallDialog : DialogEvent() {
override fun build(dialog: MagiskDialog) {
with(dialog) {
val subject = Subject.Manager(Action.APK.Upgrade)
val subject = Subject.Manager()
applyTitle(R.string.repo_install_title.res(R.string.app_name.res()))
applyMessage(R.string.repo_install_msg.res(subject.title))

View File

@@ -5,10 +5,10 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Action
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.view.MagiskDialog
class ModuleInstallDialog(private val item: Repo) : DialogEvent() {
class ModuleInstallDialog(private val item: OnlineModule) : DialogEvent() {
override fun build(dialog: MagiskDialog) {
with(dialog) {

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk.events.dialog
import android.app.ProgressDialog
import android.widget.Toast
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Info
@@ -17,8 +18,7 @@ class UninstallDialog : DialogEvent() {
.applyMessage(R.string.uninstall_magisk_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.restore_img
preventDismiss = true
onClick { restore(dialog) }
onClick { restore() }
}
if (Info.remote.uninstaller.link.isNotEmpty()) {
dialog.applyButton(MagiskDialog.ButtonType.NEGATIVE) {
@@ -28,13 +28,12 @@ class UninstallDialog : DialogEvent() {
}
}
private fun restore(dialog: MagiskDialog) {
dialog.applyTitle(R.string.restore_img)
.applyMessage(R.string.restore_img_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) {
title = ""
}
.cancellable(false)
@Suppress("DEPRECATION")
private fun restore() {
val dialog = ProgressDialog(dialog.context).apply {
setMessage(dialog.context.getString(R.string.restore_img_msg))
show()
}
Shell.su("restore_imgs").submit { result ->
dialog.dismiss()

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk.ktx
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ComponentName
import android.content.Context
@@ -7,7 +8,6 @@ import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.ComponentInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.*
import android.content.res.Configuration
@@ -57,29 +57,31 @@ import java.lang.reflect.Array as JArray
val packageName: String get() = get<Context>().packageName
val PackageInfo.processes
get() = activities?.processNames.orEmpty() +
services?.processNames.orEmpty() +
receivers?.processNames.orEmpty() +
providers?.processNames.orEmpty()
val Array<out ComponentInfo>.processNames get() = mapNotNull { it.processName }
val ApplicationInfo.packageInfo: PackageInfo get() {
val ApplicationInfo.processes: List<String> @SuppressLint("InlinedApi") get() {
val pm = get<PackageManager>()
return try {
val appProcessName = processName ?: packageName
val baseFlag = MATCH_DISABLED_COMPONENTS or MATCH_UNINSTALLED_PACKAGES
val packageInfo = try {
val request = GET_ACTIVITIES or GET_SERVICES or GET_RECEIVERS or GET_PROVIDERS
pm.getPackageInfo(packageName, request)
pm.getPackageInfo(packageName, baseFlag or request)
} catch (e: NameNotFoundException) { // EdXposed hooked, issue#3276
return listOf(appProcessName)
} catch (e: Exception) {
// Exceed binder data transfer limit, fetch each component type separately
pm.getPackageInfo(packageName, 0).apply {
pm.getPackageInfo(packageName, baseFlag).apply {
runCatching { activities = pm.getPackageInfo(packageName, GET_ACTIVITIES).activities }
runCatching { services = pm.getPackageInfo(packageName, GET_SERVICES).services }
runCatching { receivers = pm.getPackageInfo(packageName, GET_RECEIVERS).receivers }
runCatching { providers = pm.getPackageInfo(packageName, GET_PROVIDERS).providers }
}
}
fun Array<out ComponentInfo>.processNames() = map { it.processName ?: appProcessName }
return with(packageInfo) {
activities?.processNames().orEmpty() +
services?.processNames().orEmpty() +
receivers?.processNames().orEmpty() +
providers?.processNames().orEmpty()
}
}
fun Context.rawResource(id: Int) = resources.openRawResource(id)

View File

@@ -39,14 +39,19 @@ class HideItem(
get() = state
set(value) = set(value, state, { state = it }, BR.hiddenState) {
if (value == true) {
processes.filterNot { it.isHidden }
processes
.filterNot { it.isHidden }
.filter { isExpanded || it.process.name == it.process.packageName }
} else {
processes
.filter { it.isHidden }
.filter { isExpanded || it.process.name == it.process.packageName }
}.forEach { it.toggle() }
}
init {
processes.forEach { it.addOnPropertyChangedCallback(BR.hidden) { recalculateChecked() } }
addOnPropertyChangedCallback(BR.expanded) { recalculateChecked() }
recalculateChecked()
}
@@ -57,10 +62,14 @@ class HideItem(
private fun recalculateChecked() {
itemsChecked = processes.count { it.isHidden }
state = when (itemsChecked) {
0 -> false
processes.size -> true
else -> null
state = if (isExpanded) {
when (itemsChecked) {
0 -> false
processes.size -> true
else -> null
}
} else {
processes.find { it.isHidden && it.process.name == it.process.packageName } != null
}
}

View File

@@ -1,7 +1,9 @@
package com.topjohnwu.magisk.ui.hide
import android.annotation.SuppressLint
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Process
import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
@@ -11,7 +13,6 @@ import com.topjohnwu.magisk.arch.filterableListOf
import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ktx.packageInfo
import com.topjohnwu.magisk.ktx.packageName
import com.topjohnwu.magisk.ktx.processes
import com.topjohnwu.magisk.utils.Utils
@@ -27,14 +28,20 @@ class HideViewModel : BaseViewModel(), Queryable {
@get:Bindable
var isShowSystem = Config.showSystemApp
set(value) = set(value, field, { field = it }, BR.showSystem){
set(value) = set(value, field, { field = it }, BR.showSystem) {
Config.showSystemApp = it
submitQuery()
}
@get:Bindable
var isShowOS = false
set(value) = set(value, field, { field = it }, BR.showOS) {
submitQuery()
}
@get:Bindable
var query = ""
set(value) = set(value, field, { field = it }, BR.query){
set(value) = set(value, field, { field = it }, BR.query) {
submitQuery()
}
@@ -46,6 +53,7 @@ class HideViewModel : BaseViewModel(), Queryable {
it.bindExtra(BR.viewModel, this)
}
@SuppressLint("InlinedApi")
override fun refresh() = viewModelScope.launch {
if (!Utils.showSuperUser()) {
state = State.LOADING_FAILED
@@ -55,9 +63,9 @@ class HideViewModel : BaseViewModel(), Queryable {
val (apps, diff) = withContext(Dispatchers.Default) {
val pm = get<PackageManager>()
val hides = Shell.su("magiskhide --ls").exec().out.map { HideTarget(it) }
val apps = pm.getInstalledApplications(0)
val apps = pm.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES)
.asSequence()
.filter { it.enabled && it.uid >= 10000 && !blacklist.contains(it.packageName) }
.filter { it.enabled && !blacklist.contains(it.packageName) }
.map { HideAppInfo(it, pm) }
.map { createTarget(it, hides) }
.filter { it.processes.isNotEmpty() }
@@ -75,7 +83,7 @@ class HideViewModel : BaseViewModel(), Queryable {
private fun createTarget(info: HideAppInfo, hideList: List<HideTarget>): HideAppTarget {
val pkg = info.packageName
val hidden = hideList.filter { it.packageName == pkg }
val processNames = info.packageInfo.processes.distinct()
val processNames = info.processes.distinct()
val processes = processNames.map { name ->
HideProcessInfo(name, pkg, hidden.any { name == it.process })
}
@@ -88,8 +96,14 @@ class HideViewModel : BaseViewModel(), Queryable {
items.filter {
fun showHidden() = it.itemsChecked != 0
fun filterSystem() =
isShowSystem || it.info.flags and ApplicationInfo.FLAG_SYSTEM == 0
fun filterSystem() = isShowSystem || it.info.flags and ApplicationInfo.FLAG_SYSTEM == 0
fun isApp(uid: Int) = run {
val appId: Int = uid % 100000
appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID
}
fun filterOS() = (isShowSystem && isShowOS) || isApp(it.info.uid)
fun filterQuery(): Boolean {
fun inName() = it.info.label.contains(query, true)
@@ -98,7 +112,7 @@ class HideViewModel : BaseViewModel(), Queryable {
return inName() || inPackage() || inProcesses()
}
showHidden() || (filterSystem() && filterQuery())
showHidden() || (filterSystem() && filterOS() && filterQuery())
}
state = State.LOADED
}
@@ -121,4 +135,3 @@ class HideViewModel : BaseViewModel(), Queryable {
) }
}
}

View File

@@ -57,7 +57,9 @@ sealed class IconLink : RvItem() {
object App : PayPal(), AppDev
object Main : PayPal(), MainDev
object Main : PayPal() {
override val name: String get() = "magiskdonate"
}
}
object Patreon : IconLink() {

View File

@@ -18,6 +18,8 @@ import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
import org.koin.core.get
import timber.log.Timber
import java.io.IOException
import kotlin.math.roundToInt
class InstallViewModel(
@@ -64,7 +66,11 @@ class InstallViewModel(
init {
viewModelScope.launch {
notes = svc.fetchString(Info.remote.magisk.note)
try {
notes = svc.fetchString(Info.remote.magisk.note)
} catch (e: IOException) {
Timber.e(e)
}
}
}
@@ -75,6 +81,8 @@ class InstallViewModel(
this.progress = progress.times(100).roundToInt()
if (this.progress >= 100) {
state = State.LOADED
} else if (this.progress < -150) {
state = State.LOADING_FAILED
}
}

View File

@@ -3,8 +3,8 @@ package com.topjohnwu.magisk.ui.module
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.model.module.Module
import com.topjohnwu.magisk.core.model.module.Repo
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.databinding.ObservableItem
import com.topjohnwu.magisk.utils.set
@@ -39,7 +39,7 @@ class SectionTitle(
override fun contentSameAs(other: SectionTitle): Boolean = this === other
}
sealed class RepoItem(val item: Repo) : ObservableItem<RepoItem>() {
sealed class RepoItem(val item: OnlineModule) : ObservableItem<RepoItem>() {
override val layoutRes: Int = R.layout.item_repo_md2
@get:Bindable
@@ -51,21 +51,21 @@ sealed class RepoItem(val item: Repo) : ObservableItem<RepoItem>() {
override fun contentSameAs(other: RepoItem): Boolean = item == other.item
override fun itemSameAs(other: RepoItem): Boolean = item.id == other.item.id
class Update(item: Repo) : RepoItem(item) {
class Update(item: OnlineModule) : RepoItem(item) {
override val isUpdate get() = true
}
class Remote(item: Repo) : RepoItem(item) {
class Remote(item: OnlineModule) : RepoItem(item) {
override val isUpdate get() = false
}
}
class ModuleItem(val item: Module) : ObservableItem<ModuleItem>() {
class ModuleItem(val item: LocalModule) : ObservableItem<ModuleItem>() {
override val layoutRes = R.layout.item_module_md2
@get:Bindable
var repo: Repo? = null
var repo: OnlineModule? = null
set(value) = set(value, field, { field = it }, BR.repo)
@get:Bindable

View File

@@ -9,13 +9,12 @@ import com.topjohnwu.magisk.arch.*
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.model.module.Module
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.tasks.RepoUpdater
import com.topjohnwu.magisk.data.database.RepoByNameDao
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.databinding.RvItem
import com.topjohnwu.magisk.events.OpenReadmeEvent
import com.topjohnwu.magisk.events.SelectModuleEvent
import com.topjohnwu.magisk.events.OpenChangelogEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.ModuleInstallDialog
import com.topjohnwu.magisk.ktx.addOnListChangedCallback
@@ -44,8 +43,7 @@ import kotlin.math.roundToInt
* */
class ModuleViewModel(
private val repoName: RepoByNameDao,
private val repoUpdated: RepoByUpdatedDao,
private val repoDB: RepoDao,
private val repoUpdater: RepoUpdater
) : BaseViewModel(), Queryable {
@@ -117,12 +115,6 @@ class ModuleViewModel(
// ---
private var refetch = false
private val dao
get() = when (Config.repoOrder) {
Config.Value.ORDER_DATE -> repoUpdated
Config.Value.ORDER_NAME -> repoName
else -> throw IllegalArgumentException()
}
// ---
@@ -186,7 +178,7 @@ class ModuleViewModel(
}
private suspend fun loadInstalled() {
val installed = Module.installed().map { ModuleItem(it) }
val installed = LocalModule.installed().map { ModuleItem(it) }
val diff = withContext(Dispatchers.Default) {
itemsInstalled.calculateDiff(installed)
}
@@ -197,11 +189,11 @@ class ModuleViewModel(
val (updates, diff) = withContext(Dispatchers.IO) {
itemsInstalled.forEach {
launch {
it.repo = dao.getRepoById(it.item.id)
it.repo = repoDB.getModule(it.item.id)
}
}
val updates = itemsInstalled
.mapNotNull { dao.getUpdatableRepoById(it.item.id, it.item.versionCode) }
.mapNotNull { repoDB.getUpdatableModule(it.item.id, it.item.versionCode) }
.map { RepoItem.Update(it) }
val diff = itemsUpdatable.calculateDiff(updates)
return@withContext updates to diff
@@ -219,7 +211,7 @@ class ModuleViewModel(
remoteJob = viewModelScope.launch {
suspend fun loadRemoteDB(offset: Int) = withContext(Dispatchers.IO) {
dao.getRepos(offset).map { RepoItem.Remote(it) }
repoDB.getModules(offset).map { RepoItem.Remote(it) }
}
isRemoteLoading = true
@@ -253,7 +245,7 @@ class ModuleViewModel(
listOf()
} else {
withContext(Dispatchers.IO) {
dao.searchRepos(query, offset).map { RepoItem.Remote(it) }
repoDB.searchModules(query, offset).map { RepoItem.Remote(it) }
}
}
}
@@ -315,14 +307,14 @@ class ModuleViewModel(
}
fun infoPressed(item: RepoItem) =
if (isConnected.get()) OpenChangelogEvent(item.item).publish()
if (isConnected.get()) OpenReadmeEvent(item.item).publish()
else SnackbarEvent(R.string.no_connection).publish()
fun infoPressed(item: ModuleItem) {
item.repo?.also {
if (isConnected.get())
OpenChangelogEvent(it).publish()
OpenReadmeEvent(it).publish()
else
SnackbarEvent(R.string.no_connection).publish()
} ?: return

View File

@@ -11,7 +11,7 @@ import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.UpdateCheckService
import com.topjohnwu.magisk.core.tasks.PatchAPK
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.availableLocales
@@ -90,7 +90,7 @@ object Hide : BaseSettingsItem.Input() {
set(value) = set(value, field, { field = it }, BR.result, BR.error)
val maxLength
get() = PatchAPK.MAX_LABEL_LENGTH
get() = HideAPK.MAX_LABEL_LENGTH
@get:Bindable
val isError
@@ -99,11 +99,17 @@ object Hide : BaseSettingsItem.Input() {
override fun getView(context: Context) = DialogSettingsAppNameBinding
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
override fun refresh() {
isEnabled = Info.remote.stub.versionCode > 0
}
}
object Restore : BaseSettingsItem.Blank() {
override val title = R.string.settings_restore_manager_title.asTransitive()
override val description = R.string.settings_restore_manager_summary.asTransitive()
override fun refresh() {
isEnabled = Info.remote.app.versionCode > 0
}
}
object AddShortcut : BaseSettingsItem.Blank() {
@@ -189,6 +195,13 @@ object SystemlessHosts : BaseSettingsItem.Blank() {
override val description = R.string.settings_hosts_summary.asTransitive()
}
object Tapjack : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_tapjack_title.asTransitive()
override var description = R.string.settings_su_tapjack_summary.asTransitive()
override var value = Config.suTapjack
set(value) = setV(value, field, { field = it }) { Config.suTapjack = it }
}
object Biometrics : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_biometric_title.asTransitive()
override var value = Config.suBiometric
@@ -288,9 +301,9 @@ object AutomaticResponse : BaseSettingsItem.Selector() {
override val entryRes = R.array.auto_response
override val entryValRes = R.array.value_array
override var value = Config.suAutoReponse
override var value = Config.suAutoResponse
set(value) = setV(value, field, { field = it }) {
Config.suAutoReponse = entryValues[it].toInt()
Config.suAutoResponse = entryValues[it].toInt()
}
}

View File

@@ -15,11 +15,8 @@ import com.topjohnwu.magisk.arch.diffListOf
import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Action
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.tasks.PatchAPK
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.RecreateEvent
@@ -82,7 +79,7 @@ class SettingsViewModel(
if (Utils.showSuperUser()) {
list.addAll(listOf(
Superuser,
Biometrics, AccessMode, MultiuserMode, MountNamespaceMode,
Tapjack, Biometrics, AccessMode, MultiuserMode, MountNamespaceMode,
AutomaticResponse, RequestTimeout, SUNotification
))
if (Build.VERSION.SDK_INT < 23) {
@@ -104,7 +101,7 @@ class SettingsViewModel(
is Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().publish()
is ClearRepoCache -> clearRepoCache()
is SystemlessHosts -> createHosts()
is Restore -> restoreManager()
is Restore -> HideAPK.restore(view.context)
is AddShortcut -> AddHomeIconEvent().publish()
else -> callback()
}
@@ -112,7 +109,7 @@ class SettingsViewModel(
override fun onItemChanged(view: View, item: BaseSettingsItem) = when (item) {
is Language -> RecreateEvent().publish()
is UpdateChannel -> openUrlIfNecessary(view)
is Hide -> PatchAPK.hideManager(view.context, item.value)
is Hide -> HideAPK.hide(view.context, item.value)
else -> Unit
}
@@ -142,9 +139,4 @@ class SettingsViewModel(
Utils.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
}
}
private fun restoreManager() {
DownloadService.start(get(), Subject.Manager(Action.APK.Restore))
}
}

View File

@@ -28,8 +28,8 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
override fun onCreate(savedInstanceState: Bundle?) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
lockOrientation()
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
window.addFlags(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
super.onCreate(savedInstanceState)
fun showRequest() {

View File

@@ -1,11 +1,20 @@
package com.topjohnwu.magisk.ui.surequest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.CountDownTimer
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.view.accessibility.AccessibilityNodeProvider
import android.widget.Toast
import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
@@ -22,6 +31,7 @@ import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.set
import kotlinx.coroutines.launch
import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter
@@ -51,6 +61,19 @@ class SuRequestViewModel(
var grantEnabled = false
set(value) = set(value, field, { field = it }, BR.grantEnabled)
@SuppressLint("ClickableViewAccessibility")
val grantTouchListener = View.OnTouchListener { _: View, event: MotionEvent ->
// Filter obscured touches by consuming them.
if (event.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
|| event.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0) {
if (event.action == MotionEvent.ACTION_UP) {
Utils.toast(R.string.touch_filtered_warning, Toast.LENGTH_SHORT)
}
return@OnTouchListener Config.suTapjack
}
false
}
private val items = res.getStringArray(R.array.allow_timeout).map { SpinnerRvItem(it) }
val adapter = BindingListViewAdapter<SpinnerRvItem>(1).apply {
itemBinding = ItemBinding.of { binding, _, item ->
@@ -104,7 +127,7 @@ class SuRequestViewModel(
timer = SuTimer(millis, 1000).apply { start() }
// Actually show the UI
ShowUIEvent().publish()
ShowUIEvent(if (Config.suTapjack) EmptyAccessibilityDelegate else null).publish()
}
private fun respond(action: Int) {
@@ -141,4 +164,18 @@ class SuRequestViewModel(
}
}
// Invisible for accessibility services
object EmptyAccessibilityDelegate : View.AccessibilityDelegate() {
override fun sendAccessibilityEvent(host: View?, eventType: Int) {}
override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?) = true
override fun sendAccessibilityEventUnchecked(host: View?, event: AccessibilityEvent?) {}
override fun dispatchPopulateAccessibilityEvent(host: View?, event: AccessibilityEvent?) = true
override fun onPopulateAccessibilityEvent(host: View?, event: AccessibilityEvent?) {}
override fun onInitializeAccessibilityEvent(host: View?, event: AccessibilityEvent?) {}
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {}
override fun addExtraDataToAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo, extraDataKey: String, arguments: Bundle?) {}
override fun onRequestSendAccessibilityEvent(host: ViewGroup?, child: View?, event: AccessibilityEvent?): Boolean = false
override fun getAccessibilityNodeProvider(host: View?): AccessibilityNodeProvider? = null
}
}

View File

@@ -55,15 +55,15 @@ class EndlessRecyclerScrollListener(
val visibleItemPosition = if (direction == Direction.BOTTOM) {
when (layoutManager) {
is StaggeredGridLayoutManager ->
layoutManager.findLastVisibleItemPositions(null).max() ?: 0
layoutManager.findLastVisibleItemPositions(null).maxOrNull() ?: 0
is GridLayoutManager -> layoutManager.findLastVisibleItemPosition()
is LinearLayoutManager -> layoutManager.findLastVisibleItemPosition()
else -> throw IllegalArgumentException("Only LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager are supported")
}
} else {
when (layoutManager) {
is StaggeredGridLayoutManager -> layoutManager.findFirstVisibleItemPositions(null).min()
?: 0
is StaggeredGridLayoutManager ->
layoutManager.findFirstVisibleItemPositions(null).minOrNull() ?: 0
is GridLayoutManager -> layoutManager.findFirstVisibleItemPosition()
is LinearLayoutManager -> layoutManager.findFirstVisibleItemPosition()
else -> throw IllegalArgumentException("Only LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager are supported")

View File

@@ -228,7 +228,7 @@ class MagiskDialog(
dismiss()
}
}
val items = list.mapIndexed { i, it -> DialogItem(it, i) }
val items = list.mapIndexed { i, cs -> DialogItem(cs, i) }
val binding = itemBindingOf<DialogItem> { it.bindExtra(BR.listener, actualListener) }
.let { ItemBinding.of(it) }

View File

@@ -15,7 +15,6 @@ import com.topjohnwu.magisk.core.Const.ID.PROGRESS_NOTIFICATION_CHANNEL
import com.topjohnwu.magisk.core.Const.ID.UPDATE_NOTIFICATION_CHANNEL
import com.topjohnwu.magisk.core.SplashActivity
import com.topjohnwu.magisk.core.cmp
import com.topjohnwu.magisk.core.download.Action
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.intent
@@ -46,7 +45,6 @@ object Notifications {
setChannelId(UPDATE_NOTIFICATION_CHANNEL)
} else {
setSmallIcon(R.drawable.ic_magisk_outline)
setVibrate(longArrayOf(0, 100, 100, 100))
}
}
}
@@ -70,7 +68,7 @@ object Notifications {
}
fun managerUpdate(context: Context) {
val intent = DownloadService.pendingIntent(context, Subject.Manager(Action.APK.Upgrade))
val intent = DownloadService.pendingIntent(context, Subject.Manager())
val builder = updateBuilder(context)
.setContentTitle(context.getString(R.string.manager_update_title))

View File

@@ -138,6 +138,7 @@
<Button
android:id="@+id/grant_btn"
style="@style/WidgetFoundation.Button.Text"
onTouch="@{viewModel.grantTouchListener}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"

View File

@@ -306,6 +306,23 @@
</LinearLayout>
<LinearLayout
goneUnless="@{viewModel.loadFailed}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/download_file_error"
android:textAppearance="@style/AppearanceFoundation.Title" />
</LinearLayout>
</FrameLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -47,7 +47,7 @@
app:layout_constraintTop_toBottomOf="@+id/hide_filter_title_filter">
<com.google.android.material.chip.Chip
android:id="@+id/hide_filter_chip"
android:id="@+id/hide_filter_system_chip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -60,6 +60,20 @@
app:chipBackgroundColor="?colorSurfaceVariant"
tools:checked="true" />
<com.google.android.material.chip.Chip
android:id="@+id/hide_filter_os_chip"
style="@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={viewModel.showOS}"
android:nextFocusRight="@id/hide_filter_chip_data"
android:nextFocusDown="@id/hide_filter_search_field"
android:text="@string/show_os_app"
android:textAppearance="@style/AppearanceFoundation.Caption"
app:checkedIcon="@drawable/ic_check_md2"
app:chipBackgroundColor="?colorSurfaceVariant"
tools:checked="true" />
<com.google.android.material.chip.Chip
android:id="@+id/hide_filter_chip_data"
style="@style/Widget.MaterialComponents.Chip.Entry"
@@ -136,7 +150,7 @@
android:id="@+id/hide_filter_done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/hide_filter_chip"
android:nextFocusLeft="@id/hide_filter_system_chip"
app:backgroundTint="?colorPrimary"
app:elevation="0dp"
app:fabSize="mini"

View File

@@ -5,6 +5,15 @@
android:id="@+id/action_reboot_normal"
android:title="@string/reboot" />
<item
android:id="@+id/action_reboot_userspace"
android:title="@string/reboot_userspace"
android:visible="false" />
<item
android:id="@+id/action_reboot_recovery"
android:title="@string/reboot_recovery" />
<item
android:id="@+id/action_reboot_bootloader"
android:title="@string/reboot_bootloader" />
@@ -17,8 +26,4 @@
android:id="@+id/action_reboot_edl"
android:title="@string/reboot_edl" />
<item
android:id="@+id/action_reboot_recovery"
android:title="@string/reboot_recovery" />
</menu>

View File

@@ -1,13 +1,5 @@
## v8.0.1
## v8.0.3
- Fix `vbmeta.img` patching for Samsung `AP.tar` files. This fixes bootloops on devices like Galaxy S10 after flashing updated AP files.
- Properly truncate existing files before writing to prevent corrupted files
- Prevent a possible UI loop when device ran into very low memory
- Switch to use JSDelivr CDN for several files
## v8.0.0
- 100% full app rewrite! Will highlight functional changes below.
- Add detailed device info in home screen to assist user installation
- Support Magisk v21.0 communication protocol
- Support patching modern Samsung `AP.tar`
- Switch to the new Magisk Module Repo setup in preparation to allow 3rd party repos
- Add tapjacking protection on Superuser request dialog
- Stability changes and bug fixes

View File

@@ -90,7 +90,7 @@ EOF
}
adb_pm_install() {
local tmp=/data/local/tmp/patched.apk
local tmp=/data/local/tmp/temp.apk
cp -f "$1" $tmp
chmod 644 $tmp
su 2000 -c pm install $tmp || pm install $tmp

View File

@@ -31,6 +31,7 @@
<string name="invalid_update_channel">Хібны канал абнаўлення</string>
<string name="uninstall_magisk_title">Выдаліць Magisk</string>
<string name="uninstall_magisk_msg">Усе модулі будуць адключаныя/выдаленыя!\nRoot будзе выдалены!\nВашыя даныя будуць зашыфраваныя!</string>
<string name="home_check_safetynet">Праверка SafetyNet</string>
<!--Install-->
<string name="keep_force_encryption">Прымусова захаваць шыфраванне</string>
<string name="keep_dm_verity">Захаваць AVB 2.0/dm-verity</string>
@@ -97,7 +98,7 @@
<string name="hide_scroll_up">Уверх</string>
<string name="hide_filters">Фільтры</string>
<string name="hide_search">Пошук</string>
<!--Module Fragment-->
<!--Module -->
<string name="no_info_provided">(Няма інфармацыі)</string>
<string name="reboot_recovery">Перазапуск у Recovery</string>
<string name="reboot_bootloader">Перазапуск у Bootloader</string>
@@ -111,8 +112,8 @@
<string name="module_action_install_external">Усталяваць са сховішча</string>
<string name="update_available">Даступныя абнаўленні</string>
<string name="module_installed">Усталяваныя</string>
<string name="module_section_online">Анлайн</string>
<string name="sorting_order">Парадак сартавання</string>
<string name="external_rw_permission_denied">Дайце доступ да сховішча, каб уключыць гэтую функцыю</string>
<!--Settings -->
<string name="settings_dark_mode_title">Рэжым афармлення</string>
<string name="settings_dark_mode_message">Абярыце рэжым, які вам больш даспадобы!</string>
@@ -163,6 +164,9 @@
<string name="settings_su_biometric_summary">Выкарыстанне біяметрычнай аўтэнтыфікацыі для запытаў правоў суперкарыстальніка</string>
<string name="no_biometric">Не падтрымліваецца прыладай альбо не ўключана ў наладах</string>
<string name="settings_customization">Персаналізацыя</string>
<string name="setting_add_shortcut_summary">Дадаць на хатні экран прыгожы цэтлік на той выпадак, калі пасля хавання праграмы будзе цяжка разглядзець значок і назву</string>
<string name="settings_doh_title">DNS паверх HTTPS</string>
<string name="settings_doh_description">Абыходны шлях для DNS у некаторых краінах</string>
<string name="multiuser_mode">Шматкарыстальніцкі рэжым</string>
<string name="settings_owner_only">Толькі ўладальнік</string>
<string name="settings_owner_manage">Кіраванне ўладальнікам</string>
@@ -215,4 +219,8 @@
<string name="authenticate">Аўтэнтыфікацыя</string>
<string name="unsupport_magisk_title">Непадтрымліваемая версія Magisk</string>
<string name="unsupport_magisk_msg">Гэтая версія Magisk Manager не падтрымлівае Magisk версіі ніжэй за %1$s.\n\nПраграма будзе працаваць так, як быццам Magisk не ўсталяваны. Як мага хутчэй абнавіце Magisk.</string>
<string name="external_rw_permission_denied">Дайце доступ да сховішча, каб уключыць гэтую функцыю</string>
<string name="add_shortcut_title">Дадаць цэтлік на хатні экран</string>
<string name="add_shortcut_msg">Пасля хавання Magisk Manager яго значок і назву можа быць цяжка разглядзець. Хочаце дадаць цэтлік на хатні экран?</string>
<string name="app_not_found">Не знойдзена праграм для апрацоўкі гэтага дзеяння</string>
</resources>

View File

@@ -20,7 +20,7 @@
<string name="not_available">N/A</string>
<string name="hide">Verstecken</string>
<string name="status">Status</string>
<string name="home_package">Packet</string>
<string name="home_package">Paket</string>
<string name="home_notice_content">Benutzen Sie nur den quelloffenen Magisk Manager. Magisk von unbekannten Quellen kann zu schädlichen Aktionen führen.</string>
<string name="home_support_title">Unterstützen Sie uns</string>
@@ -55,9 +55,9 @@
<!--Superuser-->
<string name="su_request_title">Superuser-Anfrage</string>
<string name="deny">Verweigern</string>
<string name="prompt">Sofort</string>
<string name="prompt">Fragen</string>
<string name="grant">Gewähren</string>
<string name="su_warning">Gewähren Sie vollen Zugriff auf Ihr Gerät. Den Zugriff verweigern, wenn Sie sich nicht sicher sind!</string>
<string name="su_warning">Sie gewähren vollen Zugriff auf Ihr Gerät. Verweigern Sie den Zugriff, wenn Sie sich nicht sicher sind!</string>
<string name="forever">Für immer</string>
<string name="once">Einmalig</string>
<string name="tenmin">10 Minuten</string>
@@ -179,7 +179,7 @@
<string name="settings_user_independent">Benutzerunabhängig</string>
<string name="owner_only_summary">Nur der Besitzer hat Root-Zugriff</string>
<string name="owner_manage_summary">Nur der Besitzer verwaltet den Root-Zugriff und erhält Zugriffsanfragen</string>
<string name="user_indepenent_summary">Jeder Nutzer hat seine eingenen Root-Regeln</string>
<string name="user_indepenent_summary">Jeder Nutzer hat seine eigenen Root-Regeln</string>
<string name="mount_namespace_mode">Mount Namespace Modus</string>
<string name="settings_ns_global">Globaler Namespace</string>
@@ -193,7 +193,7 @@
<string name="update_channel">Magisk Updates</string>
<string name="progress_channel">Fortschrittsmitteilungen</string>
<string name="download_complete">Download abgeschlossen</string>
<string name="download_file_error">Fehler beim Datei herunterladen</string>
<string name="download_file_error">Fehler beim herunterladen der Datei</string>
<string name="download_open_parent">Im übergeordneten Ordner anzeigen</string>
<string name="download_open_self">Datei anzeigen</string>
<string name="magisk_update_title">Magisk Update verfügbar!</string>
@@ -222,7 +222,7 @@
<string name="proprietary_title">Proprietären Code herunterladen</string>
<string name="proprietary_notice">Magisk Manager ist FOSS und enthält nicht den proprietären SafetyNet-API-Code von Google.\n\nWollen Sie Magisk Manager erlauben, eine Erweiterung (enthält GoogleApiClient) für SafetyNet-Prüfungen herunterzuladen?</string>
<string name="setup_fail">Setup fehlgeschlagen</string>
<string name="env_fix_title">Erfordert zusätzliche Einrichtung</string>
<string name="env_fix_title">Zusätzliche Einrichtung erforderlich</string>
<string name="env_fix_msg">Ihr Gerät muss zusätzlich eingerichtet werden, damit Magisk ordnungsgemäß funktioniert. Es wird das Magisk Setup-Zip herunterladen, möchten Sie jetzt fortfahren?</string>
<string name="setup_msg">Laufzeitumgebung einrichten…</string>
<string name="authenticate">Authentifizieren</string>

View File

@@ -175,6 +175,8 @@
<string name="no_biometric">Dispositivo no compatible o las configuraciones biométricas no están habilitadas</string>
<string name="settings_customization">Personalización</string>
<string name="setting_add_shortcut_summary">Añade un bonito atajo en la pantalla de inicio en caso de que el nombre y el icono sean difíciles de reconocer después de ocultar la aplicación</string>
<string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Evitar envenenamiento de DNS en algunos países</string>
<string name="multiuser_mode">Modo multiusuario</string>
<string name="settings_owner_only">Sólo administrador del dispositivo</string>
@@ -234,5 +236,6 @@
<string name="external_rw_permission_denied">Conceder permiso de almacenamiento para habilitar esta funcionalidad</string>
<string name="add_shortcut_title">Añadir un atajo a la pantalla de inicio</string>
<string name="add_shortcut_msg">Después de esconder el Magisk Manager, su nombre e icono podría ser difícil de reconocer. ¿Quieres añadir un bonito atajo a la pantalla de inicio?</string>
<string name="app_not_found">No se ha encontrado ninguna app para manejar esta acción</string>
</resources>

View File

@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">Demande daccès superutilisateur</string>
<string name="touch_filtered_warning">Parce quune application obscurcit une demande du super-utilisateur, Magisk ne peut pas vérifier votre réponse</string>
<string name="deny">Refuser</string>
<string name="prompt">Demander</string>
<string name="grant">Accorder</string>
@@ -102,13 +103,15 @@
<!-- MagiskHide -->
<string name="show_system_app">Afficher les applications système</string>
<string name="show_os_app">Afficher les applis système</string>
<string name="hide_filter_hint">Filtrer par nom</string>
<string name="hide_scroll_up">Faire défiler vers le haut</string>
<string name="hide_filters">Filtres</string>
<string name="hide_search">Rechercher</string>
<!--Module Fragment-->
<!--Module -->
<string name="no_info_provided">(aucune info transmise)</string>
<string name="reboot_userspace">Redémarrage en douceur</string>
<string name="reboot_recovery">Redémarrer en mode récupération</string>
<string name="reboot_bootloader">Redémarrer en mode amorçage</string>
<string name="reboot_download">Redémarrer en mode téléchargement</string>
@@ -170,6 +173,8 @@
<string name="superuser_notification">Notification superutilisateur</string>
<string name="settings_su_reauth_title">Sauthentifier à nouveau après la mise à niveau</string>
<string name="settings_su_reauth_summary">Redemander une authentification pour autoriser laccès en superutilisateur après une mise à jour de lapplication</string>
<string name="settings_su_tapjack_title">Activer Protection Détournement de Clic</string>
<string name="settings_su_tapjack_summary">Le dialogue dinvite du super-utilisateur ne répondra pas à la saisie lorsquil est masqué par une autre fenêtre ou un recouvrement</string>
<string name="settings_su_biometric_title">Activer lauthentification biométrique</string>
<string name="settings_su_biometric_summary">Utiliser lauthentification biométrique pour autoriser les accès en superutilisateur</string>
<string name="no_biometric">Lappareil nest pas pris en charge ou alors aucun paramètre biométrique nest activé</string>
@@ -219,6 +224,7 @@
<string name="hide_manager_title">Masquage de Magisk Manager…</string>
<string name="hide_manager_fail_toast">Le masquage de Magisk Manager a échoué.</string>
<string name="open_link_failed_toast">Aucune application permettant douvrir le lien na été trouvée</string>
<string name="restore_manager_fail_toast">Échec de la restauration de Magisk Manager</string>
<string name="complete_uninstall">Désinstallation complète</string>
<string name="restore_img">Restauration des images</string>
<string name="restore_img_msg">Restauration…</string>
@@ -234,7 +240,8 @@
<string name="unsupport_magisk_title">Version de Magisk non prise en charge</string>
<string name="unsupport_magisk_msg">Cette version de Magisk Manager ne prend pas en charge les versions de Magisk inférieures à %1$s.\n\nLapplication se comportera comme si Magisk nétait pas installé. Veuillez mettre à jour Magisk aussi vite que possible.</string>
<string name="external_rw_permission_denied">Permettre laccès au stockage pour activer cette fonctionnalité</string>
<string name="add_shortcut_title">Ajouter un raccourcis à lécran daccueil</string>
<string name="add_shortcut_msg">Après avoir caché Magisk Manager, son nom et son icône peuvent devenir difficiles à reconnaître. Voulez-vous ajouter un joli raccourci vers lécran daccueil ?</string>
<string name="add_shortcut_title">Ajouter un raccourci à lécran daccueil</string>
<string name="add_shortcut_msg">Après avoir caché Magisk Manager, son nom et son icône peuvent devenir difficiles à reconnaître. Voulezvous ajouter un joli raccourci vers lécran daccueil?</string>
<string name="app_not_found">Aucune application trouvée pour traiter cette action</string>
</resources>

View File

@@ -1,177 +1,244 @@
<resources>
<!--Welcome Activity-->
<!--Sections-->
<string name="modules">मॉड्यूल</string>
<string name="superuser">उत्तम उपयोगकर्ता</string>
<string name="logs">अभिलेख</string>
<string name="superuser">सुपर यूज़र</string>
<string name="logs">लॉग्स</string>
<string name="settings">सेटिंग्स</string>
<string name="install">स्थापित करें</string>
<string name="unsupport_magisk_title">असमर्थित Magisk संस्करण</string>
<string name="refresh">स्थानीय डेटा रिफ्रेश करें</string>
<string name="install">इंस्टॉल</string>
<string name="section_home">घर</string>
<string name="section_theme">थीम</string>
<string name="safetynet">सेफ्टीनेट</string>
<!--Status Fragment-->
<string name="invalid_update_channel">अमान्य अपडेट चैनल</string>
<string name="safetynet_api_error">SafetyNet API त्रुटि</string>
<string name="safetynet_res_invalid">अनुक्रिया अमान्य है.</string>
<string name="keep_force_encryption">बल एन्क्रिप्शन को बनाये रखें</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity को बनाये रखें</string>
<string name="recovery_mode">रिकवरी मोड</string>
<string name="uninstall_magisk_title">Magisk की स्थापना रद्द करें</string>
<string name="uninstall_magisk_msg">सभी मॉड्यूल अक्षम/हटा दिए जाएंगे. रुट और आपका संभावित रूप से एन्क्रिप्ट डाटा हटा दिया जाएगा.</string>
<!--Home-->
<string name="no_connection">कोई कनेक्शन उपलब्ध नहीं है</string>
<string name="app_changelog">बदलाव</string>
<string name="manager">मैनेजर</string>
<string name="loading">लोड हो रहा है…</string>
<string name="update">अपडेट करें</string>
<string name="not_available">N/A</string>
<string name="hide">छिपाएँ</string>
<string name="status">स्थिति</string>
<string name="home_package">पैकेज</string>
<!--Module Fragment-->
<string name="no_info_provided">(कोई जानकारी प्रदान नहीं की गई)</string>
<string name="reboot_recovery">रिकवरी मोड में रिबूट करें</string>
<string name="reboot_bootloader">बूटलोडर में रिबूट करें</string>
<string name="reboot_download">डाउनलोड में रिबूट करें</string>
<string name="reboot_edl">EDL मोड में रिबूट करें</string>
<string name="home_notice_content">हमेशा सुनिश्चित करें कि आप ओपन-सोर्स मैजिक मैनेजर का उपयोग कर रहे हैं। अज्ञात स्रोत के प्रबंधक दुर्भावनापूर्ण कार्य कर सकते हैं।</string>
<string name="home_support_title">हमें सहयोग दीजिये</string>
<string name="home_item_source">स्रोत</string>
<string name="home_support_content">मैजिस्क है, औमेशा मुफ्त और ओपन-सोर्स रहेगा। हालाँकि आप एक छोटा सा दान भेजकर यह दिखा सकते हैं कि आप देख-भाल करते हैं।</string>
<string name="home_status_normal">साधारण</string>
<string name="home_status_stub">स्टब</string>
<string name="home_installed_version">इंस्टॉल्ड</string>
<string name="home_latest_version">नवीनतम</string>
<string name="invalid_update_channel">अमान्य अपडेट चैनल</string>
<string name="uninstall_magisk_title">मैजिस्क को अनइंस्टॉल करें</string>
<string name="uninstall_magisk_msg">सभी मॉड्यूल्स को निष्क्रिय/हटा दिया जाएगा!\n रूट को हटा दिया जाएगा!\n आपका डेटा संभावित रूप से एन्क्रिप्ट किया गया है यदि पहले से नहीं है!</string>
<string name="home_check_safetynet">सेफ्टीनेट की जाँच करें</string>
<!--Repo Fragment-->
<string name="update_available">अपडेट उपलब्ध है</string>
<string name="home_installed_version">स्थापित</string>
<string name="sorting_order">छँटाई क्रम </string>
<!--Log Fragment-->
<string name="menuSaveLog">अभिलेख सेव करें</string>
<string name="menuClearLog">अभिलेख साफ़ करें</string>
<string name="logs_cleared">अभिलेख सफलतापूर्वक साफ़ हो गया.</string>
<!--About Activity-->
<string name="app_changelog">परिवर्तन अभिलेख</string>
<!-- System Components, Notifications -->
<string name="update_channel">Magisk की अपडेट</string>
<string name="progress_channel">प्रगति सूचनाएँ</string>
<string name="download_complete">डाउनलोड सम्पन्न हुआ</string>
<string name="download_file_error">फ़ाइल डाउनलोड करने में त्रुटि</string>
<string name="download_open_parent">मूल फ़ोल्डर में दिखाएँ</string>
<string name="download_open_self">फाइल दिखाएँ</string>
<string name="magisk_update_title">Magisk की अपडेट उपलब्ध है!</string>
<string name="manager_update_title">Magisk Manager की अपडेट उपलब्ध है!</string>
<!-- Installation -->
<string name="manager_download_install">डाउनलोड और स्थापित करने के लिए दबाएँ.</string>
<string name="download_zip_only">खाली Zip डाउनलोड करें</string>
<string name="direct_install">सीधा स्थापित करें (अनुशंसित)</string>
<string name="install_inactive_slot">निष्क्रिय स्लॉट में स्थापित करें (OTA के बाद)</string>
<string name="install_inactive_slot_msg">आपके डिवाइस को रीबूट के बाद वर्तमान निष्क्रिय स्लॉट में बूट करने के लिए मजबूर किया जाएगा!\nOTA होने के बाद ही इस विकल्प का उपयोग करें.\nजारी रखें?</string>
<!--Install-->
<string name="keep_force_encryption">फ़ोर्स एन्क्रिप्शन को संरक्षित रखें</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity को संरक्षित रखें</string>
<string name="recovery_mode">रिकवरी मोड</string>
<string name="install_options_title">विकल्प</string>
<string name="install_method_title">तरीका</string>
<string name="install_next">आगे</string>
<string name="install_start">तो चलिए शुरू करते हैं!</string>
<string name="manager_download_install">डाउनलोड और इंस्टॉल करने के लिए दबाएं</string>
<string name="download_zip_only">केवल ज़िप डाउनलोड करें</string>
<string name="direct_install">प्रत्यक्ष इंस्टॉल (अनुशंसित)</string>
<string name="install_inactive_slot">निष्क्रिय स्लॉट में इंस्टॉल करें (OTA के बाद)</string>
<string name="install_inactive_slot_msg">आपका डिवाइस रीबूट होने के बाद वर्तमान निष्क्रिय स्लॉट में बूट करने के लिए मजबूर किया जाएगा!\n इस विकल्प का उपयोग सिर्फ OTA हो जाने के बाद करें।\n जारी रखें?</string>
<string name="setup_title">अतिरिक्त सेटअप</string>
<string name="select_patch_file">एक फ़ाइल का चयन और पैच करें</string>
<string name="patch_file_msg">एक कच्ची इमेज चुनें (*.img) या एक ODIN tarfile (*.tar)</string>
<string name="reboot_delay_toast">5 सेकंड में रिबूट हो रहा है</string>
<!--Toasts, Dialogs-->
<string name="repo_install_title">%1$s को स्थापित करें</string>
<string name="repo_install_msg">क्या आप %1$s को स्थापित करना चाहते हैं ?</string>
<string name="download">डाउनलोड</string>
<string name="reboot">रिबूट</string>
<string name="release_notes">रिलीज नोट्स</string>
<string name="repo_cache_cleared">Repo cache साफ़ हो गया</string>
<string name="flashing">फ़्लैश हो रहा है…</string>
<string name="done">हो गया!</string>
<string name="failure">विफल हुआ</string>
<string name="hide_manager_title">Magisk Manager छुप रहा है…</string>
<string name="hide_manager_fail_toast">Magisk Manager छुपने में असफल रहा.</string>
<string name="open_link_failed_toast">लिंक खोलने के लिए कोई एप्लिकेशन नहीं मिला.</string>
<string name="complete_uninstall">पूरी तरह से स्थापना रद्द करें</string>
<string name="restore_img">इमेजेज को पुनर्स्थापित करें</string>
<string name="restore_img_msg">वापस लाया जा रहा…</string>
<string name="restore_done">वापस ले आया गया!</string>
<string name="restore_fail">स्टॉक बैकअप मौजूद नहीं है!</string>
<string name="proprietary_title">मालिकाना कोड डाउनलोड करें</string>
<string name="proprietary_notice">Magisk Manager FOSS है और उस्में Google का मालिकाना SafetyNet API कोड शामिल नहीं है.\n\nक्या आप Magisk Manager को SafetyNet चेक के लिए एक्सटेंशन (GoogleApiClient शामिल) डाउनलोड करने की अनुमति देंगे ?</string>
<string name="setup_fail">सेटअप असफल हुआ.</string>
<string name="env_fix_title">अतिरिक्त सेटअप की आवश्यकता है</string>
<string name="env_fix_msg">ठीक से काम करने के लिए आपके डिवाइस को Magisk के लिए अतिरिक्त सेटअप की आवश्यकता है. यह Magisk सेटअप zip डाउनलोड करेगा, क्या आप आगे बढ़ना चाहते हैं?</string>
<string name="setup_msg">पर्यावरण सेटअप चल रहा है…</string>
<!--Settings Activity -->
<string name="settings_download_path_title">डाउनलोड करने की जगह</string>
<string name="settings_download_path_message">%1$s में फाइल्स रखी जाएँगी</string>
<string name="settings_clear_cache_title">Repo Cache साफ़ करें</string>
<string name="settings_clear_cache_summary">ऑनलाइन Repo के लिए Cached जानकारी साफ़ करें. यह एप्लिकेशन को ऑनलाइन रिफ्रेश होने के लिए मजबूर करता है.</string>
<string name="settings_hide_manager_title">Magisk Manager को छुपाएं</string>
<string name="settings_hide_manager_summary">Magisk Manager को क्रमरहित नाम से फिर से पैकेज करें.</string>
<string name="settings_restore_manager_title">Magisk Manager को पुनर्स्थापित करें</string>
<string name="settings_restore_manager_summary">Magisk Manager को अपने मूल पैकेज नाम से पुनर्स्थापित करें</string>
<string name="language">भाषा</string>
<string name="system_default">(सिस्टम डिफ़ॉल्ट)</string>
<string name="settings_check_update_title">अपडेट के लिए जाँच करें</string>
<string name="settings_check_update_summary">समय-समय पर बैकग्राउंड में अपडेट की जांच करते रहें.</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_magiskhide_summary">पता लगाने के विभिन्न रूपों से Magisk को छुपाएं.</string>
<string name="settings_hosts_title">सिस्टमलेस होस्ट्स</string>
<string name="settings_hosts_summary">एडब्लॉक ऍप्लिकेशन्स के लिए सिस्टमलेस होस्ट्स का समर्थन</string>
<string name="settings_hosts_toast">सिस्टमलेस होस्ट्स का मॉड्यूल जोड़ दिया गया</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_15">15 सेकंड्‌स</string>
<string name="settings_su_request_20">20 सेकंड्‌स</string>
<string name="settings_su_request_30">30 सेकंड्‌स</string>
<string name="settings_su_request_45">45 सेकंड्‌स</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="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">केवल मालिक के पास ही रूट की पहुँच है.</string>
<string name="owner_manage_summary">केवल मालिक ही रूट की पहुँच का प्रबंधन कर सकता है और अनुरोध संकेत प्राप्त कर सकता है.</string>
<string name="user_indepenent_summary">प्रत्येक उपयोगकर्ता का अपना अलग रूट नियम होता है.</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">सभी रूट सत्र वैश्विक माउंट नेमस्पेस का उपयोग करते हैं.</string>
<string name="requester_summary">रूट सत्रों को उनके अनुरोधकर्ताओं के नेमस्पेस विरासत में मिलेंगे.</string>
<string name="isolate_summary">प्रत्येक रूट सत्र का अपना अलग नेमस्पेस होगा.</string>
<string name="patch_file_msg">एक रॉ छवि (* .img) या एक ODIN tarfile (* .tar) का चयन करें</string>
<string name="reboot_delay_toast">5 सेकंड में रिबूट हो रहा है...</string>
<string name="flash_screen_title">इंस्टॉलेशन</string>
<!--Superuser-->
<string name="su_request_title">उत्तम उपयोगकर्ता का अनुरोध</string>
<string name="su_request_title">सुपरयूज़र अनुरोध</string>
<string name="deny">इंकार करें</string>
<string name="prompt">आदेश</string>
<string name="prompt">संकेत दिखाएँ</string>
<string name="grant">अनुमति दें</string>
<string name="su_warning">यह आपके डिवाइस की पूरी पहुँच की अनुमति देगा. यदि आप सुनिश्चित नहीं हैं तो इंकार करें!</string>
<string name="su_warning">यह आपके डिवाइस की पूरी पहुँच की अनुमति देगा,\n यदि आप सुनिश्चित नहीं हैं तो इंकार करें!</string>
<string name="forever">सदैव</string>
<string name="once">एक बार</string>
<string name="tenmin">10 मिनट</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="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_revoke_title">वापस लें?</string>
<string name="su_revoke_msg">%1$s के अधिकारों को वापस लेने की पुष्टि करें?</string>
<string name="toast">पॉप-अप नोट</string>
<string name="su_allow_toast"> %1$s को सुपरयूज़र अधिकार प्रदान किया गया</string>
<string name="su_deny_toast"> %1$s को सुपरयूज़र अधिकार से इकार किया गया</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_revoke_title">अधिकार वापस लें?</string>
<string name="su_revoke_msg"> %1$s के अधिकारों को रद्द करने की पुष्टि करें?</string>
<string name="toast">पॉप-अप सूचना</string>
<string name="none">कोई नहीं</string>
<!--Superuser logs-->
<string name="superuser_toggle_notification">सूचनाएं</string>
<string name="superuser_toggle_revoke">अधिकार वापस लें</string>
<string name="superuser_policy_none">किसी भी ऐप ने अभी तक सुपरयूज़र की अनुमति नहीं मांगी है।</string>
<!--Logs-->
<string name="log_data_none">कोई लॉग नहीं, अपने सुपरयूज़र सक्षम एप्लिकेशन का अधिक उपयोग करने का प्रयास करें।</string>
<string name="log_data_magisk_none">मैजिस्क लॉग खाली हैं, यह अजीब है।</string>
<string name="menuSaveLog">लॉग सहेजे</string>
<string name="menuClearLog">लॉग साफ़ करें</string>
<string name="logs_cleared">लॉग सफलतापूर्वक साफ़ किया गया।</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">लक्ष्य UID: %1$d</string>
<string name="target_uid">लक्षित UID: %1$d</string>
<!--SafetyNet-->
<string name="safetynet_api_error">सेफ्टीनेट एपीआई त्रुटि</string>
<string name="safetynet_res_invalid">प्रतिक्रिया अमान्य है</string>
<string name="safetynet_attest_success">सफलता!</string>
<string name="safetynet_attest_failure">सत्यापन विफल!</string>
<string name="safetynet_attest_loading">सिर्फ एक सेकंड…</string>
<string name="safetynet_attest_restart">पुनः प्रयास करें</string>
<!-- MagiskHide -->
<string name="show_system_app">सिस्टम ऍप्लिकेशन्स दिखाएं</string>
<string name="show_system_app">सिस्टम ऐप्स दिखाएं</string>
<string name="show_os_app">OS एप्लिकेशन दिखाएं</string>
<string name="hide_filter_hint">नाम से फ़िल्टर करें</string>
<string name="hide_scroll_up">ऊपर स्क्रॉल करें</string>
<string name="hide_filters">फिल्टर</string>
<string name="hide_search">खोजें</string>
<!--Module -->
<string name="no_info_provided">(कोई जानकारी नहीं दी गई)</string>
<string name="reboot_userspace">सॉफ्ट रिबूट</string>
<string name="reboot_recovery">रिकवरी रिबूट</string>
<string name="reboot_bootloader">बूटलोडर रिबूट</string>
<string name="reboot_download">डाउनलोड मोड रिबूट</string>
<string name="reboot_edl">EDL रिबूट</string>
<string name="module_version_author"> %2$s के द्वारा %1$s</string>
<string name="module_section_pending">अपडेट्स</string>
<string name="module_section_pending_action">सभी अपडेट करें</string>
<string name="module_state_remove">हटाएँ</string>
<string name="module_state_restore">रिस्टोर करें</string>
<string name="module_action_install_external">स्टोरेज से इनस्टॉल करें</string>
<string name="update_available">अपडेट उपलब्ध</string>
<string name="module_installed">इंस्टॉल्ड</string>
<string name="module_section_online">ऑनलाइन</string>
<string name="sorting_order">क्रमबद्ध तरीका</string>
<!--Settings -->
<string name="settings_dark_mode_title">थीम मोड</string>
<string name="settings_dark_mode_message">ऐसी थीम का चयन करें जो आपकी शैली के अनुकूल हो!</string>
<string name="settings_dark_mode_light">हमेशा सफेद रंग वाली</string>
<string name="settings_dark_mode_system">सिस्टम के अनुसार</string>
<string name="settings_dark_mode_dark">हमेशा गहरे रंग वाली</string>
<string name="settings_download_path_title">डाउनलोड पथ</string>
<string name="settings_download_path_message">फ़ाइलों को %1$s में सहेजा जाएगा</string>
<string name="settings_clear_cache_title">रेपो कैश साफ़ करें</string>
<string name="settings_clear_cache_summary">ऑनलाइन रेपो के लिए कैश्ड जानकारी साफ़ करें। यह एप्लिकेशन को ऑनलाइन रिफ्रेश करने के लिए मजबूर करता है</string>
<string name="settings_hide_manager_title">मैजिस्क मैनेजर छिपाएं</string>
<string name="settings_hide_manager_summary">बेतरतीब पैकेज और ऐप नामों के साथ मैगिस्क मैनेजर को रिपैकेज करें</string>
<string name="settings_restore_manager_title">मैजिस्क मैनेजर को रिस्टोर करें</string>
<string name="settings_restore_manager_summary">मूल पैकेज और ऐप नाम के साथ मैजिस्क मैनेजर को रिस्टोर करें</string>
<string name="language">भाषा</string>
<string name="system_default">(सिस्टम डिफ़ॉल्ट)</string>
<string name="settings_check_update_title">अपडेट जांचें</string>
<string name="settings_check_update_summary">समय-समय पर बैकग्राउंड में अपडेट की जांच करते रहें</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_magiskhide_summary">विभिन्न रूप की खोजों से बचने के लिए मैजिस्क को छिपाएं</string>
<string name="settings_hosts_title">सिस्टमलेस होस्ट</string>
<string name="settings_hosts_summary">Adblock ऐप्स के लिए सिस्टमलेस होस्ट सपोर्ट</string>
<string name="settings_hosts_toast">सिस्टमलेस होस्ट मॉड्यूल जोड़ा गया</string>
<string name="settings_app_name_hint">नया नाम</string>
<string name="settings_app_name_helper">इस नाम से ऐप को फिर से इंस्टॉल किया जाएगा</string>
<string name="settings_app_name_error">अवैध प्रारूप</string>
<string name="settings_su_app_adb">ऐप्स और एडीबी</string>
<string name="settings_su_app">केवल ऐप्स</string>
<string name="settings_su_adb">केवल एडीबी</string>
<string name="settings_su_disable">बंद है</string>
<string name="settings_su_request_10">10 सेकंड</string>
<string name="settings_su_request_15">15 सेकंड</string>
<string name="settings_su_request_20">20 सेकंड</string>
<string name="settings_su_request_30">30 सेकंड</string>
<string name="settings_su_request_45">45 सेकंड</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="settings_su_reauth_title">अपग्रेड के बाद प्रमाणीकरण</string>
<string name="settings_su_reauth_summary">एक ऐप अपडेट होने के बाद सुपरयूज़र अनुमति प्रमाणित करें</string>
<string name="settings_su_biometric_title">बायोमेट्रिक प्रमाणीकरण सक्षम करें</string>
<string name="settings_su_biometric_summary">सुपरयूज़र अनुरोधों की अनुमति देने के लिए बायोमेट्रिक प्रमाणीकरण का उपयोग करें</string>
<string name="no_biometric">असमर्थित डिवाइस या कोई बायोमेट्रिक सेटिंग सक्षम नहीं हैं</string>
<string name="settings_customization">कस्टमाईजेशन</string>
<string name="setting_add_shortcut_summary">ऐप को छिपाने के बाद नाम और आइकन को पहचानना मुश्किल है, तो होम स्क्रीन में एक सुंदर शॉर्टकट जोड़ें</string>
<string name="settings_doh_title">DNS पर HTTPS</string>
<string name="settings_doh_description">कुछ राष्ट्रों में चल रही DNS विषाक्तता का समाधान</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="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">सभी रूट सत्र ग्लोबल नेमस्पेस का उपयोग करते हैं</string>
<string name="requester_summary">रूट सत्रों को उनके अनुरोधकर्ताओं के नेमस्पेस विरासत में मिलेंगे</string>
<string name="isolate_summary">प्रत्येक रूट सत्र का अपना अलग आइसोलेटेड नेमस्पेस होगा</string>
<!--Notifications-->
<string name="update_channel">मैजिस्क अपडेट</string>
<string name="progress_channel">प्रगति सूचनाएँ</string>
<string name="download_complete">डाउनलोड सम्पन्न हुआ</string>
<string name="download_file_error">फ़ाइल डाउनलोड करने में त्रुटि</string>
<string name="download_open_parent">मूल फ़ोल्डर में दिखाएं</string>
<string name="download_open_self">फ़ाइल दिखाएँ</string>
<string name="magisk_update_title">मैजिस्क अपडेट उपलब्ध!</string>
<string name="manager_update_title">मैजिस्क मैनेजर के लिए अपडेट उपलब्ध है!</string>
<!--Toasts, Dialogs-->
<string name="yes">हाँ</string>
<string name="no">नहीं</string>
<string name="repo_install_title">इंस्टॉल %1$s</string>
<string name="repo_install_msg">क्या आप अभी %1$s इंस्टॉल करना चाहते हैं?</string>
<string name="download">डाउनलोड</string>
<string name="reboot">रीबूट</string>
<string name="release_notes">रिलीज नोट्स</string>
<string name="repo_cache_cleared">रेपो कैश साफ़ किया</string>
<string name="flashing">फ़्लैश हो रहा है...</string>
<string name="done">सफल हुआ!</string>
<string name="failure">असफल हुआ</string>
<string name="hide_manager_title">मैजिस्क मैनेजर को छिपा रहे हैं...</string>
<string name="hide_manager_fail_toast">मैजिस्क मैनेजर छिपाना विफल हुआ</string>
<string name="restore_manager_fail_toast">मैजिस्क मैनेजर को रिस्टोर करना विफल हुआ</string>
<string name="open_link_failed_toast">लिंक खोलने के लिए कोई एप्लिकेशन नहीं मिला</string>
<string name="complete_uninstall">पूर्ण रूप से अनइंस्टॉल करें</string>
<string name="restore_img">इमेज रिस्टोर करें</string>
<string name="restore_img_msg">रिस्टोर हो रहा है...</string>
<string name="restore_done">रिस्टोर सफल हुआ!</string>
<string name="restore_fail">स्टॉक बैकअप मौजूद नहीं है!</string>
<string name="proprietary_title">मालिकाना कोड डाउनलोड करें</string>
<string name="proprietary_notice">मैजिस्क मैनेजर एक मुफ्त और ओपन-सोर्स ऐप है जो गूगल के मालिकाना सेफ्टीनेट कोड का इस्तेमाल नहीं करता। क्या आप मैजिस्क मैनेजर को सेफ्टीनेट की जांच के लिए एक एक्सटेंशन डाऊनलोड करने की अनुमति प्रदान करना चाहेंगे?</string>
<string name="setup_fail">सेटअप असफल हुआ</string>
<string name="env_fix_title">अतिरिक्त सेटअप की ज़रूरत है</string>
<string name="env_fix_msg">आपके डिवाइस पर मैजिस्क को सही से काम करने के लिए अतिरिक्त सेटअप की ज़रूरत है। यह एक मैजिस्क सेटअप ज़िप डाउनलोड करेगा, क्या आप आगे बढ़ना चाहेंगे?</string>
<string name="setup_msg">वातावरण सेटअप चल रहा है...</string>
<string name="authenticate">प्रमाणित करें</string>
<string name="unsupport_magisk_title">असमर्थित मैजिस्क संस्करण</string>
<string name="unsupport_magisk_msg">मैजिस्क मैनेजर का यह संस्करण मैजिस्क संस्करण %1$s से कम का समर्थन नहीं करता। \n\nऐप इस तरह व्यवहार करेगा जैसे मैजिस्क इंस्टॉल नहीं है, कृपया मैजिस्क को जल्द अपग्रेड करें।</string>
<string name="external_rw_permission_denied">इसका उपयोग करने के लिए स्टोरेज अनुमति प्रदान करें</string>
<string name="add_shortcut_title">होम स्क्रीन पर शॉर्टकट जोड़ें</string>
<string name="add_shortcut_msg">मैजिस्क मैनेजर को छिपाने के बाद इसका नाम और आइकॉन पहचानना मुश्किल हो सकता है, क्या आप एक अच्छा दिखने वाला शॉर्टकट होम स्क्रीन पर जोड़ना चाहेंगे?</string>
<string name="app_not_found">इस एक्शन को संभालने के लिए कोई एप्लिकेशन नहीं मिली</string>
</resources>

View File

@@ -6,112 +6,61 @@
<string name="superuser">Superuser</string>
<string name="logs">Zapisnik događaja</string>
<string name="settings">Postavke</string>
<string name="refresh">Osvježite lokalne podatke</string>
<string name="install">Instaliranje</string>
<string name="section_home">Početna</string>
<string name="section_theme">Teme</string>
<string name="safetynet">SafetyNet</string>
<!--Status Fragment-->
<!--Home-->
<string name="no_connection">Nema dostupne veze</string>
<string name="app_changelog">Popis izmjena</string>
<string name="manager">Manager</string>
<string name="loading">Učitavanje…</string>
<string name="update">Ažuriraj</string>
<string name="not_available">N/A</string>
<string name="hide">Sakrij</string>
<string name="status">Status</string>
<string name="home_package">Paket</string>
<string name="safetynet_api_error">SafetyNet API greška</string>
<string name="safetynet_res_invalid">Odgovor je nevažeći</string>
<string name="home_notice_content">Uvijek provjerite koristite li Magisk Manager s otvorenim kodom. Manager nepoznatog izvora može izvoditi zlonamjerne radnje.</string>
<string name="home_support_title">Podržite nas</string>
<string name="home_item_source">Izvor</string>
<string name="home_support_content">Magisk je i uvijek će biti besplatan i otvoren. Međutim, možete nam pokazati da vam je stalo slanjem male donacije.</string>
<string name="home_status_normal">Normalno</string>
<string name="home_status_stub">Stub</string>
<string name="home_installed_version">Instalirana</string>
<string name="home_latest_version">Najnovija</string>
<string name="invalid_update_channel">Nevažeći kanal ažuriranja</string>
<string name="uninstall_magisk_title">Deinstaliraj Magisk</string>
<string name="uninstall_magisk_msg">Svi će moduli biti onemogućeni/uklonjeni!\nRoot će biti uklonjen!\nVaši su podaci potencijalno šifrirani, ako već nisu!</string>
<string name="home_check_safetynet">Provjeri SafetyNet</string>
<!--Install Fragment-->
<!--Install-->
<string name="keep_force_encryption">Zadrži prisilno šifirannje</string>
<string name="keep_dm_verity">Zadrži AVB 2.0/dm-verity</string>
<string name="uninstall_magisk_title">Deinstaliraj Magisk</string>
<string name="uninstall_magisk_msg">Svi moduli će biti onemogućeni/uklonjeni. Root će biti uklonjen i potencijalno šifrirati Vaše podatke, ukoliko Vaši podaci trenutačno nisu šifrirani</string>
<string name="update">Ažuriraj</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nema podataka)</string>
<!--Repo Fragment-->
<string name="update_available">Ažuriranje dostupno</string>
<string name="home_installed_version">Instalirano</string>
<!--Log Fragment-->
<string name="menuSaveLog">"Spremi zapisnik "</string>
<string name="menuClearLog">Očisti zapisnik sada</string>
<string name="logs_cleared">Zapisnik je uspješno izbrisan</string>
<!--About Activity-->
<string name="app_changelog">Popis izmjena aplikacije</string>
<!--Toasts, Dialogs-->
<string name="repo_install_title">Instaliraj %1$s</string>
<string name="repo_install_msg">Da li želite instalirati %1$s sada?</string>
<string name="download">Preuzmi</string>
<string name="reboot">Ponovno podizanje sustava</string>
<string name="magisk_update_title">Dostupno je novo Magisk ažuriranje!</string>
<string name="release_notes">Bilješke o izdavanju aplikacije</string>
<string name="repo_cache_cleared">Predmemorija repozitorija izbrisana</string>
<string name="manager_update_title">Dostupno je novo ažuriranje Magisk Manager aplikacije!</string>
<string name="manager_download_install">Pritisnite za preuzimanje i instalaciju</string>
<string name="update_channel">Magisk ažuriranja</string>
<string name="flashing">Apliciranje</string>
<string name="hide_manager_title">Skrivanje Magisk Manager aplikacije…</string>
<string name="hide_manager_fail_toast">Skrivanje Magisk Manager nije uspjelo</string>
<string name="recovery_mode">Recovery način</string>
<string name="install_options_title">Opcije</string>
<string name="install_method_title">Metoda</string>
<string name="install_next">Dalje</string>
<string name="install_start">Krenimo</string>
<string name="manager_download_install">Dodirnite za preuzimanje i instalaciju</string>
<string name="download_zip_only">Preuzmi samo zip</string>
<string name="direct_install">Izravna instalacija (preporuča se)</string>
<string name="complete_uninstall">Potpuna deinstalacija</string>
<string name="restore_done">Obnova je dovršena!</string>
<string name="restore_fail">Stock backup does not exist!</string>
<string name="proprietary_title">Preuzmite vlasnički kod</string>
<string name="proprietary_notice">Magisk Manager je FOSS aplikacija te ne sadrži Googleov SafetyNet API kod.\n\nDopuštate li Magisk Manager aplikaciji da preuzme proširenje (sadrži GoogleApiClient) za SafetyNet provjere?</string>
<string name="download_file_error">Pogreška prilikom preuzimanja datoteke</string>
<!--Settings Activity -->
<string name="settings_clear_cache_title">Izbriši predmemoriju repozitorija</string>
<string name="settings_clear_cache_summary">Izbrišite predmemorirane informacije za online repozitorij, prisiljavajući aplikaciju da se osvježi online</string>
<string name="settings_hide_manager_title">Sakrij Magisk Manager</string>
<string name="settings_hide_manager_summary">Privremeno sakrij Magisk Manager.\nTo će instalirati novu aplikaciju pod nazivom \"Otkrij Magisk Manager\"</string>
<string name="language">Jezik</string>
<string name="system_default">(Zadana postavka sustava)</string>
<string name="settings_update_channel_title">Kanal ažuriranja</string>
<string name="settings_update_stable">Stabilno</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_magiskhide_summary">Sakrij Magisk od raznih detekcija</string>
<string name="settings_hosts_title">Systemless hostovi</string>
<string name="settings_hosts_summary">Systemless hostovi podržavaju Adblock aplikacije</string>
<string name="settings_su_app_adb">Aplikacije i ADB</string>
<string name="settings_su_app">Samo aplikacije</string>
<string name="settings_su_adb">Samo ADB</string>
<string name="settings_su_disable">Onemogućeno</string>
<string name="settings_su_request_10">10 sekundi</string>
<string name="settings_su_request_15">15 sekundi</string>
<string name="settings_su_request_20">20 sekundi</string>
<string name="settings_su_request_30">30 sekundi</string>
<string name="settings_su_request_45">45 sekundi</string>
<string name="settings_su_request_60">60 sekundi</string>
<string name="superuser_access">Superuser pristup</string>
<string name="auto_response">Automatski odgovor</string>
<string name="request_timeout">Vremensko ograničenje zahtjeva</string>
<string name="superuser_notification">Superuser obavijest</string>
<string name="settings_su_reauth_title">Ponovno provjerite autentičnost nakon ažuriranja</string>
<string name="settings_su_reauth_summary">Ponovno provjerite autentičnost Superuser dopuštenja nakon ažuriranja aplikacije</string>
<string name="multiuser_mode">Višekorisnički način rada</string>
<string name="settings_owner_only">Samo vlasnik uređaja</string>
<string name="settings_owner_manage">Upravljano od strane vlasnika uređaja</string>
<string name="settings_user_independent">Neovisno o korisniku</string>
<string name="owner_only_summary">Samo vlasnik ima root pristup</string>
<string name="owner_manage_summary">Samo vlasnik može upravljati root pristupom i primati zahtjeve za root pristup</string>
<string name="user_indepenent_summary">Svaki korisnik ima vlastita root pravila</string>
<string name="mount_namespace_mode">Postavljanje imenskog prostora</string>
<string name="settings_ns_global">Globalni imenski prostor</string>
<string name="settings_ns_requester">Naslijediti imenski prostor</string>
<string name="settings_ns_isolate">Izolirani imenski prostor</string>
<string name="global_summary">Sve root sesije koriste globalni imenski prostor</string>
<string name="requester_summary">Root sesije će naslijediti imenski prostor tražitelja</string>
<string name="isolate_summary">Svaka root sesija ima svoj vlastiti imenski prostor</string>
<string name="direct_install">Izravna instalacija (preporučeno)</string>
<string name="install_inactive_slot">Instaliraj u neaktivni utor (Nakon OTA)</string>
<string name="install_inactive_slot_msg">Vaš će se uređaj prisiliti pokrenuti s trenutnog neaktivnog mjesta nakon ponovnog pokretanja!\nKoristite tu opciju samo nakon što je OTA dovršena.\nContinue?</string>
<string name="setup_title">Dodatno postavljanje</string>
<string name="select_patch_file">Odaberite patch datoteku</string>
<string name="patch_file_msg">Odaberite raw (*.img) ili ODIN tarfile (*.tar)</string>
<string name="reboot_delay_toast">Ponovno pokretanje za 5 sekundi…</string>
<string name="flash_screen_title">Instalacija</string>
<!--Superuser-->
<string name="su_request_title">Superuser zahtjev</string>
<string name="deny">Odbij</string>
<string name="prompt">Upitaj</string>
<string name="prompt">Upit</string>
<string name="grant">Odobri</string>
<string name="su_warning">Omogućuje potpuni pristup Vašem uređaju.\nOdbijte ako niste sigurni!</string>
<string name="su_warning">Odobren puni pristup vašem uređaju.\nOdbijte ako niste sigurni!</string>
<string name="forever">Zauvijek</string>
<string name="once">Jednom</string>
<string name="tenmin">10 min</string>
@@ -131,7 +80,161 @@
<string name="toast">Pop-up</string>
<string name="none">Nijedan</string>
<!--Superuser logs-->
<string name="superuser_toggle_notification">Obavijesti</string>
<string name="superuser_toggle_revoke">Opozovi</string>
<string name="superuser_policy_none">Još nijedna aplikacija nije zatražila Superuser prava.</string>
<!--Logs-->
<string name="log_data_none">Nemate zapisnika, pokušajte više upotrebljavati svoje aplikacije s omogućenim SU.</string>
<string name="log_data_magisk_none">Zapisnici Magiska su prazni, to je čudno.</string>
<string name="menuSaveLog">Spremi zapisnik</string>
<string name="menuClearLog">Izbriši zapisnik</string>
<string name="logs_cleared">Zapisnik uspješno izbrisan.</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Ciljani UID: %1$d</string>
<!--SafetyNet-->
<string name="safetynet_api_error">SafetyNet API greška</string>
<string name="safetynet_res_invalid">Odgovor je nevažeći</string>
<string name="safetynet_attest_success">Uspjeh!</string>
<string name="safetynet_attest_failure">Provjera nije uspjela!</string>
<string name="safetynet_attest_loading">Samo trenutak…</string>
<string name="safetynet_attest_restart">Pokušajte ponovo</string>
<!-- MagiskHide -->
<string name="show_system_app">Prikaži sistemske aplikacije</string>
<string name="hide_filter_hint">Filtriraj prema nazivu</string>
<string name="hide_scroll_up">Pomicanje gore</string>
<string name="hide_filters">Filteri</string>
<string name="hide_search">Traži</string>
<!--Module -->
<string name="no_info_provided">(Nema podataka)</string>
<string name="reboot_recovery">Ponovo pokreni u Recovery</string>
<string name="reboot_bootloader">Ponovo pokreni u Bootloader</string>
<string name="reboot_download">Ponovo pokreni u Download</string>
<string name="reboot_edl">Ponovo pokreni u EDL</string>
<string name="module_version_author">%1$s od %2$s</string>
<string name="module_section_pending">Ažuriranja</string>
<string name="module_section_pending_action">Ažuriraj sve</string>
<string name="module_state_remove">Ukloni</string>
<string name="module_state_restore">Vrati</string>
<string name="module_action_install_external">Instaliraj iz pohrane</string>
<string name="update_available">Ažuriranje dostupno</string>
<string name="module_section_online">Online</string>
<string name="sorting_order">Redoslijed sortiranja</string>
<!--Settings -->
<string name="settings_dark_mode_title">Teme</string>
<string name="settings_dark_mode_message">Odaberite temu koja najbolje odgovara vašem stilu!</string>
<string name="settings_dark_mode_light">Uvijek svijetla</string>
<string name="settings_dark_mode_system">Prati sustav</string>
<string name="settings_dark_mode_dark">Uvijek crna</string>
<string name="settings_download_path_title">Putanja preuzimanja</string>
<string name="settings_download_path_message">Datoteke će biti spremljene u %1$s</string>
<string name="settings_clear_cache_title">Obriši predmemoriju repozitorija</string>
<string name="settings_clear_cache_summary">Obrišite predmemorirane podatke za mrežne repozitorije. To prisiljava aplikaciju da se osvježi na mreži</string>
<string name="settings_hide_manager_title">Sakrij Magisk Manager</string>
<string name="settings_hide_manager_summary">Prepakiraj Magisk Manager s nasumičnim nazivima paketa i aplikacija</string>
<string name="settings_restore_manager_title">Vrati Magisk Manager</string>
<string name="settings_restore_manager_summary">Vrati Magisk Manager s izvornim nazivima paketa i aplikacija</string>
<string name="language">Jezik</string>
<string name="system_default">(Zadano sustavom)</string>
<string name="settings_check_update_title">Provjeri za ažuriranja</string>
<string name="settings_check_update_summary">Povremeno provjeravaj ima li ažuriranja u pozadini</string>
<string name="settings_update_channel_title">Kanal ažuriranja</string>
<string name="settings_update_stable">Stabilna</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Vlastiti kanal</string>
<string name="settings_update_custom_msg">Umetnite prilagođeni URL</string>
<string name="settings_magiskhide_summary">Sakrij Magisk od različitih oblika otkrivanja</string>
<string name="settings_hosts_title">Hostovi bez sistema</string>
<string name="settings_hosts_summary">Podrška za hostove bez sistema za Adblock aplikacije</string>
<string name="settings_hosts_toast">Dodan je modul hosta bez sistema</string>
<string name="settings_app_name_hint">Novi naziv</string>
<string name="settings_app_name_helper">Aplikacija će se prepakirati na ovaj naziv</string>
<string name="settings_app_name_error">Nevažeći format</string>
<string name="settings_su_app_adb">Aplikacije i ADB</string>
<string name="settings_su_app">Samo aplikacije</string>
<string name="settings_su_adb">Samo ADB</string>
<string name="settings_su_disable">Onemogućeno</string>
<string name="settings_su_request_10">10 sekundi</string>
<string name="settings_su_request_15">15 sekundi</string>
<string name="settings_su_request_20">20 sekundi</string>
<string name="settings_su_request_30">30 sekundi</string>
<string name="settings_su_request_45">45 sekundi</string>
<string name="settings_su_request_60">60 sekundi</string>
<string name="superuser_access">Superuser pristup</string>
<string name="auto_response">Automatski odgovor</string>
<string name="request_timeout">Vremensko ograničenje zahtjeva</string>
<string name="superuser_notification">Superuser obavijest</string>
<string name="settings_su_reauth_title">Ponovno provjerite autentičnost nakon ažuriranja</string>
<string name="settings_su_reauth_summary">Ponovno provjerite autentičnost Superuser-a dopuštenja nakon ažuriranja aplikacije</string>
<string name="settings_su_biometric_title">Omogući biometrijsku provjeru autentičnosti</string>
<string name="settings_su_biometric_summary">Koristi biometrijsku provjeru autentičnosti da biste omogućili zahtjeve Superuser-a</string>
<string name="no_biometric">Nepodržani uređaj ili nije omogućena biometrijska provjera autentičnosti</string>
<string name="settings_customization">Prilagodba</string>
<string name="setting_add_shortcut_summary">Dodajte lijepi prečac na početni zaslon u slučaju da je naziv i ikonu teško prepoznati nakon skrivanja aplikacije</string>
<string name="settings_doh_title">DNS preko HTTPS-a</string>
<string name="settings_doh_description">Zaobilazno trovanje DNS-om u nekim zemljama</string>
<string name="multiuser_mode">Višekorisnički način rada</string>
<string name="settings_owner_only">Samo vlasnik uređaja</string>
<string name="settings_owner_manage">Upravljano od strane vlasnika uređaja</string>
<string name="settings_user_independent">Neovisno o korisniku</string>
<string name="owner_only_summary">Samo vlasnik ima root pristup</string>
<string name="owner_manage_summary">Samo vlasnik može upravljati root pristupom i primati zahtjeve za root pristup</string>
<string name="user_indepenent_summary">Svaki korisnik ima vlastita root pravila</string>
<string name="mount_namespace_mode">Postavljanje imenskog prostora</string>
<string name="settings_ns_global">Globalni imenski prostor</string>
<string name="settings_ns_requester">Naslijediti imenski prostor</string>
<string name="settings_ns_isolate">Izolirani imenski prostor</string>
<string name="global_summary">Sve root sesije koriste globalni imenski prostor</string>
<string name="requester_summary">Root sesije će naslijediti imenski prostor tražitelja</string>
<string name="isolate_summary">Svaka root sesija ima svoj vlastiti imenski prostor</string>
<!--Notifications-->
<string name="update_channel">Magisk Ažuriranja</string>
<string name="progress_channel">Obavijesti o napretku</string>
<string name="download_complete">Preuzimanje završeno</string>
<string name="download_file_error">Pogreška pri preuzimanju datoteke</string>
<string name="download_open_parent">Prikaži u nadređenoj mapi</string>
<string name="download_open_self">Prikaži datoteku</string>
<string name="magisk_update_title">Dostupno je Magisk ažuriranje!</string>
<string name="manager_update_title">Dostupno je Magisk Manager ažuriranje! </string>
<!--Toasts, Dialogs-->
<string name="yes">Da</string>
<string name="no">Ne</string>
<string name="repo_install_title">Instaliraj %1$s</string>
<string name="repo_install_msg">Da li želite instalirati %1$s sada?</string>
<string name="download">Preuzmi</string>
<string name="reboot">Ponovno pokreni</string>
<string name="release_notes">Bilješke o izdavanju aplikacije</string>
<string name="repo_cache_cleared">Predmemorija repozitorija izbrisana</string>
<string name="flashing">Apliciranje…</string>
<string name="done">Dovršeno!</string>
<string name="failure">Nije uspjelo</string>
<string name="hide_manager_title">Skrivanje Magisk Manager-a…</string>
<string name="hide_manager_fail_toast">Skrivanje Magisk Manager-a nije uspjelo.</string>
<string name="open_link_failed_toast">Nije pronađena aplikacija za otvaranje veze</string>
<string name="complete_uninstall">Dovršite deinstalaciju</string>
<string name="restore_img">Vrati Images</string>
<string name="restore_img_msg">Vraćanje…</string>
<string name="restore_done">Vraćanje je dovršeno!</string>
<string name="restore_fail">Izvorna Sig. kopija ne postoji!</string>
<string name="proprietary_title">Preuzmite vlasnički kod</string>
<string name="proprietary_notice">Magisk Manager je FOSS i ne sadrži Googleov zaštićeni API sigurnosni kod.\n\nHoćete li dopustiti Magisk Manageru da preuzme proširenje (sadrži GoogleApiClient) za SafetyNet provjeru?</string>
<string name="setup_fail">Postavljanje nije uspjelo</string>
<string name="env_fix_title">Zahtijeva dodatno postavljanje</string>
<string name="env_fix_msg">Vašem je uređaju potrebno dodatno postavljanje kako bi Magisk ispravno radio. Preuzet će se zip za postavljanje Magiska, želite li nastaviti sada?</string>
<string name="setup_msg">Postavljanje okruženja za pokretanje…</string>
<string name="authenticate">Potvrdi</string>
<string name="unsupport_magisk_title">Nepodržana Magisk verzija</string>
<string name="unsupport_magisk_msg">Ova verzija Magisk Manager-a ne podržava Magisk verziju nižu od %1$s.\n\nAplikacija će se ponašati kao da nije instaliran Magisk, ažurirajte Magisk što je prije moguće.</string>
<string name="external_rw_permission_denied">Odobrite dopuštenje za pohranu da biste omogućili ovu funkciju</string>
<string name="add_shortcut_title">Dodaj prečac na početni zaslon</string>
<string name="add_shortcut_msg">Nakon skrivanja Magisk Manager-a, njegov naziv i ikonu moglo bi postati teško prepoznati. Želite li dodati lijepi prečac na početni zaslon?</string>
<string name="app_not_found">Nije pronađena nijedna aplikacijaza obradu ove radnju</string>
</resources>

View File

@@ -5,7 +5,7 @@
<string name="superuser">Superuser</string>
<string name="logs">Log</string>
<string name="settings">Setelan</string>
<string name="refresh">Perbarui Data Lokal</string>
<string name="refresh">Perbarui data lokal</string>
<string name="install">Instal</string>
<string name="section_home">Beranda</string>
<string name="section_theme">Tema</string>
@@ -13,7 +13,7 @@
<!--Home-->
<string name="no_connection">Koneksi tidak tersedia</string>
<string name="app_changelog">Daftar perubahan</string>
<string name="app_changelog">Catatan perubahan</string>
<string name="manager">Manager</string>
<string name="loading">Memuat…</string>
<string name="update">Update</string>
@@ -22,15 +22,15 @@
<string name="status">Status</string>
<string name="home_package">Paket</string>
<string name="home_notice_content">Pastikan Anda selalu menggunakan Magisk Manager dari sumber terbuka. Manager dari sumber yang tidak dikenal dapat melakukan tindak kejahatan.</string>
<string name="home_support_title">Dukung Kami</string>
<string name="home_notice_content">Pastikan selalu menggunakan Magisk Manager dari sumber terbuka. Manager dari sumber yang tidak dikenal dapat melakukan tindakan jahat.</string>
<string name="home_support_title">Dukung kami</string>
<string name="home_item_source">Sumber</string>
<string name="home_support_content">Magisk gratis dan bersumber terbuka, dan akan selalu seperti itu. Bagaimanapun juga Anda dapat menunjukan kepedulian Anda kepada kami dengan mengirimkan sedikit donasi.</string>
<string name="home_status_normal">Normal</string>
<string name="home_status_stub">Stub</string>
<string name="home_installed_version">Terinstal</string>
<string name="home_latest_version">Terbaru</string>
<string name="invalid_update_channel">Kanal Update Tidak Valid</string>
<string name="invalid_update_channel">Kanal update tidak valid</string>
<string name="uninstall_magisk_title">Uninstal Magisk</string>
<string name="uninstall_magisk_msg">Semua modul akan dinonaktifkan/dihapus!\nRoot akan dihapus!\nData Anda berpotensi terenkripsi jika belum!</string>
<string name="home_check_safetynet">Pemeriksaan SafetyNet</string>
@@ -42,20 +42,21 @@
<string name="install_options_title">Opsi</string>
<string name="install_method_title">Metode</string>
<string name="install_next">Berikutnya</string>
<string name="install_start">Mari mulai</string>
<string name="manager_download_install">Tekan untuk download dan instal</string>
<string name="download_zip_only">Download Zip Saja</string>
<string name="direct_install">Langsung Instal (Disarankan)</string>
<string name="install_inactive_slot">Instal pada Slot Nonaktif (Setelah OTA)</string>
<string name="install_start">Mulai</string>
<string name="manager_download_install">Sentuh untuk download dan instal</string>
<string name="download_zip_only">Download zip saja</string>
<string name="direct_install">Langsung instal (Disarankan)</string>
<string name="install_inactive_slot">Instal pada slot nonaktif (Setelah OTA)</string>
<string name="install_inactive_slot_msg">Perangkat Anda akan DIPAKSA boot ke slot yang saat ini tidak aktif setelah perangkat dinyalakan ulang!\nGunakan opsi ini hanya setelah proses OTA selesai.\nLanjutkan?</string>
<string name="setup_title">Penyiapan Tambahan</string>
<string name="select_patch_file">Pilih dan Tambal File</string>
<string name="setup_title">Penyiapan tambahan</string>
<string name="select_patch_file">Pilih dan tambal file</string>
<string name="patch_file_msg">Pilih mentahan image (*.img) atau file tar ODIN (*.tar)</string>
<string name="reboot_delay_toast">Memulai kembali dalam 5 detik…</string>
<string name="flash_screen_title">Instalasi</string>
<!--Superuser-->
<string name="su_request_title">Permintaan Superuser</string>
<string name="su_request_title">Permintaan superuser</string>
<string name="touch_filtered_warning">Karena terdapat aplikasi yang menghalangi dialog permintaan superuser, Magisk tidak dapat memverifikasi respons Anda</string>
<string name="deny">Tolak</string>
<string name="prompt">Ajukan</string>
<string name="grant">Izinkan</string>
@@ -66,14 +67,14 @@
<string name="twentymin">20 mnt</string>
<string name="thirtymin">30 mnt</string>
<string name="sixtymin">60 mnt</string>
<string name="su_allow_toast">%1$s mendapatkan hak Superuser</string>
<string name="su_deny_toast">%1$s ditolak atas hak Superuser</string>
<string name="su_snack_grant">Hak Superuser untuk %1$s diberikan</string>
<string name="su_snack_deny">Hak Superuser untuk %1$s ditolak</string>
<string name="su_snack_notif_on">Notifikasi untuk %1$s diaktifkan</string>
<string name="su_snack_notif_off">Notifikasi untuk %1$s dinonaktifkan</string>
<string name="su_snack_log_on">Log untuk %1$s diaktifkan</string>
<string name="su_snack_log_off">Log untuk %1$s dinonaktifkan</string>
<string name="su_allow_toast">%1$s mendapatkan hak superuser</string>
<string name="su_deny_toast">%1$s ditolak atas hak superuser</string>
<string name="su_snack_grant">Hak superuser %1$s diberikan</string>
<string name="su_snack_deny">Hak superuser %1$s ditolak</string>
<string name="su_snack_notif_on">Notifikasi %1$s diaktifkan</string>
<string name="su_snack_notif_off">Notifikasi %1$s dinonaktifkan</string>
<string name="su_snack_log_on">Pencatatan log %1$s diaktifkan</string>
<string name="su_snack_log_off">Pencatatan log %1$s dinonaktifkan</string>
<string name="su_revoke_title">Cabut?</string>
<string name="su_revoke_msg">Konfirmasi untuk mencabut hak %1$s?</string>
<string name="toast">Toast</string>
@@ -102,13 +103,15 @@
<!-- MagiskHide -->
<string name="show_system_app">Tampilkan aplikasi sistem</string>
<string name="show_os_app">Tampilkan aplikasi OS</string>
<string name="hide_filter_hint">Filter menurut nama</string>
<string name="hide_scroll_up">Gulir ke atas</string>
<string name="hide_filters">Filter</string>
<string name="hide_search">Penelusuran</string>
<string name="hide_search">Telusuri</string>
<!--Module -->
<string name="no_info_provided">(Info tidak tersedia)</string>
<string name="reboot_userspace">Nyalakan ulang secara halus</string>
<string name="reboot_recovery">Nyalakan ke mode Recovery</string>
<string name="reboot_bootloader">Nyalakan ke mode Bootloader</string>
<string name="reboot_download">Nyalakan ke mode Download</string>
@@ -119,36 +122,36 @@
<string name="module_state_remove">Hapus</string>
<string name="module_state_restore">Pulihkan</string>
<string name="module_action_install_external">Instal dari penyimpanan</string>
<string name="update_available">Update Tersedia</string>
<string name="update_available">Update tersedia</string>
<string name="module_installed">@string/home_installed_version</string>
<string name="module_section_online">Online</string>
<string name="sorting_order">Urutan Sortir</string>
<string name="sorting_order">Urutan sortir</string>
<!--Settings -->
<string name="settings_dark_mode_title">Mode Tema</string>
<string name="settings_dark_mode_title">Mode tema</string>
<string name="settings_dark_mode_message">Pilih mode yang paling cocok dengan gaya Anda!</string>
<string name="settings_dark_mode_light">Selalu Terang</string>
<string name="settings_dark_mode_system">Ikuti Sistem</string>
<string name="settings_dark_mode_dark">Selalu Gelap</string>
<string name="settings_dark_mode_light">Selalu terang</string>
<string name="settings_dark_mode_system">Ikuti sistem</string>
<string name="settings_dark_mode_dark">Selalu gelap</string>
<string name="settings_download_path_title">Lokasi download</string>
<string name="settings_download_path_message">File akan disimpan ke %1$s</string>
<string name="settings_clear_cache_title">Hapus Cache Repositori</string>
<string name="settings_clear_cache_summary">Hapus cache informasi repositori online. Tindakan ini memaksa aplikasi untuk memperbarui repositori online</string>
<string name="settings_clear_cache_title">Hapus cache repo</string>
<string name="settings_clear_cache_summary">Hapus cache informasi repo online. Tindakan ini memaksa aplikasi untuk memperbarui repo online</string>
<string name="settings_hide_manager_title">Sembunyikan Magisk Manager</string>
<string name="settings_hide_manager_summary">Kemas ulang Magisk Manager dengan nama paket dan nama aplikasi secara acak</string>
<string name="settings_restore_manager_title">Pulihkan Magisk Manager</string>
<string name="settings_restore_manager_summary">Pulihkan Magisk Manager dengan nama paket dan nama aplikasi aslinya</string>
<string name="language">Bahasa</string>
<string name="system_default">(Default Sistem)</string>
<string name="settings_check_update_title">Periksa Update</string>
<string name="system_default">(Default sistem)</string>
<string name="settings_check_update_title">Periksa update</string>
<string name="settings_check_update_summary">Periksa update secara berkala di latar belakang</string>
<string name="settings_update_channel_title">Kanal Update</string>
<string name="settings_update_channel_title">Kanal update</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Kanal Khusus</string>
<string name="settings_update_custom">Kanal khusus</string>
<string name="settings_update_custom_msg">Masukkan URL khusus</string>
<string name="settings_magiskhide_summary">Sembunyikan Magisk dari berbagai bentuk pendeteksian</string>
<string name="settings_hosts_title">Host Systemless</string>
<string name="settings_hosts_title">Host systemless</string>
<string name="settings_hosts_summary">Dukungan host secara systemless untuk aplikasi pemblokir iklan</string>
<string name="settings_hosts_toast">Menambahkan modul host systemless</string>
<string name="settings_app_name_hint">Nama baru</string>
@@ -164,45 +167,47 @@
<string name="settings_su_request_30">30 detik</string>
<string name="settings_su_request_45">45 detik</string>
<string name="settings_su_request_60">60 detik</string>
<string name="superuser_access">Akses Superuser</string>
<string name="auto_response">Respons Otomatis</string>
<string name="request_timeout">Batas Waktu Permintaan</string>
<string name="superuser_notification">Notifikasi Superuser</string>
<string name="superuser_access">Akses superuser</string>
<string name="auto_response">Respons otomatis</string>
<string name="request_timeout">Batas waktu permintaan</string>
<string name="superuser_notification">Notifikasi superuser</string>
<string name="settings_su_reauth_title">Autentikasi ulang setelah upgrade</string>
<string name="settings_su_reauth_summary">Autentikasi ulang izin superuser setelah aplikasi diupgrade</string>
<string name="settings_su_biometric_title">Aktifkan Autentikasi Biometrik</string>
<string name="settings_su_reauth_summary">Autentikasi ulang izin akses superuser setelah aplikasi diupgrade</string>
<string name="settings_su_tapjack_title">Aktifkan perlindungan tapjacking</string>
<string name="settings_su_tapjack_summary">Dialog permintaan superuser tidak akan menanggapi masukan saat terhalangi oleh lapisan atau jendela lainnya</string>
<string name="settings_su_biometric_title">Aktifkan autentikasi biometrik</string>
<string name="settings_su_biometric_summary">Gunakan autentikasi biometrik untuk mengizinkan permintaan superuser</string>
<string name="no_biometric">Perangkat tidak didukung atau setelan biometrik tidak diaktifkan</string>
<string name="settings_customization">Penyesuaian</string>
<string name="no_biometric">Perangkat tidak mendukung atau setelan biometrik tidak diaktifkan</string>
<string name="settings_customization">Personalisasi</string>
<string name="setting_add_shortcut_summary">Tambahkan pintasan yang menarik pada layar utama seandainya nama dan ikon sulit untuk dikenali setelah menyembunyikan aplikasi</string>
<string name="settings_doh_title">DNS melalui HTTPS</string>
<string name="settings_doh_description">Solusi untuk permasalahan DNS di beberapa negara</string>
<string name="settings_doh_description">Solusi untuk DNS poisoning di beberapa negara</string>
<string name="multiuser_mode">Mode Multi Pengguna</string>
<string name="settings_owner_only">Pemilik Perangkat Saja</string>
<string name="settings_owner_manage">Pemilik Perangkat Mengelola</string>
<string name="settings_user_independent">Pengguna Independen</string>
<string name="multiuser_mode">Mode multi pengguna</string>
<string name="settings_owner_only">Pemilik perangkat saja</string>
<string name="settings_owner_manage">Pemilik perangkat mengelola</string>
<string name="settings_user_independent">Pengguna independen</string>
<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 pesan permintaan</string>
<string name="user_indepenent_summary">Setiap pengguna memiliki aturan root mereka sendiri</string>
<string name="mount_namespace_mode">Mode Ruang-nama Mount</string>
<string name="settings_ns_global">Ruang-nama Global</string>
<string name="settings_ns_requester">Ruang-nama Warisan</string>
<string name="settings_ns_isolate">Ruang-nama Terpisah</string>
<string name="global_summary">Seluruh sesi root menggunakan ruang-nama mount global</string>
<string name="mount_namespace_mode">Mode ruang-nama mount</string>
<string name="settings_ns_global">Ruang-nama global</string>
<string name="settings_ns_requester">Ruang-nama warisan</string>
<string name="settings_ns_isolate">Ruang-nama terpisah</string>
<string name="global_summary">Semua sesi root menggunakan ruang-nama mount global</string>
<string name="requester_summary">Sesi root akan mewarisi ruang-nama peminta mereka</string>
<string name="isolate_summary">Setiap sesi root akan memiliki ruang-nama tersendiri</string>
<!--Notifications-->
<string name="update_channel">Update Magisk</string>
<string name="progress_channel">Notifikasi Berjalan</string>
<string name="progress_channel">Notifikasi Kemajuan</string>
<string name="download_complete">Download selesai</string>
<string name="download_file_error">Kesalahan saat mendownload file</string>
<string name="download_open_parent">Tampilkan dalam folder</string>
<string name="download_open_self">Tampilkan file</string>
<string name="magisk_update_title">Update Magisk Tersedia!</string>
<string name="manager_update_title">Update Magisk Manager Tersedia!</string>
<string name="magisk_update_title">Update Magisk tersedia!</string>
<string name="manager_update_title">Update Magisk Manager tersedia!</string>
<!--Toasts, Dialogs-->
<string name="yes">Ya</string>
@@ -212,29 +217,31 @@
<string name="download">Download</string>
<string name="reboot">Nyalakan ulang</string>
<string name="release_notes">Catatan rilis</string>
<string name="repo_cache_cleared">Cache repositori dihapus</string>
<string name="repo_cache_cleared">Cache repo dihapus</string>
<string name="flashing">Memasang…</string>
<string name="done">Selesai!</string>
<string name="failure">Gagal</string>
<string name="hide_manager_title">Menyembunyikan Magisk Manager…</string>
<string name="hide_manager_fail_toast">Gagal menyembunyikan Magisk Manager.</string>
<string name="restore_manager_fail_toast">Gagal memulihkan Magisk Manager</string>
<string name="open_link_failed_toast">Tidak ditemukan aplikasi untuk membuka link ini</string>
<string name="complete_uninstall">Uninstal Penuh</string>
<string name="restore_img">Pulihkan Image</string>
<string name="complete_uninstall">Uninstal penuh</string>
<string name="restore_img">Pulihkan image</string>
<string name="restore_img_msg">Memulihkan…</string>
<string name="restore_done">Pemulihan selesai!</string>
<string name="restore_fail">Cadangan stock tidak ada!</string>
<string name="proprietary_title">Download Kode Proprietari</string>
<string name="proprietary_notice">Magisk Manager adalah aplikasi FOSS dan tidak membawa kode proprietari API SafetyNet Google.\n\nMaukah mengizinkan Magisk Manager untuk mendownload ekstensi (berisi GoogleApiClient) untuk memriksa SafetyNet?</string>
<string name="proprietary_title">Download kode proprieter</string>
<string name="proprietary_notice">Magisk Manager adalah aplikasi FOSS dan tidak memiliki kode proprieter API SafetyNet Google.\n\nMaukah mengizinkan Magisk Manager untuk mendownload ekstensi (berisi GoogleApiClient) untuk memeriksa SafetyNet?</string>
<string name="setup_fail">Penyiapan gagal</string>
<string name="env_fix_title">Perlu Penyiapan Tambahan</string>
<string name="env_fix_title">Perlu penyiapan tambahan</string>
<string name="env_fix_msg">Perangkat Anda memerlukan penyiapan tambahan agar Magisk bekerja dengan baik. Perangkat akan mendownload zip untuk penyiapan Magisk, apakah Anda ingin melanjutkan sekarang?</string>
<string name="setup_msg">Memproses penyiapan lingkungan…</string>
<string name="authenticate">Autentikasi</string>
<string name="unsupport_magisk_title">Versi Magisk Tidak Didukung</string>
<string name="unsupport_magisk_title">Versi Magisk tidak didukung</string>
<string name="unsupport_magisk_msg">Versi Magisk Manager ini tidak mendukung Magisk di bawah versi %1$s.\n\nAplikasi akan berperilaku seolah-olah Magisk tidak terinstal, harap meningkatkan Magisk sesegera mungkin.</string>
<string name="external_rw_permission_denied">Berikan izin akses ke penyimpanan untuk mengaktifkan fungsi ini</string>
<string name="add_shortcut_title">Tambahkan pintasan ke layar utama</string>
<string name="add_shortcut_msg">Setelah menyembunyikan Magisk Manager, nama dan ikonnya mungkin menjadi sulit untuk dikenali. Apakah Anda ingin menambahkan pintasan yang menarik pada layar utama?</string>
<string name="app_not_found">Tidak ditemukan aplikasi untuk menangani tindakan ini</string>
</resources>

View File

@@ -16,16 +16,16 @@
<string name="app_changelog">Wijzigingslog</string>
<string name="manager">Beheer</string>
<string name="loading">Bezig met laden…</string>
<string name="update">Update</string>
<string name="update">Updaten</string>
<string name="not_available">Niet beschikbaar</string>
<string name="hide">Verbergen</string>
<string name="status">Status</string>
<string name="home_package">Pakket</string>
<string name="home_notice_content">Zorg ervoor dat je altijd de opensourceversie van Magisk Manager gebruikt. Magisk Manager van een onbekende bron kan schade veroorzaken.</string>
<string name="home_notice_content">Zorg er voor dat je altijd de opensourceversie van Magisk Manager gebruikt. Magisk Manager van een onbekende bron kan schade veroorzaken.</string>
<string name="home_support_title">Ondersteun ons</string>
<string name="home_item_source">Broncode</string>
<string name="home_support_content">Magisk is en zal altijd gratis en open source blijven, maar als je wilt kun je een kleine donatie doen.</string>
<string name="home_support_content">Magisk is en zal altijd gratis en open source blijven, maar als je wilt, kun je een kleine donatie doen.</string>
<string name="home_status_normal">Normaal</string>
<string name="home_status_stub">Inactief</string>
<string name="home_installed_version">Geïnstalleerd</string>
@@ -33,6 +33,8 @@
<string name="invalid_update_channel">Ongeldig updatekanaal</string>
<string name="uninstall_magisk_title">Magisk deïnstalleren</string>
<string name="uninstall_magisk_msg">Alle modules worden uitgeschakeld/verwijderd!\nRoot wordt verwijderd!\nJe gegevens worden, als ze dat nog niet waren, mogelijk versleuteld!</string>
<string name="home_check_safetynet">SafetyNet controleren</string>
<!--Install-->
<string name="keep_force_encryption">Afgedwongen versleuteling behouden</string>
@@ -49,7 +51,7 @@
<string name="install_inactive_slot_msg">Je apparaat wordt GEDWONGEN opgestart in de huidige inactieve sleuf na het herstarten!\nGebruik deze optie alleen NA het installeren van een OTA-update.\nWil je doorgaan?</string>
<string name="setup_title">Installatie afronden</string>
<string name="select_patch_file">Kies en patch een bestand</string>
<string name="patch_file_msg">Kies een schijfkopie (*.img) of een ODIN-tarbestand (*.tar)</string>
<string name="patch_file_msg">Kies een schijfkopie (*.img) of ODIN-tarbestand (*.tar)</string>
<string name="reboot_delay_toast">Je apparaat wordt over 5 seconden herstart…</string>
<string name="flash_screen_title">Installatie</string>
@@ -60,15 +62,15 @@
<string name="grant">Toestaan</string>
<string name="su_warning">Verleent volledige toegang tot je apparaat.\nBij twijfel, altijd weigeren!</string>
<string name="forever">Permanent</string>
<string name="once">Eénmalig</string>
<string name="once">Eenmalig</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 beschikt nu over superuserrechten</string>
<string name="su_deny_toast">Superusermachtiging van %1$s geweigerd</string>
<string name="su_deny_toast">Superuserrecht van %1$s geweigerd</string>
<string name="su_snack_grant">%1$s beschikt nu over superuserrechten</string>
<string name="su_snack_deny">Superusermachtiging van %1$s geweigerd</string>
<string name="su_snack_deny">Superuserrecht van %1$s geweigerd</string>
<string name="su_snack_notif_on">%1$s-meldingen ingeschakeld</string>
<string name="su_snack_notif_off">%1$s-meldingen uitgeschakeld</string>
<string name="su_snack_log_on">%1$s wordt nu gelogd</string>
@@ -102,14 +104,14 @@
<!-- MagiskHide -->
<string name="show_system_app">Systeemapps tonen</string>
<string name="hide_filter_hint">Filteren op naam</string>
<string name="hide_scroll_up">Omhoogscrollen</string>
<string name="hide_scroll_up">Omhoog scrollen</string>
<string name="hide_filters">Filters</string>
<string name="hide_search">Zoeken</string>
<!--Module Fragment-->
<string name="no_info_provided">(geen informatie verstrekt)</string>
<string name="reboot_recovery">Herstelmodus starten</string>
<string name="reboot_bootloader">Opstartlader starten</string>
<string name="reboot_recovery">Recovery starten</string>
<string name="reboot_bootloader">Bootloader starten</string>
<string name="reboot_download">Downloadmodus starten</string>
<string name="reboot_edl">EDL starten</string>
<string name="module_version_author">%1$s van %2$s</string>
@@ -138,7 +140,6 @@
<string name="settings_restore_manager_summary">Herstelt Magisk Manager\'s oorspronkelijke naam.</string>
<string name="language">Taal</string>
<string name="system_default">(systeemstandaard)</string>
<string name="settings_check_update_title">Controleren op updates</string>
<string name="settings_check_update_summary">Controleer automatisch op updates op de achtergrond.</string>
<string name="settings_update_channel_title">Updatekanaal</string>
<string name="settings_update_stable">Stabiel</string>
@@ -228,6 +229,9 @@
<string name="authenticate">Goedkeuren</string>
<string name="unsupport_magisk_title">Niet-ondersteunde Magisk-versie</string>
<string name="unsupport_magisk_msg">Deze versie van Magisk Manager heeft geen ondersteuning voor Magisk-versies ouder dan %1$s.\n\nDe app werkt, maar doet alsof Magisk niet geïnstalleerd is. Update Magisk zo spoedig mogelijk.</string>
<string name="external_rw_permission_denied">Verleen de opslagmachtiging om deze functie te kunnen gebruiken</string>
<string name="external_rw_permission_denied">Verleen het opslagrecht om deze functie gebruiken</string>
<string name="add_shortcut_title">Snelkoppeling maken op startscherm</string>
<string name="add_shortcut_msg">Als je Magisk Manager verbergt, herken je de naam en het pictogram mogelijk niet meer. Wil je een mooie snelkoppeling plaatsen op je startscherm?</string>
<string name="app_not_found">Er is geen app op je apparaat die deze handeling kan uitvoeren</string>
</resources>

View File

@@ -22,7 +22,7 @@
<string name="status">Status</string>
<string name="home_package">Pakiet</string>
<string name="home_notice_content">Zawsze upewnij się, że używasz otwartoźródłowego Magisk Managera. Manager z nieznanego źródła może wykonywać złośliwe działania.</string>
<string name="home_notice_content">Zawsze upewnij się, że używasz otwartoźródłowego Managera Magisk. Manager z nieznanego źródła może wykonywać złośliwe działania.</string>
<string name="home_support_title">Wesprzyj nas</string>
<string name="home_item_source">Źródło</string>
<string name="home_support_content">Magisk jest i zawsze będzie darmowy i otwarty. Niemniej możesz nam pokazać, że Ci zależy, wysyłając drobną darowiznę.</string>
@@ -31,25 +31,25 @@
<string name="home_installed_version">Zainstalowany</string>
<string name="home_latest_version">Ostatni</string>
<string name="invalid_update_channel">Nieprawidłowy kanał aktualizacji</string>
<string name="uninstall_magisk_title">Odinstaluj Magiska</string>
<string name="uninstall_magisk_msg">Wszystkie moduły zostaną wyłączone/usunięte!\nRoot zostanie usunięty!\nTwoje dane zosta potencjalnie zaszyfrowane, jeżeli obecnie nie są!</string>
<string name="uninstall_magisk_title">Odinstaluj Magisk</string>
<string name="uninstall_magisk_msg">Wszystkie moduły zostaną wyłączone/usunięte!\nRoot zostanie usunięty!\nTwoje dane mogą zostać potencjalnie zaszyfrowane, jeśli jeszcze nie są!</string>
<string name="home_check_safetynet">Sprawdź SafetyNet</string>
<!--Install-->
<string name="keep_force_encryption">Zachowaj force encryption (wymuszenie szyfrowania)</string>
<string name="keep_dm_verity">Zachowaj AVB 2.0/dm-verity (weryfikację procesu bootowania)</string>
<string name="keep_dm_verity">Zachowaj AVB 2.0/dm-verity (weryfikację rozruchu)</string>
<string name="recovery_mode">Tryb Recovery</string>
<string name="install_options_title">Opcje</string>
<string name="install_method_title">Metoda</string>
<string name="install_next">Dalej</string>
<string name="install_start">Zaczynajmy</string>
<string name="manager_download_install">Kliknij aby pobrać i zainstalować</string>
<string name="download_zip_only">Tylko pobierz paczkę Zip</string>
<string name="direct_install">Bezpośrednia instalacja (zalecane)</string>
<string name="install_inactive_slot">Zainstaluj do nieaktywnego slotu (po OTA)</string>
<string name="install_inactive_slot_msg">Po reboocie WYMUSZONE zostanie uruchomienie twojego urządzenia z aktualnie nieaktywnego slotu!\nUżywaj tej opcji wyłącznie po zakończonej aktualizacji OTA.\nKontynuować?</string>
<string name="manager_download_install">Naciśnij, aby pobrać i zainstalować</string>
<string name="download_zip_only">Pobierz tylko paczkę Zip</string>
<string name="direct_install">Bezpośrednia instalacja (zalecana)</string>
<string name="install_inactive_slot">Zainstaluj w nieaktywnym gnieździe (po OTA)</string>
<string name="install_inactive_slot_msg">Po restarcie twoje urządzenie zostanie ZMUSZONE do uruchomienia z aktualnie nieaktywnego gniazda!\nUżyj tej opcji wyłącznie po ukończeniu aktualizacji OTA.\nKontynuować?</string>
<string name="setup_title">Dodatkowa konfiguracja</string>
<string name="select_patch_file">Wybierz i zmodyfikuj plik</string>
<string name="select_patch_file">Wybierz i załataj plik</string>
<string name="patch_file_msg">Wybierz obraz raw (*.img) lub plik tar ODIN (*.tar)</string>
<string name="reboot_delay_toast">Ponowne uruchomienie za 5 sekund…</string>
<string name="flash_screen_title">Instalacja</string>
@@ -85,7 +85,7 @@
<!--Logs-->
<string name="log_data_none">Logi są puste, spróbuj użyć aplikacji wymagających roota.</string>
<string name="log_data_magisk_none">Logi Magiska są puste, to dziwne.</string>
<string name="log_data_magisk_none">Logi Magisk są puste, to jest dziwne.</string>
<string name="menuSaveLog">Zapisz log</string>
<string name="menuClearLog">Wyczyść log</string>
<string name="logs_cleared">Log został pomyślnie wyczyszczony.</string>
@@ -102,17 +102,19 @@
<!-- MagiskHide -->
<string name="show_system_app">Pokaż aplikacje systemowe</string>
<string name="show_os_app">Pokaż aplikacje OS</string>
<string name="hide_filter_hint">Filtruj według nazwy</string>
<string name="hide_scroll_up">Przewiń do góry</string>
<string name="hide_filters">Filtry</string>
<string name="hide_search">Szukaj</string>
<!--Module Fragment-->
<!--Module -->
<string name="no_info_provided">(Nie umieszczono informacji)</string>
<string name="reboot_recovery">Reboot do Recovery</string>
<string name="reboot_bootloader">Reboot do Bootloadera</string>
<string name="reboot_download">Reboot do Download</string>
<string name="reboot_edl">Reboot do EDL</string>
<string name="reboot_userspace">Miękki reboot</string>
<string name="reboot_recovery">Reboot do trybu Recovery</string>
<string name="reboot_bootloader">Reboot do trybu Bootloader</string>
<string name="reboot_download">Reboot do trybu Download</string>
<string name="reboot_edl">Reboot do trybu EDL</string>
<string name="module_version_author">%1$s by %2$s</string>
<string name="module_section_pending">Aktualizacje</string>
<string name="module_section_pending_action">Zaktualizuj wszystkie</string>
@@ -131,26 +133,26 @@
<string name="settings_dark_mode_system">Ustawienie systemowe</string>
<string name="settings_dark_mode_dark">Zawsze ciemny</string>
<string name="settings_download_path_title">Ścieżka pobierania plików</string>
<string name="settings_download_path_message">Pliki pobrane przez Managera będą zapisywane do %1$s</string>
<string name="settings_clear_cache_title">Wyczyść pamięć cache repozytorium</string>
<string name="settings_clear_cache_summary">Wyczyść zapisane informacje o repozytoriach. Wymuszone zostanie odświeżenie informacji online</string>
<string name="settings_hide_manager_title">Ukryj Magisk Managera</string>
<string name="settings_hide_manager_summary">Przepakuj Magisk Managera z losowymi nazwami pakietu oraz aplikacji</string>
<string name="settings_restore_manager_title">Przywróć Magisk Managera</string>
<string name="settings_restore_manager_summary">Przywróć Magisk Managera z oryginalnymi nazwami pakietu oraz aplikacji</string>
<string name="settings_download_path_message">Pliki zostaną zapisane do %1$s</string>
<string name="settings_clear_cache_title">Wyczyść pamięć podr. repozytoriów</string>
<string name="settings_clear_cache_summary">Wyczyść informacje z pamięci podr. dotyczące repozytoriów. Zmusza to aplikację do odświeżenia informacji online</string>
<string name="settings_hide_manager_title">Ukryj Managera Magisk</string>
<string name="settings_hide_manager_summary">Przepakuj Managera Magisk z losowymi nazwami pakietu i aplikacji</string>
<string name="settings_restore_manager_title">Przywróć Managera Magisk</string>
<string name="settings_restore_manager_summary">Przywróć Managera Magisk z oryginalnymi nazwami pakietu i aplikacji</string>
<string name="language">Język</string>
<string name="system_default">(Domyślny systemowy)</string>
<string name="settings_check_update_title">Sprawdzanie aktualizacji</string>
<string name="settings_check_update_summary">Regularnie sprawdzaj dostępność aktualizacji w tle</string>
<string name="settings_check_update_summary">Okresowo sprawdzaj dostępność aktualizacji w tle</string>
<string name="settings_update_channel_title">Kanał aktualizacji</string>
<string name="settings_update_stable">Stabilny</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Własny</string>
<string name="settings_update_custom_msg">Wprowadź adres URL własnego repozytorium</string>
<string name="settings_magiskhide_summary">Ukryj Magiska przed wieloma metodami detekcji</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Włącz wsparcie Systemless dla aplikacji typu Adblock</string>
<string name="settings_hosts_toast">Dodano moduł Systemless Hosts</string>
<string name="settings_update_custom">Własny kanał</string>
<string name="settings_update_custom_msg">Wprowadź adres URL własnego kanału</string>
<string name="settings_magiskhide_summary">Ukryj Magisk przed różnymi formami detekcji</string>
<string name="settings_hosts_title">Hosty Systemless</string>
<string name="settings_hosts_summary">Wsparcie hostów Systemless dla aplikacji typu Adblock</string>
<string name="settings_hosts_toast">Dodano moduł hostów Systemless</string>
<string name="settings_app_name_hint">Nowa nazwa</string>
<string name="settings_app_name_helper">Aplikacja zostanie przepakowana do tej nazwy</string>
<string name="settings_app_name_error">Błędny format</string>
@@ -169,21 +171,21 @@
<string name="request_timeout">Limit czasu żądania</string>
<string name="superuser_notification">Powiadomienia Superusera</string>
<string name="settings_su_reauth_title">Ponowienie uwierzytelniania po aktualizacji</string>
<string name="settings_su_reauth_summary">Ponowienie dostępu do uprawnień Superusera po aktualizacji aplikacji</string>
<string name="settings_su_reauth_summary">Ponowienie dostępu do uprawnień Superusera po uaktualnieniu aplikacji</string>
<string name="settings_su_biometric_title">Uwierzytelnianie biometryczne</string>
<string name="settings_su_biometric_summary">Używaj uwierzytelniania biometrycznego (np. odcisku palca) aby przyznać uprawnienia Superusera</string>
<string name="no_biometric">Urządzenie jest nieobsługiwane lub ustawienia biometryczne nie są włączone</string>
<string name="settings_customization">Personalizacja</string>
<string name="setting_add_shortcut_summary">Dodaj ładny skrót na ekranie głównym na wypadek, gdyby nazwa i ikona były trudne do rozpoznania po ukryciu aplikacji</string>
<string name="settings_doh_title">DNS over HTTPS</string>
<string name="settings_doh_description">Zapobiegaj zatruciu DNS (DNS poisoning) w części krajów</string>
<string name="settings_doh_description">Zapobiegaj zatruwaniu DNS (DNS poisoning) w niektórych krajach</string>
<string name="multiuser_mode">Tryb wielu użytkowników (Multiuser)</string>
<string name="settings_owner_only">Tylko właściciel urządzenia</string>
<string name="settings_owner_manage">Zarządzanie przez właściciela urządzenia</string>
<string name="settings_user_independent">Niezależni użytkownicy</string>
<string name="owner_only_summary">Tylko właściciel ma dostęp do roota</string>
<string name="owner_manage_summary">Tylko właściciel może zarządzać ustawieniami dostępu do roota i otrzymywać zapytania o dostęp</string>
<string name="owner_manage_summary">Tylko właściciel może zarządzać ustawieniami dostępu do roota i otrzymywać żądania dostępu</string>
<string name="user_indepenent_summary">Każdy użytkownik ma niezależne ustawienia dostępu do roota</string>
<string name="mount_namespace_mode">Tryb przestrzeni nazw montowania</string>
@@ -191,51 +193,52 @@
<string name="settings_ns_requester">Dziedziczona przestrzeń nazw</string>
<string name="settings_ns_isolate">Izolowana przestrzeń nazw</string>
<string name="global_summary">Wszystkie sesje roota będą używać globalnej przestrzeni nazw montowania</string>
<string name="requester_summary">Sesje roota odziedziczą przestrzeń nazw od wywołującego</string>
<string name="isolate_summary">Każda sesja roota dostanie własną, izolowaną przestrzeń nazw</string>
<string name="requester_summary">Sesje roota odziedziczą przestrzeń nazw od żądającego</string>
<string name="isolate_summary">Każda sesja roota otrzyma własną, izolowaną przestrzeń nazw</string>
<!--Notifications-->
<string name="update_channel">Aktualizacja Magiska</string>
<string name="progress_channel">Informacja o postępie</string>
<string name="update_channel">Aktualizacja Magisk</string>
<string name="progress_channel">Powiadomienia o postępach</string>
<string name="download_complete">Pobieranie zakończone</string>
<string name="download_file_error">Błąd pobierania pliku</string>
<string name="download_open_parent">Pokaż w katalogu nadrzędnym</string>
<string name="download_open_self">Pokaż plik</string>
<string name="magisk_update_title">Aktualizacja Magiska dostępna!</string>
<string name="manager_update_title">Aktualizacja Magisk Managera dostępna!</string>
<string name="magisk_update_title">Aktualizacja Magisk dostępna!</string>
<string name="manager_update_title">Aktualizacja Managera Magisk dostępna!</string>
<!--Toasts, Dialogs-->
<string name="yes">Tak</string>
<string name="no">Nie</string>
<string name="repo_install_title">Instalacja %1$s</string>
<string name="repo_install_msg">Czy chcesz zainstalować %1$s ?</string>
<string name="repo_install_msg">Czy chcesz teraz zainstalować %1$s ?</string>
<string name="download">Pobierz</string>
<string name="reboot">Reboot</string>
<string name="release_notes">Lista zmian</string>
<string name="repo_cache_cleared">Pamięć cache repozytorium została wyczyszczona</string>
<string name="repo_cache_cleared">Wyczyszczono pamięć podręczną repozytoriów</string>
<string name="flashing">Flashowanie…</string>
<string name="done">Gotowe!</string>
<string name="failure">Błąd</string>
<string name="hide_manager_title">Ukrywanie Magisk Managera</string>
<string name="hide_manager_fail_toast">Błąd ukrycia Magisk Managera.</string>
<string name="hide_manager_title">Ukrywanie Managera Magisk</string>
<string name="hide_manager_fail_toast">Ukrycie Managera Magisk nie powiodło się</string>
<string name="restore_manager_fail_toast">Przywrócenie Managera Magisk nie powiodło się</string>
<string name="open_link_failed_toast">Nie znaleziono aplikacji do otwarcia linku</string>
<string name="complete_uninstall">Odinstaluj całkowicie</string>
<string name="restore_img">Przywróć obrazy</string>
<string name="restore_img_msg">Przywracanie…</string>
<string name="restore_done">Przywracanie zakończone!</string>
<string name="restore_fail">Kopia zapasowa nie istnieje!</string>
<string name="proprietary_title">Pobierz własny kod</string>
<string name="proprietary_notice">Magisk Manager to FOSS (wolne i otwarte oprogramowanie) i nie zawiera własnościowego kodu Google - SafetyNet API.\n\nCzy zezwolić Magisk Managerowi na pobranie rozszerzenia (zawierającego GoogleApiClient) w celu sprawdzenia SafetyNet?</string>
<string name="proprietary_title">Pobierz kod własnościowy</string>
<string name="proprietary_notice">Magisk Manager to FOSS (wolne i otwarte oprogramowanie) i nie zawiera własnościowego kodu Google - SafetyNet API.\n\nCzy chcesz zezwolić Managerowi Magisk na pobranie rozszerzenia (zawierającego GoogleApiClient) w celu sprawdzenia SafetyNet?</string>
<string name="setup_fail">Konfiguracja nieudana</string>
<string name="env_fix_title">Wymaga dodatkowej konfiguracji</string>
<string name="env_fix_msg">Twoje urządzenie potrzebuje dodatkowej konfiguracji, aby Magisk działał prawidłowo. Spowoduje to pobranie paczki instalacyjnej Magisk, czy chcesz kontynuować?</string>
<string name="env_fix_msg">Twoje urządzenie potrzebuje dodatkowej konfiguracji, aby Magisk działał poprawnie. Spowoduje to pobranie pliku instalacyjnego Magisk, czy chcesz kontynuować?</string>
<string name="setup_msg">Uruchamianie środowiska konfiguracji…</string>
<string name="authenticate">Uwierzytelnianie</string>
<string name="unsupport_magisk_title">Nieobsługiwana wersja Magiska</string>
<string name="unsupport_magisk_msg">Ta wersja Magisk Managera nie obsługuje wersji Magiska poniżej %1$s.\n\nAplikacja będzie działać tak, jakby Magisk nie był zainstalowany. Zaktualizuj Magiska jak najszybciej.</string>
<string name="external_rw_permission_denied">Zezwól na dostęp do pamięci wewnętrznej, aby włączyć tę funkcjonalność.</string>
<string name="unsupport_magisk_title">Nieobsługiwana wersja Magisk</string>
<string name="unsupport_magisk_msg">Ta wersja Managera Magisk nie obsługuje wersji Magisk niższej niż %1$s.\n\nAplikacja będzie się zachowywać tak, jakby Magisk nie był zainstalowany. Zaktualizuj Magisk jak najszybciej.</string>
<string name="external_rw_permission_denied">Zezwól na dostęp do pamięci wewnętrznej, aby włączyć tę funkcję.</string>
<string name="add_shortcut_title">Utwórz skrót na ekranie głównym</string>
<string name="add_shortcut_msg">Po ukryciu Magisk Managera, jego nazwa i ikona mogą stać się trudne do rozpoznania. Czy chcesz dodać ładny skrót na ekranie głównym?</string>
<string name="add_shortcut_msg">Po ukryciu Managera Magisk, jego nazwa i ikona mogą stać się trudne do rozpoznania. Czy chcesz dodać ładny skrót na ekranie głównym?</string>
<string name="app_not_found">Nie znaleziono aplikacji do wykonania tej czynności</string>
</resources>

View File

@@ -5,6 +5,7 @@
<string name="superuser">Superusuário</string>
<string name="logs">Registros</string>
<string name="settings">Configurações</string>
<string name="refresh">Atualizar Dados Locais</string>
<string name="install">Instalar</string>
<string name="section_home">Início</string>
<string name="section_theme">Temas</string>
@@ -23,8 +24,6 @@
<string name="home_package">Pacote</string>
<string name="home_status_normal">Normal</string>
<string name="invalid_update_channel">Canal de atualização inválido</string>
<string name="safetynet_api_error">Erro do API SafetyNet</string>
<string name="safetynet_res_invalid">A resposta é inválida</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="uninstall_magisk_msg">Todos os módulos serão desativados/removidos!\nA raiz será removida!\nSeus dados potencialmente criptografados, se ainda não estiverem!</string>
<string name="update">Atualização</string>
@@ -46,6 +45,7 @@
<string name="select_patch_file">Selecione e corrija um arquivo</string>
<string name="patch_file_msg">Selecione uma imagem bruta (*.img) ou um arquivo tarin ODIN (*.tar)</string>
<string name="reboot_delay_toast">Reiniciando em 5 segundos…</string>
<string name="flash_screen_title">Instalação</string>
<!--Superuser-->
<string name="su_request_title">Solicitação de Superusuário</string>
@@ -86,6 +86,8 @@
<string name="target_uid">Alvo UID: %1$d</string>
<!--SafetyNet-->
<string name="safetynet_api_error">Erro API SafetyNet</string>
<string name="safetynet_res_invalid">A resposta é inválida</string>
<string name="safetynet_attest_success">Sucesso!</string>
<string name="safetynet_attest_failure">O certificado falhou!</string>
<string name="safetynet_attest_loading">Aguarde…</string>
@@ -113,6 +115,7 @@
<string name="update_available">Atualização disponível</string>
<string name="home_installed_version">Instalado</string>
<string name="sorting_order">Ordem de classificação</string>
<!--Settings -->
<string name="settings_dark_mode_title">Modo de tema</string>
@@ -121,6 +124,7 @@
<string name="settings_dark_mode_system">Baseado no Sistema</string>
<string name="settings_dark_mode_dark">Sempre Escuro</string><![CDATA[
    
@@ -170,7 +174,10 @@
<string name="settings_su_biometric_summary">Use a autenticação biométrica para permitir solicitações de superusuário</string>
<string name="no_biometric">Dispositivo não suportado ou nenhuma configuração biométrica está ativada</string>
<string name="settings_customization">Personalizações</string>
<string name="setting_add_shortcut_summary">Adicione um atalho na tela inicial, caso o nome e o ícone sejam difíceis de reconhecer logo após ocultar o aplicativo</string>
<string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
<string name="multiuser_mode">Modo multiusuário</string>
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
@@ -227,4 +234,8 @@
<string name="authenticate">Autenticar</string>
<string name="unsupport_magisk_title">Versão Magisk não suportada</string>
<string name="unsupport_magisk_msg">Esta versão do Magisk Manager não suporta a versão Magisk inferior a %1$s. \n\nO aplicativo se comportará como se não houvesse Magisk instalado, atualize o Magisk o mais rápido possível.</string>
<string name="add_shortcut_title">Adicionar atalho à tela inicial</string>
<string name="add_shortcut_msg">Depois de ocultar o Magisk Manager, seu nome e ícone podem se tornar difíceis de reconhecer. Você quer adicionar um atalho bonito para a tela inicial?</string>
<string name="app_not_found">Nenhum aplicativo encontrado para realizar esta ação</string>
</resources>

View File

@@ -17,7 +17,7 @@
<string name="manager">Manager</string>
<string name="loading">Загрузка…</string>
<string name="update">Обновить</string>
<string name="not_available">Н</string>
<string name="not_available">N/A</string>
<string name="hide">Скрыть</string>
<string name="status">Режим</string>
<string name="home_package">Имя пакета</string>
@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">Запрос прав суперпользователя</string>
<string name="touch_filtered_warning">Обнаружены наложения экрана, обработка запроса недоступна</string>
<string name="deny">Запретить</string>
<string name="prompt">Запросить</string>
<string name="grant">Разрешить</string>
@@ -102,6 +103,7 @@
<!--MagiskHide-->
<string name="show_system_app">Системные приложения</string>
<string name="show_os_app">Встроенные приложения</string>
<string name="hide_filter_hint">Введите имя</string>
<string name="hide_scroll_up">Вверх</string>
<string name="hide_filters">Сортировка</string>
@@ -109,11 +111,12 @@
<!--Module-->
<string name="no_info_provided">(Нет информации)</string>
<string name="reboot_userspace">Перезапуск оболочки</string>
<string name="reboot_recovery">Перезагрузка в Recovery</string>
<string name="reboot_bootloader">Перезагрузка в Bootloader</string>
<string name="reboot_download">Перезагрузка в Download</string>
<string name="reboot_edl">Перезагрузка в EDL</string>
<string name="module_version_author">Версия: %1$s\nАвтор: %2$s</string>
<string name="module_version_author">%1$s от %2$s</string>
<string name="module_section_pending">Обновления</string>
<string name="module_section_pending_action">Обновить всё</string>
<string name="module_state_remove">Удалить</string>
@@ -170,6 +173,8 @@
<string name="superuser_notification">Уведомления суперпользователя</string>
<string name="settings_su_reauth_title">Повторная аутентификация</string>
<string name="settings_su_reauth_summary">Повторный запрос прав суперпользователя после обновления приложений</string>
<string name="settings_su_tapjack_title">Защита от перехвата ввода</string>
<string name="settings_su_tapjack_summary">Окно запроса прав суперпользователя будет неактивно пока активированы наложения экрана</string>
<string name="settings_su_biometric_title">Биометрическая аутентификация</string>
<string name="settings_su_biometric_summary">Использовать биометрическую аутентификацию для запросов прав суперпользователя</string>
<string name="no_biometric">Функция не поддерживается устройством или не заданы настройки блокировки экрана</string>
@@ -218,6 +223,7 @@
<string name="failure">Ошибка!</string>
<string name="hide_manager_title">Скрытие Magisk Manager…</string>
<string name="hide_manager_fail_toast">Не удалось пересобрать Magisk Manager</string>
<string name="restore_manager_fail_toast">Не удалось восстановить Magisk Manager</string>
<string name="open_link_failed_toast">Приложения для открытия ссылки не найдены</string>
<string name="complete_uninstall">Полное удаление</string>
<string name="restore_img">Восстановить разделы</string>
@@ -236,5 +242,6 @@
<string name="external_rw_permission_denied">Пожалуйста, предоставьте доступ к хранилищу!</string>
<string name="add_shortcut_title">Создание ярлыка</string>
<string name="add_shortcut_msg">После скрытия Magisk Manager его имя и иконка могут быть неудобны для восприятия. Хотите создать ярлык на рабочем столе?</string>
<string name="app_not_found">Приложение для обработки этого действия не найдено</string>
</resources>

View File

@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">Požiadavka superužívateľa</string>
<string name="touch_filtered_warning">Pretože aplikácia zakrýva požiadavku superužívateľa, Magisk nemôže overiť vašu odpoveď</string>
<string name="deny">Zamietnuť</string>
<string name="prompt">Výzva</string>
<string name="grant">Udeliť</string>
@@ -102,6 +103,7 @@
<!-- MagiskHide -->
<string name="show_system_app">Zobraziť systémové aplikácie</string>
<string name="show_os_app">Zobraziť aplikácie OS</string>
<string name="hide_filter_hint">Filtrovať podľa názvu</string>
<string name="hide_scroll_up">Posunúť nahor</string>
<string name="hide_filters">Filtre</string>
@@ -109,6 +111,7 @@
<!--Module Fragment-->
<string name="no_info_provided">(Nie sú k dispozícii žiadne informácie)</string>
<string name="reboot_userspace">Softvérový reštart</string>
<string name="reboot_recovery">Reštartovať do Recovery</string>
<string name="reboot_bootloader">Reštartovať do Bootloader</string>
<string name="reboot_download">Reštartovať do Download</string>
@@ -172,6 +175,8 @@
<string name="superuser_notification">Upozornenia Superužívateľa</string>
<string name="settings_su_reauth_title">Overenie autentifikácie po upgrade</string>
<string name="settings_su_reauth_summary">Overí autentifikáciu oprávnení Superužívateľa po upgrade aplikácie</string>
<string name="settings_su_tapjack_title">Povoliť ochranu pred tapjackingom</string>
<string name="settings_su_tapjack_summary">Dialógové okno superužívateľa nebude reagovať na zadanie, ak je zakryté alebo prekryté iným oknom</string>
<string name="settings_su_biometric_title">Povoliť biometrické overenie</string>
<string name="settings_su_biometric_summary">Použije biometrickú autentifikáciu na povolenie žiadostí Superužívateľa</string>
<string name="no_biometric">Nepodporované zariadenie alebo žiadne biometrické nastavenia nie sú povolené</string>
@@ -218,8 +223,9 @@
<string name="flashing">Flashovanie...</string>
<string name="done">Hotovo!</string>
<string name="failure">Zlyhalo</string>
<string name="hide_manager_title">Skrytie Magisk Managera…</string>
<string name="hide_manager_fail_toast">Skrytie Magisk Manager zlyhalo.</string>
<string name="hide_manager_title">Skrývanie Magisk Managera…</string>
<string name="hide_manager_fail_toast">Skrytie Magisk Managera zlyhalo</string>
<string name="restore_manager_fail_toast">Obnovenie Magisk Managera zlyhalo</string>
<string name="open_link_failed_toast">Nepodarilo sa nájsť vhodnú aplikáciu na otvorenie odkazu</string>
<string name="complete_uninstall">Úplne odinštalovať</string>
<string name="restore_img">Obnoviť obrazy</string>

View File

@@ -2,12 +2,12 @@
<!--Welcome Activity-->
<string name="modules">Modüller</string>
<string name="superuser">Yetkili kullanıcı</string>
<string name="superuser">Yetkili Kullanıcı</string>
<string name="logs">Günlük</string>
<string name="settings">Ayarlar</string>
<string name="refresh">Yerel Verileri Yenile</string>
<string name="install">Yükle</string>
<string name="section_home">Ana ekran</string>
<string name="section_home">Ana Ekran</string>
<string name="section_theme">Temalar</string>
<string name="safetynet">SafetyNet</string>
@@ -22,10 +22,10 @@
<string name="status">Durum</string>
<string name="home_package">Paket</string>
<string name="home_notice_content">Her zaman açık kaynaklı Magisk Manager kullandığınızdan emin olun. Bilinmeyen kaynak yöneticisi kötü amaçlı eylemler gerçekleştirebilir.</string>
<string name="home_support_title">Bizi destekleyin</string>
<string name="home_notice_content">Her zaman açık kaynaklı Magisk Manager kullandığınızdan emin olun. Kaynağı bilinmeyen yönetici uygulamaları kötü amaçlı eylemler gerçekleştirebilir.</string>
<string name="home_support_title">Bizi Destekleyin</string>
<string name="home_item_source">Kaynak</string>
<string name="home_support_content">Magisk özgür ve açık kaynaklıdır ve her zaman öyle olacaktır. Ancak küçük bir bağış göndererek bize önem verdiğinizi gösterebilirsiniz.</string>
<string name="home_support_content">Magisk özgür ve açık kaynaklıdır ve her zaman da öyle kalacak. Ancak küçük bir bağış göndererek bize önem verdiğinizi gösterebilirsiniz.</string>
<string name="home_status_normal">Normal</string>
<string name="home_status_stub">Stub</string>
<string name="home_installed_version">Yüklendi</string>
@@ -47,11 +47,11 @@
<string name="download_zip_only">Sadece Zip\'i indir</string>
<string name="direct_install">Doğrudan kurulum (Önerilen)</string>
<string name="install_inactive_slot">Aktif olmayan yuvaya yükle (OTA\'dan sonra)</string>
<string name="install_inactive_slot_msg">Cihazınız, yeniden başlatmanın ardından geçerli etkin olmayan yuvaya önyüklemeye ZORLANACAK!\nBu seçeneği yalnızca OTA yapıldıktan sonra kullanın.\nDevam edilsin mi?</string>
<string name="install_inactive_slot_msg">Cihazınız, yeniden başlatmanın ardından geçerli etkin olmayan yuvaya önyüklemeye ZORLANACAK!\nBu seçeneği yalnızca OTA bittikten sonra kullanın.\nDevam edilsin mi?</string>
<string name="setup_title">Ek kurulum</string>
<string name="select_patch_file">Dosya seçin ve yamalayın</string>
<string name="patch_file_msg">Bir işlenmemiş görüntü (*.img) ya da ODIN tar dosyası (*.tar) seçin</string>
<string name="reboot_delay_toast">5 saniye içinde yeniden başlatılacak...</string>
<string name="patch_file_msg">Bir raw imaj (*.img) veya ODIN tar dosyası (*.tar) seçin</string>
<string name="reboot_delay_toast">5 saniye içinde yeniden başlatılacak</string>
<string name="flash_screen_title">Kurulum</string>
<!--Superuser-->
@@ -97,12 +97,12 @@
<string name="safetynet_res_invalid">Yanıt geçersiz</string>
<string name="safetynet_attest_success">Başarılı!</string>
<string name="safetynet_attest_failure">Onaylama başarısız oldu!</string>
<string name="safetynet_attest_loading">Sadece bir kaç saniye…</string>
<string name="safetynet_attest_restart">Tekrar deneyin</string>
<string name="safetynet_attest_loading">Sadece bir saniye…</string>
<string name="safetynet_attest_restart">Tekrar deneyiniz</string>
<!-- MagiskHide -->
<string name="show_system_app">Sistem uygulamalarını göster</string>
<string name="hide_filter_hint">Ada göre filtrele</string>
<string name="hide_filter_hint">İsme göre filtrele</string>
<string name="hide_scroll_up">Yukarı kaydır</string>
<string name="hide_filters">Filtreler</string>
<string name="hide_search">Ara</string>
@@ -121,7 +121,7 @@
<string name="module_action_install_external">Depolama alanından yükle</string>
<string name="update_available">Güncelleme mevcut</string>
<string name="module_installed">@string/home_installed_version</string>
<string name="module_section_online">Online</string>
<string name="module_section_online">Çevrim içi</string>
<string name="sorting_order">Sıralama Düzeni</string>
<!--Settings -->
@@ -130,20 +130,20 @@
<string name="settings_dark_mode_light">Her zaman aydınlık</string>
<string name="settings_dark_mode_system">Sistemi takip et</string>
<string name="settings_dark_mode_dark">Her zaman karanlık</string>
<string name="settings_download_path_title">İndirme yolu</string>
<string name="settings_download_path_title">İndirme Yolu</string>
<string name="settings_download_path_message">Dosyalar %1$s konumuna kaydedilecek</string>
<string name="settings_clear_cache_title">Depo Önbelleğini Temizle</string>
<string name="settings_clear_cache_summary">Çevrimiçi depolar için önbellek bilgilerini temizle, uygulamayı çevrimiçi yenilemeye zorla</string>
<string name="settings_clear_cache_summary">Çevrim içi depolar için önbellek bilgilerini temizle, uygulamayı çevrim içi yenilemeye zorla</string>
<string name="settings_hide_manager_title">Magisk Manager\'ı Gizle</string>
<string name="settings_hide_manager_summary">Rastgele paket adı ile Magisk Manager\'ı yeniden paketle</string>
<string name="settings_restore_manager_title">Magisk Manager\'ı Geri Yükle</string>
<string name="settings_restore_manager_summary">Orijinal paket adı ile Magisk Manager\'ı geri yükle</string>
<string name="language">Dil</string>
<string name="system_default">(Sistem Varsayılanı)</string>
<string name="settings_check_update_title">Güncellemeleri denetle</string>
<string name="settings_check_update_title">Güncellemeleri Denetle</string>
<string name="settings_check_update_summary">Düzenli aralıklarla arka planda güncellemeleri denetle</string>
<string name="settings_update_channel_title">Güncelleme Kanalı</string>
<string name="settings_update_stable">Kararlı</string>
<string name="settings_update_stable">Stabil(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>
@@ -174,12 +174,15 @@
<string name="settings_su_biometric_summary">Superuser isteklerine izin vermek için biyometrik kimlik doğrulamayı kullanın</string>
<string name="no_biometric">Desteklenmeyen cihaz veya biyometrik ayar etkinleştirilmemiş</string>
<string name="settings_customization">Özelleştirme</string>
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra ismini ve simgesini tanımakta zorlanırsan ana ekrana güzel bir kısayol ekleyebilirsin</string>
<string name="settings_doh_title">HTTPS üzerinden DNS</string>
<string name="settings_doh_description">Bazı ülkelerdeki DNS zehirlenmesini çözmeye çalışır</string>
<string name="multiuser_mode">Çok Kullanıcılı Mod</string>
<string name="multiuser_mode">Çoklu Kullanıcı Modu</string>
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</string>
<string name="settings_owner_manage">Cihaz Sahibi Tarafından Yönetilen</string>
<string name="settings_user_independent">Bağımsız Kullanıcı</string>
<string name="owner_only_summary">Yalnızca kök erişimi olan kullanıcı</string>
<string name="owner_only_summary">Yalnızca kök erişimi olan kullanıcılar</string>
<string name="owner_manage_summary">Yalnızca cihaz sahibi kök erişimini yönetebilir ve izin isteklerini alabilir</string>
<string name="user_indepenent_summary">Her kullanıcının kendi ayrı kök erişimi kuralları vardır</string>
@@ -210,7 +213,7 @@
<string name="reboot">Yeniden başlat</string>
<string name="release_notes">Sürüm notları</string>
<string name="repo_cache_cleared">Depo önbelleği temizlendi</string>
<string name="flashing">Yükleniyor...</string>
<string name="flashing">Yükleniyor</string>
<string name="done">Tamamlandı!</string>
<string name="failure">Başarısız</string>
<string name="hide_manager_title">Magisk Manager Gizleniyor…</string>
@@ -221,8 +224,8 @@
<string name="restore_img_msg">Geri Yükleniyor…</string>
<string name="restore_done">Yenileme tamamlandı!</string>
<string name="restore_fail">Stok önyükleme yedeği yok!</string>
<string name="proprietary_title">Tescil Kodunu İndirin</string>
<string name="proprietary_notice">Magisk Yöneticisi, FOSS olduğundan gerekli olan Google\'a ait SafetyNet API kodunu içermez.\n\nMagisk Manager\'ın SafetyNet kontrolü için (GoogleApiClient içeren) bir uzantıyı indirmesine izin veriyor musunuz?</string>
<string name="proprietary_title">Sahipli Kodu İndirin</string>
<string name="proprietary_notice">Magisk Yöneticisi, FOSS(açık kaynaklı) olduğundan gerekli olan Google\'ın sahipli(kapalı kaynaklı) SafetyNet API kodunu içermez.\n\nMagisk Manager\'ın SafetyNet kontrolü için (GoogleApiClient içeren) bir uzantıyı indirmesine izin veriyor musunuz?</string>
<string name="setup_fail">Kurulum başarısız</string>
<string name="env_fix_title">Ek Kurulum Gerekli</string>
<string name="env_fix_msg">Cihazınızın Magisk\'in düzgün çalışması için ek kuruluma ihtiyacı var. Bu Magisk kurulum zip dosyasını indirecektir, şimdi devam etmek istiyor musunuz?</string>
@@ -231,5 +234,8 @@
<string name="unsupport_magisk_title">Desteklenmeyen Magisk Sürümü</string>
<string name="unsupport_magisk_msg">Magisk Manager\'ın bu sürümü, %1$s daha düşük Magisk versiyonlarını desteklememektedir.\n\nUygulama hiçbir Magisk kurulu değil gibi davranacak, lütfen en kısa zamanda Magisk\'i yükseltin.</string>
<string name="external_rw_permission_denied">Bu işlevi etkinleştirmek için depolama izni verin</string>
<string name="add_shortcut_title">Ana ekrana kısayol ekle</string>
<string name="add_shortcut_msg">Magisk Manager\'ı gizledikten sonra, ismini ve simgesini tanıması güç olabilir. Ana ekrana güzel bir kısayol eklemek ister misin??</string>
<string name="app_not_found">Bu işlemi yapabilecek bir uygulama bulunamadı</string>
</resources>

View File

@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">Запит прав суперкористувача</string>
<string name="touch_filtered_warning">Magisk не може перевірити вашу відповідь, тому що застосунок заступає вікно запиту прав суперкористувача</string>
<string name="deny">Відмовити</string>
<string name="prompt">Запитувати</string>
<string name="grant">Надати</string>
@@ -102,6 +103,7 @@
<!-- MagiskHide -->
<string name="show_system_app">Показувати системні застосунки</string>
<string name="show_os_app">Показувати вбудовані застосунки</string>
<string name="hide_filter_hint">Фільтрувати за назвою</string>
<string name="hide_scroll_up">Прогорнути вгору</string>
<string name="hide_filters">Фільтри</string>
@@ -109,6 +111,7 @@
<!--Module Fragment-->
<string name="no_info_provided">(немає наданої інформації)</string>
<string name="reboot_userspace">Швидке перезавантаження</string>
<string name="reboot_recovery">Перезавантажити в Recovery</string>
<string name="reboot_bootloader">Перезавантажити в Bootloader</string>
<string name="reboot_download">Перезавантажити в Download</string>
@@ -121,6 +124,7 @@
<string name="module_action_install_external">Встановити зі сховища</string>
<string name="update_available">Доступне оновлення</string>
<string name="module_installed">@string/home_installed_version</string>
<string name="module_section_online">Онлайн</string>
<string name="sorting_order">Порядок сортування</string>
<!--Settings -->
@@ -169,10 +173,15 @@
<string name="superuser_notification">Сповіщення суперкористувача</string>
<string name="settings_su_reauth_title">Повторна автентифікація</string>
<string name="settings_su_reauth_summary">Перевидача прав суперкористувача після оновлення програ</string>
<string name="settings_su_tapjack_title">Увімкнути захист від Tapjack</string>
<string name="settings_su_tapjack_summary">Діалогове вікно суперкористувача не буде отримувати ввід від користувача, коли вікно перекрито іншим застосунком чи вікном</string>
<string name="settings_su_biometric_title">Біометрична автентифікація</string>
<string name="settings_su_biometric_summary">Використовувати біометричну автентифікацію, щоб підтверджувати запити суперкористувача</string>
<string name="no_biometric">Пристрій не підтримується, або не налаштовано біометрику</string>
<string name="settings_customization">Оформлення</string>
<string name="setting_add_shortcut_summary">Додати ярлик на домашній екран для зручного сприйняття застосунку після його приховування</string>
<string name="settings_doh_title">DNS поверх HTTPS</string>
<string name="settings_doh_description">Відключити DoH (при нестабільному підключенні)</string>
<string name="multiuser_mode">Багатокористувацький режим</string>
<string name="settings_owner_only">Тільки власник</string>
@@ -214,6 +223,7 @@
<string name="failure">Не вдалося</string>
<string name="hide_manager_title">Приховування Magisk Manager…</string>
<string name="hide_manager_fail_toast">Не вдалося приховати Magisk Manager.</string>
<string name="restore_manager_fail_toast">Не вдалося відновити Magisk Manager</string>
<string name="open_link_failed_toast">Не знайдено застосунку для відкриття посилання</string>
<string name="complete_uninstall">Повне видалення</string>
<string name="restore_img">Відновити розділи</string>
@@ -230,5 +240,8 @@
<string name="unsupport_magisk_title">Версія Magisk не підтримується</string>
<string name="unsupport_magisk_msg">Ця версія Magisk Manager не підтримує версію Magisk нижчу, ніж %1$s.\n\nЗастосунок буде працювати, ніби Magisk не встановлено. Будь ласка, оновіть Magisk якомога швидше.</string>
<string name="external_rw_permission_denied">Надайте доступ до сховища, щоб увімкнути цей функціонал</string>
<string name="add_shortcut_title">Ярлик на домашньому екрані</string>
<string name="add_shortcut_msg">Після приховування Magisk Manager, його ім\'я та іконка може сильно відрізнятися від оригіналу, що ускладнить пошук. Хочете створити ярлик на домашньому екрані?</string>
<string name="app_not_found">Не знайдено застосунку, який повинен опрацювати цю дію</string>
</resources>

View File

@@ -17,7 +17,7 @@
<string name="manager">Manager</string>
<string name="loading">正在加载</string>
<string name="update">更新</string>
<string name="not_available">不可用</string>
<string name="not_available">无法获取</string>
<string name="hide">不再显示</string>
<string name="status">状态</string>
<string name="home_package">包名</string>
@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">超级用户请求</string>
<string name="touch_filtered_warning">由于某个应用遮挡了超级用户请求界面,因此 Magisk 无法验证您的回应</string>
<string name="deny">拒绝</string>
<string name="prompt">提示</string>
<string name="grant">允许</string>
@@ -102,6 +103,7 @@
<!-- MagiskHide -->
<string name="show_system_app">显示系统应用</string>
<string name="show_os_app">显示操作系统</string>
<string name="hide_filter_hint">按名称过滤</string>
<string name="hide_scroll_up">返回顶部</string>
<string name="hide_filters">过滤</string>
@@ -109,6 +111,7 @@
<!--Module -->
<string name="no_info_provided">(未提供信息)</string>
<string name="reboot_userspace">软重启</string>
<string name="reboot_recovery">重启到 Recovery</string>
<string name="reboot_bootloader">重启到 Bootloader</string>
<string name="reboot_download">重启到 Download</string>
@@ -170,6 +173,8 @@
<string name="superuser_notification">超级用户通知</string>
<string name="settings_su_reauth_title">更新后重新认证</string>
<string name="settings_su_reauth_summary">应用更新后重新认证超级用户权限</string>
<string name="settings_su_tapjack_title">启用点按劫持保护</string>
<string name="settings_su_tapjack_summary">存在屏幕叠加层时,超级用户请求弹窗不响应允许操作</string>
<string name="settings_su_biometric_title">启用生物识别验证</string>
<string name="settings_su_biometric_summary">使用生物识别来允许超级用户请求</string>
<string name="no_biometric">设备不支持或未配置生物识别功能</string>
@@ -217,7 +222,8 @@
<string name="done">完成!</string>
<string name="failure">失败</string>
<string name="hide_manager_title">正在隐藏 Magisk Manager</string>
<string name="hide_manager_fail_toast">隐藏失败</string>
<string name="hide_manager_fail_toast">隐藏 Magisk Manager 失败</string>
<string name="restore_manager_fail_toast">还原 Magisk Manager 失败</string>
<string name="open_link_failed_toast">找不到能打开此链接的应用</string>
<string name="complete_uninstall">完全卸载</string>
<string name="restore_img">还原原厂映像</string>
@@ -235,6 +241,7 @@
<string name="unsupport_magisk_msg">此版本的 Magisk Manager 不支持低于 %1$s 版本的 Magisk。\n\n应用表现为未安装状态但升级功能可用请尽快升级 Magisk。</string>
<string name="external_rw_permission_denied">允许访问存储空间以使用此功能</string>
<string name="add_shortcut_title">添加快捷方式到桌面</string>
<string name="add_shortcut_msg">隐藏 Magisk Manager 后,其名称和图标可能会变得难以识别。需要在桌面上添加快捷方式吗?</string>
<string name="add_shortcut_msg">隐藏 Magisk Manager 后,其名称和图标会变得难以识别。需要在桌面上添加具有原始名称和图标的快捷方式吗?</string>
<string name="app_not_found">找不到可处理此操作的应用</string>
</resources>

View File

@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">超級使用者請求</string>
<string name="touch_filtered_warning">由於某個應用程式遮蔽了超級使用者請求的視窗,因此 Magisk 無法驗證您的回應</string>
<string name="deny">拒絕</string>
<string name="prompt">提示</string>
<string name="grant">允許</string>
@@ -102,6 +103,7 @@
<!-- MagiskHide -->
<string name="show_system_app">顯示系統應用程式</string>
<string name="show_os_app">顯示作業系统</string>
<string name="hide_filter_hint">過濾名稱</string>
<string name="hide_scroll_up">回到最上面</string>
<string name="hide_filters">過濾器</string>
@@ -109,6 +111,7 @@
<!--Module -->
<string name="no_info_provided">(未提供資訊)</string>
<string name="reboot_userspace">快速重新啟動</string>
<string name="reboot_recovery">重新啟動至 Recovery</string>
<string name="reboot_bootloader">重新啟動至 Bootloader</string>
<string name="reboot_download">重新啟動至 Download</string>
@@ -170,6 +173,8 @@
<string name="superuser_notification">超級使用者通知</string>
<string name="settings_su_reauth_title">更新後重新驗證</string>
<string name="settings_su_reauth_summary">應用程式更新後,重新驗證超級使用者的請求</string>
<string name="settings_su_tapjack_title">啟用點選攔截保護</string>
<string name="settings_su_tapjack_summary">發現超級使用者視窗上有應用程式重疊在上層時,不回應允許操作</string>
<string name="settings_su_biometric_title">啟用生物特徵驗證</string>
<string name="settings_su_biometric_summary">使用生物特徵驗證來允許 Superuser 的請求</string>
<string name="no_biometric">不支援的裝置或是未啟用生物特徵設定</string>
@@ -218,6 +223,7 @@
<string name="failure">失敗</string>
<string name="hide_manager_title">正在隱藏 Magisk Manager……</string>
<string name="hide_manager_fail_toast">隱藏 Magisk Manager 失敗</string>
<string name="restore_manager_fail_toast">還原 Magisk Manager 失敗</string>
<string name="open_link_failed_toast">沒有可以開啟此連結的應用程式</string>
<string name="complete_uninstall">完全解除安裝</string>
<string name="restore_img">還原原始映像檔</string>

View File

@@ -22,7 +22,7 @@
<string name="status">Status</string>
<string name="home_package">Package</string>
<string name="home_notice_content">Always make sure you\'re using open-source Magisk Manager. Manager of unknown source can perform malicious actions.</string>
<string name="home_notice_content">Always make sure you\'re using open-source Magisk Manager. Manager of unknown source can perform malicious actions!</string>
<string name="home_support_title">Support Us</string>
<string name="home_item_source">Source</string>
<string name="home_support_content">Magisk is, and always will be, free and open-source. You can however show us that you care by sending a small donation.</string>
@@ -56,6 +56,7 @@
<!--Superuser-->
<string name="su_request_title">Superuser Request</string>
<string name="touch_filtered_warning">Because an app is obscuring a superuser request, Magisk cant verify your response</string>
<string name="deny">Deny</string>
<string name="prompt">Prompt</string>
<string name="grant">Grant</string>
@@ -84,11 +85,11 @@
<string name="superuser_policy_none">No app has asked for superuser permission yet.</string>
<!--Logs-->
<string name="log_data_none">You\'re log-free, try using your SU enabled apps more.</string>
<string name="log_data_magisk_none">Magisk logs are empty, that\'s weird.</string>
<string name="log_data_none">You\'re log-free, try using your SU enabled apps more</string>
<string name="log_data_magisk_none">Magisk logs are empty, that\'s weird</string>
<string name="menuSaveLog">Save log</string>
<string name="menuClearLog">Clear log now</string>
<string name="logs_cleared">Log successfully cleared.</string>
<string name="logs_cleared">Log successfully cleared</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
@@ -100,15 +101,17 @@
<string name="safetynet_attest_loading">Just a sec…</string>
<string name="safetynet_attest_restart">Try again</string>
<!-- MagiskHide -->
<!--MagiskHide-->
<string name="show_system_app">Show system apps</string>
<string name="show_os_app">Show OS apps</string>
<string name="hide_filter_hint">Filter by name</string>
<string name="hide_scroll_up">Scroll up</string>
<string name="hide_filters">Filters</string>
<string name="hide_search">Search</string>
<!--Module -->
<!--Module-->
<string name="no_info_provided">(No info provided)</string>
<string name="reboot_userspace">Soft reboot</string>
<string name="reboot_recovery">Reboot to Recovery</string>
<string name="reboot_bootloader">Reboot to Bootloader</string>
<string name="reboot_download">Reboot to Download</string>
@@ -124,7 +127,7 @@
<string name="module_section_online">Online</string>
<string name="sorting_order">Sorting Order</string>
<!--Settings -->
<!--Settings-->
<string name="settings_dark_mode_title">Theme Mode</string>
<string name="settings_dark_mode_message">Select mode which best suits your style!</string>
<string name="settings_dark_mode_light">Always Light</string>
@@ -170,6 +173,8 @@
<string name="superuser_notification">Superuser Notification</string>
<string name="settings_su_reauth_title">Reauthenticate after upgrade</string>
<string name="settings_su_reauth_summary">Reauthenticate superuser permissions after an application upgrades</string>
<string name="settings_su_tapjack_title">Enable Tapjacking Protection</string>
<string name="settings_su_tapjack_summary">The superuser prompt dialog will not respond to input while obscured by any other window or overlay</string>
<string name="settings_su_biometric_title">Enable Biometric Authentication</string>
<string name="settings_su_biometric_summary">Use biometric authentication to allow superuser requests</string>
<string name="no_biometric">Unsupported device or no biometric settings are enabled</string>
@@ -215,9 +220,10 @@
<string name="repo_cache_cleared">Repo cache cleared</string>
<string name="flashing">Flashing…</string>
<string name="done">Done!</string>
<string name="failure">Failed</string>
<string name="failure">Failed!</string>
<string name="hide_manager_title">Hiding Magisk Manager…</string>
<string name="hide_manager_fail_toast">Hide Magisk Manager failed.</string>
<string name="hide_manager_fail_toast">Hide Magisk Manager failed</string>
<string name="restore_manager_fail_toast">Restore Magisk Manager failed</string>
<string name="open_link_failed_toast">No application found to open the link</string>
<string name="complete_uninstall">Complete Uninstall</string>
<string name="restore_img">Restore Images</string>

View File

@@ -14,11 +14,11 @@ buildscript {
maven { url = uri("https://kotlin.bintray.com/kotlinx") }
}
val vNav = "2.3.0"
val vNav = "2.3.1"
extra["vNav"] = vNav
dependencies {
classpath("com.android.tools.build:gradle:4.0.1")
classpath("com.android.tools.build:gradle:4.1.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:${vNav}")
@@ -37,7 +37,7 @@ fun Task.applyOptimize() = doLast {
val aapt2 = Paths.get(project.android.sdkDirectory.path,
"build-tools", project.android.buildToolsVersion, "aapt2")
val zip = Paths.get(project.buildDir.path, "intermediates",
"processed_res", "release", "out", "resources-release.ap_")
"shrunk_processed_res", "release", "resources-release-stripped.ap_")
val optimized = File("${zip}.opt")
val cmd = exec {
commandLine(aapt2, "optimize", "--collapse-resource-names",
@@ -45,6 +45,7 @@ fun Task.applyOptimize() = doLast {
isIgnoreExitValue = true
}
if (cmd.exitValue == 0) {
zip.toFile().delete()
optimized.renameTo(zip.toFile())
}
}
@@ -63,6 +64,7 @@ subprojects {
android.apply {
compileSdkVersion(30)
buildToolsVersion = "30.0.2"
ndkPath = "${System.getenv("ANDROID_SDK_ROOT")}/ndk/magisk"
defaultConfig {
if (minSdkVersion == null)
@@ -87,8 +89,8 @@ subprojects {
}
tasks.whenTaskAdded {
if (name == "processReleaseResources") {
finalizedBy(tasks.create("optimizeReleaseResources").applyOptimize())
if (name == "shrinkReleaseRes") {
finalizedBy(tasks.create("optimizeReleaseRes").applyOptimize())
}
}

View File

@@ -27,8 +27,8 @@ def vprint(str):
if not sys.version_info >= (3, 6):
error('Requires Python 3.6+')
if 'ANDROID_HOME' not in os.environ:
error('Please add Android SDK path to ANDROID_HOME environment variable!')
if 'ANDROID_SDK_ROOT' not in os.environ:
error('Please add Android SDK path to ANDROID_SDK_ROOT environment variable!')
try:
subprocess.run(['javac', '-version'],
@@ -55,10 +55,10 @@ arch64 = ['arm64-v8a', 'x86_64']
support_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy', 'resetprop', 'busybox', 'test']
default_targets = ['magisk', 'magiskinit', 'magiskboot', 'busybox']
ndk_ver = '21c'
ndk_ver_full = '21.2.6472646'
ndk_ver = '21d'
ndk_ver_full = '21.3.6528147'
ndk_root = op.join(os.environ['ANDROID_HOME'], 'ndk')
ndk_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'ndk')
ndk_path = op.join(ndk_root, 'magisk')
ndk_build = op.join(ndk_path, 'ndk-build')
gradlew = op.join('.', 'gradlew' + ('.bat' if is_windows else ''))
@@ -285,8 +285,8 @@ def dump_bin_headers():
def build_binary(args):
# Verify NDK install
props = parse_props(op.join(ndk_path, 'source.properties'))
if 'Pkg.Revision.orig' not in props or props['Pkg.Revision.orig'] != ndk_ver_full:
error('Incorrect NDK. Please setup NDK with "build.py ndk"')
if props['Pkg.Revision'] != ndk_ver_full:
error('Incorrect NDK. Please install/upgrade NDK with "build.py ndk"')
if args.target:
args.target = set(args.target) & set(support_targets)
@@ -550,15 +550,6 @@ def setup_ndk(args):
for path in copy_tree(src_dir, lib_dir):
vprint(f'Replaced {path}')
# Rewrite source.properties
src_prop = op.join(ndk_path, 'source.properties')
props = parse_props(src_prop)
props['Pkg.Revision.orig'] = props['Pkg.Revision']
props['Pkg.Revision'] = '99.99.99'
with open(src_prop, 'w') as p:
for key, val in props.items():
print(f'{key} = {val}', file=p)
def build_all(args):
vars(args)['target'] = []

View File

@@ -1,5 +1,5 @@
# Magisk Documentation
(Updated on 2020.10.6)
(Updated on 2020.11.13)
- [Installation Instructions](install.md)
- [Frequently Asked Questions](faq.md)

View File

@@ -1,5 +1,16 @@
# Magisk Manager Changelog
### v8.0.3
- Switch to the new Magisk Module Repo setup in preparation to allow 3rd party repos
- Add tapjacking protection on Superuser request dialog
- Stability changes and bug fixes
### v8.0.2
- Fix an issue with requesting permission on devices older than Android 10
- Make more files download through CDN
### v8.0.1
- Fix `vbmeta.img` patching for Samsung `AP.tar` files. This fixes bootloops on devices like Galaxy S10 after flashing updated AP files.

View File

@@ -1,5 +1,20 @@
# Magisk Changelog
### v21.1
- [MagiskBoot] Support boot header v3 (Pixel 5 and 4a 5G)
- [MagiskBoot] Distinguish `lz4_lg` and `lz4_legacy` (Pixel 5 and 4a 5G)
- [MagiskBoot] Support vendor boot images (for dev, not relevant for Magisk installation)
- [MagiskInit] Support kernel cmdline `androidboot.fstab_suffix`
- [MagiskInit] Support kernel initialized dm-verity on legacy SAR
- [General] Significantly broaden sepolicy.rule compatibility
- [General] Add Magisk binaries to `PATH` when executing boot scripts
- [General] Update `--remove-modules` command implementation
- [General] Make Magisk properly survive after factory reset on Android 11
- [MagiskSU] Add APEX package `com.android.i18n` to `LD_LIBRARY_PATH` when linking `libsqlite.so`
- [MagiskHide] Support hiding apps installed in secondary users (e.g. work profile)
- [MagiskHide] Make zygote detection more robust
### v21.0
- [General] Support Android 11 🎉

View File

@@ -46,7 +46,7 @@ A Magisk module is a folder placed in `/data/adb/modules` with the structure bel
│   ├── service.sh <--- This script will be executed in late_start service
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module
│   ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
│   ├── sepolicy.rule <--- Additional custom sepolicy rules to be patched
│   ├── sepolicy.rule <--- Additional custom sepolicy rules
│   │
│ │ *** Auto Generated, DO NOT MANUALLY CREATE OR MODIFY ***
│   │
@@ -96,7 +96,7 @@ This file follows the same format as `build.prop`. Each line comprises of `[key]
#### sepolicy.rule
If your module requires some additional sepolicy patches, please add those rules into this file. The module installer script and Magisk's daemon will make sure this file is copied to somewhere `magiskinit` can read pre-init to ensure these rules are injected properly.
Each line in this file will be treated as a policy statement. For more details how a policy statement is formated, please check [magiskpolicy](tools.md#magiskpolicy)'s documentation.
Each line in this file will be treated as a policy statement. For more details how a policy statement is formatted, please check [magiskpolicy](tools.md#magiskpolicy)'s documentation.
#### The `system` folder
All files you want Magisk to replace/inject for you should be placed in this folder. Please read through the [Magic Mount](details.md#magic-mount) section to understand how Magisk mount your files.

View File

@@ -1,3 +1,5 @@
# NOTE: Install to Inactive Slot is disabled in newer builds of Magisk Manager due to changes that Google introduced to the OTA process: https://twitter.com/topjohnwu/status/1303574238796808192
## OTA Upgrade Guides
Magisk does not modify most read-only partitions, which means applying official OTAs is much simpler. Here are the tutorials for several different kind of devices to apply OTAs and preserve Magisk after the installation (if possible). This is just a general guide as procedures for each device may vary.

View File

@@ -2,7 +2,7 @@
Long time no see! v21.0 is the largest release in Magisk's history. It comes with full Android 11 support (tons of stuff had to be rewritten from scratch!), and a completely redesigned Magisk Manager. These are the reasons why this particular public release took me over half a year to wrap up.
To the end user, not much has changed other than the fact that Magisk Manager has completely changed its appearance. However developers should pay some attention to some changes due to adjustments for Android 11. Full changelogs are too massive to fit, so here I'll point out the main changes and links to updated documentations.
To the end user, not much has changed other than the fact that Magisk Manager has completely changed its appearance. However developers should pay attention to some changes due to adjustments for Android 11. Full changelogs are too massive to fit, so here I'll point out the main changes and links to updated documentations.
### Highlights

5
docs/releases/21100.md Normal file
View File

@@ -0,0 +1,5 @@
## 2020.11.13 Magisk v21.1
v21.1 is a maintenance update from v21.0, mostly addressing bugs, refining some details, and adding new boot image format support (for Pixel 5 and 4a 5G). Checkout the full [v21.0 release notes](https://topjohnwu.github.io/Magisk/releases/21000.html) if coming from older releases.
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)

View File

@@ -1,5 +1,6 @@
# Release Notes
- [v21.1](21100.md)
- [v21.0](21000.md)
- [v20.4](20400.md)
- [v20.3](20300.md)

View File

@@ -100,12 +100,12 @@ Supported actions:
compress[=method] <infile> [outfile]
Compress <infile> with [method] (default: gzip), optionally to [outfile]
<infile>/[outfile] can be '-' to be STDIN/STDOUT
Supported methods: bzip2 gzip lz4 lz4_legacy lzma xz
Supported methods: bzip2 gzip lz4 lz4_legacy lz4_lg lzma xz
decompress <infile> [outfile]
Detect method and decompress <infile>, optionally to [outfile]
<infile>/[outfile] can be '-' to be STDIN/STDOUT
Supported methods: bzip2 gzip lz4 lz4_legacy lzma xz
Supported methods: bzip2 gzip lz4 lz4_legacy lz4_lg lzma xz
```
### magiskinit
@@ -258,10 +258,10 @@ Options:
Flags:
-v print verbose output to stderr
-n set properties without going through init
affects setprop and prop file loading
-p also access props directly from persist storage
affects getprop and delprop
-n set props without going through property_service
(this flag only affects setprop)
-p read/write props from/to persistent storage
(this flag only affects getprop and delprop)
```
### magiskhide

Some files were not shown because too many files have changed in this diff Show More