Commit c5aaaa7c authored by topjohnwu's avatar topjohnwu

Merge Magisk Manager into Magisk main repo

parents f86d077e f8076825
*.iml
.gradle
/local.properties
.idea/
/build
app/release
*.hprof
.externalNativeBuild/
src/full/res/raw/util_functions.sh
public.certificate.x509.pem
private.key.pk8
*.apk
# Magisk Manager
This repo is no longer an independent component. It is a submodule of the [Magisk Project](https://github.com/topjohnwu/Magisk).
# Translations
The default (English) string resources are scattered in these files: `src/full/res/values/strings.xml`, `src/main/res/values/strings.xml`, `src/stub/res/values/strings.xml`.
Place the translated XMLs in the corresponding folder to the locale.
Translations are highly appreciated via pull requests here on Github.
apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion rootProject.ext.compileSdkVersion
javaCompileOptions {
annotationProcessorOptions {
argument('butterknife.debuggable', 'false')
}
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "mode"
productFlavors {
full {
versionCode 127
versionName "5.8.1"
}
stub {
versionCode 1
versionName "stub"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dexOptions {
preDexLibraries true
javaMaxHeapSize "2g"
}
lintOptions {
disable 'MissingTranslation'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
fullImplementation project(':utils')
implementation "com.android.support:support-core-utils:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:preference-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
fullImplementation 'com.github.topjohnwu:libsu:1.3.0'
fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0'
fullImplementation 'org.kamranzafar:jtar:2.3'
fullImplementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/topjohnwu/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Keep all names, we are open source anyway :)
-keepnames class ** { *; }
# BouncyCastle
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; }
-keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; }
-keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; }
-dontwarn javax.naming.**
# Gson
-keepattributes Signature
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.topjohnwu.magisk">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application
android:name=".MagiskManager"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:exported="true" />
<activity
android:name=".SplashActivity"
android:configChanges="orientation|screenSize"
android:exported="true"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AboutActivity"
android:theme="@style/AppTheme.StatusBar" />
<activity
android:name=".SettingsActivity"
android:theme="@style/AppTheme.StatusBar" />
<activity
android:name=".FlashActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="nosensor"
android:theme="@style/AppTheme.StatusBar" />
<activity
android:name=".NoUIActivity"
android:theme="@style/AppTheme.Translucent" />
<activity
android:name=".superuser.RequestActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity="internal.superuser"
android:theme="@style/SuRequest" />
<receiver android:name=".superuser.SuReceiver" />
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.PackageReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.ManagerUpdate" />
<receiver android:name=".receivers.RebootReceiver" />
<receiver android:name=".receivers.ShortcutReceiver">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".services.OnBootIntentService" />
<service
android:name=".services.UpdateCheckService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Hardcode GMS version -->
<meta-data
android:name="com.google.android.gms.version"
android:value="7095000" />
</application>
</manifest>
\ No newline at end of file
package com.topjohnwu.magisk;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AboutActivity extends Activity {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.app_version_info) AboutCardRow appVersionInfo;
@BindView(R.id.app_changelog) AboutCardRow appChangelog;
@BindView(R.id.app_translators) AboutCardRow appTranslators;
@BindView(R.id.app_source_code) AboutCardRow appSourceCode;
@BindView(R.id.support_thread) AboutCardRow supportThread;
@BindView(R.id.donation) AboutCardRow donation;
@Override
public int getDarkTheme() {
return R.style.AppTheme_StatusBar_Dark;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.about);
ab.setDisplayHomeAsUpEnabled(true);
}
appVersionInfo.setSummary(String.format(Locale.US, "%s (%d) (%s)",
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, getPackageName()));
appChangelog.removeSummary();
appChangelog.setOnClickListener(v -> {
new MarkDownWindow(this, getString(R.string.app_changelog),
getResources().openRawResource(R.raw.changelog)).exec();
});
String translators = getString(R.string.translators);
if (TextUtils.isEmpty(translators)) {
appTranslators.setVisibility(View.GONE);
} else {
appTranslators.setSummary(translators);
}
appSourceCode.removeSummary();
appSourceCode.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.SOURCE_CODE_URL))));
supportThread.removeSummary();
supportThread.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.XDA_THREAD))));
donation.removeSummary();
donation.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.DONATION_URL))));
setFloating();
}
}
package com.topjohnwu.magisk;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.FlashZip;
import com.topjohnwu.magisk.asyncs.InstallMagisk;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class FlashActivity extends Activity {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.txtLog) TextView flashLogs;
@BindView(R.id.button_panel) public LinearLayout buttonPanel;
@BindView(R.id.reboot) public Button reboot;
@BindView(R.id.scrollView) ScrollView sv;
private List<String> logs;
@OnClick(R.id.no_thanks)
void dismiss() {
finish();
}
@OnClick(R.id.reboot)
void reboot() {
Shell.Async.su("/system/bin/reboot");
}
@OnClick(R.id.save_logs)
void saveLogs() {
Calendar now = Calendar.getInstance();
String filename = String.format(Locale.US,
"install_log_%04d%02d%02d_%02d%02d%02d.log",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
File logFile = new File(Const.EXTERNAL_PATH + "/logs", filename);
logFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(logFile)) {
for (String s : logs) {
writer.write(s);
writer.write('\n');
}
} catch (IOException e) {
e.printStackTrace();
return;
}
MagiskManager.toast(logFile.getPath(), Toast.LENGTH_LONG);
}
@Override
public int getDarkTheme() {
return R.style.AppTheme_StatusBar_Dark;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.flashing);
}
setFloating();
setFinishOnTouchOutside(false);
if (!Shell.rootAccess())
reboot.setVisibility(View.GONE);
logs = new ArrayList<>();
CallbackList<String> console = new CallbackList<String>(new ArrayList<>()) {
@Override
public void onAddElement(String s) {
logs.add(s);
flashLogs.setText(TextUtils.join("\n", this));
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
}
};
// We must receive a Uri of the target zip
Intent intent = getIntent();
Uri uri = intent.getData();
switch (intent.getStringExtra(Const.Key.FLASH_ACTION)) {
case Const.Value.FLASH_ZIP:
new FlashZip(this, uri, console, logs).exec();
break;
case Const.Value.UNINSTALL:
new UninstallMagisk(this, uri, console, logs).exec();
break;
case Const.Value.FLASH_MAGISK:
new InstallMagisk(this, console, logs, uri, InstallMagisk.DIRECT_MODE).exec();
break;
case Const.Value.FLASH_SECOND_SLOT:
new InstallMagisk(this, console, logs, uri, InstallMagisk.SECOND_SLOT_MODE).exec();
break;
case Const.Value.PATCH_BOOT:
new InstallMagisk(this, console, logs, uri,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec();
break;
}
}
@Override
public void onBackPressed() {
// Prevent user accidentally press back button
}
private static class UninstallMagisk extends FlashZip {
private UninstallMagisk(Activity context, Uri uri, List<String> console, List<String> logs) {
super(context, uri, console, logs);
}
@Override
protected void onPostExecute(Integer result) {
if (result == 1) {
new Handler().postDelayed(() ->
RootUtils.uninstallPkg(getActivity().getPackageName()), 3000);
} else {
super.onPostExecute(result);
}
}
}
}
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.topjohnwu.magisk.adapters.TabFragmentAdapter;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Const;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class LogFragment extends Fragment {
private Unbinder unbinder;
@BindView(R.id.container) ViewPager viewPager;
@BindView(R.id.tab) TabLayout tab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_log, container, false);
unbinder = ButterKnife.bind(this, v);
((MainActivity) getActivity()).toolbar.setElevation(0);
TabFragmentAdapter adapter = new TabFragmentAdapter(getChildFragmentManager());
if (!(Const.USER_ID > 0 && getApplication().multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
adapter.addTab(new SuLogFragment(), getString(R.string.superuser));
}
adapter.addTab(new MagiskLogFragment(), getString(R.string.magisk));
tab.setupWithViewPager(viewPager);
tab.setVisibility(View.VISIBLE);
viewPager.setAdapter(adapter);
return v;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
package com.topjohnwu.magisk;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.CardView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.asyncs.CheckSafetyNet;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
import com.topjohnwu.magisk.utils.ShowUI;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class MagiskFragment extends Fragment
implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView {
private Container expandableContainer = new Container();
private MagiskManager mm;
private Unbinder unbinder;
private static boolean shownDialog = false;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.magisk_update) RelativeLayout magiskUpdate;
@BindView(R.id.magisk_update_icon) ImageView magiskUpdateIcon;
@BindView(R.id.magisk_update_status) TextView magiskUpdateText;
@BindView(R.id.magisk_update_progress) ProgressBar magiskUpdateProgress;
@BindView(R.id.magisk_status_icon) ImageView magiskStatusIcon;
@BindView(R.id.magisk_version) TextView magiskVersionText;
@BindView(R.id.safetyNet_card) CardView safetyNetCard;
@BindView(R.id.safetyNet_refresh) ImageView safetyNetRefreshIcon;
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText;
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress;
@BindView(R.id.expand_layout) LinearLayout expandLayout;
@BindView(R.id.cts_status_icon) ImageView ctsStatusIcon;
@BindView(R.id.cts_status) TextView ctsStatusText;
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
@BindView(R.id.basic_status) TextView basicStatusText;
@BindView(R.id.install_option_card) CardView installOptionCard;
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
@BindView(R.id.install_button) CardView installButton;
@BindView(R.id.install_text) TextView installText;
@BindView(R.id.uninstall_button) CardView uninstallButton;
@BindColor(R.color.red500) int colorBad;
@BindColor(R.color.green500) int colorOK;
@BindColor(R.color.yellow500) int colorWarn;
@BindColor(R.color.grey500) int colorNeutral;
@BindColor(R.color.blue500) int colorInfo;
@OnClick(R.id.safetyNet_title)
void safetyNet() {
Runnable task = () -> {
safetyNetProgress.setVisibility(View.VISIBLE);
safetyNetRefreshIcon.setVisibility(View.GONE);
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
new CheckSafetyNet(getActivity()).exec();
collapse();
};
if (!TextUtils.equals(mm.getPackageName(), Const.ORIG_PKG_NAME)) {
new AlertDialogBuilder(getActivity())
.setTitle(R.string.cannot_check_sn_title)
.setMessage(R.string.cannot_check_sn_notice)
.setCancelable(true)
.setPositiveButton(R.string.ok, null)
.show();
} else if (!CheckSafetyNet.dexPath.exists()) {
// Show dialog
new AlertDialogBuilder(getActivity())
.setTitle(R.string.proprietary_title)
.setMessage(R.string.proprietary_notice)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> task.run())
.setNegativeButton(R.string.no_thanks, null)
.show();
} else {
task.run();
}
}
@OnClick(R.id.install_button)
void install() {
shownDialog = true;
// Show Manager update first
if (mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
ShowUI.managerInstallDialog(getActivity());
return;
}
((NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
ShowUI.magiskInstallDialog(getActivity());
}
@OnClick(R.id.uninstall_button)
void uninstall() {
ShowUI.uninstallDialog(getActivity());
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_magisk, container, false);
unbinder = ButterKnife.bind(this, v);
getActivity().setTitle(R.string.magisk);
mm = getApplication();
expandableContainer.expandLayout = expandLayout;
setupExpandable();
keepVerityChkbox.setChecked(mm.keepVerity);
keepVerityChkbox.setOnCheckedChangeListener((view, checked) -> mm.keepVerity = checked);
keepEncChkbox.setChecked(mm.keepEnc);
keepEncChkbox.setOnCheckedChangeListener((view, checked) -> mm.keepEnc = checked);
mSwipeRefreshLayout.setOnRefreshListener(this);
updateUI();
return v;
}
@Override
public void onRefresh() {
mm.loadMagiskInfo();
updateUI();
magiskUpdateText.setText(R.string.checking_for_updates);
magiskUpdateProgress.setVisibility(View.VISIBLE);
magiskUpdateIcon.setVisibility(View.GONE);
safetyNetStatusText.setText(R.string.safetyNet_check_text);
mm.safetyNetDone.reset();
mm.updateCheckDone.reset();
mm.remoteMagiskVersionString = null;
mm.remoteMagiskVersionCode = -1;
collapse();
shownDialog = false;
// Trigger state check
if (Utils.checkNetworkStatus()) {
new CheckUpdates().exec();
} else {
mSwipeRefreshLayout.setRefreshing(false);
}
}
@Override
public void onTopicPublished(Topic topic) {
if (topic == mm.updateCheckDone) {
updateCheckUI();
} else if (topic == mm.safetyNetDone) {
updateSafetyNetUI((int) topic.getResults()[0]);
}
}
@Override
public Topic[] getSubscription() {
return new Topic[] { mm.updateCheckDone, mm.safetyNetDone };
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public Container getContainer() {
return expandableContainer;
}
private void updateUI() {
((MainActivity) getActivity()).checkHideSection();
boolean hasNetwork = Utils.checkNetworkStatus();
boolean hasRoot = Shell.rootAccess();
boolean isUpToDate = mm.magiskVersionCode > Const.MAGISK_VER.UNIFIED;
magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
safetyNetCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
installOptionCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
uninstallButton.setVisibility(isUpToDate && hasRoot ? View.VISIBLE : View.GONE);
int image, color;
if (mm.magiskVersionCode < 0) {
color = colorBad;
image = R.drawable.ic_cancel;
magiskVersionText.setText(R.string.magisk_version_error);
} else {
color = colorOK;
image = R.drawable.ic_check_circle;
magiskVersionText.setText(getString(R.string.current_magisk_title, "v" + mm.magiskVersionString));
}
magiskStatusIcon.setImageResource(image);
magiskStatusIcon.setColorFilter(color);
}
private void updateCheckUI() {
int image, color;
if (mm.remoteMagiskVersionCode < 0) {
color = colorNeutral;
image = R.drawable.ic_help;
magiskUpdateText.setText(R.string.invalid_update_channel);
installButton.setVisibility(View.GONE);
} else {
color = colorOK;
image = R.drawable.ic_check_circle;
magiskUpdateText.setText(getString(R.string.install_magisk_title, "v" + mm.remoteMagiskVersionString));
installButton.setVisibility(View.VISIBLE);
if (mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
installText.setText(getString(R.string.update, getString(R.string.app_name)));
} else if (mm.magiskVersionCode > 0 && mm.remoteMagiskVersionCode > mm.magiskVersionCode) {
installText.setText(getString(R.string.update, getString(R.string.magisk)));
} else {
installText.setText(R.string.install);
}
}
magiskUpdateIcon.setImageResource(image);
magiskUpdateIcon.setColorFilter(color);
magiskUpdateIcon.setVisibility(View.VISIBLE);
magiskUpdateProgress.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
if (!shownDialog) {
if (mm.remoteMagiskVersionCode > mm.magiskVersionCode
|| mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
install();
} else if (mm.remoteMagiskVersionCode >= Const.MAGISK_VER.FIX_ENV &&
!ShellUtils.fastCmdResult("env_check")) {
ShowUI.envFixDialog(getActivity());
}
}
}
private void updateSafetyNetUI(int response) {
safetyNetProgress.setVisibility(View.GONE);
safetyNetRefreshIcon.setVisibility(View.VISIBLE);
if ((response & 0x0F) == 0) {
safetyNetStatusText.setText(R.string.safetyNet_check_success);
boolean b;
b = (response & ISafetyNetHelper.CTS_PASS) != 0;
ctsStatusText.setText("ctsProfile: " + b);
ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
ctsStatusIcon.setColorFilter(b ? colorOK : colorBad);
b = (response & ISafetyNetHelper.BASIC_PASS) != 0;
basicStatusText.setText("basicIntegrity: " + b);
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
expand();
} else {
@StringRes int resid;
switch (response) {
case ISafetyNetHelper.CAUSE_SERVICE_DISCONNECTED:
resid = R.string.safetyNet_network_loss;
break;
case ISafetyNetHelper.CAUSE_NETWORK_LOST:
resid = R.string.safetyNet_service_disconnected;
break;
case ISafetyNetHelper.RESPONSE_ERR:
resid = R.string.safetyNet_res_invalid;
break;
case ISafetyNetHelper.CONNECTION_FAIL:
default:
resid = R.string.safetyNet_api_error;
break;
}
safetyNetStatusText.setText(resid);
}
}
}
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SearchView;
import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Topic;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
private Unbinder unbinder;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
private ApplicationAdapter appAdapter;
private SearchView.OnQueryTextListener searchListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false);
unbinder = ButterKnife.bind(this, view);
mSwipeRefreshLayout.setRefreshing(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> appAdapter.refresh());
appAdapter = new ApplicationAdapter();
recyclerView.setAdapter(appAdapter);
searchListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
appAdapter.filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
appAdapter.filter(newText);
return false;
}
};
getActivity().setTitle(R.string.magiskhide);
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_magiskhide, menu);
SearchView search = (SearchView) menu.findItem(R.id.app_search).getActionView();
search.setOnQueryTextListener(searchListener);
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onTopicPublished(Topic topic) {
mSwipeRefreshLayout.setRefreshing(false);
appAdapter.filter(null);
}
@Override
public Topic[] getSubscription() {
return new Topic[] { getApplication().magiskHideDone };
}
}
package com.topjohnwu.magisk;
import android.Manifest;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class MagiskLogFragment extends Fragment {
private Unbinder unbinder;
@BindView(R.id.txtLog) TextView txtLog;
@BindView(R.id.svLog) ScrollView svLog;
@BindView(R.id.hsvLog) HorizontalScrollView hsvLog;
@BindView(R.id.progressBar) ProgressBar progressBar;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_log, container, false);
unbinder = ButterKnife.bind(this, view);
setHasOptionsMenu(true);
txtLog.setTextIsSelectable(true);
return view;
}
@Override
public void onStart() {
super.onStart();
getActivity().setTitle(R.string.log);
}
@Override
public void onResume() {
super.onResume();
readLogs();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_log, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh:
readLogs();
return true;
case R.id.menu_save:
runWithPermission(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, this::saveLogs);
return true;
case R.id.menu_clear:
clearLogs();
return true;
default:
return true;
}
}
public void readLogs() {
Shell.Async.su(new Shell.Async.Callback() {
@Override
public void onTaskResult(@Nullable List<String> out, @Nullable List<String> err) {
progressBar.setVisibility(View.GONE);
if (ShellUtils.isValidOutput(out)) {
txtLog.setText(TextUtils.join("\n", out));
} else {
txtLog.setText(R.string.log_is_empty);
}
svLog.postDelayed(() -> svLog.fullScroll(ScrollView.FOCUS_DOWN), 100);
hsvLog.postDelayed(() -> hsvLog.fullScroll(ScrollView.FOCUS_LEFT), 100);
}
@Override
public void onTaskError(@NonNull Throwable throwable) {
txtLog.setText(R.string.log_is_empty);
}
}, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
}
public void saveLogs() {
Calendar now = Calendar.getInstance();
String filename = Utils.fmt("magisk_log_%04d%02d%02d_%02d%02d%02d.log",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
File targetFile = new File(Const.EXTERNAL_PATH + "/logs", filename);
targetFile.getParentFile().mkdirs();
try {
targetFile.createNewFile();
} catch (IOException e) {
return;
}
Shell.Async.su(new Shell.Async.Callback() {
@Override
public void onTaskResult(@Nullable List<String> out, @Nullable List<String> err) {
SnackbarMaker.make(txtLog, targetFile.getPath(), Snackbar.LENGTH_SHORT).show();
}
@Override
public void onTaskError(@NonNull Throwable throwable) {}
}, "cat " + Const.MAGISK_LOG + " > " + targetFile);
}
public void clearLogs() {
Shell.Async.su("echo -n > " + Const.MAGISK_LOG);
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
}
}
package com.topjohnwu.magisk;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Xml;
import com.topjohnwu.magisk.components.Application;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.magisk.utils.ShellInitializer;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import com.topjohnwu.superuser.io.SuFileInputStream;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class MagiskManager extends Application implements Shell.Container {
// Topics
public final Topic magiskHideDone = new Topic();
public final Topic reloadActivity = new Topic();
public final Topic moduleLoadDone = new Topic();
public final Topic repoLoadDone = new Topic();
public final Topic updateCheckDone = new Topic();
public final Topic safetyNetDone = new Topic();
public final Topic localeDone = new Topic();
// Info
public boolean hasInit = false;
public String magiskVersionString;
public int magiskVersionCode = -1;
public String remoteMagiskVersionString;
public int remoteMagiskVersionCode = -1;
public String remoteManagerVersionString;
public int remoteManagerVersionCode = -1;
public String magiskLink;
public String magiskNoteLink;
public String managerLink;
public String managerNoteLink;
public String uninstallerLink;
public boolean keepVerity = false;
public boolean keepEnc = false;
// Data
public Map<String, Module> moduleMap;
public List<Locale> locales;
public boolean magiskHide;
public boolean isDarkTheme;
public int suRequestTimeout;
public int suLogTimeout = 14;
public int suAccessState;
public int multiuserMode;
public int suResponseType;
public int suNotificationType;
public int suNamespaceMode;
public String localeConfig;
public int updateChannel;
public String bootFormat;
public int repoOrder;
// Global resources
public SharedPreferences prefs;
public MagiskDatabaseHelper mDB;
public RepoDatabaseHelper repoDB;
private volatile Shell mShell;
public MagiskManager() {
weakSelf = new WeakReference<>(this);
Shell.setContainer(this);
}
@Nullable
@Override
public Shell getShell() {
return mShell;
}
@Override
public void setShell(@Nullable Shell shell) {
mShell = shell;
}
@Override
public void onCreate() {
super.onCreate();
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
Shell.verboseLogging(BuildConfig.DEBUG);
Shell.setInitializer(ShellInitializer.class);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
mDB = MagiskDatabaseHelper.getInstance(this);
String pkg = mDB.getStrings(Const.Key.SU_MANAGER, null);
if (pkg != null && getPackageName().equals(Const.ORIG_PKG_NAME)) {
mDB.setStrings(Const.Key.SU_MANAGER, null);
RootUtils.uninstallPkg(pkg);
}
if (TextUtils.equals(pkg, getPackageName())) {
try {
// We are the manager, remove com.topjohnwu.magisk as it could be malware
getPackageManager().getApplicationInfo(Const.ORIG_PKG_NAME, 0);
RootUtils.uninstallPkg(Const.ORIG_PKG_NAME);
} catch (PackageManager.NameNotFoundException ignored) {}
}
setLocale();
loadConfig();
}
public static MagiskManager get() {
return (MagiskManager) weakSelf.get();
}
public void setLocale() {
localeConfig = prefs.getString(Const.Key.LOCALE, "");
if (localeConfig.isEmpty()) {
locale = defaultLocale;
} else {
locale = Locale.forLanguageTag(localeConfig);
}
Resources res = getBaseContext().getResources();
Configuration config = new Configuration(res.getConfiguration());
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
public void loadConfig() {
// su
suRequestTimeout = Utils.getPrefsInt(prefs, Const.Key.SU_REQUEST_TIMEOUT, Const.Value.timeoutList[2]);
suResponseType = Utils.getPrefsInt(prefs, Const.Key.SU_AUTO_RESPONSE, Const.Value.SU_PROMPT);
suNotificationType = Utils.getPrefsInt(prefs, Const.Key.SU_NOTIFICATION, Const.Value.NOTIFICATION_TOAST);
suAccessState = mDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB);
multiuserMode = mDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY);
suNamespaceMode = mDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER);
// config
isDarkTheme = prefs.getBoolean(Const.Key.DARK_THEME, false);
updateChannel = Utils.getPrefsInt(prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL);
bootFormat = prefs.getString(Const.Key.BOOT_FORMAT, ".img");
repoOrder = prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_NAME);
}
public void writeConfig() {
prefs.edit()
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE.exists())
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
.putString(Const.Key.ROOT_ACCESS, String.valueOf(suAccessState))
.putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(multiuserMode))
.putString(Const.Key.SU_MNT_NS, String.valueOf(suNamespaceMode))
.putString(Const.Key.UPDATE_CHANNEL, String.valueOf(updateChannel))
.putString(Const.Key.LOCALE, localeConfig)
.putString(Const.Key.BOOT_FORMAT, bootFormat)
.putInt(Const.Key.UPDATE_SERVICE_VER, Const.UPDATE_SERVICE_VER)
.putInt(Const.Key.REPO_ORDER, repoOrder)
.apply();
}
public void loadMagiskInfo() {
try {
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
String s = ShellUtils.fastCmd((magiskVersionCode >= Const.MAGISK_VER.RESETPROP_PERSIST ?
"resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
magiskHide = s == null || Integer.parseInt(s) != 0;
} catch (Exception ignored) {}
}
public void getDefaultInstallFlags() {
keepVerity = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPVERITY"));
keepEnc = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPFORCEENCRYPT"));
}
public void setupUpdateCheck() {
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
if (prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
if (scheduler.getAllPendingJobs().isEmpty() ||
Const.UPDATE_SERVICE_VER > prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
ComponentName service = new ComponentName(this, UpdateCheckService.class);
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setPeriodic(8 * 60 * 60 * 1000)
.build();
scheduler.schedule(info);
}
} else {
scheduler.cancel(Const.UPDATE_SERVICE_VER);
}
}
public void dumpPrefs() {
// Flush prefs to disk
prefs.edit().commit();
File xml = new File(getFilesDir().getParent() + "/shared_prefs",
getPackageName() + "_preferences.xml");
Shell.Sync.su(Utils.fmt("for usr in /data/user/*; do cat %s > ${usr}/%s; done", xml, Const.MANAGER_CONFIGS));
}
public void loadPrefs() {
SuFile config = new SuFile(Utils.fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS));
if (config.exists()) {
SharedPreferences.Editor editor = prefs.edit();
try {
SuFileInputStream is = new SuFileInputStream(config);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, "UTF-8");
parser.nextTag();
parser.require(XmlPullParser.START_TAG, null, "map");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG)
continue;
String key = parser.getAttributeValue(null, "name");
String value = parser.getAttributeValue(null, "value");
switch (parser.getName()) {
case "string":
parser.require(XmlPullParser.START_TAG, null, "string");
editor.putString(key, parser.nextText());
parser.require(XmlPullParser.END_TAG, null, "string");
break;
case "boolean":
parser.require(XmlPullParser.START_TAG, null, "boolean");
editor.putBoolean(key, Boolean.parseBoolean(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "boolean");
break;
case "int":
parser.require(XmlPullParser.START_TAG, null, "int");
editor.putInt(key, Integer.parseInt(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "int");
break;
case "long":
parser.require(XmlPullParser.START_TAG, null, "long");
editor.putLong(key, Long.parseLong(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "long");
break;
case "float":
parser.require(XmlPullParser.START_TAG, null, "int");
editor.putFloat(key, Float.parseFloat(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "int");
break;
default:
parser.next();
}
}
} catch (IOException | XmlPullParserException e) {
e.printStackTrace();
}
editor.remove(Const.Key.ETAG_KEY);
editor.apply();
loadConfig();
config.delete();
}
}
}
package com.topjohnwu.magisk;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import butterknife.BindView;
import butterknife.ButterKnife;
public class MainActivity extends Activity
implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber {
private final Handler mDrawerHandler = new Handler();
private int mDrawerItem;
private boolean fromShortcut = true;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.drawer_layout) DrawerLayout drawer;
@BindView(R.id.nav_view) public NavigationView navigationView;
private float toolbarElevation;
@Override
public int getDarkTheme() {
return R.style.AppTheme_Dark;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
MagiskManager mm = getMagiskManager();
if (!mm.hasInit) {
Intent intent = new Intent(this, SplashActivity.class);
String section = getIntent().getStringExtra(Const.Key.OPEN_SECTION);
if (section != null) {
intent.putExtra(Const.Key.OPEN_SECTION, section);
}
startActivity(intent);
finish();
}
String perm = getIntent().getStringExtra(Const.Key.INTENT_PERM);
if (perm != null) {
ActivityCompat.requestPermissions(this, new String[] { perm }, 0);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.magisk, R.string.magisk) {
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
super.onDrawerSlide(drawerView, 0); // this disables the arrow @ completed tate
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, 0); // this disables the animation
}
};
toolbarElevation = toolbar.getElevation();
drawer.addDrawerListener(toggle);
toggle.syncState();
if (savedInstanceState == null)
navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION));
navigationView.setNavigationItemSelectedListener(this);
}
@Override
protected void onResume() {
super.onResume();
checkHideSection();
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(navigationView)) {
drawer.closeDrawer(navigationView);
} else if (mDrawerItem != R.id.magisk && !fromShortcut) {
navigate(R.id.magisk);
} else {
finish();
}
}
@Override
public boolean onNavigationItemSelected(@NonNull final MenuItem menuItem) {
mDrawerHandler.removeCallbacksAndMessages(null);
mDrawerHandler.postDelayed(() -> navigate(menuItem.getItemId()), 250);
drawer.closeDrawer(navigationView);
return true;
}
@Override
public void onTopicPublished(Topic topic) {
recreate();
}
@Override
public Topic[] getSubscription() {
return new Topic[] { getMagiskManager().reloadActivity };
}
public void checkHideSection() {
MagiskManager mm = getMagiskManager();
Menu menu = navigationView.getMenu();
menu.findItem(R.id.magiskhide).setVisible(
Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false));
menu.findItem(R.id.modules).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
Shell.rootAccess() && mm.magiskVersionCode >= 0);
menu.findItem(R.id.downloads).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false)
&& Utils.checkNetworkStatus() && Shell.rootAccess() && mm.magiskVersionCode >= 0);
menu.findItem(R.id.log).setVisible(Shell.rootAccess());
menu.findItem(R.id.superuser).setVisible(Shell.rootAccess() &&
!(Const.USER_ID > 0 && mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED));
}
public void navigate(String item) {
int itemId = R.id.magisk;
if (item != null) {
switch (item) {
case "superuser":
itemId = R.id.superuser;
break;
case "modules":
itemId = R.id.modules;
break;
case "downloads":
itemId = R.id.downloads;
break;
case "magiskhide":
itemId = R.id.magiskhide;
break;
case "log":
itemId = R.id.log;
break;
case "settings":
itemId = R.id.settings;
break;
case "about":
itemId = R.id.app_about;
break;
}
}
navigate(itemId);
}
public void navigate(int itemId) {
int bak = mDrawerItem;
mDrawerItem = itemId;
navigationView.setCheckedItem(itemId);
switch (itemId) {
case R.id.magisk:
fromShortcut = false;
displayFragment(new MagiskFragment(), true);
break;
case R.id.superuser:
displayFragment(new SuperuserFragment(), true);
break;
case R.id.modules:
displayFragment(new ModulesFragment(), true);
break;
case R.id.downloads:
displayFragment(new ReposFragment(), true);
break;
case R.id.magiskhide:
displayFragment(new MagiskHideFragment(), true);
break;
case R.id.log:
displayFragment(new LogFragment(), false);
break;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
mDrawerItem = bak;
break;
case R.id.app_about:
startActivity(new Intent(this, AboutActivity.class));
mDrawerItem = bak;
break;
}
}
private void displayFragment(@NonNull Fragment navFragment, boolean setElevation) {
supportInvalidateOptionsMenu();
getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.content_frame, navFragment)
.commitNow();
toolbar.setElevation(setElevation ? toolbarElevation : 0);
}
}
package com.topjohnwu.magisk;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.ModulesAdapter;
import com.topjohnwu.magisk.asyncs.LoadModules;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class ModulesFragment extends Fragment implements Topic.Subscriber {
private Unbinder unbinder;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@OnClick(R.id.fab)
public void selectFile() {
runWithPermission(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/zip");
startActivityForResult(intent, Const.ID.FETCH_ZIP);
});
}
private List<Module> listModules = new ArrayList<>();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_modules, container, false);
unbinder = ButterKnife.bind(this, view);
setHasOptionsMenu(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE);
new LoadModules().exec();
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
mSwipeRefreshLayout.setEnabled(recyclerView.getChildAt(0).getTop() >= 0);
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
getActivity().setTitle(R.string.modules);
return view;
}
@Override
public void onTopicPublished(Topic topic) {
updateUI();
}
@Override
public Topic[] getSubscription() {
return new Topic[] { getApplication().moduleLoadDone };
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) {
// Get the URI of the selected file
Intent intent = new Intent(getActivity(), FlashActivity.class);
intent.setData(data.getData()).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
startActivity(intent);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_reboot, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.reboot:
Shell.Async.su("/system/bin/reboot");
return true;
case R.id.reboot_recovery:
Shell.Async.su("/system/bin/reboot recovery");
return true;
case R.id.reboot_bootloader:
Shell.Async.su("/system/bin/reboot bootloader");
return true;
case R.id.reboot_download:
Shell.Async.su("/system/bin/reboot download");
return true;
default:
return false;
}
}
private void updateUI() {
listModules.clear();
listModules.addAll(getApplication().moduleMap.values());
if (listModules.size() == 0) {
emptyRv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
emptyRv.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
recyclerView.setAdapter(new ModulesAdapter(listModules));
}
mSwipeRefreshLayout.setRefreshing(false);
}
}
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
public class NoUIActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] perms = getIntent().getStringArrayExtra(Const.Key.INTENT_PERM);
if (perms != null) {
ActivityCompat.requestPermissions(this, perms, 0);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
finish();
}
}
package com.topjohnwu.magisk;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SearchView;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class ReposFragment extends Fragment implements Topic.Subscriber {
private Unbinder unbinder;
private MagiskManager mm;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
public static ReposAdapter adapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_repos, container, false);
unbinder = ButterKnife.bind(this, view);
mm = getApplication();
mSwipeRefreshLayout.setRefreshing(mm.repoLoadDone.isPending());
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.VISIBLE);
emptyRv.setVisibility(View.GONE);
new UpdateRepos(true).exec();
});
getActivity().setTitle(R.string.downloads);
return view;
}
@Override
public void onResume() {
adapter = new ReposAdapter(mm.repoDB, mm.moduleMap);
recyclerView.setAdapter(adapter);
super.onResume();
}
@Override
public void onPause() {
super.onPause();
adapter = null;
}
@Override
public void onTopicPublished(Topic topic) {
mSwipeRefreshLayout.setRefreshing(false);
recyclerView.setVisibility(adapter.getItemCount() == 0 ? View.GONE : View.VISIBLE);
emptyRv.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
@Override
public Topic[] getSubscription() {
return new Topic[] { mm.repoLoadDone };
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_repo, menu);
SearchView search = (SearchView) menu.findItem(R.id.repo_search).getActionView();
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.filter(newText);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.repo_sort) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.sorting_order)
.setSingleChoiceItems(R.array.sorting_orders, mm.repoOrder, (d, which) -> {
mm.repoOrder = which;
mm.prefs.edit().putInt(Const.Key.REPO_ORDER, mm.repoOrder).apply();
adapter.notifyDBChanged();
d.dismiss();
}).show();
}
return true;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
package com.topjohnwu.magisk;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.asyncs.HideManager;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.IOException;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SettingsActivity extends Activity implements Topic.Subscriber {
@BindView(R.id.toolbar) Toolbar toolbar;
@Override
public int getDarkTheme() {
return R.style.AppTheme_StatusBar_Dark;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.settings);
ab.setDisplayHomeAsUpEnabled(true);
}
setFloating();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, new SettingsFragment()).commit();
}
}
@Override
public void onTopicPublished(Topic topic) {
recreate();
}
@Override
public Topic[] getSubscription() {
return new Topic[] { getMagiskManager().reloadActivity };
}
public static class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener, Topic.Subscriber {
private SharedPreferences prefs;
private PreferenceScreen prefScreen;
private ListPreference updateChannel, suAccess, autoRes, suNotification,
requestTimeout, multiuserMode, namespaceMode;
private MagiskManager mm;
private PreferenceCategory generalCatagory;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.app_settings, rootKey);
mm = Utils.getMagiskManager(getActivity());
prefs = mm.prefs;
prefScreen = getPreferenceScreen();
generalCatagory = (PreferenceCategory) findPreference("general");
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
Preference hideManager = findPreference("hide");
Preference restoreManager = findPreference("restore");
findPreference("clear").setOnPreferenceClickListener((pref) -> {
prefs.edit().remove(Const.Key.ETAG_KEY).apply();
mm.repoDB.clearRepo();
MagiskManager.toast(R.string.repo_cache_cleared, Toast.LENGTH_SHORT);
return true;
});
updateChannel = (ListPreference) findPreference(Const.Key.UPDATE_CHANNEL);
suAccess = (ListPreference) findPreference(Const.Key.ROOT_ACCESS);
autoRes = (ListPreference) findPreference(Const.Key.SU_AUTO_RESPONSE);
requestTimeout = (ListPreference) findPreference(Const.Key.SU_REQUEST_TIMEOUT);
suNotification = (ListPreference) findPreference(Const.Key.SU_NOTIFICATION);
multiuserMode = (ListPreference) findPreference(Const.Key.SU_MULTIUSER_MODE);
namespaceMode = (ListPreference) findPreference(Const.Key.SU_MNT_NS);
SwitchPreference reauth = (SwitchPreference) findPreference(Const.Key.SU_REAUTH);
SwitchPreference fingerprint = (SwitchPreference) findPreference(Const.Key.SU_FINGERPRINT);
updateChannel.setOnPreferenceChangeListener((pref, o) -> {
mm.updateChannel = Integer.parseInt((String) o);
if (mm.updateChannel == Const.Value.CUSTOM_CHANNEL) {
View v = LayoutInflater.from(getActivity()).inflate(R.layout.custom_channel_dialog, null);
EditText url = v.findViewById(R.id.custom_url);
url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
new AlertDialog.Builder(getActivity())
.setTitle(R.string.settings_update_custom)
.setView(v)
.setPositiveButton(R.string.ok, (d, i) ->
prefs.edit().putString(Const.Key.CUSTOM_CHANNEL,
url.getText().toString()).apply())
.setNegativeButton(R.string.close, null)
.show();
}
return true;
});
setSummary();
// Disable dangerous settings in secondary user
if (Const.USER_ID > 0) {
suCategory.removePreference(multiuserMode);
}
// Disable re-authentication option on Android O, it will not work
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
reauth.setEnabled(false);
reauth.setSummary(R.string.android_o_not_support);
}
// Disable fingerprint option if not possible
if (!FingerprintHelper.canUseFingerprint()) {
fingerprint.setEnabled(false);
fingerprint.setSummary(R.string.disable_fingerprint);
}
if (mm.magiskVersionCode >= Const.MAGISK_VER.MANAGER_HIDE) {
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
hideManager.setOnPreferenceClickListener((pref) -> {
new HideManager(getActivity()).exec();
return true;
});
generalCatagory.removePreference(restoreManager);
} else {
if (Utils.checkNetworkStatus()) {
restoreManager.setOnPreferenceClickListener((pref) -> {
Utils.dlAndReceive(
getActivity(), new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
mm.dumpPrefs();
if (ShellUtils.fastCmdResult("pm install " + uri.getPath()))
RootUtils.uninstallPkg(context.getPackageName());
}
},
mm.managerLink,
Utils.fmt("MagiskManager-v%s.apk", mm.remoteManagerVersionString)
);
return true;
});
} else {
generalCatagory.removePreference(restoreManager);
}
generalCatagory.removePreference(hideManager);
}
} else {
generalCatagory.removePreference(restoreManager);
generalCatagory.removePreference(hideManager);
}
if (!Shell.rootAccess() || (Const.USER_ID > 0 &&
mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
prefScreen.removePreference(suCategory);
}
if (!Shell.rootAccess()) {
prefScreen.removePreference(magiskCategory);
generalCatagory.removePreference(hideManager);
} else if (mm.magiskVersionCode < Const.MAGISK_VER.UNIFIED) {
prefScreen.removePreference(magiskCategory);
}
}
private void setLocalePreference(ListPreference lp) {
CharSequence[] entries = new CharSequence[mm.locales.size() + 1];
CharSequence[] entryValues = new CharSequence[mm.locales.size() + 1];
entries[0] = Utils.getLocaleString(MagiskManager.defaultLocale, R.string.system_default);
entryValues[0] = "";
int i = 1;
for (Locale locale : mm.locales) {
entries[i] = locale.getDisplayName(locale);
entryValues[i++] = locale.toLanguageTag();
}
lp.setEntries(entries);
lp.setEntryValues(entryValues);
lp.setSummary(MagiskManager.locale.getDisplayName(MagiskManager.locale));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
prefs.registerOnSharedPreferenceChangeListener(this);
subscribeTopics();
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onDestroyView() {
prefs.unregisterOnSharedPreferenceChangeListener(this);
unsubscribeTopics();
super.onDestroyView();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
switch (key) {
case Const.Key.DARK_THEME:
mm.isDarkTheme = prefs.getBoolean(key, false);
mm.reloadActivity.publish(false);
return;
case Const.Key.COREONLY:
if (prefs.getBoolean(key, false)) {
try {
Const.MAGISK_DISABLE_FILE.createNewFile();
} catch (IOException ignored) {}
} else {
Const.MAGISK_DISABLE_FILE.delete();
}
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
break;
case Const.Key.MAGISKHIDE:
if (prefs.getBoolean(key, false)) {
Shell.Async.su("magiskhide --enable");
} else {
Shell.Async.su("magiskhide --disable");
}
break;
case Const.Key.HOSTS:
if (prefs.getBoolean(key, false)) {
Shell.Async.su(
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE,
"mount -o bind " + Const.MAGISK_HOST_FILE + " /system/etc/hosts");
} else {
Shell.Async.su(
"umount -l /system/etc/hosts",
"rm -f " + Const.MAGISK_HOST_FILE);
}
break;
case Const.Key.ROOT_ACCESS:
case Const.Key.SU_MULTIUSER_MODE:
case Const.Key.SU_MNT_NS:
mm.mDB.setSettings(key, Utils.getPrefsInt(prefs, key));
break;
case Const.Key.LOCALE:
mm.setLocale();
mm.reloadActivity.publish(false);
break;
case Const.Key.UPDATE_CHANNEL:
new CheckUpdates().exec();
break;
case Const.Key.CHECK_UPDATES:
mm.setupUpdateCheck();
break;
}
mm.loadConfig();
setSummary();
}
private void setSummary() {
updateChannel.setSummary(getResources()
.getStringArray(R.array.update_channel)[mm.updateChannel]);
suAccess.setSummary(getResources()
.getStringArray(R.array.su_access)[mm.suAccessState]);
autoRes.setSummary(getResources()
.getStringArray(R.array.auto_response)[mm.suResponseType]);
suNotification.setSummary(getResources()
.getStringArray(R.array.su_notification)[mm.suNotificationType]);
requestTimeout.setSummary(
getString(R.string.request_timeout_summary, prefs.getString(Const.Key.SU_REQUEST_TIMEOUT, "10")));
multiuserMode.setSummary(getResources()
.getStringArray(R.array.multiuser_summary)[mm.multiuserMode]);
namespaceMode.setSummary(getResources()
.getStringArray(R.array.namespace_summary)[mm.suNamespaceMode]);
}
@Override
public void onTopicPublished(Topic topic) {
setLocalePreference((ListPreference) findPreference(Const.Key.LOCALE));
}
@Override
public Topic[] getSubscription() {
return new Topic[] { mm.localeDone };
}
}
}
package com.topjohnwu.magisk;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.asyncs.LoadModules;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RootUtils.init();
MagiskManager mm = getMagiskManager();
mm.repoDB = new RepoDatabaseHelper(this);
mm.loadMagiskInfo();
mm.getDefaultInstallFlags();
mm.loadPrefs();
// Dynamic detect all locales
new LoadLocale().exec();
// Create notification channel on Android O
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(Const.ID.NOTIFICATION_CHANNEL,
getString(R.string.magisk_updates), NotificationManager.IMPORTANCE_DEFAULT);
getSystemService(NotificationManager.class).createNotificationChannel(channel);
}
// Setup shortcuts
sendBroadcast(new Intent(this, ShortcutReceiver.class));
LoadModules loadModuleTask = new LoadModules();
if (Utils.checkNetworkStatus()) {
// Fire update check
new CheckUpdates().exec();
// Add repo update check
loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec());
}
// Magisk working as expected
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
// Update check service
mm.setupUpdateCheck();
// Fire asynctasks
loadModuleTask.exec();
}
// Write back default values
mm.writeConfig();
mm.hasInit = true;
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(Const.Key.OPEN_SECTION, getIntent().getStringExtra(Const.Key.OPEN_SECTION));
intent.putExtra(Const.Key.INTENT_PERM, getIntent().getStringExtra(Const.Key.INTENT_PERM));
startActivity(intent);
finish();
}
static class LoadLocale extends ParallelTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
MagiskManager.get().locales = Utils.getAvailableLocale();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
MagiskManager.get().localeDone.publish();
}
}
}
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.SuLogAdapter;
import com.topjohnwu.magisk.components.Fragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class SuLogFragment extends Fragment {
@BindView(R.id.empty_rv) TextView emptyRv;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
private Unbinder unbinder;
private MagiskManager mm;
private SuLogAdapter adapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_log, menu);
menu.findItem(R.id.menu_save).setVisible(false);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_su_log, container, false);
unbinder = ButterKnife.bind(this, v);
mm = getApplication();
adapter = new SuLogAdapter(mm.mDB);
recyclerView.setAdapter(adapter);
updateList();
return v;
}
private void updateList() {
adapter.notifyDBChanged();
if (adapter.getSectionCount() == 0) {
emptyRv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
emptyRv.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh:
updateList();
return true;
case R.id.menu_clear:
mm.mDB.clearLogs();
updateList();
return true;
default:
return true;
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
package com.topjohnwu.magisk;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.PolicyAdapter;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.container.Policy;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class SuperuserFragment extends Fragment {
private Unbinder unbinder;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_superuser, container, false);
unbinder = ButterKnife.bind(this, view);
PackageManager pm = getActivity().getPackageManager();
MagiskManager mm = getApplication();
List<Policy> policyList = mm.mDB.getPolicyList(pm);
if (policyList.size() == 0) {
emptyRv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
recyclerView.setAdapter(new PolicyAdapter(policyList, mm.mDB, pm));
emptyRv.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
return view;
}
@Override
public void onStart() {
super.onStart();
getActivity().setTitle(getString(R.string.superuser));
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
package com.topjohnwu.magisk.adapters;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
private List<ApplicationInfo> fullList, showList;
private List<String> hideList;
private PackageManager pm;
private ApplicationFilter filter;
public ApplicationAdapter() {
fullList = showList = Collections.emptyList();
hideList = Collections.emptyList();
filter = new ApplicationFilter();
pm = MagiskManager.get().getPackageManager();
new LoadApps().exec();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
return new ViewHolder(mView);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
ApplicationInfo info = showList.get(position);
holder.appIcon.setImageDrawable(info.loadIcon(pm));
holder.appName.setText(info.loadLabel(pm));
holder.appPackage.setText(info.packageName);
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(hideList.contains(info.packageName));
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
if (isChecked) {
Shell.Async.su("magiskhide --add " + info.packageName);
hideList.add(info.packageName);
} else {
Shell.Async.su("magiskhide --rm " + info.packageName);
hideList.remove(info.packageName);
}
});
}
@Override
public int getItemCount() {
return showList.size();
}
public void filter(String constraint) {
filter.filter(constraint);
}
public void refresh() {
new LoadApps().exec();
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.package_name) TextView appPackage;
@BindView(R.id.checkbox) CheckBox checkBox;
ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
private class ApplicationFilter extends Filter {
private boolean lowercaseContains(String s, CharSequence filter) {
return !TextUtils.isEmpty(s) && s.toLowerCase().contains(filter);
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint == null || constraint.length() == 0) {
showList = fullList;
} else {
showList = new ArrayList<>();
String filter = constraint.toString().toLowerCase();
for (ApplicationInfo info : fullList) {
if (lowercaseContains(info.loadLabel(pm).toString(), filter)
|| lowercaseContains(info.packageName, filter)) {
showList.add(info);
}
}
}
return null;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notifyDataSetChanged();
}
}
private class LoadApps extends ParallelTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
fullList = pm.getInstalledApplications(0);
hideList = Shell.Sync.su("magiskhide --ls");
for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
i.remove();
}
}
Collections.sort(fullList, (a, b) -> {
boolean ah = hideList.contains(a.packageName);
boolean bh = hideList.contains(b.packageName);
if (ah == bh) {
return a.loadLabel(pm).toString().toLowerCase().compareTo(
b.loadLabel(pm).toString().toLowerCase());
} else if (ah) {
return -1;
} else {
return 1;
}
});
return null;
}
@Override
protected void onPostExecute(Void v) {
MagiskManager.get().magiskHideDone.publish(false);
}
}
}
package com.topjohnwu.magisk.adapters;
import android.content.Context;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.superuser.Shell;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHolder> {
private final List<Module> mList;
public ModulesAdapter(List<Module> list) {
mList = list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Context context = holder.itemView.getContext();
final Module module = mList.get(position);
String version = module.getVersion();
String author = module.getAuthor();
String description = module.getDescription();
String noInfo = context.getString(R.string.no_info_provided);
holder.title.setText(module.getName());
holder.versionName.setText( TextUtils.isEmpty(version) ? noInfo : version);
holder.author.setText( TextUtils.isEmpty(author) ? noInfo : context.getString(R.string.author, author));
holder.description.setText( TextUtils.isEmpty(description) ? noInfo : description);
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(module.isEnabled());
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
int snack;
if (isChecked) {
module.removeDisableFile();
snack = R.string.disable_file_removed;
} else {
module.createDisableFile();
snack = R.string.disable_file_created;
}
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
});
holder.delete.setOnClickListener(v -> {
boolean removed = module.willBeRemoved();
int snack;
if (removed) {
module.deleteRemoveFile();
snack = R.string.remove_file_deleted;
} else {
module.createRemoveFile();
snack = R.string.remove_file_created;
}
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
updateDeleteButton(holder, module);
});
if (module.isUpdated()) {
holder.notice.setVisibility(View.VISIBLE);
holder.notice.setText(R.string.update_file_created);
holder.delete.setEnabled(false);
} else {
updateDeleteButton(holder, module);
}
}
private void updateDeleteButton(ViewHolder holder, Module module) {
holder.notice.setVisibility(module.willBeRemoved() ? View.VISIBLE : View.GONE);
if (module.willBeRemoved()) {
holder.delete.setImageResource(R.drawable.ic_undelete);
} else {
holder.delete.setImageResource(R.drawable.ic_delete);
}
}
@Override
public int getItemCount() {
return mList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title;
@BindView(R.id.version_name) TextView versionName;
@BindView(R.id.description) TextView description;
@BindView(R.id.notice) TextView notice;
@BindView(R.id.checkbox) CheckBox checkBox;
@BindView(R.id.author) TextView author;
@BindView(R.id.delete) ImageView delete;
ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (!Shell.rootAccess()) {
checkBox.setEnabled(false);
delete.setEnabled(false);
}
}
}
}
package com.topjohnwu.magisk.adapters;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import butterknife.BindView;
import butterknife.ButterKnife;
public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> {
private List<Policy> policyList;
private MagiskDatabaseHelper dbHelper;
private PackageManager pm;
private Set<Policy> expandList = new HashSet<>();
public PolicyAdapter(List<Policy> list, MagiskDatabaseHelper db, PackageManager pm) {
policyList = list;
dbHelper = db;
this.pm = pm;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_policy, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Policy policy = policyList.get(position);
holder.setExpanded(expandList.contains(policy));
holder.itemView.setOnClickListener(view -> {
if (holder.isExpanded()) {
holder.collapse();
expandList.remove(policy);
} else {
holder.expand();
expandList.add(policy);
}
});
holder.appName.setText(policy.appName);
holder.packageName.setText(policy.packageName);
holder.appIcon.setImageDrawable(policy.info.loadIcon(pm));
holder.masterSwitch.setOnCheckedChangeListener((v, isChecked) -> {
if ((isChecked && policy.policy == Policy.DENY) ||
(!isChecked && policy.policy == Policy.ALLOW)) {
policy.policy = isChecked ? Policy.ALLOW : Policy.DENY;
String message = v.getContext().getString(
isChecked ? R.string.su_snack_grant : R.string.su_snack_deny, policy.appName);
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
dbHelper.updatePolicy(policy);
}
});
holder.notificationSwitch.setOnCheckedChangeListener((v, isChecked) -> {
if ((isChecked && !policy.notification) ||
(!isChecked && policy.notification)) {
policy.notification = isChecked;
String message = v.getContext().getString(
isChecked ? R.string.su_snack_notif_on : R.string.su_snack_notif_off, policy.appName);
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
dbHelper.updatePolicy(policy);
}
});
holder.loggingSwitch.setOnCheckedChangeListener((v, isChecked) -> {
if ((isChecked && !policy.logging) ||
(!isChecked && policy.logging)) {
policy.logging = isChecked;
String message = v.getContext().getString(
isChecked ? R.string.su_snack_log_on : R.string.su_snack_log_off, policy.appName);
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
dbHelper.updatePolicy(policy);
}
});
holder.delete.setOnClickListener(v -> new AlertDialogBuilder((Activity) v.getContext())
.setTitle(R.string.su_revoke_title)
.setMessage(v.getContext().getString(R.string.su_revoke_msg, policy.appName))
.setPositiveButton(R.string.yes, (dialog, which) -> {
policyList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, policyList.size());
SnackbarMaker.make(holder.itemView, v.getContext().getString(R.string.su_snack_revoke, policy.appName),
Snackbar.LENGTH_SHORT).show();
dbHelper.deletePolicy(policy);
})
.setNegativeButton(R.string.no_thanks, null)
.setCancelable(true)
.show());
holder.masterSwitch.setChecked(policy.policy == Policy.ALLOW);
holder.notificationSwitch.setChecked(policy.notification);
holder.loggingSwitch.setChecked(policy.logging);
// Hide for now
holder.moreInfo.setVisibility(View.GONE);
}
@Override
public int getItemCount() {
return policyList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.package_name) TextView packageName;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.master_switch) Switch masterSwitch;
@BindView(R.id.notification_switch) Switch notificationSwitch;
@BindView(R.id.logging_switch) Switch loggingSwitch;
@BindView(R.id.expand_layout) ViewGroup expandLayout;
@BindView(R.id.delete) ImageView delete;
@BindView(R.id.more_info) ImageView moreInfo;
private Container container = new Container();
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
container.expandLayout = expandLayout;
setupExpandable();
}
@Override
public Container getContainer() {
return container;
}
}
}
package com.topjohnwu.magisk.adapters;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.container.Repo;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.utils.Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, ReposAdapter.RepoHolder> {
private static final int UPDATES = 0;
private static final int INSTALLED = 1;
private static final int OTHERS = 2;
private Cursor repoCursor = null;
private Map<String, Module> moduleMap;
private RepoDatabaseHelper repoDB;
private List<Pair<Integer, List<Repo>>> repoPairs;
public ReposAdapter(RepoDatabaseHelper db, Map<String, Module> map) {
repoDB = db;
moduleMap = map;
repoPairs = new ArrayList<>();
notifyDBChanged();
}
@Override
public int getSectionCount() {
return repoPairs.size();
}
@Override
public int getItemCount(int section) {
return repoPairs.get(section).second.size();
}
@Override
public SectionHolder onCreateSectionViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.section, parent, false);
return new SectionHolder(v);
}
@Override
public RepoHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false);
return new RepoHolder(v);
}
@Override
public void onBindSectionViewHolder(SectionHolder holder, int section) {
switch (repoPairs.get(section).first) {
case UPDATES:
holder.sectionText.setText(R.string.update_available);
break;
case INSTALLED:
holder.sectionText.setText(R.string.installed);
break;
case OTHERS:
holder.sectionText.setText(R.string.not_installed);
break;
}
}
@Override
public void onBindItemViewHolder(RepoHolder holder, int section, int position) {
Repo repo = repoPairs.get(section).second.get(position);
Context context = holder.itemView.getContext();
holder.title.setText(repo.getName());
holder.versionName.setText(repo.getVersion());
String author = repo.getAuthor();
holder.author.setText(TextUtils.isEmpty(author) ? null : context.getString(R.string.author, author));
holder.description.setText(repo.getDescription());
holder.updateTime.setText(context.getString(R.string.updated_on, repo.getLastUpdateString()));
holder.infoLayout.setOnClickListener(v ->
new MarkDownWindow((Activity) context, null, repo.getDetailUrl()).exec());
holder.downloadImage.setOnClickListener(v -> {
String filename = repo.getName() + "-" + repo.getVersion() + ".zip";
new AlertDialogBuilder((Activity) context)
.setTitle(context.getString(R.string.repo_install_title, repo.getName()))
.setMessage(context.getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (d, i) ->
new ProcessRepoZip((Activity) context, repo.getZipUrl(),
Utils.getLegalFilename(filename), true).exec()
)
.setNeutralButton(R.string.download, (d, i) ->
new ProcessRepoZip((Activity) context, repo.getZipUrl(),
Utils.getLegalFilename(filename), false).exec())
.setNegativeButton(R.string.no_thanks, null)
.show();
});
}
public void notifyDBChanged() {
if (repoCursor != null)
repoCursor.close();
repoCursor = repoDB.getRepoCursor();
filter("");
}
public void filter(String s) {
List<Repo> updates = new ArrayList<>();
List<Repo> installed = new ArrayList<>();
List<Repo> others = new ArrayList<>();
repoPairs.clear();
while (repoCursor.moveToNext()) {
Repo repo = new Repo(repoCursor);
if (repo.getName().toLowerCase().contains(s.toLowerCase())
|| repo.getAuthor().toLowerCase().contains(s.toLowerCase())
|| repo.getDescription().toLowerCase().contains(s.toLowerCase())
) {
// Passed the repoFilter
Module module = moduleMap.get(repo.getId());
if (module != null) {
if (repo.getVersionCode() > module.getVersionCode()) {
// Updates
updates.add(repo);
} else {
installed.add(repo);
}
} else {
others.add(repo);
}
}
}
repoCursor.moveToFirst();
if (!updates.isEmpty())
repoPairs.add(new Pair<>(UPDATES, updates));
if (!installed.isEmpty())
repoPairs.add(new Pair<>(INSTALLED, installed));
if (!others.isEmpty())
repoPairs.add(new Pair<>(OTHERS, others));
notifyDataSetChanged();
}
static class SectionHolder extends RecyclerView.ViewHolder {
@BindView(R.id.section_text) TextView sectionText;
SectionHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
static class RepoHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title;
@BindView(R.id.version_name) TextView versionName;
@BindView(R.id.description) TextView description;
@BindView(R.id.author) TextView author;
@BindView(R.id.info_layout) LinearLayout infoLayout;
@BindView(R.id.download) ImageView downloadImage;
@BindView(R.id.update_time) TextView updateTime;
RepoHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
package com.topjohnwu.magisk.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
public abstract class SectionedAdapter<S extends RecyclerView.ViewHolder, C extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int SECTION_TYPE = Integer.MIN_VALUE;
@Override
final public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == SECTION_TYPE)
return onCreateSectionViewHolder(parent);
return onCreateItemViewHolder(parent, viewType);
}
@Override
@SuppressWarnings("unchecked")
final public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
PositionInfo info = getPositionInfo(position);
if (info.position == -1)
onBindSectionViewHolder((S) holder, info.section);
else
onBindItemViewHolder((C) holder, info.section, info.position);
}
@Override
final public int getItemCount() {
int size, sec;
size = sec = getSectionCount();
for (int i = 0; i < sec; ++i){
size += getItemCount(i);
}
return size;
}
@Override
final public int getItemViewType(int position) {
PositionInfo info = getPositionInfo(position);
if (info.position == -1)
return SECTION_TYPE;
else
return getItemViewType(info.section, info.position);
}
public int getItemViewType(int section, int position) {
return 0;
}
protected int getSectionPosition(int section) {
return getItemPosition(section, -1);
}
protected int getItemPosition(int section, int position) {
int realPosition = 0;
// Previous sections
for (int i = 0; i < section; ++i) {
realPosition += getItemCount(i) + 1;
}
// Current section
realPosition += position + 1;
return realPosition;
}
private PositionInfo getPositionInfo(int position) {
int section = 0;
while (true) {
if (position == 0)
return new PositionInfo(section, -1);
position -= 1;
if (position < getItemCount(section))
return new PositionInfo(section, position);
position -= getItemCount(section++);
}
}
private static class PositionInfo {
int section;
int position;
PositionInfo(int section, int position) {
this.section = section;
this.position = position;
}
}
public abstract int getSectionCount();
public abstract int getItemCount(int section);
public abstract S onCreateSectionViewHolder(ViewGroup parent);
public abstract C onCreateItemViewHolder(ViewGroup parent, int viewType);
public abstract void onBindSectionViewHolder(S holder, int section);
public abstract void onBindItemViewHolder(C holder, int section, int position);
}
package com.topjohnwu.magisk.adapters;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, SuLogAdapter.LogViewHolder> {
private List<List<Integer>> logEntryList;
private Set<Integer> itemExpanded, sectionExpanded;
private MagiskDatabaseHelper suDB;
private Cursor suLogCursor = null;
public SuLogAdapter(MagiskDatabaseHelper db) {
suDB = db;
logEntryList = Collections.emptyList();
sectionExpanded = new HashSet<>();
itemExpanded = new HashSet<>();
}
@Override
public int getSectionCount() {
return logEntryList.size();
}
@Override
public int getItemCount(int section) {
return sectionExpanded.contains(section) ? logEntryList.get(section).size() : 0;
}
@Override
public SectionHolder onCreateSectionViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sulog_group, parent, false);
return new SectionHolder(v);
}
@Override
public LogViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sulog, parent, false);
return new LogViewHolder(v);
}
@Override
public void onBindSectionViewHolder(SectionHolder holder, int section) {
suLogCursor.moveToPosition(logEntryList.get(section).get(0));
SuLogEntry entry = new SuLogEntry(suLogCursor);
holder.arrow.setRotation(sectionExpanded.contains(section) ? 180 : 0);
holder.itemView.setOnClickListener(v -> {
RotateAnimation rotate;
if (sectionExpanded.contains(section)) {
holder.arrow.setRotation(0);
rotate = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sectionExpanded.remove(section);
notifyItemRangeRemoved(getItemPosition(section, 0), logEntryList.get(section).size());
} else {
rotate = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sectionExpanded.add(section);
notifyItemRangeInserted(getItemPosition(section, 0), logEntryList.get(section).size());
}
rotate.setDuration(300);
rotate.setFillAfter(true);
holder.arrow.setAnimation(rotate);
});
holder.date.setText(entry.getDateString());
}
@Override
public void onBindItemViewHolder(LogViewHolder holder, int section, int position) {
int sqlPosition = logEntryList.get(section).get(position);
suLogCursor.moveToPosition(sqlPosition);
SuLogEntry entry = new SuLogEntry(suLogCursor);
holder.setExpanded(itemExpanded.contains(sqlPosition));
holder.itemView.setOnClickListener(view -> {
if (holder.isExpanded()) {
holder.collapse();
itemExpanded.remove(sqlPosition);
} else {
holder.expand();
itemExpanded.add(sqlPosition);
}
});
holder.appName.setText(entry.appName);
holder.action.setText(entry.action ? R.string.grant : R.string.deny);
holder.command.setText(entry.command);
holder.fromPid.setText(String.valueOf(entry.fromPid));
holder.toUid.setText(String.valueOf(entry.toUid));
holder.time.setText(entry.getTimeString());
}
public void notifyDBChanged() {
if (suLogCursor != null)
suLogCursor.close();
suLogCursor = suDB.getLogCursor();
logEntryList = suDB.getLogStructure();
itemExpanded.clear();
sectionExpanded.clear();
sectionExpanded.add(0);
notifyDataSetChanged();
}
static class SectionHolder extends RecyclerView.ViewHolder {
@BindView(R.id.date) TextView date;
@BindView(R.id.arrow) ImageView arrow;
SectionHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.action) TextView action;
@BindView(R.id.time) TextView time;
@BindView(R.id.fromPid) TextView fromPid;
@BindView(R.id.toUid) TextView toUid;
@BindView(R.id.command) TextView command;
@BindView(R.id.expand_layout) ViewGroup expandLayout;
private Container container = new Container();
LogViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
container.expandLayout = expandLayout;
setupExpandable();
}
@Override
public Container getContainer() {
return container;
}
}
}
package com.topjohnwu.magisk.adapters;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class TabFragmentAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
private List<String> titleList;
public TabFragmentAdapter(FragmentManager fm) {
super(fm);
fragmentList = new ArrayList<>();
titleList = new ArrayList<>();
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titleList.get(position);
}
public void addTab(Fragment fragment, String title) {
fragmentList.add(fragment);
titleList.add(title);
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import dalvik.system.DexClassLoader;
public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
public static final File dexPath =
new File(MagiskManager.get().getFilesDir().getParent() + "/snet", "snet.apk");
private ISafetyNetHelper helper;
public CheckSafetyNet(Activity activity) {
super(activity);
}
private void dlSnet() throws Exception {
Shell.Sync.sh("rm -rf " + dexPath.getParent());
dexPath.getParentFile().mkdir();
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
try (
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
InputStream in = new BufferedInputStream(conn.getInputStream())) {
ShellUtils.pump(in, out);
} finally {
conn.disconnect();
}
}
private void dyload() throws Exception {
DexClassLoader loader = new DexClassLoader(dexPath.getPath(), dexPath.getParent(),
null, ISafetyNetHelper.class.getClassLoader());
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.SafetyNetHelper");
helper = (ISafetyNetHelper) clazz.getConstructors()[0]
.newInstance(getActivity(), (ISafetyNetHelper.Callback)
code -> MagiskManager.get().safetyNetDone.publish(false, code));
if (helper.getVersion() != Const.SNET_VER) {
throw new Exception();
}
}
@Override
protected Exception doInBackground(Void... voids) {
try {
try {
dyload();
} catch (Exception e) {
// If dynamic load failed, try re-downloading and reload
dlSnet();
dyload();
}
} catch (Exception e) {
return e;
}
return null;
}
@Override
protected void onPostExecute(Exception e) {
if (e == null) {
helper.attest();
} else {
e.printStackTrace();
MagiskManager.get().safetyNetDone.publish(false, -1);
}
super.onPostExecute(e);
}
}
package com.topjohnwu.magisk.asyncs;
import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.ShowUI;
import com.topjohnwu.magisk.utils.WebService;
import org.json.JSONException;
import org.json.JSONObject;
public class CheckUpdates extends ParallelTask<Void, Void, Void> {
private boolean showNotification;
public CheckUpdates() {
this(false);
}
public CheckUpdates(boolean b) {
showNotification = b;
}
@Override
protected Void doInBackground(Void... voids) {
MagiskManager mm = MagiskManager.get();
String jsonStr = "";
switch (mm.updateChannel) {
case Const.Value.STABLE_CHANNEL:
jsonStr = WebService.getString(Const.Url.STABLE_URL);
break;
case Const.Value.BETA_CHANNEL:
jsonStr = WebService.getString(Const.Url.BETA_URL);
break;
case Const.Value.CUSTOM_CHANNEL:
jsonStr = WebService.getString(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
break;
}
try {
JSONObject json = new JSONObject(jsonStr);
JSONObject magisk = json.getJSONObject("magisk");
mm.remoteMagiskVersionString = magisk.getString("version");
mm.remoteMagiskVersionCode = magisk.getInt("versionCode");
mm.magiskLink = magisk.getString("link");
mm.magiskNoteLink = magisk.getString("note");
JSONObject manager = json.getJSONObject("app");
mm.remoteManagerVersionString = manager.getString("version");
mm.remoteManagerVersionCode = manager.getInt("versionCode");
mm.managerLink = manager.getString("link");
mm.managerNoteLink = manager.getString("note");
JSONObject uninstaller = json.getJSONObject("uninstaller");
mm.uninstallerLink = uninstaller.getString("link");
} catch (JSONException ignored) {}
return null;
}
@Override
protected void onPostExecute(Void v) {
MagiskManager mm = MagiskManager.get();
if (showNotification) {
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
ShowUI.managerUpdateNotification();
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
ShowUI.magiskUpdateNotification();
}
}
mm.updateCheckDone.publish();
super.onPostExecute(v);
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public class FlashZip extends ParallelTask<Void, Void, Integer> {
private Uri mUri;
private File mCachedFile;
private List<String> console, logs;
public FlashZip(Activity context, Uri uri, List<String> console, List<String> logs) {
super(context);
mUri = uri;
this.console = console;
this.logs = logs;
mCachedFile = new File(context.getCacheDir(), "install.zip");
}
private boolean unzipAndCheck() throws Exception {
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
return ShellUtils.fastCmdResult("grep -q '#MAGISK' " + new File(mCachedFile.getParentFile(), "updater-script"));
}
@Override
protected Integer doInBackground(Void... voids) {
MagiskManager mm = MagiskManager.get();
try {
console.add("- Copying zip to temp directory");
mCachedFile.delete();
try (
InputStream in = mm.getContentResolver().openInputStream(mUri);
OutputStream out = new BufferedOutputStream(new FileOutputStream(mCachedFile))
) {
if (in == null) throw new FileNotFoundException();
InputStream buf= new BufferedInputStream(in);
ShellUtils.pump(buf, out);
} catch (FileNotFoundException e) {
console.add("! Invalid Uri");
throw e;
} catch (IOException e) {
console.add("! Cannot copy to cache");
throw e;
}
if (!unzipAndCheck()) return 0;
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
Shell.Sync.su(console, logs,
"cd " + mCachedFile.getParent(),
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
);
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
return -1;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
console.add("- All done!");
return 1;
}
// -1 = error, manual install; 0 = invalid zip; 1 = success
@Override
protected void onPostExecute(Integer result) {
FlashActivity activity = (FlashActivity) getActivity();
Shell.Async.su(
"rm -rf " + mCachedFile.getParent(),
"rm -rf " + Const.TMP_FOLDER_PATH
);
switch (result) {
case -1:
console.add("! Installation failed");
SnackbarMaker.showUri(getActivity(), mUri);
break;
case 0:
console.add("! This zip is not a Magisk Module!");
break;
case 1:
// Success
new LoadModules().exec();
break;
}
activity.reboot.setVisibility(result > 0 ? View.VISIBLE : View.GONE);
activity.buttonPanel.setVisibility(View.VISIBLE);
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.PatchAPK;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import com.topjohnwu.superuser.io.SuFileOutputStream;
import java.io.FileNotFoundException;
import java.security.SecureRandom;
public class HideManager extends ParallelTask<Void, Void, Boolean> {
private ProgressDialog dialog;
public HideManager(Activity activity) {
super(activity);
}
private String genPackageName(String prefix, int length) {
StringBuilder builder = new StringBuilder(length);
builder.append(prefix);
length -= prefix.length();
SecureRandom random = new SecureRandom();
String base = "abcdefghijklmnopqrstuvwxyz";
String alpha = base + base.toUpperCase();
String full = alpha + "0123456789..........";
char next, prev = '\0';
for (int i = 0; i < length; ++i) {
if (prev == '.' || i == length - 1 || i == 0) {
next = alpha.charAt(random.nextInt(alpha.length()));
} else {
next = full.charAt(random.nextInt(full.length()));
}
builder.append(next);
prev = next;
}
return builder.toString();
}
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(getActivity(),
getActivity().getString(R.string.hide_manager_toast),
getActivity().getString(R.string.hide_manager_toast2));
}
@Override
protected Boolean doInBackground(Void... voids) {
MagiskManager mm = MagiskManager.get();
// Generate a new app with random package name
SuFile repack = new SuFile("/data/local/tmp/repack.apk");
String pkg = genPackageName("com.", Const.ORIG_PKG_NAME.length());
try {
if (!PatchAPK.patchPackageID(
mm.getPackageCodePath(),
new SuFileOutputStream(repack),
Const.ORIG_PKG_NAME, pkg))
return false;
} catch (FileNotFoundException e) {
return false;
}
// Install the application
if (!ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack))
return false;
repack.delete();
mm.mDB.setStrings(Const.Key.SU_MANAGER, pkg);
mm.dumpPrefs();
RootUtils.uninstallPkg(Const.ORIG_PKG_NAME);
return true;
}
@Override
protected void onPostExecute(Boolean b) {
dialog.dismiss();
if (!b) {
MagiskManager.toast(R.string.hide_manager_fail_toast, Toast.LENGTH_LONG);
}
super.onPostExecute(b);
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.TarEntry;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFileInputStream;
import com.topjohnwu.utils.SignBoot;
import org.kamranzafar.jtar.TarInputStream;
import org.kamranzafar.jtar.TarOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
private static final int PATCH_MODE = 0;
public static final int DIRECT_MODE = 1;
private static final int FIX_ENV_MODE = 2;
public static final int SECOND_SLOT_MODE = 3;
private Uri bootUri, mZip;
private List<String> console, logs;
private String mBoot;
private int mode;
private File installDir;
private ProgressDialog dialog;
private MagiskManager mm;
public InstallMagisk(Activity context, Uri zip) {
super(context);
mZip = zip;
mm = MagiskManager.get();
mode = FIX_ENV_MODE;
}
public InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip, int mode) {
this(context, zip);
this.console = console;
this.logs = logs;
this.mode = mode;
}
public InstallMagisk(FlashActivity context, List<String> console, List<String> logs, Uri zip, Uri boot) {
this(context, console, logs, zip, PATCH_MODE);
bootUri = boot;
}
@Override
protected void onPreExecute() {
if (mode == FIX_ENV_MODE) {
Activity a = getActivity();
dialog = ProgressDialog.show(a, a.getString(R.string.setup_title), a.getString(R.string.setup_msg));
console = new NOPList<>();
}
}
private void extractFiles(String arch) throws IOException {
console.add("- Extracting files");
try (InputStream in = mm.getContentResolver().openInputStream(mZip)) {
if (in == null) throw new FileNotFoundException();
BufferedInputStream buf = new BufferedInputStream(in);
buf.mark(Integer.MAX_VALUE);
ZipUtils.unzip(buf, installDir, arch + "/", true);
buf.reset();
ZipUtils.unzip(buf, installDir, "common/", true);
buf.reset();
ZipUtils.unzip(buf, installDir, "chromeos/", false);
buf.reset();
ZipUtils.unzip(buf, installDir, "META-INF/com/google/android/update-binary", true);
buf.close();
} catch (FileNotFoundException e) {
console.add("! Invalid Uri");
throw e;
} catch (IOException e) {
console.add("! Cannot unzip zip");
throw e;
}
Shell.Sync.sh(Utils.fmt("chmod -R 755 %s/*; %s/magiskinit -x magisk %s/magisk",
installDir, installDir, installDir));
}
private boolean dumpBoot() {
console.add("- Copying image locally");
// Copy boot image to local
try (InputStream in = mm.getContentResolver().openInputStream(bootUri);
OutputStream out = new FileOutputStream(mBoot)
) {
if (in == null)
throw new FileNotFoundException();
InputStream src;
if (Utils.getNameFromUri(mm, bootUri).endsWith(".tar")) {
// Extract boot.img from tar
TarInputStream tar = new TarInputStream(new BufferedInputStream(in));
org.kamranzafar.jtar.TarEntry entry;
while ((entry = tar.getNextEntry()) != null) {
if (entry.getName().equals("boot.img"))
break;
}
src = tar;
} else {
// Direct copy raw image
src = new BufferedInputStream(in);
}
ShellUtils.pump(src, out);
} catch (FileNotFoundException e) {
console.add("! Invalid Uri");
return false;
} catch (IOException e) {
console.add("! Copy failed");
return false;
}
return true;
}
private File patchBoot() throws IOException {
boolean isSigned;
try (InputStream in = new SuFileInputStream(mBoot)) {
isSigned = SignBoot.verifySignature(in, null);
if (isSigned) {
console.add("- Boot image is signed with AVB 1.0");
}
} catch (IOException e) {
console.add("! Unable to check signature");
throw e;
}
// Patch boot image
Shell.Sync.sh(console, logs,
"cd " + installDir,
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b sh update-binary indep " +
"boot_patch.sh %s || echo 'Failed!'",
mm.keepEnc, mm.keepVerity, mBoot));
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
return null;
Shell.Sync.sh("mv bin/busybox busybox",
"rm -rf magisk.apk bin boot.img update-binary",
"cd /");
File patched = new File(installDir, "new-boot.img");
if (isSigned) {
console.add("- Signing boot image with test keys");
File signed = new File(installDir, "signed.img");
try (InputStream in = new SuFileInputStream(patched);
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
) {
SignBoot.doSignature("/boot", in, out, null, null);
}
Shell.Sync.su("mv -f " + signed + " " + patched);
}
return patched;
}
private void outputBoot(File patched) throws IOException {
switch (mode) {
case PATCH_MODE:
File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat);
dest.getParentFile().mkdirs();
OutputStream out;
switch (mm.bootFormat) {
case ".img.tar":
out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
((TarOutputStream) out).putNextEntry(new TarEntry(patched, "boot.img"));
break;
default:
case ".img":
out = new BufferedOutputStream(new FileOutputStream(dest));
break;
}
try (InputStream in = new SuFileInputStream(patched)) {
ShellUtils.pump(in, out);
out.close();
}
Shell.Sync.su("rm -f " + patched);
console.add("");
console.add("****************************");
console.add(" Patched image is placed in ");
console.add(" " + dest + " ");
console.add("****************************");
break;
case SECOND_SLOT_MODE:
case DIRECT_MODE:
Shell.Sync.sh(console, logs,
Utils.fmt("direct_install %s %s %s", patched, mBoot, installDir));
if (!mm.keepVerity)
Shell.Sync.sh(console, logs, "find_dtbo_image", "patch_dtbo_image");
break;
}
}
@Override
protected Boolean doInBackground(Void... voids) {
if (mode == FIX_ENV_MODE) {
installDir = new File("/data/adb/magisk");
Shell.Sync.sh("rm -rf /data/adb/magisk/*");
} else {
installDir = new File(
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
mm.createDeviceProtectedStorageContext() : mm)
.getFilesDir().getParent()
, "install");
Shell.Sync.sh("rm -rf " + installDir);
installDir.mkdirs();
}
switch (mode) {
case PATCH_MODE:
mBoot = new File(installDir, "boot.img").getAbsolutePath();
if (!dumpBoot())
return false;
break;
case DIRECT_MODE:
console.add("- Detecting target image");
mBoot = ShellUtils.fastCmd("find_boot_image", "echo \"$BOOTIMAGE\"");
break;
case SECOND_SLOT_MODE:
console.add("- Detecting target image");
char slot[] = ShellUtils.fastCmd("echo $SLOT").toCharArray();
if (slot[1] == 'a') slot[1] = 'b';
else slot[1] = 'a';
mBoot = ShellUtils.fastCmd("SLOT=" + String.valueOf(slot),
"find_boot_image", "echo \"$BOOTIMAGE\"");
Shell.Async.su("mount_partitions");
break;
case FIX_ENV_MODE:
mBoot = "";
break;
}
if (mBoot == null) {
console.add("! Unable to detect target image");
return false;
}
console.add("- Target image: " + mBoot);
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
String arch;
if (mm.remoteMagiskVersionCode >= Const.MAGISK_VER.SEPOL_REFACTOR) {
// 32-bit only
if (abis.contains("x86")) arch = "x86";
else arch = "arm";
} else {
if (abis.contains("x86_64")) arch = "x64";
else if (abis.contains("arm64-v8a")) arch = "arm64";
else if (abis.contains("x86")) arch = "x86";
else arch = "arm";
}
console.add("- Device platform: " + Build.SUPPORTED_ABIS[0]);
try {
extractFiles(arch);
if (mode == FIX_ENV_MODE) {
Shell.Sync.sh("fix_env");
} else {
File patched = patchBoot();
if (patched == null)
return false;
outputBoot(patched);
console.add("- All done!");
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (mode == FIX_ENV_MODE) {
dialog.dismiss();
MagiskManager.toast(result ? R.string.setup_done : R.string.setup_fail, Toast.LENGTH_LONG);
} else {
// Running in FlashActivity
FlashActivity activity = (FlashActivity) getActivity();
if (!result) {
Shell.Async.sh("rm -rf " + installDir);
console.add("! Installation failed");
activity.reboot.setVisibility(View.GONE);
}
activity.buttonPanel.setVisibility(View.VISIBLE);
}
}
private static class NOPList<E> extends AbstractList<E> {
@Override
public E get(int index) {
return null;
}
@Override
public int size() {
return 0;
}
@Override
public void add(int index, E element) {}
}
}
package com.topjohnwu.magisk.asyncs;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.container.ValueSortedMap;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.superuser.Shell;
import java.util.List;
public class LoadModules extends ParallelTask<Void, Void, Void> {
private List<String> getModList() {
String command = "ls -d " + Const.MAGISK_PATH + "/* | grep -v lost+found";
return Shell.Sync.su(command);
}
@Override
protected Void doInBackground(Void... voids) {
MagiskManager mm = MagiskManager.get();
mm.moduleMap = new ValueSortedMap<>();
for (String path : getModList()) {
Module module = new Module(path);
mm.moduleMap.put(module.getId(), module);
}
return null;
}
@Override
protected void onPostExecute(Void v) {
MagiskManager.get().moduleLoadDone.publish();
super.onPostExecute(v);
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.support.v7.app.AlertDialog;
import android.webkit.WebView;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.superuser.ShellUtils;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class MarkDownWindow extends ParallelTask<Void, Void, String> {
private String mTitle;
private String mUrl;
private InputStream is;
public MarkDownWindow(Activity context, String title, String url) {
super(context);
mTitle = title;
mUrl = url;
}
public MarkDownWindow(Activity context, String title, InputStream in) {
super(context);
mTitle = title;
is = in;
}
@Override
protected String doInBackground(Void... voids) {
MagiskManager mm = MagiskManager.get();
String md;
if (mUrl != null) {
md = WebService.getString(mUrl);
} else {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
ShellUtils.pump(is, out);
md = out.toString();
is.close();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
String css;
try (
InputStream in = mm.getResources().openRawResource(
mm.isDarkTheme ? R.raw.dark : R.raw.light);
ByteArrayOutputStream out = new ByteArrayOutputStream()
) {
ShellUtils.pump(in, out);
css = out.toString();
in.close();
} catch (IOException e) {
e.printStackTrace();
return "";
}
Parser parser = Parser.builder().build();
HtmlRenderer renderer = HtmlRenderer.builder().build();
Node doc = parser.parse(md);
return String.format("<style>%s</style>%s", css, renderer.render(doc));
}
@Override
protected void onPostExecute(String html) {
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle(mTitle);
WebView wv = new WebView(getActivity());
wv.loadDataWithBaseURL("fake://", html, "text/html", "UTF-8", null);
alert.setView(wv);
alert.setNegativeButton(R.string.close, (dialog, id) -> dialog.dismiss());
alert.show();
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.os.AsyncTask;
import java.lang.ref.WeakReference;
public abstract class ParallelTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private WeakReference<Activity> weakActivity;
private Runnable callback = null;
public ParallelTask() {}
public ParallelTask(Activity context) {
weakActivity = new WeakReference<>(context);
}
protected Activity getActivity() {
return weakActivity.get();
}
@SuppressWarnings("unchecked")
public ParallelTask<Params, Progress, Result> exec(Params... params) {
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
return this;
}
@Override
protected void onPostExecute(Result result) {
if (callback != null) callback.run();
}
public ParallelTask<Params, Progress, Result> setCallBack(Runnable next) {
callback = next;
return this;
}
}
package com.topjohnwu.magisk.asyncs;
import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.widget.Toast;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.WebService;
import com.topjohnwu.magisk.utils.ZipUtils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
private ProgressDialog progressDialog;
private boolean mInstall;
private String mLink;
private File mFile;
private int progress = 0, total = -1;
private Handler mHandler;
public ProcessRepoZip(Activity context, String link, String filename, boolean install) {
super(context);
mLink = link;
mFile = new File(Const.EXTERNAL_PATH, filename);
mInstall = install;
mHandler = new Handler();
}
private void removeTopFolder(File input, File output) throws IOException {
JarEntry entry;
try (
JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(input)));
JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output)))
) {
String path;
while ((entry = in.getNextJarEntry()) != null) {
// Remove the top directory from the path
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
// If it's the top folder, ignore it
if (path.isEmpty()) {
continue;
}
// Don't include placeholder
if (path.equals("system/placeholder")) {
continue;
}
out.putNextEntry(new JarEntry(path));
ShellUtils.pump(in, out);
}
}
}
@Override
protected void onPreExecute() {
Activity activity = getActivity();
mFile.getParentFile().mkdirs();
progressDialog = ProgressDialog.show(activity, activity.getString(R.string.zip_download_title), activity.getString(R.string.zip_download_msg, 0));
}
@Override
protected Boolean doInBackground(Void... params) {
Activity activity = getActivity();
if (activity == null) return null;
try {
// Request zip from Internet
HttpURLConnection conn;
do {
conn = WebService.request(mLink, null);
total = conn.getContentLength();
if (total < 0)
conn.disconnect();
else
break;
} while (true);
// Temp files
File temp1 = new File(activity.getCacheDir(), "1.zip");
File temp2 = new File(temp1.getParentFile(), "2.zip");
temp1.getParentFile().mkdir();
// First download the zip, Web -> temp1
try (
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
) {
ShellUtils.pump(in, out);
in.close();
}
conn.disconnect();
mHandler.post(() -> {
progressDialog.setTitle(R.string.zip_process_title);
progressDialog.setMessage(getActivity().getString(R.string.zip_process_msg));
});
// First remove top folder in Github source zip, temp1 -> temp2
removeTopFolder(temp1, temp2);
// Then sign the zip
ZipUtils.signZip(temp2, mFile);
// Delete temp files
temp1.delete();
temp2.delete();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
Activity activity = getActivity();
if (activity == null) return;
progressDialog.dismiss();
if (result) {
Uri uri = Uri.fromFile(mFile);
if (Shell.rootAccess() && mInstall) {
Intent intent = new Intent(activity, FlashActivity.class);
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
activity.startActivity(intent);
} else {
SnackbarMaker.showUri(activity, uri);
}
} else {
MagiskManager.toast(R.string.process_error, Toast.LENGTH_LONG);
}
super.onPostExecute(result);
}
@Override
public ParallelTask<Void, Object, Boolean> exec(Void... voids) {
com.topjohnwu.magisk.components.Activity.runWithPermission(
getActivity(), new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
() -> super.exec(voids));
return this;
}
private class ProgressInputStream extends FilterInputStream {
ProgressInputStream(InputStream in) {
super(in);
}
private void updateDlProgress(int step) {
progress += step;
progressDialog.setMessage(getActivity().getString(R.string.zip_download_msg, (int) (100 * (double) progress / total + 0.5)));
}
@Override
public synchronized int read() throws IOException {
int b = super.read();
if (b > 0) {
mHandler.post(() -> updateDlProgress(1));
}
return b;
}
@Override
public int read(@NonNull byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public synchronized int read(@NonNull byte[] b, int off, int len) throws IOException {
int read = super.read(b, off, len);
if (read > 0) {
mHandler.post(() -> updateDlProgress(read));
}
return read;
}
}
}
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.superuser.ShellUtils;
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
private ProgressDialog dialog;
public RestoreImages(Activity activity) {
super(activity);
}
@Override
protected void onPreExecute() {
Activity a = getActivity();
dialog = ProgressDialog.show(a, a.getString(R.string.restore_img), a.getString(R.string.restore_img_msg));
}
@Override
protected Boolean doInBackground(Void... voids) {
return ShellUtils.fastCmdResult("restore_imgs");
}
@Override
protected void onPostExecute(Boolean result) {
dialog.cancel();
if (result) {
MagiskManager.toast(R.string.restore_done, Toast.LENGTH_SHORT);
} else {
MagiskManager.toast(R.string.restore_fail, Toast.LENGTH_LONG);
}
}
}
package com.topjohnwu.magisk.asyncs;
import android.database.Cursor;
import android.os.AsyncTask;
import android.text.TextUtils;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.ReposFragment;
import com.topjohnwu.magisk.container.Repo;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.HttpURLConnection;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
public class UpdateRepos extends ParallelTask<Void, Void, Void> {
private static final int CHECK_ETAG = 0;
private static final int LOAD_NEXT = 1;
private static final int LOAD_PREV = 2;
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
private MagiskManager mm;
private List<String> etags, newEtags = new LinkedList<>();
private Set<String> cached;
private boolean forceUpdate;
private AtomicInteger taskCount = new AtomicInteger(0);
final private Object allDone = new Object();
public UpdateRepos(boolean force) {
mm = MagiskManager.get();
mm.repoLoadDone.reset();
forceUpdate = force;
}
private void queueTask(Runnable task) {
// Thread pool's queue has an upper bound, batch it with 64 tasks
while (taskCount.get() >= 64) {
waitTasks();
}
taskCount.incrementAndGet();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
task.run();
if (taskCount.decrementAndGet() == 0) {
synchronized (allDone) {
allDone.notify();
}
}
});
}
private void waitTasks() {
if (taskCount.get() == 0)
return;
synchronized (allDone) {
try {
allDone.wait();
} catch (InterruptedException e) {
// Wait again
waitTasks();
}
}
}
private boolean loadJSON(String jsonString) throws JSONException, ParseException {
JSONArray jsonArray = new JSONArray(jsonString);
// Empty page, halt
if (jsonArray.length() == 0)
return false;
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject rawRepo = jsonArray.getJSONObject(i);
String id = rawRepo.getString("description");
String name = rawRepo.getString("name");
Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
Set<String> set = Collections.synchronizedSet(cached);
queueTask(() -> {
Repo repo = mm.repoDB.getRepo(id);
try {
if (repo == null)
repo = new Repo(name);
else
set.remove(id);
repo.update(date);
mm.repoDB.addRepo(repo);
publishProgress();
} catch (Repo.IllegalRepoException e) {
Logger.debug(e.getMessage());
mm.repoDB.removeRepo(id);
}
});
}
return true;
}
private boolean loadPage(int page, int mode) {
Map<String, String> header = new HashMap<>();
if (mode == CHECK_ETAG && page < etags.size())
header.put(Const.Key.IF_NONE_MATCH, etags.get(page));
String url = Utils.fmt(Const.Url.REPO_URL, page + 1);
try {
HttpURLConnection conn = WebService.request(url, header);
if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
// Current page is not updated, check the next page
return loadPage(page + 1, CHECK_ETAG);
}
if (!loadJSON(WebService.getString(conn)))
return mode != CHECK_ETAG;
} catch (Exception e) {
e.printStackTrace();
return false;
}
/* If one page is updated, we force update all pages */
// Update ETAG
String etag = header.get(Const.Key.ETAG_KEY);
etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1);
if (mode == LOAD_PREV) {
// We are loading a previous page, push the new tag to the front
newEtags.add(0, etag);
} else {
newEtags.add(etag);
}
String links = header.get(Const.Key.LINK_KEY);
if (links != null) {
for (String s : links.split(", ")) {
if (mode != LOAD_PREV && s.contains("next")) {
// Force load all next pages
loadPage(page + 1, LOAD_NEXT);
}
if (mode != LOAD_NEXT && s.contains("prev")) {
// Back propagation
loadPage(page - 1, LOAD_PREV);
}
}
}
return true;
}
@Override
protected void onProgressUpdate(Void... values) {
if (ReposFragment.adapter != null)
ReposFragment.adapter.notifyDBChanged();
}
@Override
protected void onPreExecute() {
mm.repoLoadDone.setPending();
}
@Override
protected Void doInBackground(Void... voids) {
etags = Arrays.asList(mm.prefs.getString(Const.Key.ETAG_KEY, "").split(","));
cached = mm.repoDB.getRepoIDSet();
if (loadPage(0, CHECK_ETAG)) {
waitTasks();
// The leftover cached means they are removed from online repo
mm.repoDB.removeRepo(cached);
// Update ETag
mm.prefs.edit().putString(Const.Key.ETAG_KEY, TextUtils.join(",", newEtags)).apply();
} else if (forceUpdate) {
Cursor c = mm.repoDB.getRawCursor();
while (c.moveToNext()) {
Repo repo = new Repo(c);
queueTask(() -> {
try {
repo.update();
mm.repoDB.addRepo(repo);
} catch (Repo.IllegalRepoException e) {
Logger.debug(e.getMessage());
mm.repoDB.removeRepo(repo);
}
});
}
waitTasks();
}
return null;
}
@Override
protected void onPostExecute(Void v) {
mm.repoLoadDone.publish();
super.onPostExecute(v);
}
}
/*
* Copyright 2016 dvdandroid
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.topjohnwu.magisk.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
/**
* @author dvdandroid
*/
public class AboutCardRow extends LinearLayout {
private final String title;
private final Drawable icon;
private final TextView mTitle;
private final TextView mSummary;
private final ImageView mIcon;
private final View mView;
public AboutCardRow(Context context) {
this(context, null);
}
public AboutCardRow(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AboutCardRow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.info_item_row, this);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AboutCardRow, 0, 0);
try {
title = a.getString(R.styleable.AboutCardRow_text);
icon = a.getDrawable(R.styleable.AboutCardRow_icon);
} finally {
a.recycle();
}
mView = findViewById(R.id.container);
mTitle = (TextView) findViewById(android.R.id.title);
mSummary = (TextView) findViewById(android.R.id.summary);
mIcon = (ImageView) findViewById(android.R.id.icon);
mTitle.setText(title);
mIcon.setImageDrawable(icon);
}
@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mView.setOnClickListener(l);
}
public void setSummary(String s) {
mSummary.setText(s);
}
public void removeSummary() {
mSummary.setVisibility(GONE);
}
}
\ No newline at end of file
package com.topjohnwu.magisk.components;
import android.app.Activity;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AlertDialogBuilder extends AlertDialog.Builder {
@BindView(R.id.button_panel) LinearLayout buttons;
@BindView(R.id.message_panel) LinearLayout messagePanel;
@BindView(R.id.negative) Button negative;
@BindView(R.id.positive) Button positive;
@BindView(R.id.neutral) Button neutral;
@BindView(R.id.message) TextView messageView;
private DialogInterface.OnClickListener positiveListener;
private DialogInterface.OnClickListener negativeListener;
private DialogInterface.OnClickListener neutralListener;
private AlertDialog dialog;
public AlertDialogBuilder(@NonNull Activity context) {
super(context);
setup();
}
public AlertDialogBuilder(@NonNull Activity context, @StyleRes int themeResId) {
super(context, themeResId);
setup();
}
private void setup() {
View v = LayoutInflater.from(getContext()).inflate(R.layout.alert_dialog, null);
ButterKnife.bind(this, v);
super.setView(v);
negative.setVisibility(View.GONE);
positive.setVisibility(View.GONE);
neutral.setVisibility(View.GONE);
buttons.setVisibility(View.GONE);
messagePanel.setVisibility(View.GONE);
}
@Override
public AlertDialog.Builder setTitle(int titleId) {
return super.setTitle(titleId);
}
@Override
public AlertDialog.Builder setView(int layoutResId) { return this; }
@Override
public AlertDialog.Builder setView(View view) { return this; }
@Override
public AlertDialog.Builder setMessage(@Nullable CharSequence message) {
messageView.setText(message);
messagePanel.setVisibility(View.VISIBLE);
return this;
}
@Override
public AlertDialog.Builder setMessage(@StringRes int messageId) {
return setMessage(getContext().getString(messageId));
}
@Override
public AlertDialog.Builder setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener) {
buttons.setVisibility(View.VISIBLE);
positive.setVisibility(View.VISIBLE);
positive.setText(text);
positiveListener = listener;
positive.setOnClickListener((v) -> {
if (positiveListener != null) {
positiveListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
}
dialog.dismiss();
});
return this;
}
@Override
public AlertDialog.Builder setPositiveButton(@StringRes int textId, DialogInterface.OnClickListener listener) {
return setPositiveButton(getContext().getString(textId), listener);
}
@Override
public AlertDialog.Builder setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener) {
buttons.setVisibility(View.VISIBLE);
negative.setVisibility(View.VISIBLE);
negative.setText(text);
negativeListener = listener;
negative.setOnClickListener((v) -> {
if (negativeListener != null) {
negativeListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
}
dialog.dismiss();
});
return this;
}
@Override
public AlertDialog.Builder setNegativeButton(@StringRes int textId, DialogInterface.OnClickListener listener) {
return setNegativeButton(getContext().getString(textId), listener);
}
@Override
public AlertDialog.Builder setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener) {
buttons.setVisibility(View.VISIBLE);
neutral.setVisibility(View.VISIBLE);
neutral.setText(text);
neutralListener = listener;
neutral.setOnClickListener((v) -> {
if (neutralListener != null) {
neutralListener.onClick(dialog, DialogInterface.BUTTON_NEUTRAL);
}
dialog.dismiss();
});
return this;
}
@Override
public AlertDialog.Builder setNeutralButton(@StringRes int textId, DialogInterface.OnClickListener listener) {
return setNeutralButton(getContext().getString(textId), listener);
}
@Override
public AlertDialog create() {
dialog = super.create();
return dialog;
}
@Override
public AlertDialog show() {
create();
dialog.show();
return dialog;
}
}
package com.topjohnwu.magisk.components;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
public interface ExpandableView {
class Container {
public ViewGroup expandLayout;
ValueAnimator expandAnimator, collapseAnimator;
boolean mExpanded = false;
int expandHeight = 0;
}
// Provide state info
Container getContainer();
default void setupExpandable() {
Container container = getContainer();
container.expandLayout.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (container.expandHeight == 0) {
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
container.expandLayout.measure(widthSpec, heightSpec);
container.expandHeight = container.expandLayout.getMeasuredHeight();
}
container.expandLayout.getViewTreeObserver().removeOnPreDrawListener(this);
container.expandLayout.setVisibility(View.GONE);
container.expandAnimator = slideAnimator(0, container.expandHeight);
container.collapseAnimator = slideAnimator(container.expandHeight, 0);
return true;
}
});
}
default boolean isExpanded() {
return getContainer().mExpanded;
}
default void setExpanded(boolean expanded) {
Container container = getContainer();
container.mExpanded = expanded;
ViewGroup.LayoutParams layoutParams = container.expandLayout.getLayoutParams();
layoutParams.height = expanded ? container.expandHeight : 0;
container.expandLayout.setLayoutParams(layoutParams);
container.expandLayout.setVisibility(expanded ? View.VISIBLE : View.GONE);
}
default void expand() {
Container container = getContainer();
if (container.mExpanded) return;
container.expandLayout.setVisibility(View.VISIBLE);
container.expandAnimator.start();
container.mExpanded = true;
}
default void collapse() {
Container container = getContainer();
if (!container.mExpanded) return;
container.collapseAnimator.start();
container.mExpanded = false;
}
default ValueAnimator slideAnimator(int start, int end) {
Container container = getContainer();
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(valueAnimator -> {
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = container.expandLayout.getLayoutParams();
layoutParams.height = value;
container.expandLayout.setLayoutParams(layoutParams);
});
return animator;
}
}
package com.topjohnwu.magisk.components;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.Keep;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Topic;
public abstract class FlavorActivity extends AppCompatActivity {
private AssetManager swappedAssetManager = null;
private Resources swappedResources = null;
private Resources.Theme backupTheme = null;
@StyleRes
public int getDarkTheme() {
return -1;
}
public MagiskManager getMagiskManager() {
return (MagiskManager) super.getApplication();
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this instanceof Topic.Subscriber) {
((Topic.Subscriber) this).subscribeTopics();
}
if (getMagiskManager().isDarkTheme && getDarkTheme() != -1) {
setTheme(getDarkTheme());
}
}
@Override
protected void onDestroy() {
if (this instanceof Topic.Subscriber) {
((Topic.Subscriber) this).unsubscribeTopics();
}
super.onDestroy();
}
protected void setFloating() {
boolean isTablet = getResources().getBoolean(R.bool.isTablet);
if (isTablet) {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.height = getResources().getDimensionPixelSize(R.dimen.floating_height);
params.width = getResources().getDimensionPixelSize(R.dimen.floating_width);
params.alpha = 1.0f;
params.dimAmount = 0.6f;
params.flags |= 2;
getWindow().setAttributes(params);
setFinishOnTouchOutside(true);
}
}
@Override
public Resources.Theme getTheme() {
return backupTheme == null ? super.getTheme() : backupTheme;
}
@Override
public AssetManager getAssets() {
return swappedAssetManager == null ? super.getAssets() : swappedAssetManager;
}
private AssetManager getAssets(String apk) {
try {
AssetManager asset = AssetManager.class.newInstance();
AssetManager.class.getMethod("addAssetPath", String.class).invoke(asset, apk);
return asset;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public Resources getResources() {
return swappedResources == null ? super.getResources() : swappedResources;
}
@Keep
public void swapResources(String dexPath) {
AssetManager asset = getAssets(dexPath);
if (asset != null) {
backupTheme = super.getTheme();
Resources res = super.getResources();
swappedResources = new Resources(asset, res.getDisplayMetrics(), res.getConfiguration());
swappedAssetManager = asset;
}
}
@Keep
public void restoreResources() {
swappedAssetManager = null;
swappedResources = null;
backupTheme = null;
}
}
package com.topjohnwu.magisk.components;
import android.content.Intent;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
public class Fragment extends android.support.v4.app.Fragment {
public MagiskManager getApplication() {
return Utils.getMagiskManager(getActivity());
}
@Override
public void onResume() {
super.onResume();
if (this instanceof Topic.Subscriber) {
((Topic.Subscriber) this).subscribeTopics();
}
}
@Override
public void onPause() {
if (this instanceof Topic.Subscriber) {
((Topic.Subscriber) this).unsubscribeTopics();
}
super.onPause();
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, this::onActivityResult);
}
public void startActivityForResult(Intent intent, int requestCode, Activity.ActivityResultListener listener) {
((Activity) getActivity()).startActivityForResult(intent, requestCode, listener);
}
public void runWithPermission(String[] permissions, Runnable callback) {
Activity.runWithPermission(getActivity(), permissions, callback);
}
}
package com.topjohnwu.magisk.components;
import android.app.Activity;
import android.net.Uri;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils;
public class SnackbarMaker {
public static Snackbar make(Activity activity, CharSequence text, int duration) {
View view = activity.findViewById(android.R.id.content);
return make(view, text, duration);
}
public static Snackbar make(Activity activity, @StringRes int resId, int duration) {
return make(activity, activity.getString(resId), duration);
}
public static Snackbar make(View view, CharSequence text, int duration) {
Snackbar snack = Snackbar.make(view, text, duration);
setup(snack);
return snack;
}
public static Snackbar make(View view, @StringRes int resId, int duration) {
Snackbar snack = Snackbar.make(view, resId, duration);
setup(snack);
return snack;
}
private static void setup(Snackbar snack) {
TextView text = snack.getView().findViewById(android.support.design.R.id.snackbar_text);
text.setMaxLines(Integer.MAX_VALUE);
}
public static void showUri(Activity activity, Uri uri) {
make(activity, activity.getString(R.string.internal_storage,
"/MagiskManager/" + Utils.getNameFromUri(activity, uri)),
Snackbar.LENGTH_LONG)
.setAction(R.string.ok, (v)->{}).show();
}
}
package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.database.Cursor;
import android.support.annotation.NonNull;
import java.util.List;
public abstract class BaseModule implements Comparable<BaseModule> {
private String mId = null, mName, mVersion, mAuthor, mDescription;
private int mVersionCode = -1, minMagiskVersion = -1;
protected BaseModule() {}
protected BaseModule(Cursor c) {
mId = c.getString(c.getColumnIndex("id"));
mName = c.getString(c.getColumnIndex("name"));
mVersion = c.getString(c.getColumnIndex("version"));
mVersionCode = c.getInt(c.getColumnIndex("versionCode"));
mAuthor = c.getString(c.getColumnIndex("author"));
mDescription = c.getString(c.getColumnIndex("description"));
minMagiskVersion = c.getInt(c.getColumnIndex("minMagisk"));
}
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put("id", mId);
values.put("name", mName);
values.put("version", mVersion);
values.put("versionCode", mVersionCode);
values.put("author", mAuthor);
values.put("description", mDescription);
values.put("minMagisk", minMagiskVersion);
return values;
}
protected void parseProps(List<String> props) { parseProps(props.toArray(new String[0])); }
protected void parseProps(String[] props) throws NumberFormatException {
for (String line : props) {
String[] prop = line.split("=", 2);
if (prop.length != 2)
continue;
String key = prop[0].trim();
String value = prop[1].trim();
if (key.isEmpty() || key.charAt(0) == '#')
continue;
switch (key) {
case "id":
mId = value;
break;
case "name":
mName = value;
break;
case "version":
mVersion = value;
break;
case "versionCode":
mVersionCode = Integer.parseInt(value);
break;
case "author":
mAuthor = value;
break;
case "description":
mDescription = value;
break;
case "minMagisk":
case "template":
minMagiskVersion = Integer.parseInt(value);
break;
default:
break;
}
}
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getVersion() {
return mVersion;
}
public String getAuthor() {
return mAuthor;
}
public String getId() {
return mId;
}
public void setId(String id) {
mId = id;
}
public String getDescription() {
return mDescription;
}
public int getVersionCode() {
return mVersionCode;
}
public int getMinMagiskVersion() {
return minMagiskVersion;
}
@Override
public int compareTo(@NonNull BaseModule module) {
return this.getName().toLowerCase().compareTo(module.getName().toLowerCase());
}
}
package com.topjohnwu.magisk.container;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.io.SuFile;
public class Module extends BaseModule {
private SuFile mRemoveFile, mDisableFile, mUpdateFile;
private boolean mEnable, mRemove, mUpdated;
public Module(String path) {
try {
parseProps(Shell.Sync.su("dos2unix < " + path + "/module.prop"));
} catch (NumberFormatException ignored) {}
mRemoveFile = new SuFile(path + "/remove");
mDisableFile = new SuFile(path + "/disable");
mUpdateFile = new SuFile(path + "/update");
if (getId() == null) {
int sep = path.lastIndexOf('/');
setId(path.substring(sep + 1));
}
if (getName() == null) {
setName(getId());
}
mEnable = !mDisableFile.exists();
mRemove = mRemoveFile.exists();
mUpdated = mUpdateFile.exists();
}
public void createDisableFile() {
mEnable = false;
mDisableFile.createNewFile();
}
public void removeDisableFile() {
mEnable = true;
mDisableFile.delete();
}
public boolean isEnabled() {
return mEnable;
}
public void createRemoveFile() {
mRemove = true;
mRemoveFile.createNewFile();
}
public void deleteRemoveFile() {
mRemove = false;
mRemoveFile.delete();
}
public boolean willBeRemoved() {
return mRemove;
}
public boolean isUpdated() {
return mUpdated;
}
}
\ No newline at end of file
package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.support.annotation.NonNull;
public class Policy implements Comparable<Policy>{
public static final int INTERACTIVE = 0;
public static final int DENY = 1;
public static final int ALLOW = 2;
public int uid, policy = INTERACTIVE;
public long until;
public boolean logging = true, notification = true;
public String packageName, appName;
public ApplicationInfo info;
public Policy(int uid, PackageManager pm) throws PackageManager.NameNotFoundException {
String[] pkgs = pm.getPackagesForUid(uid);
if (pkgs == null || pkgs.length == 0)
throw new PackageManager.NameNotFoundException();
this.uid = uid;
packageName = pkgs[0];
info = pm.getApplicationInfo(packageName, 0);
appName = info.loadLabel(pm).toString();
}
public Policy(Cursor c, PackageManager pm) throws PackageManager.NameNotFoundException {
uid = c.getInt(c.getColumnIndex("uid"));
packageName = c.getString(c.getColumnIndex("package_name"));
policy = c.getInt(c.getColumnIndex("policy"));
until = c.getLong(c.getColumnIndex("until"));
logging = c.getInt(c.getColumnIndex("logging")) != 0;
notification = c.getInt(c.getColumnIndex("notification")) != 0;
info = pm.getApplicationInfo(packageName, 0);
if (info.uid != uid)
throw new PackageManager.NameNotFoundException();
appName = info.loadLabel(pm).toString();
}
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put("uid", uid);
values.put("package_name", packageName);
values.put("policy", policy);
values.put("until", until);
values.put("logging", logging ? 1 : 0);
values.put("notification", notification ? 1 : 0);
return values;
}
@Override
public int compareTo(@NonNull Policy policy) {
return appName.toLowerCase().compareTo(policy.appName.toLowerCase());
}
}
package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.database.Cursor;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import java.text.DateFormat;
import java.util.Date;
public class Repo extends BaseModule {
private String repoName;
private Date mLastUpdate;
public Repo(String name) {
repoName = name;
}
public Repo(Cursor c) {
super(c);
repoName = c.getString(c.getColumnIndex("repo_name"));
mLastUpdate = new Date(c.getLong(c.getColumnIndex("last_update")));
}
public void update() throws IllegalRepoException {
String props[] = Utils.dos2unix(WebService.getString(getManifestUrl())).split("\\n");
try {
parseProps(props);
} catch (NumberFormatException e) {
throw new IllegalRepoException("Repo [" + repoName + "] parse error: " + e.getMessage());
}
if (getId() == null) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain id");
}
if (getVersionCode() < 0) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain versionCode");
}
if (getMinMagiskVersion() < Const.MIN_MODULE_VER()) {
Logger.debug("Repo [" + repoName + "] is outdated");
}
}
public void update(Date lastUpdate) throws IllegalRepoException {
mLastUpdate = lastUpdate;
update();
}
@Override
public ContentValues getContentValues() {
ContentValues values = super.getContentValues();
values.put("repo_name", repoName);
values.put("last_update", mLastUpdate.getTime());
return values;
}
public String getRepoName() {
return repoName;
}
public String getZipUrl() {
return String.format(Const.Url.ZIP_URL, repoName);
}
public String getManifestUrl() {
return String.format(Const.Url.FILE_URL, repoName, "module.prop");
}
public String getDetailUrl() {
return String.format(Const.Url.FILE_URL, repoName, "README.md");
}
public String getLastUpdateString() {
return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM,
MagiskManager.locale).format(mLastUpdate);
}
public Date getLastUpdate() {
return mLastUpdate;
}
public class IllegalRepoException extends Exception {
IllegalRepoException(String message) {
super(message);
}
}
}
package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.database.Cursor;
import com.topjohnwu.magisk.MagiskManager;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SuLogEntry {
public int fromUid, toUid, fromPid;
public String packageName, appName, command;
public boolean action;
public Date date;
public SuLogEntry(Policy policy) {
fromUid = policy.uid;
packageName = policy.packageName;
appName = policy.appName;
}
public SuLogEntry(Cursor c) {
fromUid = c.getInt(c.getColumnIndex("from_uid"));
fromPid = c.getInt(c.getColumnIndex("from_pid"));
toUid = c.getInt(c.getColumnIndex("to_uid"));
packageName = c.getString(c.getColumnIndex("package_name"));
appName = c.getString(c.getColumnIndex("app_name"));
command = c.getString(c.getColumnIndex("command"));
action = c.getInt(c.getColumnIndex("action")) != 0;
date = new Date(c.getLong(c.getColumnIndex("time")));
}
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put("from_uid", fromUid);
values.put("package_name", packageName);
values.put("app_name", appName);
values.put("from_pid", fromPid);
values.put("command", command);
values.put("to_uid", toUid);
values.put("action", action ? 1 : 0);
values.put("time", date.getTime());
return values;
}
public String getDateString() {
return DateFormat.getDateInstance(DateFormat.MEDIUM, MagiskManager.locale).format(date);
}
public String getTimeString() {
return new SimpleDateFormat("h:mm a", MagiskManager.locale).format(date);
}
}
package com.topjohnwu.magisk.container;
import org.kamranzafar.jtar.TarHeader;
import java.io.File;
import java.util.Arrays;
public class TarEntry extends org.kamranzafar.jtar.TarEntry {
public TarEntry(File file, String entryName) {
super(file, entryName);
}
/*
* Workaround missing java.nio.file.attribute.PosixFilePermission
* Simply just assign a default permission to the file
* */
@Override
public void extractTarHeader(String entryName) {
int permissions = file.isDirectory() ? 000755 : 000644;
header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory(), permissions);
header.userName = new StringBuffer("");
header.groupName = header.userName;
}
/*
* Rewrite the header to GNU format
* */
@Override
public void writeEntryHeader(byte[] outbuf) {
super.writeEntryHeader(outbuf);
System.arraycopy("ustar \0".getBytes(), 0, outbuf, 257, TarHeader.USTAR_MAGICLEN);
getOctalBytes(header.mode, outbuf, 100, TarHeader.MODELEN);
getOctalBytes(header.userId, outbuf, 108, TarHeader.UIDLEN);
getOctalBytes(header.groupId, outbuf, 116, TarHeader.GIDLEN);
getOctalBytes(header.size, outbuf, 124, TarHeader.SIZELEN);
getOctalBytes(header.modTime, outbuf, 136, TarHeader.MODTIMELEN);
Arrays.fill(outbuf, 148, 148 + TarHeader.CHKSUMLEN, (byte) ' ');
Arrays.fill(outbuf, 329, 329 + TarHeader.USTAR_DEVLEN, (byte) '\0');
Arrays.fill(outbuf, 337, 337 + TarHeader.USTAR_DEVLEN, (byte) '\0');
// Recalculate checksum
getOctalBytes(computeCheckSum(outbuf), outbuf, 148, TarHeader.CHKSUMLEN);
}
/*
* Proper octal to ASCII conversion
* */
private void getOctalBytes(long value, byte[] buf, int offset, int length) {
int idx = length - 1;
buf[offset + idx] = 0;
--idx;
for (long val = value; idx >= 0; --idx) {
buf[offset + idx] = (byte) ((byte) '0' + (byte) (val & 7));
val = val >> 3;
}
}
}
package com.topjohnwu.magisk.container;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ValueSortedMap<K, V extends Comparable<? super V>> extends HashMap<K, V> {
private List<V> sorted = new ArrayList<>();
@NonNull
@Override
public Collection<V> values() {
if (sorted.isEmpty()) {
sorted.addAll(super.values());
Collections.sort(sorted);
}
return sorted;
}
@Override
public V put(K key, V value) {
sorted.clear();
return super.put(key, value);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
sorted.clear();
super.putAll(m);
}
@Override
public V remove(Object key) {
sorted.clear();
return super.remove(key);
}
}
package com.topjohnwu.magisk.database;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Process;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.io.SuFile;
import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class MagiskDatabaseHelper {
private static final int DATABASE_VER = 5;
private static final String POLICY_TABLE = "policies";
private static final String LOG_TABLE = "logs";
private static final String SETTINGS_TABLE = "settings";
private static final String STRINGS_TABLE = "strings";
private PackageManager pm;
private SQLiteDatabase db;
@NonNull
public static MagiskDatabaseHelper getInstance(MagiskManager mm) {
try {
return new MagiskDatabaseHelper(mm);
} catch (Exception e) {
// Let's cleanup everything and try again
Shell.Sync.su("db_clean '*'");
return new MagiskDatabaseHelper(mm);
}
}
private MagiskDatabaseHelper(MagiskManager mm) {
pm = mm.getPackageManager();
db = openDatabase(mm);
db.disableWriteAheadLogging();
int version = db.getVersion();
if (version < DATABASE_VER) {
onUpgrade(db, version);
} else if (version > DATABASE_VER) {
onDowngrade(db);
}
db.setVersion(DATABASE_VER);
clearOutdated();
}
private SQLiteDatabase openDatabase(MagiskManager mm) {
final File DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? mm.createDeviceProtectedStorageContext() : mm;
if (!DB_FILE.canWrite()) {
if (!Shell.rootAccess()) {
// We don't want the app to crash, create a db and return
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
}
mm.loadMagiskInfo();
// Cleanup
Shell.Sync.su("db_clean " + Const.USER_ID);
if (mm.magiskVersionCode < Const.MAGISK_VER.FBE_AWARE) {
// Super old legacy mode
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else if (mm.magiskVersionCode < Const.MAGISK_VER.HIDDEN_PATH) {
// Legacy mode with FBE aware
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
de.moveDatabaseFrom(mm, "su.db");
}
return de.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else {
// Global database
final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db");
mm.deleteDatabase("su.db");
de.deleteDatabase("su.db");
if (mm.magiskVersionCode < Const.MAGISK_VER.SEPOL_REFACTOR) {
// We need some additional policies on old versions
Shell.Sync.su("db_sepatch");
}
if (!GLOBAL_DB.exists()) {
Shell.Sync.su("db_init");
SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close();
Shell.Sync.su("db_restore");
}
}
Shell.Sync.su("db_setup " + Process.myUid());
}
// Not using legacy mode, open the mounted global DB
return SQLiteDatabase.openOrCreateDatabase(DB_FILE, null);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion) {
if (oldVersion == 0) {
createTables(db);
oldVersion = 3;
}
if (oldVersion == 1) {
// We're dropping column app_name, rename and re-construct table
db.execSQL(Utils.fmt("ALTER TABLE %s RENAME TO %s_old", POLICY_TABLE));
// Create the new tables
createTables(db);
// Migrate old data to new tables
db.execSQL(Utils.fmt("INSERT INTO %s SELECT " +
"uid, package_name, policy, until, logging, notification FROM %s_old",
POLICY_TABLE, POLICY_TABLE));
db.execSQL(Utils.fmt("DROP TABLE %s_old", POLICY_TABLE));
MagiskManager.get().deleteDatabase("sulog.db");
++oldVersion;
}
if (oldVersion == 2) {
db.execSQL(Utils.fmt("UPDATE %s SET time=time*1000", LOG_TABLE));
++oldVersion;
}
if (oldVersion == 3) {
db.execSQL(Utils.fmt("CREATE TABLE IF NOT EXISTS %s (key TEXT, value TEXT, PRIMARY KEY(key))", STRINGS_TABLE));
++oldVersion;
}
if (oldVersion == 4) {
db.execSQL(Utils.fmt("UPDATE %s SET uid=uid%%100000", POLICY_TABLE));
++oldVersion;
}
}
// Remove everything, we do not support downgrade
public void onDowngrade(SQLiteDatabase db) {
MagiskManager.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG);
db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + SETTINGS_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + STRINGS_TABLE);
onUpgrade(db, 0);
}
private void createTables(SQLiteDatabase db) {
// Policies
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + POLICY_TABLE + " " +
"(uid INT, package_name TEXT, policy INT, " +
"until INT, logging INT, notification INT, " +
"PRIMARY KEY(uid))");
// Logs
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + LOG_TABLE + " " +
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " +
"to_uid INT, action INT, time INT, command TEXT)");
// Settings
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + SETTINGS_TABLE + " " +
"(key TEXT, value INT, PRIMARY KEY(key))");
}
public void clearOutdated() {
// Clear outdated policies
db.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
// Clear outdated logs
db.delete(LOG_TABLE, Utils.fmt("time < %d", System.currentTimeMillis() - MagiskManager.get().suLogTimeout * 86400000), null);
}
public void deletePolicy(Policy policy) {
deletePolicy(policy.uid);
}
public void deletePolicy(String pkg) {
db.delete(POLICY_TABLE, "package_name=?", new String[] { pkg });
}
public void deletePolicy(int uid) {
db.delete(POLICY_TABLE, Utils.fmt("uid=%d", uid), null);
}
public Policy getPolicy(int uid) {
Policy policy = null;
try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid=%d", uid), null, null, null, null)) {
if (c.moveToNext()) {
policy = new Policy(c, pm);
}
} catch (PackageManager.NameNotFoundException e) {
deletePolicy(uid);
return null;
}
return policy;
}
public void addPolicy(Policy policy) {
db.replace(POLICY_TABLE, null, policy.getContentValues());
}
public void updatePolicy(Policy policy) {
db.update(POLICY_TABLE, policy.getContentValues(), Utils.fmt("uid=%d", policy.uid), null);
}
public List<Policy> getPolicyList(PackageManager pm) {
try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid/100000=%d", Const.USER_ID),
null, null, null, null)) {
List<Policy> ret = new ArrayList<>(c.getCount());
while (c.moveToNext()) {
try {
Policy policy = new Policy(c, pm);
ret.add(policy);
} catch (PackageManager.NameNotFoundException e) {
// The app no longer exist, remove from DB
deletePolicy(c.getInt(c.getColumnIndex("uid")));
}
}
Collections.sort(ret);
return ret;
}
}
public List<List<Integer>> getLogStructure() {
try (Cursor c = db.query(LOG_TABLE, new String[] { "time" }, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
null, null, null, "time DESC")) {
List<List<Integer>> ret = new ArrayList<>();
List<Integer> list = null;
String dateString = null, newString;
while (c.moveToNext()) {
Date date = new Date(c.getLong(c.getColumnIndex("time")));
newString = DateFormat.getDateInstance(DateFormat.MEDIUM, MagiskManager.locale).format(date);
if (!TextUtils.equals(dateString, newString)) {
dateString = newString;
list = new ArrayList<>();
ret.add(list);
}
list.add(c.getPosition());
}
return ret;
}
}
public Cursor getLogCursor() {
return db.query(LOG_TABLE, null, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
null, null, null, "time DESC");
}
public void addLog(SuLogEntry log) {
db.insert(LOG_TABLE, null, log.getContentValues());
}
public void clearLogs() {
db.delete(LOG_TABLE, null, null);
}
public void setSettings(String key, int value) {
ContentValues data = new ContentValues();
data.put("key", key);
data.put("value", value);
db.replace(SETTINGS_TABLE, null, data);
}
public int getSettings(String key, int defaultValue) {
int value = defaultValue;
try (Cursor c = db.query(SETTINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
if (c.moveToNext()) {
value = c.getInt(c.getColumnIndex("value"));
}
}
return value;
}
public void setStrings(String key, String value) {
if (value == null) {
db.delete(STRINGS_TABLE, "key=?", new String[] { key });
} else {
ContentValues data = new ContentValues();
data.put("key", key);
data.put("value", value);
db.replace(STRINGS_TABLE, null, data);
}
}
public String getStrings(String key, String defaultValue) {
String value = defaultValue;
try (Cursor c = db.query(STRINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
if (c.moveToNext()) {
value = c.getString(c.getColumnIndex("value"));
}
}
return value;
}
}
package com.topjohnwu.magisk.database;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.container.Repo;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import java.util.HashSet;
import java.util.Set;
public class RepoDatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VER = 3;
private static final String TABLE_NAME = "repos";
private SQLiteDatabase mDb;
private MagiskManager mm;
public RepoDatabaseHelper(Context context) {
super(context, "repo.db", null, DATABASE_VER);
mm = Utils.getMagiskManager(context);
mDb = getWritableDatabase();
// Remove outdated repos
mDb.delete(TABLE_NAME, "minMagisk<?",
new String[] { String.valueOf(Const.MIN_MODULE_VER()) });
}
@Override
public void onCreate(SQLiteDatabase db) {
onUpgrade(db, 0, DATABASE_VER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
if (oldVersion < 3) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " " +
"(id TEXT, name TEXT, version TEXT, versionCode INT, minMagisk INT, " +
"author TEXT, description TEXT, repo_name TEXT, last_update INT, " +
"PRIMARY KEY(id))");
mm.prefs.edit().remove(Const.Key.ETAG_KEY).apply();
oldVersion = 3;
}
} catch (Exception e) {
e.printStackTrace();
// Reset database
onDowngrade(db, DATABASE_VER, 0);
}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, 0, DATABASE_VER);
}
public void clearRepo() {
mDb.delete(TABLE_NAME, null, null);
}
public void removeRepo(String id) {
mDb.delete(TABLE_NAME, "id=?", new String[] { id });
}
public void removeRepo(Repo repo) {
mDb.delete(TABLE_NAME, "repo_name=?", new String[] { repo.getRepoName() });
}
public void removeRepo(Iterable<String> list) {
for (String id : list) {
if (id == null) continue;
mDb.delete(TABLE_NAME, "id=?", new String[] { id });
}
}
public void addRepo(Repo repo) {
mDb.replace(TABLE_NAME, null, repo.getContentValues());
}
public Repo getRepo(String id) {
try (Cursor c = mDb.query(TABLE_NAME, null, "id=?", new String[] { id }, null, null, null)) {
if (c.moveToNext()) {
return new Repo(c);
}
}
return null;
}
public Cursor getRawCursor() {
return mDb.query(TABLE_NAME, null, null, null, null, null, null);
}
public Cursor getRepoCursor() {
String orderBy = null;
switch (mm.repoOrder) {
case Const.Value.ORDER_NAME:
orderBy = "name COLLATE NOCASE";
break;
case Const.Value.ORDER_DATE:
orderBy = "last_update DESC";
}
return mDb.query(TABLE_NAME, null, "minMagisk<=? AND minMagisk>=?",
new String[] { String.valueOf(mm.magiskVersionCode), String.valueOf(Const.MIN_MODULE_VER()) },
null, null, orderBy);
}
public Set<String> getRepoIDSet() {
HashSet<String> set = new HashSet<>(300);
try (Cursor c = mDb.query(TABLE_NAME, null, null, null, null, null, null)) {
while (c.moveToNext()) {
set.add(c.getString(c.getColumnIndex("id")));
}
}
return set;
}
}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import com.topjohnwu.magisk.services.OnBootIntentService;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, OnBootIntentService.class));
} else {
context.startService(new Intent(context, OnBootIntentService.class));
}
}
}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.PatchAPK;
import com.topjohnwu.magisk.utils.Utils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class ManagerUpdate extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Utils.dlAndReceive(
context, new PatchedInstall(),
intent.getStringExtra(Const.Key.INTENT_SET_LINK),
intent.getStringExtra(Const.Key.INTENT_SET_FILENAME)
);
}
private static class PatchedInstall extends ManagerInstall {
@Override
public void onDownloadDone(Context context, Uri uri) {
if (!context.getPackageName().equals(Const.ORIG_PKG_NAME)) {
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
String o = uri.getPath();
String p = o.substring(0, o.lastIndexOf('.')) + "-patched.apk";
try {
PatchAPK.patchPackageID(o, new BufferedOutputStream(new FileOutputStream(p)),
Const.ORIG_PKG_NAME, context.getPackageName());
} catch (FileNotFoundException ignored) { }
super.onDownloadDone(context, Uri.fromFile(new File(p)));
});
} else {
super.onDownloadDone(context, uri);
}
}
}
}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class PackageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
MagiskManager mm = Utils.getMagiskManager(context);
String pkg = intent.getData().getEncodedSchemeSpecificPart();
switch (intent.getAction()) {
case Intent.ACTION_PACKAGE_REPLACED:
// This will only work pre-O
if (mm.prefs.getBoolean(Const.Key.SU_REAUTH, false)) {
mm.mDB.deletePolicy(pkg);
}
break;
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
mm.mDB.deletePolicy(pkg);
Shell.Async.su("magiskhide --rm " + pkg);
break;
}
}
}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.topjohnwu.superuser.Shell;
public class RebootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Shell.Async.su("/system/bin/reboot");
}
}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.SplashActivity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
public class ShortcutReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
MagiskManager mm = Utils.getMagiskManager(context);
ShortcutManager manager = context.getSystemService(ShortcutManager.class);
if (TextUtils.equals(intent.getAction(), Intent.ACTION_LOCALE_CHANGED)) {
// It is triggered with locale change, manual load Magisk info
mm.loadMagiskInfo();
}
manager.setDynamicShortcuts(getShortCuts(mm));
}
}
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
private ArrayList<ShortcutInfo> getShortCuts(MagiskManager mm) {
ArrayList<ShortcutInfo> shortCuts = new ArrayList<>();
if (Shell.rootAccess() &&
!(Const.USER_ID > 0 &&
mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
shortCuts.add(new ShortcutInfo.Builder(mm, "superuser")
.setShortLabel(mm.getString(R.string.superuser))
.setIntent(new Intent(mm, SplashActivity.class)
.putExtra(Const.Key.OPEN_SECTION, "superuser")
.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
.setIcon(Icon.createWithResource(mm, R.drawable.sc_superuser))
.setRank(0)
.build());
}
if (Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false)) {
shortCuts.add(new ShortcutInfo.Builder(mm, "magiskhide")
.setShortLabel(mm.getString(R.string.magiskhide))
.setIntent(new Intent(mm, SplashActivity.class)
.putExtra(Const.Key.OPEN_SECTION, "magiskhide")
.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
.setIcon(Icon.createWithResource(mm, R.drawable.sc_magiskhide))
.setRank(1)
.build());
}
if (!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
Shell.rootAccess() && mm.magiskVersionCode >= 0) {
shortCuts.add(new ShortcutInfo.Builder(mm, "modules")
.setShortLabel(mm.getString(R.string.modules))
.setIntent(new Intent(mm, SplashActivity.class)
.putExtra(Const.Key.OPEN_SECTION, "modules")
.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
.setIcon(Icon.createWithResource(mm, R.drawable.sc_extension))
.setRank(3)
.build());
shortCuts.add(new ShortcutInfo.Builder(mm, "downloads")
.setShortLabel(mm.getString(R.string.download))
.setIntent(new Intent(mm, SplashActivity.class)
.putExtra(Const.Key.OPEN_SECTION, "downloads")
.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
.setIcon(Icon.createWithResource(mm, R.drawable.sc_cloud_download))
.setRank(2)
.build());
}
return shortCuts;
}
}
package com.topjohnwu.magisk.services;
import android.app.IntentService;
import android.content.Intent;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.RootUtils;
public class OnBootIntentService extends IntentService {
public OnBootIntentService() {
super("OnBootIntentService");
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(Const.ID.ONBOOT_NOTIFICATION_ID,
new NotificationCompat.Builder(this, Const.ID.NOTIFICATION_CHANNEL)
.setSmallIcon(R.drawable.ic_magisk_outline)
.setContentTitle("Startup Operations")
.setContentText("Running startup operations...")
.build());
}
}
@Override
protected void onHandleIntent(Intent intent) {
/* Pixel 2 (XL) devices will need to patch dtbo.img.
* However, that is not possible if Magisk is installed by
* patching boot image with Magisk Manager and fastboot flash
* the boot image, since at that time we do not have root.
* Check for dtbo status every boot time, and prompt user
* to reboot if dtbo wasn't patched and patched by Magisk Manager.
* */
MagiskManager.get().loadMagiskInfo();
RootUtils.patchDTBO();
}
}
package com.topjohnwu.magisk.services;
import android.app.job.JobParameters;
import android.app.job.JobService;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.utils.Utils;
public class UpdateCheckService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
Utils.getMagiskManager(this).loadMagiskInfo();
new CheckUpdates(true)
.setCallBack(() -> jobFinished(params, false)).exec();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return true;
}
}
package com.topjohnwu.magisk.superuser;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.FileObserver;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Utils;
import java.io.DataInputStream;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
public class RequestActivity extends Activity {
@BindView(R.id.su_popup) LinearLayout suPopup;
@BindView(R.id.timeout) Spinner timeout;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appNameView;
@BindView(R.id.package_name) TextView packageNameView;
@BindView(R.id.grant_btn) Button grant_btn;
@BindView(R.id.deny_btn) Button deny_btn;
@BindView(R.id.fingerprint) ImageView fingerprintImg;
@BindView(R.id.warning) TextView warning;
private String socketPath;
private LocalSocket socket;
private PackageManager pm;
private MagiskManager mm;
private boolean hasTimeout;
private Policy policy;
private CountDownTimer timer;
private FingerprintHelper fingerprintHelper;
@Override
public int getDarkTheme() {
return R.style.SuRequest_Dark;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
pm = getPackageManager();
mm = Utils.getMagiskManager(this);
mm.mDB.clearOutdated();
Intent intent = getIntent();
socketPath = intent.getStringExtra("socket");
hasTimeout = intent.getBooleanExtra("timeout", true);
new FileObserver(socketPath) {
@Override
public void onEvent(int fileEvent, String path) {
if (fileEvent == FileObserver.DELETE_SELF) {
finish();
}
}
}.startWatching();
new SocketManager(this).exec();
}
@Override
public void finish() {
if (timer != null)
timer.cancel();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
super.finish();
}
private boolean cancelTimeout() {
timer.cancel();
deny_btn.setText(getString(R.string.deny));
return false;
}
private void showRequest() {
switch (mm.suResponseType) {
case Const.Value.SU_AUTO_DENY:
handleAction(Policy.DENY, 0);
return;
case Const.Value.SU_AUTO_ALLOW:
handleAction(Policy.ALLOW, 0);
return;
case Const.Value.SU_PROMPT:
default:
}
// If not interactive, response directly
if (policy.policy != Policy.INTERACTIVE) {
handleAction();
return;
}
setContentView(R.layout.activity_request);
ButterKnife.bind(this);
appIcon.setImageDrawable(policy.info.loadIcon(pm));
appNameView.setText(policy.appName);
packageNameView.setText(policy.packageName);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.allow_timeout, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
timeout.setAdapter(adapter);
timer = new CountDownTimer(mm.suRequestTimeout * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
deny_btn.setText(getString(R.string.deny_with_str, "(" + millisUntilFinished / 1000 + ")"));
}
@Override
public void onFinish() {
deny_btn.setText(getString(R.string.deny_with_str, "(0)"));
handleAction(Policy.DENY);
}
};
boolean useFingerprint = mm.prefs.getBoolean(Const.Key.SU_FINGERPRINT, false) && FingerprintHelper.canUseFingerprint();
if (useFingerprint) {
try {
fingerprintHelper = new FingerprintHelper() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
warning.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
warning.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
handleAction(Policy.ALLOW);
}
@Override
public void onAuthenticationFailed() {
warning.setText(R.string.auth_fail);
}
};
fingerprintHelper.startAuth();
} catch (Exception e) {
e.printStackTrace();
useFingerprint = false;
}
}
if (!useFingerprint) {
grant_btn.setOnClickListener(v -> {
handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
}
grant_btn.setVisibility(useFingerprint ? View.GONE : View.VISIBLE);
fingerprintImg.setVisibility(useFingerprint ? View.VISIBLE : View.GONE);
deny_btn.setOnClickListener(v -> {
handleAction(Policy.DENY);
timer.cancel();
});
suPopup.setOnClickListener(v -> cancelTimeout());
timeout.setOnTouchListener((v, event) -> cancelTimeout());
if (hasTimeout) {
timer.start();
} else {
cancelTimeout();
}
}
@Override
public void onBackPressed() {
if (policy != null) {
handleAction(Policy.DENY);
} else {
finish();
}
}
void handleAction() {
String response;
if (policy.policy == Policy.ALLOW) {
response = "socket:ALLOW";
} else {
response = "socket:DENY";
}
try {
socket.getOutputStream().write((response).getBytes());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
finish();
}
void handleAction(int action) {
handleAction(action, Const.Value.timeoutList[timeout.getSelectedItemPosition()]);
}
void handleAction(int action, int time) {
policy.policy = action;
if (time >= 0) {
policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
mm.mDB.addPolicy(policy);
}
handleAction();
}
private class SocketManager extends ParallelTask<Void, Void, Boolean> {
SocketManager(Activity context) {
super(context);
}
@Override
protected Boolean doInBackground(Void... params) {
try {
socket = new LocalSocket();
socket.connect(new LocalSocketAddress(socketPath, LocalSocketAddress.Namespace.FILESYSTEM));
DataInputStream is = new DataInputStream(socket.getInputStream());
ContentValues payload = new ContentValues();
while (true) {
int nameLen = is.readInt();
byte[] nameBytes = new byte[nameLen];
is.readFully(nameBytes);
String name = new String(nameBytes);
if (TextUtils.equals(name, "eof"))
break;
int dataLen = is.readInt();
byte[] dataBytes = new byte[dataLen];
is.readFully(dataBytes);
String data = new String(dataBytes);
payload.put(name, data);
}
if (payload.getAsInteger("uid") == null) {
return false;
}
int uid = payload.getAsInteger("uid");
policy = mm.mDB.getPolicy(uid);
if (policy == null) {
policy = new Policy(uid, pm);
}
/* Never allow com.topjohnwu.magisk (could be malware) */
if (TextUtils.equals(policy.packageName, Const.ORIG_PKG_NAME))
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
showRequest();
} else {
finish();
}
}
}
}
package com.topjohnwu.magisk.superuser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Process;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import java.util.Date;
public class SuReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int fromUid, toUid, pid, mode;
String command, action;
Policy policy;
MagiskManager mm = Utils.getMagiskManager(context);
if (intent == null) return;
mode = intent.getIntExtra("mode", -1);
if (mode < 0) return;
if (mode == Const.Value.NOTIFY_USER_TO_OWNER) {
MagiskManager.toast(R.string.multiuser_hint_owner_request, Toast.LENGTH_LONG);
return;
}
fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return;
if (fromUid == Process.myUid()) return; // Don't show anything if it's Magisk Manager
action = intent.getStringExtra("action");
if (action == null) return;
policy = mm.mDB.getPolicy(fromUid);
if (policy == null) {
try {
policy = new Policy(fromUid, context.getPackageManager());
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return;
}
}
SuLogEntry log = new SuLogEntry(policy);
String message;
switch (action) {
case "allow":
message = context.getString(R.string.su_allow_toast, policy.appName);
log.action = true;
break;
case "deny":
message = context.getString(R.string.su_deny_toast, policy.appName);
log.action = false;
break;
default:
return;
}
if (policy.notification && mm.suNotificationType == Const.Value.NOTIFICATION_TOAST) {
MagiskManager.toast(message, Toast.LENGTH_SHORT);
}
if (mode == Const.Value.NOTIFY_NORMAL_LOG && policy.logging) {
toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return;
pid = intent.getIntExtra("pid", -1);
if (pid < 0) return;
command = intent.getStringExtra("command");
if (command == null) return;
log.toUid = toUid;
log.fromPid = pid;
log.command = command;
log.date = new Date();
mm.mDB.addLog(log);
}
}
}
package com.topjohnwu.magisk.utils;
import android.support.annotation.Keep;
import com.topjohnwu.utils.SignBoot;
import java.io.FileInputStream;
import java.io.InputStream;
public class BootSigner {
@Keep
public static void main(String[] args) throws Exception {
if (args.length > 0 && "-verify".equals(args[0])) {
String certPath = "";
if (args.length >= 2) {
/* args[1] is the path to a public key certificate */
certPath = args[1];
}
boolean signed = SignBoot.verifySignature(System.in,
certPath.isEmpty() ? null : new FileInputStream(certPath));
System.exit(signed ? 0 : 1);
} else if (args.length > 0 && "-sign".equals(args[0])) {
InputStream cert = null;
InputStream key = null;
if (args.length >= 3) {
cert = new FileInputStream(args[1]);
key = new FileInputStream(args[2]);
}
boolean success = SignBoot.doSignature("/boot", System.in, System.out, cert, key);
System.exit(success ? 0 : 1);
} else {
System.err.println(
"BootSigner <actions> [args]\n" +
"Input from stdin, outputs to stdout\n" +
"\n" +
"Actions:\n" +
" -verify [x509.pem]\n" +
" verify image, cert is optional\n" +
" -sign [x509.pem] [pk8]\n" +
" sign image, cert and key pair is optional\n"
);
}
}
}
package com.topjohnwu.magisk.utils;
import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import com.topjohnwu.magisk.MagiskManager;
import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@TargetApi(Build.VERSION_CODES.M)
public abstract class FingerprintHelper {
private FingerprintManager manager;
private Cipher cipher;
private CancellationSignal cancel;
public static boolean canUseFingerprint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
return false;
MagiskManager mm = MagiskManager.get();
KeyguardManager km = mm.getSystemService(KeyguardManager.class);
FingerprintManager fm = mm.getSystemService(FingerprintManager.class);
return km.isKeyguardSecure() && fm != null && fm.isHardwareDetected() && fm.hasEnrolledFingerprints();
}
protected FingerprintHelper() throws Exception {
MagiskManager mm = MagiskManager.get();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
manager = mm.getSystemService(FingerprintManager.class);
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(Const.SU_KEYSTORE_KEY, null);
if (key == null) {
key = generateKey();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (KeyPermanentlyInvalidatedException e) {
// Only happens on Marshmallow
key = generateKey();
cipher.init(Cipher.ENCRYPT_MODE, key);
}
}
public abstract void onAuthenticationError(int errorCode, CharSequence errString);
public abstract void onAuthenticationHelp(int helpCode, CharSequence helpString);
public abstract void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result);
public abstract void onAuthenticationFailed();
public void startAuth() {
cancel = new CancellationSignal();
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
manager.authenticate(cryptoObject, cancel, 0, new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
FingerprintHelper.this.onAuthenticationError(errorCode, errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
FingerprintHelper.this.onAuthenticationHelp(helpCode, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
FingerprintHelper.this.onAuthenticationSucceeded(result);
}
@Override
public void onAuthenticationFailed() {
FingerprintHelper.this.onAuthenticationFailed();
}
}, null);
}
public void cancel() {
if (cancel != null)
cancel.cancel();
}
private SecretKey generateKey() throws Exception {
KeyGenerator keygen = KeyGenerator
.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
Const.SU_KEYSTORE_KEY,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setInvalidatedByBiometricEnrollment(false);
}
keygen.init(builder.build());
return keygen.generateKey();
}
}
package com.topjohnwu.magisk.utils;
import android.support.annotation.Keep;
public interface ISafetyNetHelper {
int CAUSE_SERVICE_DISCONNECTED = 0x01;
int CAUSE_NETWORK_LOST = 0x02;
int RESPONSE_ERR = 0x04;
int CONNECTION_FAIL = 0x08;
int BASIC_PASS = 0x10;
int CTS_PASS = 0x20;
void attest();
int getVersion();
interface Callback {
@Keep
void onResponse(int responseCode);
}
}
package com.topjohnwu.magisk.utils;
import android.util.Log;
import com.topjohnwu.magisk.BuildConfig;
import java.util.Locale;
public class Logger {
public static void debug(String line) {
if (BuildConfig.DEBUG)
Log.d(Const.DEBUG_TAG, "DEBUG: " + line);
}
public static void debug(String fmt, Object... args) {
debug(Utils.fmt(fmt, args));
}
public static void error(String line) {
Log.e(Const.DEBUG_TAG, "ERROR: " + line);
}
public static void error(String fmt, Object... args) {
error(Utils.fmt(fmt, args));
}
}
package com.topjohnwu.magisk.utils;
import com.topjohnwu.utils.JarMap;
import java.io.OutputStream;
import java.util.jar.JarEntry;
public class PatchAPK {
private static int findOffset(byte buf[], byte pattern[]) {
int offset = -1;
for (int i = 0; i < buf.length - pattern.length; ++i) {
boolean match = true;
for (int j = 0; j < pattern.length; ++j) {
if (buf[i + j] != pattern[j]) {
match = false;
break;
}
}
if (match) {
offset = i;
break;
}
}
return offset;
}
/* It seems that AAPT sometimes generate another type of string format */
private static boolean fallbackPatch(byte xml[], String from, String to) {
byte[] target = new byte[from.length() * 2 + 2];
for (int i = 0; i < from.length(); ++i) {
target[i * 2] = (byte) from.charAt(i);
}
int offset = findOffset(xml, target);
if (offset < 0)
return false;
byte[] dest = new byte[target.length - 2];
for (int i = 0; i < to.length(); ++i) {
dest[i * 2] = (byte) to.charAt(i);
}
System.arraycopy(dest, 0, xml, offset, dest.length);
return true;
}
private static boolean findAndPatch(byte xml[], String from, String to) {
byte target[] = (from + '\0').getBytes();
int offset = findOffset(xml, target);
if (offset < 0)
return fallbackPatch(xml, from, to);
System.arraycopy(to.getBytes(), 0, xml, offset, to.length());
return true;
}
public static boolean patchPackageID(String fileName, OutputStream out, String from, String to) {
try {
JarMap apk = new JarMap(fileName);
JarEntry je = apk.getJarEntry(Const.ANDROID_MANIFEST);
byte xml[] = apk.getRawData(je);
if (!findAndPatch(xml, from, to))
return false;
if (!findAndPatch(xml, from + ".provider", to + ".provider"))
return false;
// Write in changes
apk.getOutputStream(je).write(xml);
// Sign the APK
ZipUtils.signZip(apk, out);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}
package com.topjohnwu.magisk.utils;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
public class RootUtils {
public static void init() {
if (Shell.rootAccess()) {
Const.MAGISK_DISABLE_FILE = new SuFile("/cache/.disable_magisk");
SuFile file = new SuFile("/sbin/.core/img");
if (file.exists()) {
Const.MAGISK_PATH = file;
} else if ((file = new SuFile("/dev/magisk/img")).exists()) {
Const.MAGISK_PATH = file;
} else {
Const.MAGISK_PATH = new SuFile("/magisk");
}
Const.MAGISK_HOST_FILE = new SuFile(Const.MAGISK_PATH + "/.core/hosts");
}
}
public static void uninstallPkg(String pkg) {
Shell.Sync.su("db_clean " + Const.USER_ID, "pm uninstall " + pkg);
}
public static void patchDTBO() {
if (Shell.rootAccess()) {
MagiskManager mm = MagiskManager.get();
if (mm.magiskVersionCode >= Const.MAGISK_VER.DTBO_SUPPORT) {
if (Boolean.parseBoolean(ShellUtils.fastCmd("mm_patch_dtbo")))
ShowUI.dtboPatchedNotification();
}
}
}
}
package com.topjohnwu.magisk.utils;
import android.content.Context;
import android.support.annotation.NonNull;
import com.topjohnwu.magisk.R;
import com.topjohnwu.superuser.BusyBox;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.File;
import java.io.InputStream;
public class ShellInitializer extends Shell.Initializer {
static {
BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH);
}
@Override
public boolean onRootShellInit(Context context, @NonNull Shell shell) throws Exception {
try (InputStream magiskUtils = context.getResources().openRawResource(R.raw.util_functions);
InputStream managerUtils = context.getResources().openRawResource(R.raw.utils)
) {
shell.execTask((in, err, out) -> {
ShellUtils.pump(magiskUtils, in);
ShellUtils.pump(managerUtils, in);
});
}
shell.run(null, null,
"mount_partitions",
"get_flags",
"run_migrations");
return true;
}
}
package com.topjohnwu.magisk.utils;
import android.Manifest;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.SplashActivity;
import com.topjohnwu.magisk.asyncs.InstallMagisk;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.asyncs.RestoreImages;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.receivers.RebootReceiver;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
import java.util.List;
public class ShowUI {
public static void magiskUpdateNotification() {
MagiskManager mm = MagiskManager.get();
Intent intent = new Intent(mm, SplashActivity.class);
intent.putExtra(Const.Key.OPEN_SECTION, "magisk");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm);
stackBuilder.addParentStack(SplashActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
builder.setSmallIcon(R.drawable.ic_magisk_outline)
.setContentTitle(mm.getString(R.string.magisk_update_title))
.setContentText(mm.getString(R.string.magisk_update_available, mm.remoteMagiskVersionString))
.setVibrate(new long[]{0, 100, 100, 100})
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build());
}
public static void managerUpdateNotification() {
MagiskManager mm = MagiskManager.get();
String filename = Utils.fmt("MagiskManager-v%s(%d).apk",
mm.remoteManagerVersionString, mm.remoteManagerVersionCode);
Intent intent = new Intent(mm, ManagerUpdate.class);
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
builder.setSmallIcon(R.drawable.ic_magisk_outline)
.setContentTitle(mm.getString(R.string.manager_update_title))
.setContentText(mm.getString(R.string.manager_download_install))
.setVibrate(new long[]{0, 100, 100, 100})
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.ID.APK_UPDATE_NOTIFICATION_ID, builder.build());
}
public static void dtboPatchedNotification() {
MagiskManager mm = MagiskManager.get();
Intent intent = new Intent(mm, RebootReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
builder.setSmallIcon(R.drawable.ic_magisk_outline)
.setContentTitle(mm.getString(R.string.dtbo_patched_title))
.setContentText(mm.getString(R.string.dtbo_patched_reboot))
.setVibrate(new long[]{0, 100, 100, 100})
.addAction(R.drawable.ic_refresh, mm.getString(R.string.reboot), pendingIntent);
NotificationManager notificationManager =
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.ID.DTBO_NOTIFICATION_ID, builder.build());
}
public static void envFixDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
String filename = Utils.fmt("Magisk-v%s(%d).zip",
mm.remoteMagiskVersionString, mm.remoteMagiskVersionCode);
new AlertDialogBuilder(activity)
.setTitle(R.string.env_fix_title)
.setMessage(R.string.env_fix_msg)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> {
Utils.dlAndReceive(activity, new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
new InstallMagisk(activity, uri).exec();
}
}, mm.magiskLink, filename);
})
.setNegativeButton(R.string.no_thanks, null)
.show();
}
public static void magiskInstallDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
String filename = Utils.fmt("Magisk-v%s(%d).zip",
mm.remoteMagiskVersionString, mm.remoteMagiskVersionCode);
AlertDialog.Builder b = new AlertDialogBuilder(activity)
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.magisk)))
.setMessage(mm.getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (d, i) -> {
List<String> options = new ArrayList<>();
options.add(mm.getString(R.string.download_zip_only));
options.add(mm.getString(R.string.patch_boot_file));
if (Shell.rootAccess()) {
options.add(mm.getString(R.string.direct_install));
}
new AlertDialog.Builder(activity)
.setTitle(R.string.select_method)
.setItems(
options.toArray(new String [0]),
(dialog, idx) -> {
DownloadReceiver receiver = null;
switch (idx) {
case 1:
if (mm.remoteMagiskVersionCode < 1400) {
MagiskManager.toast(R.string.no_boot_file_patch_support, Toast.LENGTH_LONG);
return;
}
MagiskManager.toast(R.string.boot_file_patch_msg, Toast.LENGTH_LONG);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
((com.topjohnwu.magisk.components.Activity) activity)
.startActivityForResult(intent, Const.ID.SELECT_BOOT,
(requestCode, resultCode, data) -> {
if (requestCode == Const.ID.SELECT_BOOT
&& resultCode == Activity.RESULT_OK && data != null) {
Utils.dlAndReceive(
activity,
new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
Intent intent = new Intent(mm, FlashActivity.class);
intent.setData(uri)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(Const.Key.FLASH_SET_BOOT, data.getData())
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_BOOT);
mm.startActivity(intent);
}
},
mm.magiskLink,
filename
);
}
});
return;
case 0:
receiver = new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
SnackbarMaker.showUri(activity, uri);
}
};
break;
case 2:
receiver = new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
Intent intent = new Intent(mm, FlashActivity.class);
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION,
Const.Value.FLASH_MAGISK);
activity.startActivity(intent);
}
};
break;
case 3:
receiver = new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
Intent intent = new Intent(mm, FlashActivity.class);
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION,
Const.Value.FLASH_SECOND_SLOT);
activity.startActivity(intent);
}
};
default:
}
Utils.dlAndReceive(activity, receiver, mm.magiskLink, filename);
}
).show();
})
.setNegativeButton(R.string.no_thanks, null);
if (!TextUtils.isEmpty(mm.magiskNoteLink)) {
b.setNeutralButton(R.string.release_notes, (d, i) -> {
if (mm.magiskNoteLink.contains("forum.xda-developers")) {
// Open forum links in browser
Intent openLink = new Intent(Intent.ACTION_VIEW, Uri.parse(mm.magiskNoteLink));
openLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mm.startActivity(openLink);
} else {
new MarkDownWindow(activity, null, mm.magiskNoteLink).exec();
}
});
}
b.show();
}
public static void managerInstallDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
String filename = Utils.fmt("MagiskManager-v%s(%d).apk",
mm.remoteManagerVersionString, mm.remoteManagerVersionCode);
AlertDialog.Builder b = new AlertDialogBuilder(activity)
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.app_name)))
.setMessage(mm.getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (d, i) -> {
com.topjohnwu.magisk.components.Activity.runWithPermission(activity,
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
Intent intent = new Intent(mm, ManagerUpdate.class);
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
mm.sendBroadcast(intent);
});
})
.setNegativeButton(R.string.no_thanks, null);
if (!TextUtils.isEmpty(mm.managerNoteLink)) {
b.setNeutralButton(R.string.app_changelog, (d, i) ->
new MarkDownWindow(activity, null, mm.managerNoteLink).exec());
}
b.show();
}
public static void uninstallDialog(Activity activity) {
MagiskManager mm = Utils.getMagiskManager(activity);
AlertDialog.Builder b = new AlertDialogBuilder(activity)
.setTitle(R.string.uninstall_magisk_title)
.setMessage(R.string.uninstall_magisk_msg)
.setNeutralButton(R.string.restore_img, (d, i) -> new RestoreImages(activity).exec());
if (!TextUtils.isEmpty(mm.uninstallerLink)) {
b.setPositiveButton(R.string.complete_uninstall, (d, i) ->
Utils.dlAndReceive(activity, new DownloadReceiver() {
@Override
public void onDownloadDone(Context context, Uri uri) {
Intent intent = new Intent(context, FlashActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setData(uri)
.putExtra(Const.Key.FLASH_ACTION, Const.Value.UNINSTALL);
context.startActivity(intent);
}
}, mm.uninstallerLink, "magisk-uninstaller.zip"));
}
b.show();
}
}
package com.topjohnwu.magisk.utils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
public class Topic {
private static final int NON_INIT = 0;
private static final int PENDING = 1;
private static final int PUBLISHED = 2;
private int state = NON_INIT;
private List<WeakReference<Subscriber>> subscribers;
private Object[] results;
public Topic() {
subscribers = new SyncArrayList<>();
}
public synchronized void subscribe(Subscriber sub) {
subscribers.add(new WeakReference<>(sub));
}
public synchronized void unsubscribe() {
subscribers = new SyncArrayList<>();
}
public synchronized void unsubscribe(Subscriber sub) {
List<WeakReference<Subscriber>> subs = subscribers;
subscribers = new ArrayList<>();
for (WeakReference<Subscriber> subscriber : subs) {
if (subscriber.get() != null && subscriber.get() != sub)
subscribers.add(subscriber);
}
}
public void reset() {
state = NON_INIT;
results = null;
}
public boolean isPublished() {
return state == PUBLISHED;
}
public void publish() {
publish(true);
}
public void publish(boolean record, Object... results) {
if (record)
state = PUBLISHED;
this.results = results;
// Snapshot
List<WeakReference<Subscriber>> subs = subscribers;
for (WeakReference<Subscriber> subscriber : subs) {
if (subscriber != null && subscriber.get() != null)
subscriber.get().onTopicPublished(this);
}
}
public Object[] getResults() {
return results;
}
public boolean isPending() {
return state == PENDING;
}
public void setPending() {
state = PENDING;
}
public interface Subscriber {
default void subscribeTopics() {
for (Topic topic : getSubscription()) {
if (topic.isPublished()) {
onTopicPublished(topic);
}
topic.subscribe(this);
}
}
default void unsubscribeTopics() {
for (Topic event : getSubscription()) {
event.unsubscribe(this);
}
}
void onTopicPublished(Topic topic);
Topic[] getSubscription();
}
private static class SyncArrayList<E> extends ArrayList<E> {
@Override
public synchronized boolean add(E e) {
return super.add(e);
}
}
}
package com.topjohnwu.magisk.utils;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import com.topjohnwu.superuser.io.SuFileOutputStream;
import com.topjohnwu.utils.JarMap;
import com.topjohnwu.utils.SignAPK;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipUtils {
public static void unzip(File zip, File folder, String path, boolean junkPath) throws IOException {
InputStream in = new BufferedInputStream(new FileInputStream(zip));
unzip(in, folder, path, junkPath);
in.close();
}
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws IOException {
try {
ZipInputStream zipfile = new ZipInputStream(zip);
ZipEntry entry;
while ((entry = zipfile.getNextEntry()) != null) {
if (!entry.getName().startsWith(path) || entry.isDirectory()){
// Ignore directories, only create files
continue;
}
String name;
if (junkPath) {
name = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
} else {
name = entry.getName();
}
File dest = new File(folder, name);
if (!dest.getParentFile().exists() && !dest.getParentFile().mkdirs()) {
dest = new SuFile(folder, name);
dest.getParentFile().mkdirs();
}
try (OutputStream out = new SuFileOutputStream(dest)) {
ShellUtils.pump(zipfile, out);
}
}
}
catch(IOException e) {
e.printStackTrace();
throw e;
}
}
public static void signZip(File input, File output) throws Exception {
try (JarMap map = new JarMap(input, false);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output))) {
signZip(map, out);
}
}
public static void signZip(JarMap input, OutputStream output) throws Exception {
SignAPK.signZip(null, null, input, output);
}
}
This diff was suppressed by a .gitattributes entry.
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/su_request_background" />
<foreground>
<inset
android:drawable="@drawable/ic_cloud_download"
android:inset="30%" />
</foreground>
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/su_request_background" />
<foreground>
<inset
android:drawable="@drawable/ic_extension"
android:inset="30%" />
</foreground>
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/su_request_background" />
<foreground>
<inset
android:drawable="@drawable/ic_magiskhide"
android:inset="30%" />
</foreground>
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/su_request_background" />
<foreground>
<inset
android:drawable="@drawable/ic_superuser"
android:inset="30%" />
</foreground>
</adaptive-icon>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="#000000"
android:pathData="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z" />
<path
android:pathData="M0-0.75h24v24H0z" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#757575"
android:pathData="M11.8,10.9c-2.27,-0.59 -3,-1.2 -3,-2.15 0,-1.09 1.01,-1.85 2.7,-1.85 1.78,0 2.44,0.85 2.5,2.1h2.21c-0.07,-1.72 -1.12,-3.3 -3.21,-3.81V3h-3v2.16c-1.94,0.42 -3.5,1.68 -3.5,3.61 0,2.31 1.91,3.46 4.7,4.13 2.5,0.6 3,1.48 3,2.41 0,0.69 -0.49,1.79 -2.7,1.79 -2.06,0 -2.87,-0.92 -2.98,-2.1h-2.2c0.12,2.19 1.76,3.42 3.68,3.83V21h3v-2.15c1.95,-0.37 3.5,-1.5 3.5,-3.55 0,-2.84 -2.43,-3.81 -4.7,-4.4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#fff"
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#fff"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/primary_dark"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="?attr/imageColorTint"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M13,7h-2v2h2L13,7zM13,11h-2v6h2v-6zM17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="@color/primary_dark"
android:pathData="M20.5,11H19V7c0,-1.1 -0.9,-2 -2,-2h-4V3.5C13,2.12 11.88,1 10.5,1S8,2.12 8,3.5V5H4c-1.1,0 -1.99,0.9 -1.99,2v3.8H3.5c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7H2V20c0,1.1 0.9,2 2,2h3.8v-1.5c0,-1.49 1.21,-2.7 2.7,-2.7 1.49,0 2.7,1.21 2.7,2.7V22H17c1.1,0 2,-0.9 2,-2v-4h1.5c1.38,0 2.5,-1.12 2.5,-2.5S21.88,11 20.5,11z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#000"
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M17.81,4.47c-0.08,0 -0.16,-0.02 -0.23,-0.06C15.66,3.42 14,3 12.01,3c-1.98,0 -3.86,0.47 -5.57,1.41 -0.24,0.13 -0.54,0.04 -0.68,-0.2 -0.13,-0.24 -0.04,-0.55 0.2,-0.68C7.82,2.52 9.86,2 12.01,2c2.13,0 3.99,0.47 6.03,1.52 0.25,0.13 0.34,0.43 0.21,0.67 -0.09,0.18 -0.26,0.28 -0.44,0.28zM3.5,9.72c-0.1,0 -0.2,-0.03 -0.29,-0.09 -0.23,-0.16 -0.28,-0.47 -0.12,-0.7 0.99,-1.4 2.25,-2.5 3.75,-3.27C9.98,4.04 14,4.03 17.15,5.65c1.5,0.77 2.76,1.86 3.75,3.25 0.16,0.22 0.11,0.54 -0.12,0.7 -0.23,0.16 -0.54,0.11 -0.7,-0.12 -0.9,-1.26 -2.04,-2.25 -3.39,-2.94 -2.87,-1.47 -6.54,-1.47 -9.4,0.01 -1.36,0.7 -2.5,1.7 -3.4,2.96 -0.08,0.14 -0.23,0.21 -0.39,0.21zM9.75,21.79c-0.13,0 -0.26,-0.05 -0.35,-0.15 -0.87,-0.87 -1.34,-1.43 -2.01,-2.64 -0.69,-1.23 -1.05,-2.73 -1.05,-4.34 0,-2.97 2.54,-5.39 5.66,-5.39s5.66,2.42 5.66,5.39c0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0,-2.42 -2.09,-4.39 -4.66,-4.39 -2.57,0 -4.66,1.97 -4.66,4.39 0,1.44 0.32,2.77 0.93,3.85 0.64,1.15 1.08,1.64 1.85,2.42 0.19,0.2 0.19,0.51 0,0.71 -0.11,0.1 -0.24,0.15 -0.37,0.15zM16.92,19.94c-1.19,0 -2.24,-0.3 -3.1,-0.89 -1.49,-1.01 -2.38,-2.65 -2.38,-4.39 0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0,1.41 0.72,2.74 1.94,3.56 0.71,0.48 1.54,0.71 2.54,0.71 0.24,0 0.64,-0.03 1.04,-0.1 0.27,-0.05 0.53,0.13 0.58,0.41 0.05,0.27 -0.13,0.53 -0.41,0.58 -0.57,0.11 -1.07,0.12 -1.21,0.12zM14.91,22c-0.04,0 -0.09,-0.01 -0.13,-0.02 -1.59,-0.44 -2.63,-1.03 -3.72,-2.1 -1.4,-1.39 -2.17,-3.24 -2.17,-5.22 0,-1.62 1.38,-2.94 3.08,-2.94 1.7,0 3.08,1.32 3.08,2.94 0,1.07 0.93,1.94 2.08,1.94s2.08,-0.87 2.08,-1.94c0,-3.77 -3.25,-6.83 -7.25,-6.83 -2.84,0 -5.44,1.58 -6.61,4.03 -0.39,0.81 -0.59,1.76 -0.59,2.8 0,0.78 0.07,2.01 0.67,3.61 0.1,0.26 -0.03,0.55 -0.29,0.64 -0.26,0.1 -0.55,-0.04 -0.64,-0.29 -0.49,-1.31 -0.73,-2.61 -0.73,-3.96 0,-1.2 0.23,-2.29 0.68,-3.24 1.33,-2.79 4.28,-4.6 7.51,-4.6 4.55,0 8.25,3.51 8.25,7.83 0,1.62 -1.38,2.94 -3.08,2.94s-3.08,-1.32 -3.08,-2.94c0,-1.07 -0.93,-1.94 -2.08,-1.94s-2.08,0.87 -2.08,1.94c0,1.71 0.66,3.31 1.87,4.51 0.95,0.94 1.86,1.46 3.27,1.85 0.27,0.07 0.42,0.35 0.35,0.61 -0.05,0.23 -0.26,0.38 -0.47,0.38z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dip"
android:height="24.0dip"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#fff"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"/>
</vector>
<vector android:height="48dp" android:viewportHeight="720"
android:viewportWidth="720" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff" android:pathData="M332.48,421.18c0,0 3.77,22.45 -0.82,71.95c-5.76,62.06 23.64,160.64 23.64,160.64c0,0 40.1,-98.78 33.1,-162.59c-5.75,-52.45 2.6,-70.79 0.82,-68.33c-30.81,42.57 -56.75,-1.67 -56.75,-1.67z"/>
<path android:fillColor="#ffffff" android:pathData="M407.6,474.45c5.01,38.77 -0.57,60.01 -7.81,101.51c-3.66,20.99 74.78,-63.1 104.86,-113.23c5.02,-8.36 -28.77,32.6 -62.19,3.35c-23.18,-20.28 -27.16,-26.44 -45.18,-44.06c-6.08,-5.94 6.74,24.72 10.32,52.43z"/>
<path android:fillColor="#ffffff" android:pathData="M321.99,425.09c-18.02,17.62 -22,23.78 -45.18,44.06c-33.42,29.25 -67.21,-11.71 -62.19,-3.35c30.08,50.13 108.52,134.22 104.86,113.23c-7.24,-41.5 -12.82,-62.74 -7.81,-101.51c3.58,-27.71 16.4,-58.37 10.32,-52.43z"/>
<path android:fillColor="#ffffff" android:pathData="M399.15,355.87c36.67,10.57 50.89,61.5 87.91,67.8c7.65,1.3 16.27,3.6 26.31,3.12c18.77,-0.9 42.51,-11.51 74.22,-56.5c9.38,-13.3 -23.27,85.66 -105.13,86.86c-59.96,0.88 -66.97,-58.7 -106.93,-60.51c-14.43,-0.65 -15.34,-28.17 -15.34,-28.17c0,0 17.22,-18.86 38.96,-12.6z"/>
<path android:fillColor="#ffffff" android:pathData="M321.51,355.59c-36.67,10.57 -50.89,61.5 -87.91,67.8c-7.65,1.3 -16.27,3.6 -26.31,3.12c-18.77,-0.9 -42.51,-11.51 -74.22,-56.5c-9.38,-13.3 23.27,85.66 105.13,86.86c59.96,0.88 66.97,-58.7 106.93,-60.51c14.43,-0.65 15.34,-28.17 15.34,-28.17c0,0 -17.22,-18.86 -38.96,-12.6z"/>
<path android:fillColor="#ffffff" android:pathData="M458.64,355.09c36.87,27.94 25.88,58.7 46.57,49.92c69.7,-29.55 57.51,-181.21 51.87,-162.87c-31.77,103.41 -100.99,109.2 -167.61,61.63c-13.01,-9.29 48.38,35.57 69.16,51.31z"/>
<path android:fillColor="#ffffff" android:pathData="M330.91,303.77c-66.62,47.56 -135.84,41.78 -167.61,-61.63c-5.63,-18.34 -17.82,133.31 51.87,162.87c20.7,8.78 9.7,-21.98 46.57,-49.92c20.78,-15.75 82.17,-60.6 69.16,-51.31z"/>
<path android:fillColor="#ffffff" android:pathData="M465.61,318c80.43,-3.32 95.29,-135.17 88.96,-119.08c-28.39,72.22 -135.86,45.05 -146.13,90.64c-2.02,8.94 18.2,30.06 57.17,28.45z"/>
<path android:fillColor="#ffffff" android:pathData="M311.95,289.55c-10.27,-45.59 -117.75,-18.41 -146.13,-90.64c-6.32,-16.09 8.53,115.76 88.96,119.08c38.97,1.61 59.19,-19.5 57.17,-28.45z"/>
<path android:fillColor="#ffffff" android:pathData="M403.42,269.47c0,0 43.73,-23.5 81.16,-33.74c34.99,-9.58 61.22,-33.13 64.14,-58.01c2.18,-18.53 -27.05,-53.55 -27.05,-53.55c0,0 -20.51,56.9 -47.41,85.34c-29.28,30.96 -18.15,26.78 -70.84,59.96z"/>
<path android:fillColor="#ffffff" android:pathData="M246.13,209.51c-26.9,-28.44 -47.41,-85.34 -47.41,-85.34c0,0 -29.23,35.01 -27.05,53.55c2.93,24.88 29.16,48.43 64.14,58.01c37.43,10.25 81.16,33.74 81.16,33.74c-52.69,-33.18 -41.55,-29 -70.84,-59.96z"/>
<path android:fillColor="#ffffff" android:pathData="M398.12,265.85c47.36,-38.85 72.53,-89.54 113.51,-145.02c7.73,-10.46 -34.58,-35.7 -51.31,-37.37c-16.73,-1.67 -30.77,59.79 -32.35,95.94c-1.44,33.01 -36.21,91.68 -29.84,86.45z"/>
<path android:fillColor="#ffffff" android:pathData="M292.42,179.39c-1.58,-36.15 -15.62,-97.61 -32.35,-95.94c-16.73,1.67 -59.04,26.91 -51.31,37.37c40.98,55.48 66.14,106.17 113.51,145.02c6.37,5.22 -28.4,-53.45 -29.84,-86.45z"/>
<path android:fillColor="#ffffff" android:pathData="M402.86,140.35c3.34,-26.76 15.37,-46.32 39.32,-62.75c-21.17,-7.08 -38.77,-12.83 -47.97,-5.3c-9.2,7.53 -34.2,32.7 -30.85,73.68c3.34,40.98 0.18,194.09 7.43,191.25c3.9,-104.87 37.09,-135 32.07,-196.89z"/>
<path android:fillColor="#ffffff" android:pathData="M349.59,337.24c7.24,2.83 4.08,-150.27 7.43,-191.25c3.34,-40.98 -21.65,-66.16 -30.85,-73.68c-9.2,-7.53 -26.8,-1.78 -47.97,5.3c23.95,16.43 35.98,35.98 39.32,62.75c-5.02,61.89 28.17,92.02 32.07,196.89z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="400.0"
android:viewportWidth="400.0"
android:width="24dp">
<path
android:fillAlpha="1.00"
android:fillColor="@color/primary_dark"
android:pathData="M200.6,24.2C231.8,24.2 263,33 289.6,49.5C304.7,58.8 318.2,70.7 329.8,84.1C351.5,109.6 365.2,141.7 368.8,175C373.6,217.4 361.5,261.5 335.5,295.5C334.2,297.1 332.8,298.7 331.9,300.7C341.7,310.1 351,320 360.9,329.3C322.7,339.3 284.5,349.6 246.3,359.9C256.4,323.5 266,287 275.7,250.5C262.4,250.5 249.1,250.5 235.8,250.5C228.5,269.8 221.2,289.1 214.1,308.4C205.9,308.6 197.8,308.5 189.6,308.5C188.4,306.7 187.1,304.9 185.9,303C192.4,285.5 199.1,268 205.6,250.5C189.5,250.6 173.4,250.3 157.4,250.6C150.4,270 142.9,289.2 135.8,308.5C129.8,308.5 123.9,308.4 117.9,308.6C130.4,317.8 144,325.6 158.9,330.3C171.9,334.6 185.6,336.6 199.4,336.7C199.4,349.4 199.3,362.1 199.4,374.8C165.8,374.9 132.2,364.5 104.4,345.6C91.7,337 80.3,326.5 70.2,314.9C48.5,289.4 34.8,257.3 31.2,224C26.3,180.4 39.2,134.9 66.8,100.7C67.2,99.9 67.7,99.2 68.1,98.4C58.3,88.9 49,79 39.1,69.7C77.3,59.7 115.6,49.4 153.7,39.1C143.6,75.7 133.8,112.5 124.1,149.3C137.9,149.3 151.7,149.2 165.5,149.3C172.9,130 180.2,110.6 187.3,91.2C195.5,90.8 203.7,91 211.8,91C213,92.8 214.3,94.6 215.5,96.3C209.1,114 202.3,131.6 195.8,149.2C211.8,149.3 227.8,149.2 243.9,149.3C251.2,129.9 258.3,110.3 265.8,90.9C271.5,90.8 277.3,91.6 282.9,90.4C280.2,89.5 278.1,87.7 275.9,86.1C254,70.7 227.4,62.2 200.6,62.3C200.6,49.6 200.7,36.9 200.6,24.2M292.5,100C286.4,116.4 280.2,132.8 274,149.3C280.9,149.2 287.8,149.3 294.7,149.2C296,150.8 297.3,152.4 298.6,153.9C297.1,162.1 295.7,170.3 294.3,178.5C283.9,178.5 273.4,178.5 262.9,178.5C257.5,192.7 252.1,206.9 246.9,221.2C258.7,221.3 270.5,221.1 282.3,221.3C283.5,222.9 284.8,224.4 286.1,225.9C284.9,233.7 283.4,241.4 282.1,249.1C281.6,251 283.6,252.1 284.6,253.3C291.5,259.8 297.7,266.9 304.8,273.1C312.9,262.1 319.6,250.1 324.2,237.3C334.3,208.7 334.2,176.7 323.7,148.3C317,130.1 306.4,113.4 292.5,100M95.2,125.9C86.2,138 79,151.4 74.5,165.8C65.3,194.4 66.4,226.3 77.6,254.2C84.6,271.5 95.1,287.4 108.7,300.1C114.9,283.6 121.3,267.1 127.2,250.5C121.5,250.5 115.8,250.5 110,250.5C108.6,250.4 106.7,251 105.8,249.5C104.5,247.9 102.3,246.3 102.9,244.1C104.2,236.5 105.5,228.9 106.8,221.2C117.4,221.2 128.1,221.4 138.7,221.1C143.9,206.9 149.3,192.7 154.6,178.5C142.9,178.4 131.1,178.6 119.3,178.4C117.6,177.3 116.4,175.3 115,173.8C116.3,165.8 117.9,157.9 119,150C118.3,148.2 116.6,147.1 115.3,145.7C108.6,139.2 102.3,132.1 95.2,125.9M168.8,221.2C184.8,221.2 200.8,221.3 216.8,221.2C222.2,207 227.5,192.8 232.8,178.5C216.8,178.5 200.7,178.5 184.6,178.5C179.4,192.8 174,207 168.8,221.2Z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0" >
<path
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2S10.9,8 12,8zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2c1.1,0 2,-0.9 2,-2S13.1,10 12,10zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2c1.1,0 2,-0.9 2,-2S13.1,16 12,16z"
android:fillColor="#757575"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="?attr/imageColorTint"
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#fff"
android:pathData="M10,16h4c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1v-1c0,-1.11 -0.9,-2 -2,-2 -1.11,0 -2,0.9 -2,2v1c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM10.8,10c0,-0.66 0.54,-1.2 1.2,-1.2 0.66,0 1.2,0.54 1.2,1.2v1h-2.4v-1zM17,1L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-2 -2,-2zM17,19L7,19L7,5h10v14z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="?attr/imageColorTint"
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/imageColorTint"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/ic_launcher_background" />
<item>
<bitmap
android:src="@drawable/logo"
android:gravity="center"/>
</item>
</layer-list>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFd32f2f"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/primary_dark"
android:pathData="M5.41,21L6.12,17H2.12L2.47,15H6.47L7.53,9H3.53L3.88,7H7.88L8.59,3H10.59L9.88,7H15.88L16.59,3H18.59L17.88,7H21.88L21.53,9H17.53L16.47,15H20.47L20.12,17H16.12L15.41,21H13.41L14.12,17H8.12L7.41,21H5.41M9.53,9L8.47,15H14.47L15.53,9H9.53Z" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#757575"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#fff"
android:pathData="M21,10.12h-6.78l2.74,-2.82c-2.73,-2.7 -7.15,-2.8 -9.88,-0.1 -2.73,2.71 -2.73,7.08 0,9.79 2.73,2.71 7.15,2.71 9.88,0C18.32,15.65 19,14.08 19,12.1h2c0,1.98 -0.88,4.55 -2.64,6.29 -3.51,3.48 -9.21,3.48 -12.72,0 -3.5,-3.47 -3.53,-9.11 -0.02,-12.58 3.51,-3.47 9.14,-3.47 12.65,0L21,3v7.12zM12.5,8v4.25l3.5,2.08 -0.72,1.21L11,13V8h1.5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#757575"
android:pathData="M-0.05,16.79L3.19,12.97L-0.05,9.15L1.5,7.86L4.5,11.41L7.5,7.86L9.05,9.15L5.81,12.97L9.05,16.79L7.5,18.07L4.5,14.5L1.5,18.07L-0.05,16.79M24,17A1,1 0 0,1 23,18H20A2,2 0 0,1 18,16V14A2,2 0 0,1 20,12H22V10H18V8H23A1,1 0 0,1 24,9M22,14H20V16H22V14M16,17A1,1 0 0,1 15,18H12A2,2 0 0,1 10,16V10A2,2 0 0,1 12,8H14V5H16V17M14,16V10H12V16H14Z"/>
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/su_request_background"/>
</shape>
</item>
<item>
<inset
android:drawable="@drawable/ic_cloud_download"
android:inset="13dp"/>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/su_request_background"/>
</shape>
</item>
<item>
<inset
android:drawable="@drawable/ic_extension"
android:inset="13dp"/>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/su_request_background"/>
</shape>
</item>
<item>
<inset
android:drawable="@drawable/ic_magiskhide"
android:inset="13dp"/>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/su_request_background"/>
</shape>
</item>
<item>
<inset
android:drawable="@drawable/ic_superuser"
android:inset="13dp"/>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar"/>
<ScrollView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="8dp"
tools:ignore="UseCompoundDrawables,ContentDescription">
<LinearLayout
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?attr/cardStyle"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="72dp"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:layout_width="72dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_logo"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>
</LinearLayout>
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/app_version_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_info_outline"
app:text="@string/app_version"/>
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/app_changelog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_history"
app:text="@string/app_changelog"/>
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/app_translators"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_language"
app:text="@string/app_translators"/>
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/app_source_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_github"
app:text="@string/app_source_code"/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?attr/cardStyle"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/support_thread"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_xda"
app:text="@string/support_thread"/>
<com.topjohnwu.magisk.components.AboutCardRow
android:id="@+id/donation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_attach_money"
app:text="@string/donation"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/flashing_background_color"
tools:context="com.topjohnwu.magisk.FlashActivity">
<include layout="@layout/toolbar"/>
<ScrollView
android:id="@+id/scrollView"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:padding="8dp"
android:textColor="@android:color/white"
android:textSize="10sp" />
</HorizontalScrollView>
</ScrollView>
<LinearLayout
android:id="@+id/button_panel"
style="?android:buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:visibility="gone">
<Button
android:id="@+id/no_thanks"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:text="@string/close" />
<Button
android:id="@+id/save_logs"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:text="@string/menuSaveLog" />
<Button
android:id="@+id/reboot"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:text="@string/reboot" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
android:orientation="vertical">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/toolbar" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/su_popup"
tools:context=".superuser.RequestActivity"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="350dp"
android:layout_gravity="center"
android:orientation="vertical"
android:background="?attr/colorBackgroundFloating">
<TextView
android:text="@string/su_request_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/request_title"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_gravity="center_horizontal">
<ImageView
android:id="@+id/app_icon"
android:layout_weight="0"
android:layout_marginEnd="10dp"
android:layout_height="50dp"
android:layout_width="50dp"
android:layout_marginStart="5dp"
android:layout_gravity="center_vertical" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="1"
android:layout_gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
android:maxWidth="300dp"
android:maxLines="1"
android:ellipsize="end"
android:textColor="?android:textColorPrimary"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/app_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
android:maxWidth="300dp"
android:maxLines="1"
android:ellipsize="end"
android:textColor="?android:textColorSecondary"
android:id="@+id/package_name" />
</LinearLayout>
</LinearLayout>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/timeout"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_su_warning"
android:textColor="?android:textColorSecondary"
android:text="@string/su_warning"
android:layout_gravity="center_horizontal"
android:layout_margin="5dp"
android:drawablePadding="10dp" />
<LinearLayout
style="?android:buttonBarStyle"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="30dp"
android:paddingRight="30dp">
<Button
style="?android:buttonBarButtonStyle"
android:text="@string/deny_with_str"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/deny_btn"
android:layout_weight="1" />
<Button
android:id="@+id/grant_btn"
style="?android:buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/grant" />
<ImageView
android:id="@+id/fingerprint"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="7dp"
android:tint="?attr/colorAccent"
android:src="@drawable/ic_fingerprint" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/message_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="12dip"
android:paddingEnd="20dip"
android:paddingStart="20dip"
android:paddingTop="12dip">
<TextView
android:id="@+id/message"
style="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dip" />
</LinearLayout>
<LinearLayout
style="?android:attr/buttonBarStyle"
android:id="@+id/button_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="54dip"
android:measureWithLargestChild="true"
android:orientation="horizontal"
android:paddingEnd="2dip"
android:paddingStart="2dip"
android:paddingTop="4dip">
<Button
android:id="@+id/negative"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_weight="1"
android:maxLines="2" />
<Button
android:id="@+id/neutral"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:maxLines="2" />
<Button
android:id="@+id/positive"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_weight="1"
android:maxLines="2" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingEnd="15dp"
android:paddingStart="15dp"
android:paddingTop="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:labelFor="@id/custom_url"
android:text="@string/settings_update_custom_msg"
android:textColor="?android:textColorPrimary"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/custom_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri" />
</LinearLayout>
\ No newline at end of file
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="?attr/actionBarSize"
tools:context="com.topjohnwu.magisk.LogFragment">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:id="@+id/tab"
app:tabPaddingEnd="20dp"
app:tabPaddingStart="20dp"
android:elevation="4dp"
android:visibility="gone">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/container"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="7dp"
android:paddingTop="7dp">
<RelativeLayout
android:id="@+id/magisk_update"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/magisk_update_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/magisk_update_status"
android:visibility="gone" />
<ProgressBar
android:id="@+id/magisk_update_progress"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/magisk_update_status" />
<TextView
android:id="@+id/magisk_update_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minWidth="225dp"
android:padding="6dp"
android:text="@string/checking_for_updates"
android:textStyle="bold" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/magisk_status_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/magisk_version" />
<TextView
android:id="@+id/magisk_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minWidth="225dp"
android:padding="6dp"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/safetyNet_card"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/safetyNet_title"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/safetyNet_refresh"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_margin="15dp"
android:layout_toStartOf="@+id/safetyNet_status"
android:src="@drawable/ic_refresh" />
<ProgressBar
android:id="@+id/safetyNet_check_progress"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_margin="15dp"
android:layout_toStartOf="@+id/safetyNet_status"
android:visibility="gone" />
<TextView
android:id="@+id/safetyNet_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minWidth="175dp"
android:padding="6dp"
android:text="@string/safetyNet_check_text"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:id="@+id/expand_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="10dp"
android:paddingStart="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/cts_status_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp" />
<TextView
android:id="@+id/cts_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minWidth="150dp"
android:padding="6dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/basic_status_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_margin="10dp" />
<TextView
android:id="@+id/basic_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minWidth="150dp"
android:padding="6dp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/install_option_card"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingBottom="10dp"
android:text="@string/advanced_settings_title"
android:textStyle="bold" />
<CheckBox
android:id="@+id/keep_force_enc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:layout_marginStart="50dp"
android:text="@string/keep_force_encryption" />
<CheckBox
android:id="@+id/keep_verity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:layout_marginStart="50dp"
android:text="@string/keep_dm_verity" />
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/install_button"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginEnd="40dp"
android:layout_marginStart="40dp"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
app:srcCompat="@drawable/ic_logo" />
<TextView
android:id="@+id/install_text"
android:layout_width="180dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:ems="10"
android:fontFamily="sans-serif"
android:gravity="center"
android:text="@string/install"
android:textAllCaps="false"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/uninstall_button"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation"
android:focusable="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:ems="10"
android:fontFamily="sans-serif"
android:gravity="center"
android:text="@string/uninstall"
android:textAllCaps="false"
android:textSize="20sp"
android:textStyle="bold" />
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="@+id/svLog"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize">
<HorizontalScrollView
android:id="@+id/hsvLog"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ScrollViewSize">
<TextView
android:id="@+id/txtLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:padding="8dp"
android:textIsSelectable="true"
android:textSize="10sp" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:dividerHeight="@dimen/card_divider_space"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
<TextView
android:id="@+id/empty_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:text="@string/no_modules_found"
android:textSize="20sp"
android:textStyle="italic"
android:visibility="gone" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="@dimen/fab_padding"
android:elevation="6dp"
android:src="@drawable/ic_add"
tools:fabSize="normal"
tools:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_marginTop="?attr/actionBarSize"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/empty_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:text="@string/no_modules_found"
android:textSize="20sp"
android:textStyle="italic"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.topjohnwu.magisk.SuLogFragment">
<TextView
android:id="@+id/empty_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:text="@string/log_is_empty"
android:textSize="20sp"
android:textStyle="italic"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/empty_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:text="@string/no_apps_found"
android:textSize="20sp"
android:textStyle="italic"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2016 dvdandroid
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<LinearLayout android:id="@+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:gravity="center_vertical"
android:minHeight="48dp"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<ImageView
android:id="@android:id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="#757575"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingTop="8dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_vertical_margin"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="@dimen/card_vertical_margin"
style="?attr/cardStyle"
android:minHeight="?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/info_layout"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:gravity="end" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">
<TextView
android:id="@+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false"/>
<TextView
android:id="@+id/package_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false" />
</LinearLayout>
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_menu_overflow_material"
android:checked="false" />
</LinearLayout>
</android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="?attr/cardStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_vertical_margin"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="@dimen/card_vertical_margin"
android:minHeight="?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:padding="@dimen/card_layout_padding">
<TextView
android:id="@+id/title"
android:layout_width="@dimen/card_textview_width"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false"/>
<TextView
android:id="@+id/version_name"
android:layout_width="@dimen/card_textview_width"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic"/>
<TextView
android:id="@+id/author"
android:layout_width="@dimen/card_textview_width"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@id/version_name"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic"/>
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/author"
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textIsSelectable="false"/>
<TextView
android:id="@+id/notice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/description"
android:layout_gravity="center_vertical"
android:text="@string/remove_file_created"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/red500"
android:visibility="gone"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/title"
android:layout_alignParentEnd="true"
android:orientation="horizontal"
android:gravity="end">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="center"
android:padding="@dimen/checkbox_padding"
android:src="@drawable/ic_menu_overflow_material"
tools:ignore="ContentDescription"/>
<ImageView
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:focusable="false"
android:gravity="center"
android:padding="@dimen/checkbox_padding"
android:src="@drawable/ic_delete"
android:tint="@color/icon_grey"
tools:ignore="ContentDescription"/>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_vertical_margin"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="@dimen/card_vertical_margin"
android:minHeight="?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/info_layout"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:gravity="end" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">
<TextView
android:id="@+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false"/>
<TextView
android:id="@+id/package_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false" />
</LinearLayout>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/master_switch"
android:layout_weight="0"
android:checked="false"
android:layout_gravity="center_vertical"
android:gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:id="@+id/expand_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_notifications"
android:layout_gravity="center_vertical"
android:tint="@color/icon_grey"
android:layout_marginEnd="10dp" />
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/notification_switch"
android:checked="false"
android:layout_gravity="center_vertical"
android:gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_bug_report"
android:layout_gravity="center_vertical"
android:tint="@color/icon_grey"
android:layout_marginEnd="10dp" />
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/logging_switch"
android:checked="false"
android:layout_gravity="center_vertical"
android:gravity="center_vertical" />
</LinearLayout>
<ImageView
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_delete"
android:tint="@color/icon_grey"
android:layout_gravity="center" />
<ImageView
android:id="@+id/more_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_more"
android:tint="@color/icon_grey"
android:layout_gravity="center" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_vertical_margin"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="@dimen/card_vertical_margin"
android:minHeight="?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/card_layout_padding">
<LinearLayout
android:id="@+id/info_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false" />
<TextView
android:id="@+id/version_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_info_provided"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic" />
<TextView
android:id="@+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_info_provided"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic" />
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/no_info_provided"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textIsSelectable="false" />
<TextView
android:id="@+id/update_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic" />
</LinearLayout>
<ImageView
android:id="@+id/download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/ic_file_download_black"
android:backgroundTint="@color/icon_grey"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:focusable="false"
android:gravity="end" />
</LinearLayout>
</android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="2dp"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="2dp"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/info_layout"
android:padding="10dp">
<TextView
android:id="@+id/app_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textIsSelectable="false"
android:layout_weight="2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/action"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:gravity="center_horizontal" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/time"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
android:id="@+id/expand_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:gravity="center"
android:layout_gravity="center_horizontal">
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_weight="1">
<TextView
android:text="@string/pid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fromPid"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_weight="1">
<TextView
android:text="@string/target_uid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/toUid"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_weight="2">
<TextView
android:text="@string/command"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/command"
android:textColor="?android:attr/textColorSecondary"
android:gravity="start"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_arrow" />
<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="2017/1/1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:textAllCaps="true"
android:textColor="?android:colorAccent"
android:background="@android:color/transparent"
android:textSize="16sp"
android:id="@+id/section_text"
android:textStyle="bold"
android:maxLines="1" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"/>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:checkableBehavior="single"
android:id="@+id/main_group">
<item
android:id="@+id/magisk"
android:icon="@drawable/ic_magisk_outline"
android:title="@string/magisk"/>
<item
android:id="@+id/superuser"
android:icon="@drawable/ic_superuser"
android:title="@string/superuser"
android:visible="false"/>
<item
android:id="@+id/magiskhide"
android:icon="@drawable/ic_magiskhide"
android:title="@string/magiskhide" />
</group>
<group
android:checkableBehavior="single"
android:id="@+id/second_group">
<item
android:id="@+id/modules"
android:icon="@drawable/ic_extension"
android:title="@string/modules"/>
<item
android:id="@+id/downloads"
android:icon="@drawable/ic_cloud_download"
android:title="@string/downloads"/>
</group>
<group
android:checkableBehavior="single"
android:id="@+id/third_group">
<item
android:id="@+id/log"
android:icon="@drawable/ic_bug_report"
android:title="@string/log" />
<item
android:checkable="false"
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings"/>
<item
android:checkable="false"
android:id="@+id/app_about"
android:icon="@drawable/ic_info_outline"
android:title="@string/about"/>
</group>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_save"
android:icon="@drawable/ic_save"
android:title="@string/menuSaveLog"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_clear"
android:icon="@drawable/ic_delete"
android:title="@string/menuClearLog"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_refresh"
android:title="@string/menuReload"
app:showAsAction="ifRoom"/>
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/app_search"
android:title=""
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always"/>
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/reboot"
android:title="@string/reboot"
app:showAsAction="never" />
<item
android:id="@+id/reboot_recovery"
android:title="@string/reboot_recovery"
app:showAsAction="never" />
<item
android:id="@+id/reboot_bootloader"
android:title="@string/reboot_bootloader"
app:showAsAction="never" />
<item
android:id="@+id/reboot_download"
android:title="@string/reboot_download"
app:showAsAction="never" />
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/repo_sort"
android:icon="@drawable/ic_sort"
app:showAsAction="always"/>
<item
android:id="@+id/repo_search"
android:title=""
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always"/>
</menu>
\ No newline at end of file
### v5.8.1
- Fix a bug that cause the root shell initializer not running in BusyBox.
This is the cause of freezes on some older devices and DTBO being patched unconditionally.
### Note
If your device has a separate DTBO, and you do NOT want it patched but it was patched due to the bug,
follow these instructions to fix it:
1. Uninstall → Restore Images. Do **NOT** reboot afterwards!
2. Check **Preserve AVB 2.0/dm-verity** in Advanced Settings
3. Install → Install → Direct Install to install correctly with proper settings
body {
font-family: Helvetica, arial, sans-serif;
font-size: 14px;
line-height: 1.6;
padding-top: 10px;
padding-bottom: 10px;
background-color: #424242;
color: white;
padding: 15px; }
body > *:first-child {
margin-top: 0 !important; }
body > *:last-child {
margin-bottom: 0 !important; }
a {
color: #4183C4; }
a.absent {
color: #cc0000; }
a.anchor {
display: block;
padding-left: 30px;
margin-left: -30px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
bottom: 0; }
h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
cursor: text;
position: relative; }
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;
text-decoration: none; }
h1 tt, h1 code {
font-size: inherit; }
h2 tt, h2 code {
font-size: inherit; }
h3 tt, h3 code {
font-size: inherit; }
h4 tt, h4 code {
font-size: inherit; }
h5 tt, h5 code {
font-size: inherit; }
h6 tt, h6 code {
font-size: inherit; }
h1 {
font-size: 28px; }
h2 {
font-size: 24px;
border-bottom: 1px solid #cccccc; }
h3 {
font-size: 18px; }
h4 {
font-size: 16px; }
h5 {
font-size: 14px; }
h6 {
color: #888888;
font-size: 14px; }
p, blockquote, ul, ol, dl, li, table, pre {
margin: 15px 0; }
hr {
background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0;
border: 0 none;
color: #cccccc;
height: 4px;
padding: 0; }
body > h2:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child + h2 {
margin-top: 0;
padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
margin-top: 0;
padding-top: 0; }
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0; }
h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
margin-top: 0; }
li p.first {
display: inline-block; }
ul, ol {
padding-left: 30px; }
ul :first-child, ol :first-child {
margin-top: 0; }
ul :last-child, ol :last-child {
margin-bottom: 0; }
dl {
padding: 0; }
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px; }
dl dt:first-child {
padding: 0; }
dl dt > :first-child {
margin-top: 0; }
dl dt > :last-child {
margin-bottom: 0; }
dl dd {
margin: 0 0 15px;
padding: 0 15px; }
dl dd > :first-child {
margin-top: 0; }
dl dd > :last-child {
margin-bottom: 0; }
blockquote {
border-left: 4px solid #404040;
padding: 0 15px;
color: #888888; }
blockquote > :first-child {
margin-top: 0; }
blockquote > :last-child {
margin-bottom: 0; }
table {
padding: 0; }
table tr {
border-top: 1px solid #707070;
background-color: #303030;
margin: 0;
padding: 0; }
table tr:nth-child(2n) {
background-color: #505050; }
table tr th {
font-weight: bold;
border: 1px solid #707070;
text-align: left;
margin: 0;
padding: 6px 13px; }
table tr td {
border: 1px solid #707070;
text-align: left;
margin: 0;
padding: 6px 13px; }
table tr th :first-child, table tr td :first-child {
margin-top: 0; }
table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }
img {
max-width: 100%; }
span.frame {
display: block;
overflow: hidden; }
span.frame > span {
border: 1px solid #dddddd;
display: block;
float: left;
overflow: hidden;
margin: 13px 0 0;
padding: 7px;
width: auto; }
span.frame span img {
display: block;
float: left; }
span.frame span span {
clear: both;
color: #cccccc;
display: block;
padding: 5px 0 0; }
span.align-center {
display: block;
overflow: hidden;
clear: both; }
span.align-center > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: center; }
span.align-center span img {
margin: 0 auto;
text-align: center; }
span.align-right {
display: block;
overflow: hidden;
clear: both; }
span.align-right > span {
display: block;
overflow: hidden;
margin: 13px 0 0;
text-align: right; }
span.align-right span img {
margin: 0;
text-align: right; }
span.float-left {
display: block;
margin-right: 13px;
overflow: hidden;
float: left; }
span.float-left span {
margin: 13px 0 0; }
span.float-right {
display: block;
margin-left: 13px;
overflow: hidden;
float: right; }
span.float-right > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: right; }
code, tt {
margin: 0 2px;
padding: 0 5px;
white-space: nowrap;
border: 1px solid #707070;
background-color: #606060;
border-radius: 3px; }
pre code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent; }
.highlight pre {
background-color: #3f3f3f;
border: 1px solid #707070;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre {
background-color: #606060;
border: 1px solid #707070;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre code, pre tt {
background-color: transparent;
border: none; }
\ No newline at end of file
body {
font-family: Helvetica, arial, sans-serif;
font-size: 14px;
line-height: 1.6;
padding-top: 10px;
padding-bottom: 10px;
background-color: white;
padding: 15px; }
body > *:first-child {
margin-top: 0 !important; }
body > *:last-child {
margin-bottom: 0 !important; }
a {
color: #4183C4; }
a.absent {
color: #cc0000; }
a.anchor {
display: block;
padding-left: 30px;
margin-left: -30px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
bottom: 0; }
h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
cursor: text;
position: relative; }
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;
text-decoration: none; }
h1 tt, h1 code {
font-size: inherit; }
h2 tt, h2 code {
font-size: inherit; }
h3 tt, h3 code {
font-size: inherit; }
h4 tt, h4 code {
font-size: inherit; }
h5 tt, h5 code {
font-size: inherit; }
h6 tt, h6 code {
font-size: inherit; }
h1 {
font-size: 28px;
color: black; }
h2 {
font-size: 24px;
border-bottom: 1px solid #cccccc;
color: black; }
h3 {
font-size: 18px; }
h4 {
font-size: 16px; }
h5 {
font-size: 14px; }
h6 {
color: #777777;
font-size: 14px; }
p, blockquote, ul, ol, dl, li, table, pre {
margin: 15px 0; }
hr {
background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0;
border: 0 none;
color: #cccccc;
height: 4px;
padding: 0; }
body > h2:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child + h2 {
margin-top: 0;
padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
margin-top: 0;
padding-top: 0; }
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0; }
h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
margin-top: 0; }
li p.first {
display: inline-block; }
ul, ol {
padding-left: 30px; }
ul :first-child, ol :first-child {
margin-top: 0; }
ul :last-child, ol :last-child {
margin-bottom: 0; }
dl {
padding: 0; }
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px; }
dl dt:first-child {
padding: 0; }
dl dt > :first-child {
margin-top: 0; }
dl dt > :last-child {
margin-bottom: 0; }
dl dd {
margin: 0 0 15px;
padding: 0 15px; }
dl dd > :first-child {
margin-top: 0; }
dl dd > :last-child {
margin-bottom: 0; }
blockquote {
border-left: 4px solid #dddddd;
padding: 0 15px;
color: #777777; }
blockquote > :first-child {
margin-top: 0; }
blockquote > :last-child {
margin-bottom: 0; }
table {
padding: 0; }
table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
table tr:nth-child(2n) {
background-color: #f8f8f8; }
table tr th {
font-weight: bold;
border: 1px solid #cccccc;
text-align: left;
margin: 0;
padding: 6px 13px; }
table tr td {
border: 1px solid #cccccc;
text-align: left;
margin: 0;
padding: 6px 13px; }
table tr th :first-child, table tr td :first-child {
margin-top: 0; }
table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }
img {
max-width: 100%; }
span.frame {
display: block;
overflow: hidden; }
span.frame > span {
border: 1px solid #dddddd;
display: block;
float: left;
overflow: hidden;
margin: 13px 0 0;
padding: 7px;
width: auto; }
span.frame span img {
display: block;
float: left; }
span.frame span span {
clear: both;
color: #333333;
display: block;
padding: 5px 0 0; }
span.align-center {
display: block;
overflow: hidden;
clear: both; }
span.align-center > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: center; }
span.align-center span img {
margin: 0 auto;
text-align: center; }
span.align-right {
display: block;
overflow: hidden;
clear: both; }
span.align-right > span {
display: block;
overflow: hidden;
margin: 13px 0 0;
text-align: right; }
span.align-right span img {
margin: 0;
text-align: right; }
span.float-left {
display: block;
margin-right: 13px;
overflow: hidden;
float: left; }
span.float-left span {
margin: 13px 0 0; }
span.float-right {
display: block;
margin-left: 13px;
overflow: hidden;
float: right; }
span.float-right > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: right; }
code, tt {
margin: 0 2px;
padding: 0 5px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px; }
pre code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent; }
.highlight pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre code, pre tt {
background-color: transparent;
border: none; }
\ No newline at end of file
db_sepatch() {
magiskpolicy --live 'create magisk_file' 'attradd magisk_file mlstrustedobject' \
'allow * magisk_file file *' 'allow * magisk_file dir *' \
'allow magisk_file * filesystem associate'
}
db_clean() {
local USERID=$1
local DIR="/sbin/.core/db-${USERID}"
umount -l /data/user*/*/*/databases/su.db $DIR $DIR/*
rm -rf $DIR
[ "$USERID" = "*" ] && rm -fv /data/adb/magisk.db*
}
db_init() {
# Temporary let the folder rw by anyone
chcon u:object_r:magisk_file:s0 /data/adb
chmod 777 /data/adb
}
db_restore() {
chmod 700 /data/adb
magisk --restorecon
}
db_setup() {
local USER=$1
local USERID=$(($USER / 100000))
local DIR=/sbin/.core/db-${USERID}
mkdir -p $DIR
touch $DIR/magisk.db
mount -o bind /data/adb/magisk.db $DIR/magisk.db
rm -f /data/adb/magisk.db-*
chcon u:object_r:magisk_file:s0 $DIR $DIR/*
chmod 700 $DIR
chown $USER.$USER $DIR
chmod 666 $DIR/*
}
env_check() {
for file in busybox magisk magiskboot magiskinit util_functions.sh boot_patch.sh; do
[ -f /data/adb/magisk/$file ] || return 1
done
return 0
}
fix_env() {
cd /data/adb/magisk
sh update-binary extract
rm -f update-binary magisk.apk
cd /
rm -rf /sbin/.core/busybox/*
/sbin/.core/mirror/bin/busybox --install -s /sbin/.core/busybox
}
direct_install() {
flash_boot_image $1 $2
rm -f $1
rm -rf /data/adb/magisk/* 2>/dev/null
mkdir -p /data/adb/magisk 2>/dev/null
chmod 700 /data/adb
cp -rf $3/* /data/adb/magisk
rm -rf $3
}
mm_patch_dtbo() {
if $KEEPVERITY; then
echo false
else
find_dtbo_image
patch_dtbo_image >/dev/null 2>&1 && echo true || echo false
fi
}
restore_imgs() {
SHA1=`cat /.backup/.sha1`
[ -z $SHA1 ] && SHA1=`grep_prop #STOCKSHA1`
[ -z $SHA1 ] && return 1
STOCKBOOT=/data/stock_boot_${SHA1}.img.gz
STOCKDTBO=/data/stock_dtbo.img.gz
[ -f $STOCKBOOT ] || return 1
find_boot_image
find_dtbo_image
magisk --unlock-blocks 2>/dev/null
if [ -b "$DTBOIMAGE" -a -f $STOCKDTBO ]; then
gzip -d < $STOCKDTBO > $DTBOIMAGE
fi
if [ -b "$BOOTIMAGE" -a -f $STOCKBOOT ]; then
gzip -d < $STOCKBOOT | cat - /dev/zero > $BOOTIMAGE 2>/dev/null
return 0
fi
return 1
}
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">الإضافات</string>
<string name="downloads">التنزيلات</string>
<string name="superuser">Superuser</string>
<string name="log">السجل</string>
<string name="settings">الإعدادات</string>
<string name="install">التثبيت</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk غير مثبت</string>
<string name="checking_for_updates">البحث عن تحديثات…</string>
<string name="magisk_update_available">Magisk v%1$s متاح!</string>
<string name="safetyNet_check_text">انقر لبدء فحص SafetyNet</string>
<string name="checking_safetyNet_status">التحقق من حالة SafetyNet…</string>
<string name="safetyNet_check_success">نجح فحص SafetyNet</string>
<string name="safetyNet_network_loss">فقدان الاتصال بالشبكة</string>
<string name="safetyNet_service_disconnected">تم إنهاء الخدمة</string>
<string name="safetyNet_res_invalid">الاستجابة غير صالحه</string>
<!--Install Fragment-->
<string name="advanced_settings_title">إعدادات متقدمة</string>
<string name="keep_force_encryption">الحفاظ علي قوه التشفير</string>
<string name="keep_dm_verity">إبقاء AVB 2.0/dm-verity</string>
<string name="current_magisk_title">نسخة Magisk المثبته: %1$s</string>
<string name="install_magisk_title">آخر نسخة Magisk: %1$s</string>
<string name="uninstall">إلغاء التثبيت</string>
<string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string>
<!--Module Fragment-->
<string name="no_info_provided">(لم يتم توفير أي معلومات)</string>
<string name="no_modules_found">لم يعثر على الإضافات</string>
<string name="update_file_created">سيتم تحديث الإضافة في إعادة التشغيل التالي</string>
<string name="remove_file_created">سيتم حذف الإضافة في إعادة التشغيل التالي</string>
<string name="remove_file_deleted">لن يتم حذف الإضافة في إعادة التشغيل التالي</string>
<string name="disable_file_created">سيتم تعطيل الإضافة في إعادة التشغيل التالي</string>
<string name="disable_file_removed">سيتم تمكين الإضافة في إعادة التشغيل التالي</string>
<string name="author">انشئ بواسطة %1$s</string>
<!--Repo Fragment-->
<string name="update_available">يتوفر تحديث</string>
<string name="installed">مثبت</string>
<string name="not_installed">غير مثبت</string>
<!--Log Fragment-->
<string name="menuReload">إعادة تحميل</string>
<string name="menuClearLog">حذف السجل الآن</string>
<string name="logs_cleared">تم حذف السجل بنجاح</string>
<string name="log_is_empty">السجل فارغ</string>
<!--About Activity-->
<string name="about">حول</string>
<string name="app_changelog">تغييرات التطبيق</string>
<string name="translators">xx6600xx ,silent_6600</string>
<string name="app_version">إصدار التطبيق</string>
<string name="app_source_code">الشفرة المصدرية</string>
<string name="donation">التبرع</string>
<string name="app_translators">مترجم التطبيق</string>
<string name="support_thread">منتدى الدعم</string>
<!--Toasts, Dialogs-->
<string name="close">إغلاق</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="zip_process_msg">معالجة الملف المضغوط …</string>
<string name="magisk_update_title">تحديث Magisk جديد متوفر!</string>
<string name="settings_reboot_toast">إعادة التشغيل لتطبيق الإعدادات</string>
<string name="release_notes">ملاحظات الإصدار</string>
<string name="repo_cache_cleared">تم مسح الذاكرة المؤقته للمستودع</string>
<string name="process_error">خطأ في العملية</string>
<string name="internal_storage">يتم تخزين الملف المضغوط في:\n[التخزين الداخلي]%1$s</string>
<string name="zip_process_title">معالجة</string>
<!--Settings Activity -->
<string name="settings_general_category">عام</string>
<string name="settings_dark_theme_title">السمة الغامقة</string>
<string name="settings_dark_theme_summary">تفعيل السمة الغامقة</string>
<string name="settings_clear_cache_title">حذف الذاكرة المؤقتة للمستودع</string>
<string name="settings_clear_cache_summary">حذف المعلومات المخزنة مؤقتا للمستودع على الانترنت، يجبر التطبيق لتحديث عبر الانترنت</string>
<string name="settings_core_only_title">Magisk الوضع الأساسي فقط</string>
<string name="settings_core_only_summary">تمكين الميزات الأساسية فقط، لن يتم تحميل جميع الإضافات. MagiskSU، MagiskHide، systemless hosts، و لا يزال ممكنا</string>
<string name="settings_magiskhide_summary">إخفاء Magisk من مختلف الاكتشافات</string>
<string name="settings_hosts_title">تمكين المضيفين(الهوست) لـ systemless</string>
<string name="settings_hosts_summary">Systemless يدعم تطبيقات حجب الإعلانات</string>
<string name="settings_su_app_adb">التطبيقات و ADB</string>
<string name="settings_su_app">التطبيقات فقط</string>
<string name="settings_su_adb">ADB فقط</string>
<string name="settings_su_disable">معطل</string>
<string name="settings_su_request_10">10 ثواني</string>
<string name="settings_su_request_20">20 ثانية</string>
<string name="settings_su_request_30">30 ثانية</string>
<string name="settings_su_request_60">60 ثانية</string>
<string name="superuser_access">Superuser صلاحيات</string>
<string name="auto_response">استجابة تلقائية</string>
<string name="request_timeout">مهلة الطلب</string>
<string name="superuser_notification">Superuser إشعارات</string>
<string name="request_timeout_summary">%1$s ثانية</string>
<string name="multiuser_mode">وضع تعدد المستخدمين</string>
<string name="settings_owner_only">مالك الجهاز فقط</string>
<string name="settings_owner_manage">إدارة مالك الجهاز</string>
<string name="settings_user_independent">مستخدم مستقل</string>
<string name="owner_only_summary">المالك فقط لديه صلاحيات الروت</string>
<string name="owner_manage_summary">يمكن للمالك فقط إدارة صلاحيات الروت وتلقي مطالبات الطلب</string>
<string name="user_indepenent_summary">كل مستخدم لديه قواعد روت منفصلة خاصة به</string>
<string name="multiuser_hint_owner_request">تم إرسال طلب إلى مالك الجهاز. يرجى التبديل إلى المالك ومنح الإذن</string>
<!--Superuser-->
<string name="su_request_title">Superuser طلبات</string>
<string name="deny_with_str">رفض%1$s</string>
<string name="deny">رفض</string>
<string name="prompt">طلب</string>
<string name="grant">سماح</string>
<string name="su_warning">منح حق الوصول الكامل إلى جهازك.\nرفض إذا كنت غير متأكد!</string>
<string name="forever">للابد</string>
<string name="once">مره</string>
<string name="tenmin">10 دقائق</string>
<string name="twentymin">20 دقائق</string>
<string name="thirtymin">30 دقائق</string>
<string name="sixtymin">60 دقائق</string>
<string name="su_allow_toast">%1$s يتم منح صلاحيات Superuser</string>
<string name="su_deny_toast">%1$s يتم رفض صلاحيات Superuser</string>
<string name="no_apps_found">لا توجد تطبيقات</string>
<string name="su_snack_grant">Superuser الصلاحيات لـ %1$s تم منحها</string>
<string name="su_snack_deny">Superuser الصلاحيات لـ %1$s تم رفضها</string>
<string name="su_snack_notif_on">الإشعارات لـ %1$s تم تفعيلها</string>
<string name="su_snack_notif_off">الإشعارات لـ %1$s تم تعطيلها</string>
<string name="su_snack_log_on">السجلات لـ %1$s تم تفعيلها</string>
<string name="su_snack_log_off">السجلات لـ %1$s تم تعطيلها</string>
<string name="su_snack_revoke">%1$s الصلاحيات سحبت</string>
<string name="su_revoke_title">سحب؟</string>
<string name="su_revoke_msg">تأكيد لسحب صلاحيات %1$s ?</string>
<string name="toast">نخب</string>
<string name="none">بدون</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">الهدف UID:\u0020</string>
<string name="command">الأمر:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Модули</string>
<string name="downloads">Изтегляния</string>
<string name="superuser">Superuser</string>
<string name="log">Дневник</string>
<string name="settings">Настройки</string>
<string name="install">Инсталиране</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk не е инсталиран</string>
<string name="checking_for_updates">Проверяваме за актуализации…</string>
<string name="magisk_update_available">Magisk версия %1$s е налице!</string>
<string name="invalid_update_channel">Невалиден канал за актуализации</string>
<string name="safetyNet_check_text">Докоснете за стартиране на SafetyNet проверката</string>
<string name="checking_safetyNet_status">Проверяване статуса на SafetyNet…</string>
<string name="safetyNet_check_success">SafetyNet проверката е успешна</string>
<string name="safetyNet_api_error">Грешка в SafetyNet ППИ</string>
<string name="safetyNet_network_loss">Не е налична мрежова връзка</string>
<string name="safetyNet_service_disconnected">Услугата е прекъсната</string>
<string name="safetyNet_res_invalid">Невалиден отговор</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Допълнителни настройки</string>
<string name="keep_force_encryption">Запазване на наложеното криптиране</string>
<string name="keep_dm_verity">Запазване на AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Инсталирана версия: %1$s</string>
<string name="install_magisk_title">Най-нова версия: %1$s</string>
<string name="uninstall">Деинсталиране</string>
<string name="uninstall_magisk_title">Деинсталиране на Magisk</string>
<string name="uninstall_magisk_msg">Всички модули ще бъдат изключени/премахнати. Руут достъпът ще бъде премахнат и е възможно криптиране на данните Ви</string>
<string name="update">Актуализация %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Не е представена информация)</string>
<string name="no_modules_found">Няма намерени модули</string>
<string name="update_file_created">Модулът ще бъде обновен при следващото рестартиране</string>
<string name="remove_file_created">Модулът ще бъде премахнат при следващото рестартиране</string>
<string name="remove_file_deleted">Модулът няма да бъде премахнат при следващото рестартиране</string>
<string name="disable_file_created">Модулът ще бъде изключен при следващото рестартиране</string>
<string name="disable_file_removed">Модулът ще бъде активиран при следващото рестартиране</string>
<string name="author">Създаден от %1$s</string>
<string name="reboot_recovery">Рестартиране в режима за възстановяване</string>
<string name="reboot_bootloader">Рестартиране в буутлоудъра</string>
<string name="reboot_download">Рестартиране в даунлоуд режима</string>
<!--Repo Fragment-->
<string name="update_available">Налице е актуализация</string>
<string name="installed">Инсталиран</string>
<string name="not_installed">Не е инсталиран</string>
<string name="updated_on">Актуализиран на: %1$s</string>
<string name="sorting_order">Сортиране</string>
<string name="sort_by_name">Сортиране по наименование</string>
<string name="sort_by_update">Сортиране по последно обновяване</string>
<!--Log Fragment-->
<string name="menuSaveLog">Запазване на доклад</string>
<string name="menuReload">Презареждане</string>
<string name="menuClearLog">Изчистване на дневника</string>
<string name="logs_cleared">Успешно изчистване на дневника</string>
<string name="log_is_empty">Дневникът е празен</string>
<!--About Activity-->
<string name="about">Относно</string>
<string name="app_changelog">Списък с промени</string>
<string name="translators" />
<string name="app_version">Версия</string>
<string name="app_source_code">Изходен код</string>
<string name="donation">Дарение</string>
<string name="app_translators">Преводачи</string>
<string name="support_thread">Страница за поддръжка</string>
<!--Toasts, Dialogs-->
<string name="close">Затваряне</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="magisk_update_title">Налице е нова версия на Magisk!</string>
<string name="settings_reboot_toast">Трябва да рестартирате за прилагане на настройките</string>
<string name="release_notes">Бележки</string>
<string name="repo_cache_cleared">Кешът на хранилището е изчистен</string>
<string name="process_error">Грешка при процеса</string>
<string name="internal_storage">Архивът е записан във:\n[Вътрешната памет]%1$s</string>
<string name="zip_download_title">Изтегляне</string>
<string name="zip_download_msg">Изтегляне на архив (%1$d%%)…</string>
<string name="zip_process_title">Обработване</string>
<string name="zip_process_msg">Обработване на архива…</string>
<string name="manager_update_title">Налице е нова версия на Magisk Manager!</string>
<string name="manager_download_install">Докоснете за изтегляне и инсталиране</string>
<string name="dtbo_patched_title">DTBO беше модифициран!</string>
<string name="dtbo_patched_reboot">Magisk Manager модифицира dtbo.img, моля да рестартирате</string>
<string name="magisk_updates">Актуализации на Magisk</string>
<string name="flashing">Инсталиране</string>
<string name="hide_manager_toast">Скриване на Magisk Manager…</string>
<string name="hide_manager_toast2">Може да отнеме време…</string>
<string name="hide_manager_fail_toast">Скриването на Magisk Manager е неуспешно…</string>
<string name="download_zip_only">Изтегляне само на архив</string>
<string name="patch_boot_file">Модифициране на Boot образа</string>
<string name="direct_install">Директно инсталиране (Препоръчва се)</string>
<string name="install_second_slot">Инсталиране на втория слот (След OTA)</string>
<string name="select_method">Избор на метод</string>
<string name="no_boot_file_patch_support">Избраната версия на Magisk не поддържа модифициране на Boot образи</string>
<string name="boot_file_patch_msg">Изберете стоков Boot образ с формат .img или .img.tar</string>
<string name="complete_uninstall">Пълно деинсталиране</string>
<string name="restore_img">Възстановяване на образи</string>
<string name="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 и затова не включва частния код за SafetyNet ППИ на Google.\n\nПозволявате ли на Magisk Manager да изтегли добавката (включва GoogleApiClient) за SafetyNet проверки?</string>
<string name="su_db_corrupt">Базата данни за SU е повредена, ще създадем нов db файл</string>
<string name="cannot_check_sn_title">Не можем да проверим SafetyNet статуса</string>
<string name="cannot_check_sn_notice">Поради промени в Услугите за Google Play, не можем да проверим SafetyNet статуса с модифициран Magisk Manager</string>
<string name="setup_done">Първоначалната настройка е готова</string>
<string name="setup_fail">Първоначалната настройка е неуспешна</string>
<string name="env_fix_title">Изисква допълнително настройване</string>
<string name="env_fix_msg">Вашето устройство се нуждае от допълнителни настройки за Magisk, за да работи перфектно. Ще бъде изтеглен архивът за настройка на Magisk. Желаете ли да продължите?</string>
<string name="setup_title">Допълнителни настройване</string>
<string name="setup_msg">Настройването на средата е в ход…</string>
<!--Settings Activity -->
<string name="settings_general_category">Общи</string>
<string name="settings_dark_theme_title">Тъмна тема</string>
<string name="settings_dark_theme_summary">Включване на тъмната тема</string>
<string name="settings_clear_cache_title">Изчистване кеша на хранилището</string>
<string name="settings_clear_cache_summary"> Изчистване на кешираната информация на онлайн хранилището за принудително обновяване</string>
<string name="settings_hide_manager_title">Скриване на Magisk Manager</string>
<string name="settings_hide_manager_summary">Смяна пакетното наименование на Magisk Manager със случайно наименование</string>
<string name="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_update">Настройки за актуализиране</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_boot_format_title">Изходен формат за модифициран Boot образ</string>
<string name="settings_boot_format_summary">Избор на изходен формат за модифициран Boot образ.\nИзберете .img, за инсталиране чрез fastboot/download режим; изберете .img.tar за инсталиране чрез ODIN.</string>
<string name="settings_core_only_title">Режим Magisk Core Only</string>
<string name="settings_core_only_summary">Работят само основни функции, като MagiskSU, MagiskHide и несистемни хостове, без модули.</string>
<string name="settings_magiskhide_summary">Скриване на Magisk от различни детектори</string>
<string name="settings_hosts_title">Несистемни хостове</string>
<string name="settings_hosts_summary">Поддръжка на несистемни хостове за използване на приложения, блокиращи реклами</string>
<string name="settings_su_app_adb">Приложения и ADB</string>
<string name="settings_su_app">Само приложения</string>
<string name="settings_su_adb">Само ADB</string>
<string name="settings_su_disable">Изключен</string>
<string name="settings_su_request_10">10 секунди</string>
<string name="settings_su_request_20">20 секунди</string>
<string name="settings_su_request_30">30 секунди</string>
<string name="settings_su_request_60">60 секунди</string>
<string name="superuser_access">Superuser достъп</string>
<string name="auto_response">Автоматичен отговор</string>
<string name="request_timeout">Време за запитване</string>
<string name="superuser_notification">Superuser известие</string>
<string name="request_timeout_summary">%1$s секунди</string>
<string name="settings_su_reauth_title">Повторно запитване след ъпгрейд</string>
<string name="settings_su_reauth_summary">Повторно запитване за Superuser достъп след ъпгрейд на приложение</string>
<string name="settings_su_fingerprint_title"> Superuser права само с пръстов отпечатък</string>
<string name="settings_su_fingerprint_summary">Използване на сензора за пръстови отпечатъци за разрешаване на Superuser досъп</string>
<string name="multiuser_mode">Потребителски достъп</string>
<string name="settings_owner_only">Само собственик</string>
<string name="settings_owner_manage">Управление от страна на собственика</string>
<string name="settings_user_independent">Независими потребители</string>
<string name="owner_only_summary">Само собственикът има руут достъп</string>
<string name="owner_manage_summary">Само собственикът може да управлява руут достъпа и да получава запитвания за достъп</string>
<string name="user_indepenent_summary">Всеки потребител има собствени правила за руут достъп</string>
<string name="multiuser_hint_owner_request">Направено е запитване до собственика на устройството. Моля да преминете в режим на собственик и да дадете разрешение</string>
<string name="mount_namespace_mode">Монтиране по именни пространства</string>
<string name="settings_ns_global">Глобално</string>
<string name="settings_ns_requester">Наследено</string>
<string name="settings_ns_isolate">Изолирано</string>
<string name="global_summary">Всички сесии с руут достъп използват глобалното именно пространство</string>
<string name="requester_summary">Всички сесии с руут достъп наследяват именното пространство на запитващото приложение</string>
<string name="isolate_summary">Всички сесии с руут достъп имат собствени именни пространства</string>
<string name="android_o_not_support">Не поддържа Android 8.0+</string>
<string name="disable_fingerprint">Не са добавени пръстови отпечатъци или устройството не поддържа тази функция</string>
<!--Superuser-->
<string name="su_request_title">Запитване за Superuser достъп</string>
<string name="deny_with_str">Отказ%1$s</string>
<string name="deny">Отказ</string>
<string name="prompt">Запитване</string>
<string name="grant">Разрешаване</string>
<string name="su_warning">Дава пълен достъп до устройството Ви.\Откажете, ако не Сте сигурен/на!</string>
<string name="forever">Завинаги</string>
<string name="once">Веднъж</string>
<string name="tenmin">10 мин</string>
<string name="twentymin">20 мин</string>
<string name="thirtymin">30 мин</string>
<string name="sixtymin">60 мин</string>
<string name="su_allow_toast">На %1$s бе разрешен Superuser достъп</string>
<string name="su_deny_toast">На %1$s бе отказан Superuser достъп</string>
<string name="no_apps_found">Няма намерени приложения</string>
<string name="su_snack_grant">На %1$s е предоставен Superuser достъп</string>
<string name="su_snack_deny">На %1$s е отказан Superuser достъп</string>
<string name="su_snack_notif_on">Извесията за %1$s са включени</string>
<string name="su_snack_notif_off">Извесията за %1$s са изключени</string>
<string name="su_snack_log_on">Записването в дневника за %1$s е включено</string>
<string name="su_snack_log_off">Записването в дневника за %1$s е изключено</string>
<string name="su_snack_revoke">Настройките за достъп на %1$s са анулирани</string>
<string name="su_revoke_title">Анулиране?</string>
<string name="su_revoke_msg">Потвърждавате ли анулирането на настройките за достъп на %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Без</string>
<string name="auth_fail">Неуспешна заверка</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Целеви UID:\u0020</string>
<string name="command">Команда:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moduly</string>
<string name="downloads">Stahování</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Nastavení</string>
<string name="install">Instalovat</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk není nainstalován</string>
<string name="checking_for_updates">Kontrola aktualizací…</string>
<string name="magisk_update_available">Magisk v%1$s je dostupný!</string>
<string name="safetyNet_check_text">Kliknutím zahájíte SafetyNet kontrolu</string>
<string name="checking_safetyNet_status">Kontrola stavu SafetyNet…</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Pokročilá Nastavení</string>
<string name="keep_force_encryption">Udržet "force encryption"</string>
<string name="keep_dm_verity">Udržet AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Nainstalovaná verze: %1$s</string>
<string name="install_magisk_title">Poslední verze: %1$s</string>
<string name="uninstall">Odinstalovat</string>
<string name="uninstall_magisk_title">Odinstalovat Magisk</string>
<!--Module Fragment-->
<string name="no_info_provided">(Žádné info)</string>
<string name="no_modules_found">Žádný modul nenalezen</string>
<string name="update_file_created">Modul bude aktualizován během příštího restartu</string>
<string name="remove_file_created">Modul bude smazán během příštího restartu</string>
<string name="remove_file_deleted">Modul nebude smazán během příštího restartu</string>
<string name="disable_file_created">Modul bude zakázán během příštího restartu</string>
<string name="disable_file_removed">Modul bude povolen během příštího restartu</string>
<string name="author">Vytvořeno %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Dostupná Aktualizace</string>
<string name="installed">Nainstalováno</string>
<string name="not_installed">Nenainstalováno</string>
<!--Log Fragment-->
<string name="menuSaveLog">Uložit log</string>
<string name="menuReload">Aktualizovat</string>
<string name="menuClearLog">Smazat Log</string>
<string name="logs_cleared">Log byl smazán</string>
<string name="log_is_empty">Log je prázdný</string>
<!--About Activity-->
<string name="about">O aplikaci</string>
<string name="app_changelog">Seznam změn</string>
<string name="translators" />
<string name="app_version">Verze aplikace</string>
<string name="app_source_code">Zdrojový kód</string>
<string name="donation">Příspěvek</string>
<string name="app_translators">Překladatelé aplikace</string>
<string name="support_thread">Vlákno podpory na fóru</string>
<!--Toasts, Dialogs-->
<string name="close">Zavřít</string>
<string name="repo_install_title">Instalovat %1$s</string>
<string name="repo_install_msg">Chcete nainstalovat %1$s ?</string>
<string name="download">Stáhnout</string>
<string name="reboot">Restart</string>
<string name="zip_process_msg">Zpracování zip souboru …</string>
<string name="magisk_update_title">K dispozici je aktualizace Magisk!</string>
<string name="settings_reboot_toast">Restartovat pro použití nastavení</string>
<string name="release_notes">Poznámky k vydání</string>
<string name="repo_cache_cleared">Mezipaměť smazána</string>
<string name="process_error">Chyba při Zpracování</string>
<string name="internal_storage">Zip je uchován v:\n[Interním Úložišti]%1$s</string>
<string name="zip_process_title">Zpracování</string>
<!--Settings Activity -->
<string name="settings_general_category">Obecné</string>
<string name="settings_dark_theme_title">Tmavý Vzhled</string>
<string name="settings_dark_theme_summary">Povolit tmavý vzhled</string>
<string name="settings_clear_cache_title">Smazat Uchovanou Mezipaměť</string>
<string name="settings_clear_cache_summary">Smaže informace online použití v Mezipaměti, donutí aplikaci obnovit informace online</string>
<string name="settings_magiskhide_summary">Skryje root (MagiskSU) před různými aplikacemi</string>
<string name="settings_hosts_title">Nesystémová "hosts" data</string>
<string name="settings_hosts_summary">Podpora nesystémových dat "hosts" pro Adblock aplikace</string>
<string name="settings_su_app_adb">Aplikace i ADB</string>
<string name="settings_su_app">Pouze aplikace</string>
<string name="settings_su_adb">Pouze ADB</string>
<string name="settings_su_disable">Zakázáno</string>
<string name="settings_su_request_10">10 sekund</string>
<string name="settings_su_request_20">20 sekund</string>
<string name="settings_su_request_30">30 sekund</string>
<string name="settings_su_request_60">60 sekund</string>
<string name="superuser_access">Přístup Superuser</string>
<string name="auto_response">Automatická Reakce</string>
<string name="request_timeout">Časový limit Požadavku</string>
<string name="superuser_notification">Oznámení Superuser</string>
<string name="request_timeout_summary">%1$s sekund</string>
<!--Superuser-->
<string name="su_request_title">Požadavek Superuser</string>
<string name="deny_with_str">Zamítnout%1$s</string>
<string name="deny">Zamítnout</string>
<string name="prompt">Dotaz</string>
<string name="grant">Povolit</string>
<string name="su_warning">Povolí plný přístup k vašemu zařízení.\nZamítněte pokud si nejste jisti!</string>
<string name="forever">Navždy</string>
<string name="once">Jednou</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">Pro %1$s bylo oprávnění Superuser povoleno</string>
<string name="su_deny_toast">Pro %1$s bylo oprávnění Superuser zamítnuto</string>
<string name="no_apps_found">Zatím zde není žádná aplikace</string>
<string name="su_snack_grant">Superuser oprávnění pro %1$s je povoleno</string>
<string name="su_snack_deny">Superuser oprávnění pro %1$s je zamítnuto</string>
<string name="su_snack_notif_on">Oznámení pro %1$s je povoleno</string>
<string name="su_snack_notif_off">Oznámení pro %1$s je zakázáno</string>
<string name="su_snack_log_on">Logování %1$s je povoleno</string>
<string name="su_snack_log_off">Logování %1$s je zakázáno</string>
<string name="su_snack_revoke">Záznamy oprávnění %1$s jsou smazány</string>
<string name="su_revoke_title">Smazat?</string>
<string name="su_revoke_msg">Smazat záznam ohledně oprávnění pro %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Žádné</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Cílové UID:\u0020</string>
<string name="command">Příkaz:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Module</string>
<string name="downloads">Downloads</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Einstellungen</string>
<string name="install">Installieren</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk ist nicht installiert</string>
<string name="checking_for_updates">Suche nach Aktualisierungen…</string>
<string name="magisk_update_available">Magisk %1$s ist verfügbar!</string>
<string name="invalid_update_channel">Nicht valider Aktualisierungskanal</string>
<string name="safetyNet_check_text">SafetyNet-Status abfragen</string>
<string name="checking_safetyNet_status">Prüfe SafetyNet-Status…</string>
<string name="safetyNet_check_success">SafetyNet-Test erfolgreich</string>
<string name="safetyNet_api_error">SafetyNet API Fehler</string>
<string name="safetyNet_network_loss">Netzwerkverbindung verloren</string>
<string name="safetyNet_service_disconnected">Der Dienst wurde beendet</string>
<string name="safetyNet_res_invalid">Die Antwort ist ungültig</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Erweiterte Optionen</string>
<string name="keep_force_encryption">\"force encryption\" beibehalten</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity beibehalten</string>
<string name="current_magisk_title">Installierte Version: %1$s</string>
<string name="install_magisk_title">Neueste Version: %1$s</string>
<string name="uninstall">Deinstallieren</string>
<string name="uninstall_magisk_title">Magisk deinstallieren</string>
<string name="uninstall_magisk_msg">Alle Module werden deaktiviert/entfernt. Root wird entfernt und wenn die Daten nicht verschlüsselt sind, werden sie möglicherweise verschlüsselt.</string>
<string name="update">Aktualisierung %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nichts angegeben)</string>
<string name="no_modules_found">Keine Module gefunden</string>
<string name="update_file_created">Modul wird beim nächsten Neustart aktualisiert</string>
<string name="remove_file_created">Modul wird beim nächsten Neustart entfernt</string>
<string name="remove_file_deleted">Modul wird beim nächsten Neustart nicht entfernt</string>
<string name="disable_file_created">Modul wird beim nächsten Neustart deaktiviert</string>
<string name="disable_file_removed">Modul wird beim nächsten Neustart aktiviert</string>
<string name="author">Erstellt von %1$s</string>
<string name="reboot_recovery">Neustart in die Recovery</string>
<string name="reboot_bootloader">Neustart in den Bootloader</string>
<string name="reboot_download">Neustart in den Download-Modus</string>
<!--Repo Fragment-->
<string name="update_available">Aktualisierung verfügbar</string>
<string name="installed">Installiert</string>
<string name="not_installed">Nicht installiert</string>
<string name="updated_on">Zuletzt aktualisiert: %1$s</string>
<string name="sorting_order">Sortierung</string>
<string name="sort_by_name">Nach Namen sortiert</string>
<string name="sort_by_update">Nach Aktualisierung sortiert</string>
<!--Log Fragment-->
<string name="menuSaveLog">Protokoll speichern</string>
<string name="menuReload">Log erneut laden</string>
<string name="menuClearLog">Log löschen</string>
<string name="logs_cleared">Log gelöscht</string>
<string name="log_is_empty">Log ist leer</string>
<!--About Activity-->
<string name="about">Über</string>
<string name="app_changelog">Änderungen</string>
<string name="translators">skalnet, c727, jenslody</string>
<string name="app_version">Version</string>
<string name="app_source_code">Quelltext</string>
<string name="donation">Spende</string>
<string name="app_translators">Übersetzer</string>
<string name="support_thread">Hilfeforum</string>
<!--Toasts, Dialogs-->
<string name="close">Schließen</string>
<string name="repo_install_title">Installiere %1$s</string>
<string name="repo_install_msg">Möchtest du %1$s installieren?</string>
<string name="download">Herunterladen</string>
<string name="reboot">Neustart</string>
<string name="magisk_update_title">Neue Magisk-Aktualisierung verfügbar!</string>
<string name="settings_reboot_toast">Neustarten, um die Änderungen anzuwenden</string>
<string name="release_notes">Änderungen</string>
<string name="repo_cache_cleared">Repo-Cache gelöscht</string>
<string name="process_error">Prozessfehler</string>
<string name="internal_storage">Die zip-Datei ist gespeichert unter:\n[Interner Speicher]%1$s</string>
<string name="zip_download_title">Herunterladen</string>
<string name="zip_download_msg">Lade Zip-Datei herunter (%1$d%%) …</string>
<string name="zip_process_title">Verarbeite</string>
<string name="zip_process_msg">Verarbeite Zip-Datei…</string>
<string name="manager_update_title">Aktualisierung für Magisk Manager verfügbar!</string>
<string name="manager_download_install">Herunterladen und installieren</string>
<string name="dtbo_patched_title">DTBO wurde gepatched!</string>
<string name="dtbo_patched_reboot">Magisk Manager hat dtbo.img gepatched, bitte Neustart durchführen</string>
<string name="magisk_updates">Magisk Aktualisierungen</string>
<string name="flashing">Flashing</string>
<string name="hide_manager_toast">Verberge Magisk Manager…</string>
<string name="hide_manager_toast2">Dies könnte einige Zeit in Anspruch nehmen…</string>
<string name="hide_manager_fail_toast">Verbergen von Magisk Manager fehlgeschlagen…</string>
<string name="download_zip_only">Zip-Datei nur herunterladen</string>
<string name="patch_boot_file">Boot-Image-Datei patchen</string>
<string name="direct_install">Direkt installieren (empfohlen)</string>
<string name="install_second_slot">Installiere auf zweiten Slot (Nach OTA)</string>
<string name="select_method">Methode auswählen</string>
<string name="no_boot_file_patch_support">Magisk Zielversion unterstützt das Patchen des Boot-Images nicht</string>
<string name="boot_file_patch_msg">Selektiere das originale Boot image dump im Format .img oder .img.tar</string>
<string name="complete_uninstall">Komplette Deinstallation</string>
<string name="restore_img">Images wiederherstellen</string>
<string name="restore_img_msg">Wiederherstellen...</string>
<string name="restore_done">Wiederherstellung durchgeführt!</string>
<string name="restore_fail">Kein Original Backup vorhanden!</string>
<string name="proprietary_title">Lade proprietären Code herunter</string>
<string name="proprietary_notice">Magisk Manager ist FOSS und enthält keinen proprietären SafetyNet API Code von Google. Magisk Manager erlauben eine Erweiterung (enthält GoogleApiClient) für SafetyNet-Checks herunterzuladen?</string>
<string name="su_db_corrupt">Datenbank für SU ist fehlerhaft, es wird eine neue erstellt</string>
<string name="cannot_check_sn_title">Überprüfung von SafetyNet nicht möglich</string>
<string name="cannot_check_sn_notice">Aufgrund von Änderungen in den Google Play-Diensten, ist es nicht möglich SafetyNet auf neu verpackten Magisk Manager Versionen zu überprüfen</string>
<string name="setup_done">Einrichtung abgeschlossen</string>
<string name="setup_fail">Einrichtung fehlgeschlagen</string>
<string name="env_fix_title">Zusätzliche Einrichtung erforderlich</string>
<string name="env_fix_msg">Um Magisk ordnungsgemäß zu nutzen, benötigt das Geräte eine zusätzliche Einrichtung. Magisk Einrichtungs-zip wird heruntergeladen, fortsetzen?</string>
<string name="setup_title">Zusätzliche Einrichtung</string>
<string name="setup_msg">Umgebungseinrichtung läuft…</string>
<!--Settings Activity -->
<string name="settings_general_category">Allgemein</string>
<string name="settings_dark_theme_title">Dunkles Theme</string>
<string name="settings_dark_theme_summary">Dunkles Theme aktivieren</string>
<string name="settings_clear_cache_title">Repo-Cache löschen</string>
<string name="settings_clear_cache_summary">Löscht die zwischengespeicherten Informationen der Online-Repos. Erzwingt eine Online-Aktualisierung</string>
<string name="settings_hide_manager_title">Magisk Manager verbergen</string>
<string name="settings_hide_manager_summary">Magisk Manager mit zufälligem Paketnamen neu packen</string>
<string name="settings_restore_manager_title">Stelle Magisk Manager wieder her</string>
<string name="settings_restore_manager_summary">Stelle Magisk Manager mit ursprünglichem Paket wieder her</string>
<string name="language">Sprache</string>
<string name="system_default">(Systemstandard)</string>
<string name="settings_update">Aktualisierungs-Einstellungen</string>
<string name="settings_check_update_title">Prüfe nach Aktualisierungen</string>
<string name="settings_check_update_summary">Prüfe regelmäßig im Hintergrund nach Aktualisierungen</string>
<string name="settings_update_channel_title">Aktualisierungs-Kanal</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Benutzerdefiniert</string>
<string name="settings_update_custom_msg">Gebe eine benutzerdefinierte URL ein</string>
<string name="settings_boot_format_title">Ausgabeformat des gepatchten Boot-Images</string>
<string name="settings_boot_format_summary">Wähle das Ausgabeformat des gepatchten Boot-Images.\nWähle .img, um mit \"fastboot/download mode\" zu flashen; wähle .img.tar zum Flashen mit ODIN.</string>
<string name="settings_core_only_title">Nur Kernfunktionen</string>
<string name="settings_core_only_summary">Aktiviert lediglich die Kernfunktionen, Module werden nicht geladen. MagiskSU, Magisk Hide und Systemless hosts bleiben weiterhin aktiv</string>
<string name="settings_magiskhide_summary">Versteckt Magisk vor diversen Entdeckungsmethoden</string>
<string name="settings_hosts_title">Systemlose hosts-Datei</string>
<string name="settings_hosts_summary">Systemlose Unterstützung für Werbeblocker</string>
<string name="settings_su_app_adb">Apps und ADB</string>
<string name="settings_su_app">Nur Apps</string>
<string name="settings_su_adb">Nur ADB</string>
<string name="settings_su_disable">Deaktiviert</string>
<string name="settings_su_request_10">10 Sekunden</string>
<string name="settings_su_request_20">20 Sekunden</string>
<string name="settings_su_request_30">30 Sekunden</string>
<string name="settings_su_request_60">60 Sekunden</string>
<string name="superuser_access">Superuser-Zugriff</string>
<string name="auto_response">Automatisch beantworten</string>
<string name="request_timeout">Zeitlimit für Anfrage</string>
<string name="superuser_notification">Superuser-Benachrichtigung</string>
<string name="request_timeout_summary">%1$s Sekunden</string>
<string name="settings_su_reauth_title">Nach Aktualisierung erneut authentifizieren</string>
<string name="settings_su_reauth_summary">Superuser-Zugriff nach App-Aktualisierung erneut abfragen</string>
<string name="settings_su_fingerprint_title">Aktiviere Authentifizierung durch Fingerabdruck</string>
<string name="settings_su_fingerprint_summary">Fingerabdrucksensor benutzen um Superuser-Anfragen zu erlauben</string>
<string name="multiuser_mode">Mehrbenutzermodus</string>
<string name="settings_owner_only">Nur der Gerätebesitzer</string>
<string name="settings_owner_manage">Durch Gerätebesitzer verwaltet</string>
<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 Zugriffs-Anfragen</string>
<string name="user_indepenent_summary">Jeder Nutzer hat seine eingenen Root-Regeln</string>
<string name="multiuser_hint_owner_request">Eine Anfrage wurde an den Gerätebesitzer gesendet. Bitte wechsle zum Bersitzerkonto und gewähre die Rechte</string>
<string name="mount_namespace_mode">Namensraum-Modus</string>
<string name="settings_ns_global">Globaler Namensraum</string>
<string name="settings_ns_requester">Geerbter Namensraum</string>
<string name="settings_ns_isolate">Isolierter Namensraum</string>
<string name="global_summary">Alle Root-Sitzungen benutzen den global angelegten Namensraum</string>
<string name="requester_summary">Root-Sitzungen erben den Namensraum des Abfragenden</string>
<string name="isolate_summary">Jede Root-Sitzung hat ihren isolierten Namensraum</string>
<string name="android_o_not_support">Android 8.0+ wird nicht unterstützt</string>
<string name="disable_fingerprint">Keine Fingerabdrücke gespeichert oder keine Geräteunterstützung</string>
<!--Superuser-->
<string name="su_request_title">Superuser-Anfrage</string>
<string name="deny_with_str">Verweigern%1$s</string>
<string name="deny">Verweigern</string>
<string name="prompt">Nachfragen</string>
<string name="grant">Gewähren</string>
<string name="su_warning">Erlaubt den vollen Zugriff auf das Gerät.\nVerweigere, wenn du dir unsicher bist!</string>
<string name="forever">Dauerhaft</string>
<string name="once">Einmalig</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">Superuser-Rechte für %1$s gewährt</string>
<string name="su_deny_toast">Superuser-Rechte für %1$s verweigert</string>
<string name="no_apps_found">Keine Apps gefunden</string>
<string name="su_snack_grant">Superuser-Rechte werden für %1$s gewährt</string>
<string name="su_snack_deny">Superuser-Rechte werden für %1$s verweigert</string>
<string name="su_snack_notif_on">Benachrichtigungen sind für %1$s aktiviert</string>
<string name="su_snack_notif_off">Benachrichtigungen sind für %1$s deaktiviert</string>
<string name="su_snack_log_on">Logging ist für %1$s aktiviert</string>
<string name="su_snack_log_off">Logging ist für %1$s deaktiviert</string>
<string name="su_snack_revoke">Die Rechte für %1$s wurden entzogen</string>
<string name="su_revoke_title">Entziehen?</string>
<string name="su_revoke_msg">Möchtest du die Rechte für %1$s entziehen?</string>
<string name="toast">Popup</string>
<string name="none">Keine</string>
<string name="auth_fail">Authentifizierung fehlgeschlagen</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Ziel-UID:\u0020</string>
<string name="command">Befehl:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Λήψεις</string>
<string name="superuser">Υπερχρήστης</string>
<string name="log">Αρχείο Καταγραφής</string>
<string name="settings">Ρυθμίσεις</string>
<string name="install">Εγκατάσταση</string>
<!--Status Fragment-->
<string name="magisk_version_error">Το Magisk δεν είναι εγκατεστημένο</string>
<string name="checking_for_updates">Έλεγχος για ενημερώσεις…</string>
<string name="magisk_update_available">Το Magisk v%1$s είναι διαθέσιμο!</string>
<string name="invalid_update_channel">Λανθασμένο κανάλι ενημέρωσης</string>
<string name="safetyNet_check_text">Πατήστε για έλεγχο του SafetyNet</string>
<string name="checking_safetyNet_status">Έλεγχος κατάστασης SafetyNet…</string>
<string name="safetyNet_check_success">Ο Έλεγχος του SafetyNet Ήταν Επιτυχής</string>
<string name="safetyNet_api_error">Σφάλμα του SafetyNet API</string>
<string name="safetyNet_network_loss">Αδυναμία σύνδεσης στο δίκτυο</string>
<string name="safetyNet_service_disconnected">Η υπηρεσία τερματίστηκε</string>
<string name="safetyNet_res_invalid">Η απόκριση είναι άκυρη</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Προηγμένες ρυθμίσεις</string>
<string name="keep_force_encryption">Διατήρηση επιβεβλημένης κρυπτογράφησης</string>
<string name="keep_dm_verity">Διατήρηση dm-verity</string>
<string name="current_magisk_title">Εγκατεστημένη έκδοση: %1$s</string>
<string name="install_magisk_title">Τελευταία έκδοση: %1$s</string>
<string name="uninstall">Απεγκατάσταση</string>
<string name="uninstall_magisk_title">Απεγκατάσταση Magisk</string>
<string name="uninstall_magisk_msg">Όλα τα modules θα απενεργοποιηθούν/αφαιρεθούν. Το root θα αφαιρεθεί και ενδέχεται να κρυπτογραφηθούν τα δεδομένα σας, εάν δεν είναι κρυπτογραφημένα</string>
<string name="update">Ενημέρωση %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Δεν δόθηκαν πληροφορίες)</string>
<string name="no_modules_found">Δεν βρέθηκαν modules</string>
<string name="update_file_created">Η ενότητα θα ενημερωθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_created">Η ενότητα θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="remove_file_deleted">Η ενότητα δεν θα αφαιρεθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_created">Η ενότητα θα απενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="disable_file_removed">Η ενότητα θα ενεργοποιηθεί στην επόμενη επανεκκίνηση</string>
<string name="author">Δημιουργήθηκε από τον/την %1$s</string>
<string name="reboot_recovery">Επανεκκίνηση στο Recovery</string>
<string name="reboot_bootloader">Επανεκκίνηση στο Bootloader</string>
<string name="reboot_download">Επανεκκίνηση για λήψη</string>
<!--Repo Fragment-->
<string name="update_available">Διαθέσιμη Ενημέρωση</string>
<string name="installed">Εγκαταστάθηκε</string>
<string name="not_installed">Μη εγκατεστημένη</string>
<string name="updated_on">Αναβαθμίστηκε στις: %1$s</string>
<string name="sorting_order">Ταξινόμηση κατά</string>
<string name="sort_by_name">Ταξινόμηση κατά όνομα</string>
<string name="sort_by_update">Ταξινόμηση κατά τελευταία αναβάθμιση</string>
<!--Log Fragment-->
<string name="menuSaveLog">"Αποθήκευση καταγραφής "</string>
<string name="menuReload">Επαναφόρτωση</string>
<string name="menuClearLog">Εκκαθάριση αρχείου καταγραφής τώρα</string>
<string name="logs_cleared">Το αρχείο καταγραφής εκκαθαρίστηκε επιτυχώς</string>
<string name="log_is_empty">Το αρχείο καταγραφής είναι κενό</string>
<!--About Activity-->
<string name="about">Περί</string>
<string name="app_changelog">Καταγραφή αλλαγών εφαρμογής</string>
<string name="translators">GreatApo, JpegXguy</string>
<string name="app_version">Έκδοση εφαρμογής</string>
<string name="app_source_code">Πηγαίος κώδικας</string>
<string name="donation">Δωρεά</string>
<string name="app_translators">Μεταφραστές εφαρμογής</string>
<string name="support_thread">Σύνδεσμος υποστήριξης</string>
<!--Toasts, Dialogs-->
<string name="close">Κλείσιμο</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="magisk_update_title">Νέα Ενημέρωση Magisk Διαθέσιμη!</string>
<string name="settings_reboot_toast">Επανεκκίνηση για εφαρμογή ρυθμίσεων</string>
<string name="release_notes">Σημειώσεις έκδοσης</string>
<string name="repo_cache_cleared">Η Repo cache καθαρίστηκε</string>
<string name="process_error">Σφάλμα διαδικασίας</string>
<string name="internal_storage">Το zip είναι αποθηκευμένο σε:\n[Εσωτερική μνήμη]%1$s</string>
<string name="zip_download_title">Γίνεται λήψη</string>
<string name="zip_download_msg">Λήψη αρχείου zip (%1$d%%) …</string>
<string name="zip_process_title">Γίνεται επεξεργασία</string>
<string name="zip_process_msg">Επεξεργασία αρχείου zip …</string>
<string name="manager_update_title">Νέα Ενημέρωση Magisk Manager Διαθέσιμη!</string>
<string name="manager_download_install">Πιέστε για λήψη και εγκατάσταση</string>
<string name="dtbo_patched_title">Έγινε patch στο DTBO!</string>
<string name="dtbo_patched_reboot">Το Magisk Manager έκανε patch το dtbo.img, παρακαλώ κάντε επανεκκίνηση</string>
<string name="magisk_updates">Ενημερώσεις Magisk</string>
<string name="flashing">Γίνεται flash</string>
<string name="hide_manager_toast">Κρύβοντας το Magisk Manager…</string>
<string name="hide_manager_toast2">Αυτό μπορεί να πάρει λίγη ώρα…</string>
<string name="hide_manager_fail_toast">Η απόκρυψη του Magisk Manager απέτυχε…</string>
<string name="download_zip_only">Λήψη Zip Μόνο</string>
<string name="patch_boot_file">Εφαρμογή Patch στο Αρχείο Εικόνας Boot</string>
<string name="direct_install">Απευθείας Εγκατάσταση (Προτείνεται)</string>
<string name="install_second_slot">Εγκατάσταση σε Second Slot (Μετά από ΟΤΑ)</string>
<string name="select_method">Επιλογή Μεθόδου</string>
<string name="no_boot_file_patch_support">Αυτή η Magisk έκδοση δεν υποστηρίζει patch του boot image αρχείου</string>
<string name="boot_file_patch_msg">Επιλογή stock boot image dump σε μορφή .img ή .img.tar</string>
<string name="complete_uninstall">Πλήρης απεγκατάσταση</string>
<string name="restore_done">Η ανάκτηση έγινε!</string>
<string name="restore_fail">Δεν υπάρχει αντίγραφο ασφαλείας!</string>
<string name="proprietary_title">Λήψη Ιδιόκτητου Κώδικα</string>
<string name="proprietary_notice">Το Magisk Manager είναι FOSS οπότε δεν περιέχει της Google τον ιδιόκτητο κώδικα του SafetyNet API.\n\nΕπιτρέπετε στο Magisk Manager να κατεβάσει μια επέκταση (περιέχει το GoogleApiClient) για ελέγχους του SafetyNet?</string>
<string name="su_db_corrupt">Η βάση δεδομένων SU είναι κατεστραμμένη, θα αναδημιουργηθεί νέα</string>
<!--Settings Activity -->
<string name="settings_general_category">Γενικά</string>
<string name="settings_dark_theme_title">Σκούρο θέμα</string>
<string name="settings_dark_theme_summary">Ενεργοποίηση σκούρου θέματος</string>
<string name="settings_clear_cache_title">Εκκαθάριση προσωρινής μνήμης αποθετηρίων</string>
<string name="settings_clear_cache_summary">Καθαρίζει τις κρυφές πληροφορίες για απευθείας συνδεδεμένα αποθετήρια, αναγκάζει την εφαρμογή να κάνει ανανέωση σε απευθείας σύνδεση</string>
<string name="settings_hide_manager_title">Απόκρυψη του Magisk Manager</string>
<string name="settings_hide_manager_summary">Ανασυγκρότηση του Magisk Manager με τυχαίο όνομα πακέτου</string>
<string name="language">Γλώσσα</string>
<string name="system_default">(Προεπιλογή Συστήματος)</string>
<string name="settings_update">Ρυθμίσεις Ενημερώσεων</string>
<string name="settings_update_channel_title">Κανάλι Ενημερώσεων</string>
<string name="settings_update_stable">Σταθερό</string>
<string name="settings_update_beta">Δοκιμαστικό</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Εισαγωγή ενός custom URL</string>
<string name="settings_boot_format_title">Μορφή Τροποποιημένης Εικόνας Boot</string>
<string name="settings_boot_format_summary">Επιλέξτε τη μορφή της εξαγόμενης εικόνας boot μετά το patch.\nΕπιλέξτε .img για flash μέσω λειτουργίας fastboot/download· επιλέξτε .img.tar για flash μέσω ODIN.</string>
<string name="settings_core_only_title">Magisk Λειτουργία Πυρήνα Μόνο</string>
<string name="settings_core_only_summary">Ενεργοποίηση μόνο των λειτουργιών πυρήνα, καμία από τις ενότητες δεν θα ενεργοποιηθεί. Τα MagiskSU, MagiskHide, και systemless hosts θα παραμείνουν ενεργά</string>
<string name="settings_magiskhide_summary">Κρύβει το Magisk από διάφορες ανιχνεύσεις</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Υποστήριξη Systemless hosts για εφαρμογές Adblock</string>
<string name="settings_su_app_adb">Εφαρμογές και ADB</string>
<string name="settings_su_app">Εφαρμογές μόνο</string>
<string name="settings_su_adb">ADB μόνο</string>
<string name="settings_su_disable">Απενεργοποιημένο</string>
<string name="settings_su_request_10">10 δευτερόλεπτα</string>
<string name="settings_su_request_20">20 δευτερόλεπτα</string>
<string name="settings_su_request_30">30 δευτερόλεπτα</string>
<string name="settings_su_request_60">60 δευτερόλεπτα</string>
<string name="superuser_access">Πρόσβαση Υπερχρήστη</string>
<string name="auto_response">Αυτόματη Απόκριση</string>
<string name="request_timeout">Χρονικό όριο Αιτήματος</string>
<string name="superuser_notification">Ειδοποίηση Υπερχρήστη</string>
<string name="request_timeout_summary">%1$s δευτερόλεπτα</string>
<string name="settings_su_reauth_title">Επαναπιστοποίηση μετά από αναβάθμιση</string>
<string name="settings_su_reauth_summary">Επαναπιστοποίηση αδειών υπερχρήστη μετά την αναβάθμιση μίας εφαρμογής</string>
<string name="multiuser_mode">Λειτουργία Πολλών Χρηστών</string>
<string name="settings_owner_only">Μόνο Ιδιοκτήτης Συσκευής</string>
<string name="settings_owner_manage">Διαχειριζόμενη από τον Ιδιοκτήτη</string>
<string name="settings_user_independent">Ανεξάρτητη από τον χρήστη</string>
<string name="owner_only_summary">Μόνο ο ιδιοκτήτης έχει πρόσβαση root</string>
<string name="owner_manage_summary">Μόνο ο ιδιοκτήτης μπορεί να διαχειριστεί την πρόσβαση root και να δεχτεί προτροπές αίτημάτων</string>
<string name="user_indepenent_summary">Κάθε χρήστης έχει τους δικούς του ξεχωριστούς κανόνες root</string>
<string name="multiuser_hint_owner_request">Ένα αίτημα έχει σταλεί στον ιδιοκτήτη της συσκευής. Παρακαλώ αλλάξτε σε ιδιοκτήτη και δώστε την άδεια</string>
<string name="mount_namespace_mode">Λειτουργία προσάρτησης χώρου ονομάτων</string>
<string name="settings_ns_global">Καθολικός Χώρος Ονομάτων</string>
<string name="settings_ns_requester">Κληρονόμησε Χώρο Ονομάτων</string>
<string name="settings_ns_isolate">Απομονωμένος Χώρος Ονομάτων</string>
<string name="global_summary">Όλες οι συνεδρίες root χρησιμοποιούν τον καθολικό χώρο oνομάτων προσάρτησης</string>
<string name="requester_summary">Οι συνεδρίες root θα κληρονομούν το χώρο ονομάτων του αιτούντα τους</string>
<string name="isolate_summary">Κάθε συνεδρία root θα έχει το δικό της απομονωμένο χώρο ονομάτων</string>
<string name="android_o_not_support">Δεν υποστηρίζεται Android 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Αίτημα υπερχρήστη</string>
<string name="deny_with_str">Άρνηση%1$s</string>
<string name="deny">Άρνηση</string>
<string name="prompt">Προτροπή</string>
<string name="grant">Αποδοχή</string>
<string name="su_warning">Δίνει πλήρη πρόσβαση στη συσκευή σας.\nΑρνηθείτε αν δεν είστε σίγουρος/η!</string>
<string name="forever">Πάντα</string>
<string name="once">Μία φορά</string>
<string name="tenmin">10 λεπτά</string>
<string name="twentymin">20 λεπτά</string>
<string name="thirtymin">30 λεπτά</string>
<string name="sixtymin">60 λεπτά</string>
<string name="su_allow_toast">Παραχωρήθηκαν δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_deny_toast">Απορρίφθηκαν τα δικαιώματα υπερχρήστη του %1$s</string>
<string name="no_apps_found">Δεν βρέθηκαν εφαρμογές</string>
<string name="su_snack_grant">Παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_deny">Δεν παραχορούνται δικαιώματα υπερχρήστη στο %1$s</string>
<string name="su_snack_notif_on">Οι ειδοποιήσεις του %1$s είναι ενεργοποιημένες</string>
<string name="su_snack_notif_off">Οι ειδοποιήσεις του %1$s είναι απενεργοποιημένες</string>
<string name="su_snack_log_on">Η καταγραφή του %1$s είναι ενεργοποιημένη</string>
<string name="su_snack_log_off">Η καταγραφή του %1$s είναι απενεργοποιημένη</string>
<string name="su_snack_revoke">Τα δικαιώματα του %1$s ανακαλούνται</string>
<string name="su_revoke_title">Ανάκληση;</string>
<string name="su_revoke_msg">Επιβεβαίωση για ανάκληση δικαιωμάτων %1$s;</string>
<string name="toast">Αναδυόμενο παράθυρο</string>
<string name="none">Κανένα</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID Στόχος:\u0020</string>
<string name="command">Εντολή:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Módulos</string>
<string name="downloads">Descargas</string>
<string name="superuser">Superusuario</string>
<string name="log">Registro</string>
<string name="settings">Ajustes</string>
<string name="install">Instalar</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk no está instalado</string>
<string name="checking_for_updates">Comprobando Actualizaciones…</string>
<string name="magisk_update_available">¡Disponible Magisk v%1$s!</string>
<string name="invalid_update_channel">Canal de actualización inválido</string>
<string name="safetyNet_check_text">Comprobar el estado de SafetyNet</string>
<string name="checking_safetyNet_status">Comprobando estado de SafetyNet…</string>
<string name="safetyNet_check_success">La comprobación fue exitosa</string>
<string name="safetyNet_api_error">Error en la API de SafetyNet</string>
<string name="safetyNet_network_loss">Red no Disponible</string>
<string name="safetyNet_service_disconnected">Se ha detenido el servicio</string>
<string name="safetyNet_res_invalid">La respuesta no es válida</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Ajustes avanzados</string>
<string name="keep_force_encryption">Mantener cifrado forzado</string>
<string name="keep_dm_verity">Mantener AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versión instalada: %1$s</string>
<string name="install_magisk_title">Última versión: %1$s</string>
<string name="uninstall">Desinstalar</string>
<string name="uninstall_magisk_msg">Todos los módulos serán desactivados / eliminados. El acceso Root se eliminará y, posiblemente, cifrará los datos si los datos no están cifrados actualmente.</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="update">Actualización %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(No hay información)</string>
<string name="no_modules_found">No se encontraron módulos</string>
<string name="update_file_created">El módulo se actualizará en el siguiente reinicio</string>
<string name="remove_file_created">El módulo se eliminará en el siguiente reinicio</string>
<string name="remove_file_deleted">El módulo no se eliminará en el siguiente reinicio</string>
<string name="disable_file_created">El módulo se desactivará en el siguiente reinicio</string>
<string name="disable_file_removed">El módulo se activará en el siguiente reinicio</string>
<string name="author">Creado por %1$s</string>
<string name="reboot_recovery">Reiniciar en Modo Recovery</string>
<string name="reboot_bootloader">Reiniciar en Modo Bootloader</string>
<string name="reboot_download">Reiniciar en Modo Download</string>
<!--Repo Fragment-->
<string name="update_available">Actualización Disponible</string>
<string name="installed">Instalado</string>
<string name="not_installed">No Instalado</string>
<string name="updated_on">Actualizado el: %1$s</string>
<string name="sorting_order">Orden de Clasificación</string>
<string name="sort_by_name">Ordenar por nombre</string>
<string name="sort_by_update">Ordenar según la última actualización</string>
<!--Log Fragment-->
<string name="menuSaveLog">Guardar registro</string>
<string name="menuReload">Recargar</string>
<string name="menuClearLog">Limpiar registro ahora</string>
<string name="logs_cleared">Registro limpiado correctamente</string>
<string name="log_is_empty">El registro está vacio</string>
<!--About Activity-->
<string name="about">Acerca de</string>
<string name="app_changelog">Registro de cambios</string>
<string name="translators">dark-basic, Gawenda, netizen, Deiki, Nosi</string>
<string name="app_version">Versión</string>
<string name="app_source_code">Código fuente</string>
<string name="donation">Donar</string>
<string name="app_translators">Traductores</string>
<string name="support_thread">Hilo de soporte</string>
<!--Toasts, Dialogs-->
<string name="close">Cerrar</string>
<string name="repo_install_title">Instalar %1$s</string>
<string name="repo_install_msg">¿Quieres instalar %1$s ahora?</string>
<string name="download">Descargar</string>
<string name="reboot">Reiniciar</string>
<string name="zip_process_msg">Procesando archivo zip…</string>
<string name="magisk_update_title">¡Nueva actualización de Magisk disponible!</string>
<string name="settings_reboot_toast">Reinicia para aplicar los ajustes</string>
<string name="release_notes">Notas de lanzamiento</string>
<string name="repo_cache_cleared">Caché del repositorio limpiada</string>
<string name="process_error">Error de proceso</string>
<string name="internal_storage">El zip es almacenado en:\n[Internal Storage]%1$s</string>
<string name="zip_download_title">Descargando</string>
<string name="zip_download_msg">Descargando el archivo zip (%1$d%%)…</string>
<string name="zip_process_title">Procesando</string>
<string name="manager_update_title">Nueva actualización de Magisk Manager disponible!</string>
<string name="manager_download_install">Pulse para descargar e instalar</string>
<string name="dtbo_patched_title">DTBO fue parchado!</string>
<string name="dtbo_patched_reboot">Magisk Manager ha parcheado dtbo.img, por favor reinicia</string>
<string name="magisk_updates">Actualización de Magisk</string>
<string name="flashing">Flasheando</string>
<string name="hide_manager_toast">Ocultando Magisk Manager…</string>
<string name="hide_manager_toast2">Esto podría tomar un tiempo…</string>
<string name="hide_manager_fail_toast">La Ocultación de Magisk Manager ha fallado…</string>
<string name="download_zip_only">Descargar sólo el archivo ZIP</string>
<string name="patch_boot_file">Parcheo de la imagen boot</string>
<string name="direct_install">Instalación Directa (Recomendado)</string>
<string name="install_second_slot">Instalación en el segundo espacio (Después de OTA)</string>
<string name="select_method">Seleccionar Método</string>
<string name="no_boot_file_patch_support">La versión de Magisk no admite el parcheo de la imagen boot</string>
<string name="boot_file_patch_msg">Seleccione el volcado de la imagen boot en formato .img o .img.tar</string>
<string name="complete_uninstall">Desinstalación completa</string>
<string name="restore_img">Restaurar imágenes</string>
<string name="restore_done">¡Restauración Terminada!</string>
<string name="restore_img_msg">Restaurando ...</string>
<string name="restore_fail">¡El respaldo de la imagen boot Stock no existe!</string>
<string name="proprietary_title">Descargar Código Propietario</string>
<string name="proprietary_notice">Magisk Manager es un Software Libre por lo que no contiene el código API de SafetyNet (Código Propietario de Google).\n\n ¿Puede permitir que Magisk Manager descargue una extensión (contiene el GoogleApiClient) para la comprobación de SafetyNet?</string>
<string name="su_db_corrupt">La base de datos SU está dañada, se creará nueva base de datos</string>
<string name="cannot_check_sn_title">No es posible verificar SafetyNet!</string>
<string name="cannot_check_sn_notice">Debido a algunos cambios en los Servicios de Google Play, no es posible verificar SafetyNet en la versión reempaquetada de Magisk Manager</string>
<string name="setup_done">Instalación Realizada</string>
<string name="setup_fail">Instalación Fallida</string>
<string name="env_fix_title">Se Requiere una Instalación Adicional</string>
<string name="env_fix_msg">Su dispositivo requiere una instalación adicional para que Magisk funcione correctamente. Se descargará el zip de instalación de Magisk, desea continuar ahora?</string>
<string name="setup_title">Configuración Adicional</string>
<string name="setup_msg">Ejecutando Configuración de Entorno</string>
<!--Settings Activity -->
<string name="settings_general_category">General</string>
<string name="settings_dark_theme_title">Tema oscuro</string>
<string name="settings_dark_theme_summary">Habilitar el tema oscuro</string>
<string name="settings_clear_cache_title">Limpiar caché del repositorio</string>
<string name="settings_clear_cache_summary">Limpiar la información en caché para los repositorios en línea, fuerza a la aplicación a actualizar en línea</string>
<string name="settings_hide_manager_title">Ocultar Magisk Manager</string>
<string name="settings_hide_manager_summary">Re-empaquetar Magisk Manager con un nombre de paquete al azar</string>
<string name="settings_restore_manager_title">Restaurar Magisk Manager</string>
<string name="settings_restore_manager_summary">Restaura Magisk Manager con el paquete original</string>
<string name="language">Idioma</string>
<string name="system_default">(Idioma del sistema)</string>
<string name="settings_update">Ajustes de Actualización</string>
<string name="settings_check_update_title">Comprobar Actualizaciones</string>
<string name="settings_check_update_summary">Comprobar periódicamente en segundo plano si existen actualizaciones</string>
<string name="settings_update_channel_title">Canal de Actualización</string>
<string name="settings_update_stable">Estable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Personalizado</string>
<string name="settings_update_custom_msg">Insertar una URL personalizada</string>
<string name="settings_boot_format_title">Parchear imagen boot por tipo de formato</string>
<string name="settings_boot_format_summary">Seleccionar el formato de salida para parchear la imagen boot.\nEscoja .img para flashear mediante fastboot/download mode; escoja .img.tar para flashear con ODIN.</string>
<string name="settings_core_only_summary">Habilitar sólo funciones principales, no se cargarán todos los módulos. MagiskSU, MagiskHide, y Systemless Hosts seguirán habilitados</string>
<string name="settings_magiskhide_summary">Ocultar Magisk de varias detecciones</string>
<string name="settings_hosts_title">Systemless Hosts</string>
<string name="settings_hosts_summary">Soporte para aplicaciones Adblock fuera de la partición system</string>
<string name="settings_su_app_adb">Aplicaciones y ADB</string>
<string name="settings_su_app">Sólo aplicaciones</string>
<string name="settings_su_adb">Sólo ADB</string>
<string name="settings_su_disable">Deshabilitado</string>
<string name="settings_su_request_10">10 segundos</string>
<string name="settings_su_request_20">20 segundos</string>
<string name="settings_su_request_30">30 segundos</string>
<string name="settings_su_request_60">60 segundos</string>
<string name="superuser_access">Acceso de superusuario</string>
<string name="auto_response">Respuesta automática</string>
<string name="request_timeout">Tiempo de petición</string>
<string name="superuser_notification">Notificación de superusuario</string>
<string name="request_timeout_summary">%1$s segundos</string>
<string name="settings_su_reauth_title">Re-autenticación</string>
<string name="settings_su_reauth_summary">Pedir permisos de superusuario nuevamente si una aplicación es actualizada o reinstalada</string>
<string name="settings_su_fingerprint_title">Autenticación por Huella Dactilar</string>
<string name="settings_su_fingerprint_summary">Utilizar el sensor de Huella Dactilar para permitir las solicitudes de superusuario</string>
<string name="multiuser_mode">Modo MultiUsuario</string>
<string name="settings_owner_only">Sólo Administrador del Dispositivo</string>
<string name="settings_owner_manage">Administrador del Dispositivo</string>
<string name="settings_user_independent">Usuario Independiente</string>
<string name="owner_only_summary">Sólo el administrador tiene acceso root</string>
<string name="owner_manage_summary">Sólo el administrador puede supervisar el acceso root y recibir solicitudes de otros usuarios</string>
<string name="user_indepenent_summary">Cada usuario tiene separadas sus propias reglas de root </string>
<string name="multiuser_hint_owner_request">Se ha enviado una solicitud al administrador del dispositivo. Por favor, cambie a la cuenta del administrador y conceda el permiso</string>
<string name="mount_namespace_mode">Montar Namespace </string>
<string name="settings_ns_global">Global Namespace</string>
<string name="settings_ns_requester">Heredar Namespace</string>
<string name="settings_ns_isolate">Aislar Namespace</string>
<string name="global_summary">Todas las sesiones de root utilizan el soporte Global Namespace</string>
<string name="requester_summary">Las sesiones de root heredarán las peticiones Namespace</string>
<string name="isolate_summary">Cada sesión root tendrá su propia Namespace</string>
<string name="android_o_not_support">No es compatible con Android 8.0+</string>
<string name="disable_fingerprint">No se establecieron huellas dactilares o no existe soporte del dispositivo</string>
<!--Superuser-->
<string name="su_request_title">Petición de superusuario</string>
<string name="deny_with_str">Denegar%1$s</string>
<string name="deny">Denegar</string>
<string name="prompt">Preguntar</string>
<string name="grant">Permitir</string>
<string name="su_warning">Permite acceso total a tu dispositivo.\n¡Denegar si no está seguro!</string>
<string name="forever">Siempre</string>
<string name="once">Una vez</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">Permitidos derechos de superusuario para %1$s</string>
<string name="su_deny_toast">Denegados derechos de superusuario para %1$s</string>
<string name="no_apps_found">No se encontraron aplicaciones</string>
<string name="su_snack_grant">Derechos de superusuario para %1$s permitidos</string>
<string name="su_snack_deny">Derechos de superusuario para %1$s denegados</string>
<string name="su_snack_notif_on">Notificaciones de %1$s habilitadas</string>
<string name="su_snack_notif_off">Notificaciones de %1$s deshabilitadas</string>
<string name="su_snack_log_on">Registros de %1$s habilitados</string>
<string name="su_snack_log_off">Registros de %1$s deshabilitados</string>
<string name="su_snack_revoke">Anulados derechos de %1$s</string>
<string name="su_revoke_title">¿Revocar?</string>
<string name="su_revoke_msg">¿Confirmar para revocar derechos de %1$s?</string>
<string name="toast">Aviso</string>
<string name="none">Nada</string>
<string name="auth_fail">Autenticación fallida</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID de objetivo:\u0020</string>
<string name="command">Comando:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moodulid</string>
<string name="downloads">Allalaadimised</string>
<string name="superuser">Superkasutaja</string>
<string name="log">Logi</string>
<string name="settings">Seaded</string>
<string name="install">Installi</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk pole installitud</string>
<string name="checking_for_updates">Kontrollin uuendusi…</string>
<string name="magisk_update_available">Magisk v%1$s on saadaval!</string>
<string name="invalid_update_channel">Sobimatu uuenduste kanal</string>
<string name="safetyNet_check_text">Koputa, et alustada SafetyNet\'i kontrolli</string>
<string name="checking_safetyNet_status">Kontrollin SafetyNet\'i olekut…</string>
<string name="safetyNet_check_success">SafetyNet\'i kontroll edukas</string>
<string name="safetyNet_api_error">SafetyNet\'i API viga</string>
<string name="safetyNet_network_loss">Võrguühendus puudub</string>
<string name="safetyNet_service_disconnected">Teenus on sundsuletud</string>
<string name="safetyNet_res_invalid">Vastus on sobimatu</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Täpsemad seaded</string>
<string name="keep_force_encryption">Säilita sunnitud krüpteering</string>
<string name="keep_dm_verity">Säilita AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Installitud versioon: %1$s</string>
<string name="install_magisk_title">Viimane versioon: %1$s</string>
<string name="uninstall">Eemalda</string>
<string name="uninstall_magisk_title">Eemalda Magisk</string>
<string name="uninstall_magisk_msg">Kõik moodulid keelatakse/eemaldatakse. Juurkasutaja eemaldatakse ning potensiaalselt krüptitakse su andmed, kui need ei ole hetkel krüpteeritud</string>
<string name="update">Uuenda %1$s\'i</string>
<!--Module Fragment-->
<string name="no_info_provided">(Info puudub)</string>
<string name="no_modules_found">Mooduleid ei leitud</string>
<string name="update_file_created">Moodul uuendatakse järgmisel taaskäivitusel</string>
<string name="remove_file_created">Moodul eemaldatakse järgmisel taaskäivitusel</string>
<string name="remove_file_deleted">Moodulit ei eemaldata järgmisel taaskäivitusel</string>
<string name="disable_file_created">Moodul keelatakse järgmisel taaskäivitusel</string>
<string name="disable_file_removed">Moodul lubatakse järgmisel taaskäivitusel</string>
<string name="author">Loodud %1$s poolt</string>
<string name="reboot_recovery">Taaskäivita taastusesse</string>
<string name="reboot_bootloader">Taaskäivita käivitushaldurisse</string>
<string name="reboot_download">Taaskäivita allalaadimisrežiimi</string>
<!--Repo Fragment-->
<string name="update_available">Uuendus saadaval</string>
<string name="installed">Installitud</string>
<string name="not_installed">Pole installitud</string>
<string name="updated_on">Uuendatud: %1$s</string>
<string name="sorting_order">Sorteerimisjärjekord</string>
<string name="sort_by_name">Sorteeri nime järgi</string>
<string name="sort_by_update">Sorteeri viimase uuenduse järgi</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salvesta logi</string>
<string name="menuReload">Laadi uuesti</string>
<string name="menuClearLog">Tühjenda logi nüüd</string>
<string name="logs_cleared">Logi edukalt tühjendatud</string>
<string name="log_is_empty">Logi on tühi</string>
<!--About Activity-->
<string name="about">Teave</string>
<string name="app_changelog">Rakenduse muutuste logi</string>
<string name="translators" />
<string name="app_version">Rakenduse versioon</string>
<string name="app_source_code">Lähtekood</string>
<string name="donation">Annetus</string>
<string name="app_translators">Rakenduse tõlkijad</string>
<string name="support_thread">Foorumi tugiteema</string>
<!--Toasts, Dialogs-->
<string name="close">Sulge</string>
<string name="repo_install_title">Installi %1$s</string>
<string name="repo_install_msg">Kas soovid kohe installida %1$s?</string>
<string name="download">Allalaadimine</string>
<string name="reboot">Taaskäivita</string>
<string name="magisk_update_title">Magisk\'ile on uuendus saadaval!</string>
<string name="settings_reboot_toast">Taaskäivita seadete rakendamiseks</string>
<string name="release_notes">Väljalaskemärkmed</string>
<string name="repo_cache_cleared">Hoidla vahemälu tühjendatud</string>
<string name="process_error">Protsessi viga</string>
<string name="internal_storage">ZIP on salvestatud:\n
[Sisemälu]%1$s</string>
<string name="zip_download_title">Laadin alla</string>
<string name="zip_download_msg">Laadin ZIP-faili alla (%1$d%%)…</string>
<string name="zip_process_title">Töötlen</string>
<string name="zip_process_msg">Töötlen ZIP-faili…</string>
<string name="manager_update_title">Magisk Manager\'ile on uuendus saadaval!</string>
<string name="manager_download_install">Vajuta allalaadimiseks ja installimiseks</string>
<string name="dtbo_patched_title">DTBO sai paigatud!</string>
<string name="dtbo_patched_reboot">Magisk Manager on paiganud dtbo.img, palun taaskäivita</string>
<string name="magisk_updates">Magisk\'i uuendused</string>
<string name="flashing">Välgutamine</string>
<string name="hide_manager_toast">Peidan Magisk Manager\'i…</string>
<string name="hide_manager_toast2">See võib aega võtta…</string>
<string name="hide_manager_fail_toast">Magisk Manager\'i peitmine ebaõnnestus…</string>
<string name="download_zip_only">Laadi ainult ZIP alla</string>
<string name="patch_boot_file">Paika käivituspildi fail</string>
<string name="direct_install">Otsene install (soovitatud)</string>
<string name="install_second_slot">Installi teise lahtrisse (pärast üle õhu uuendust)</string>
<string name="select_method">Vali meetod</string>
<string name="no_boot_file_patch_support">Magisk\'i sihtversioon ei toeta käivituspildi faili paikamist</string>
<string name="boot_file_patch_msg">Vali originaalne käivituspildi väljastus .img või .img.tar vormingus</string>
<string name="complete_uninstall">Täielik eemaldus</string>
<string name="restore_img">Taasta pildid</string>
<string name="restore_done">Taastus valmis!</string>
<string name="restore_fail">Originaalne varundus puudub!</string>
<string name="proprietary_title">Laadi alla suletud koodi</string>
<string name="proprietary_notice">Magisk Manager on vaba ja avatud lähtekoodiga, mis ei sisalda Google\'i suletud SafetyNet\'i API koodi.\n
\n
Kas lubad Magisk Manager\'il SafetyNet\'i kontrollide jaoks laadida alla laiendus (sisaldab GoogleApiClient\'i)?</string>
<string name="su_db_corrupt">Superkasutaja andmebaas on korrumpteerunud, loon uue andmebaasi</string>
<!--Settings Activity -->
<string name="settings_general_category">Üldine</string>
<string name="settings_dark_theme_title">Tume teema</string>
<string name="settings_dark_theme_summary">Luba tume teema</string>
<string name="settings_clear_cache_title">Tühjenda hoidla vahemälu</string>
<string name="settings_clear_cache_summary">Tühjenda võrgus olevate hoidlate vahemälus olev teave, sunnib rakendust võrgust värskendama</string>
<string name="settings_hide_manager_title">Peida Magisk Manager</string>
<string name="settings_hide_manager_summary">Taaspaki Magisk Manager juhusliku nimega</string>
<string name="language">Keel</string>
<string name="system_default">(Süsteemi vaikesäte)</string>
<string name="settings_update">Uuenda seadeid</string>
<string name="settings_update_channel_title">Uuenduste kanal</string>
<string name="settings_update_stable">Stabiilne</string>
<string name="settings_update_beta">Beeta</string>
<string name="settings_update_custom">Kohandatud</string>
<string name="settings_update_custom_msg">Sisesta kohandatud URL</string>
<string name="settings_boot_format_title">Paigatud käivitusväljundi vorming</string>
<string name="settings_boot_format_summary">Vali väljutatava paigatud käivituspildi vorming.\n
Vali .img, mida välgutada fastboot/allalaadimisrežiimi kaudu; vali .img.tar, mida välgutada ODIN\'i kaudu.</string>
<string name="settings_core_only_title">Magisk\'i ainult tuuma režiim</string>
<string name="settings_core_only_summary">Luba ainult põhifunktsioonid. MagiskSU, MagiskHide ja süsteemivaba hosts siiski lubatakse, ent mooduleid ei laadita.</string>
<string name="settings_magiskhide_summary">Peida Magisk erinevate tuvastuste eest</string>
<string name="settings_hosts_title">Süsteemivaba hosts</string>
<string name="settings_hosts_summary">Süsteemivaba hosts-tugi reklaamiblokeerijatest rakendustele</string>
<string name="settings_su_app_adb">Rakendused ja ADB</string>
<string name="settings_su_app">Ainult rakendused</string>
<string name="settings_su_adb">Ainult ADB</string>
<string name="settings_su_disable">Keelatud</string>
<string name="settings_su_request_10">10 sekundit</string>
<string name="settings_su_request_20">20 sekundit</string>
<string name="settings_su_request_30">30 sekundit</string>
<string name="settings_su_request_60">60 sekundit</string>
<string name="superuser_access">Superkasutaja ligipääs</string>
<string name="auto_response">Automaatne vastus</string>
<string name="request_timeout">Taotluse ajalõpp</string>
<string name="superuser_notification">Superkasutaja teade</string>
<string name="request_timeout_summary">%1$s sekundit</string>
<string name="settings_su_reauth_title">Taas-autendi peale uuendust</string>
<string name="settings_su_reauth_summary">Taas-autendi superkasutaja õigused peale rakenduse uuendust</string>
<string name="settings_su_fingerprint_title">Luba sõrmejäljega autentimine</string>
<string name="settings_su_fingerprint_summary">Kasuta sõrmejäljelugejat superkasutaja taotluste lubamiseks</string>
<string name="multiuser_mode">Mitmikkasutaja režiim</string>
<string name="settings_owner_only">Ainult seadme omanik</string>
<string name="settings_owner_manage">Seadme omaniku hallatud</string>
<string name="settings_user_independent">Kasutajast sõltumatu</string>
<string name="owner_only_summary">Ainult omanikul on juurkasutaja õigused</string>
<string name="owner_manage_summary">Ainult omanik saab hallata juurkasutaja ligipääsu ja saada taotlusküsimusi</string>
<string name="user_indepenent_summary">Igal kasutajal on oma isiklikud juurkasutaja reeglid</string>
<string name="multiuser_hint_owner_request">Taotlus on saadetud seadme omanikule. Palun lülitu omanikule ja anna vajalikud load</string>
<string name="mount_namespace_mode">Nimeruumi monteerimisrežiim</string>
<string name="settings_ns_global">Globaalne nimeruum</string>
<string name="settings_ns_requester">Võta nimeruum üle</string>
<string name="settings_ns_isolate">Isoleeritud nimeruum</string>
<string name="global_summary">Kõik juurkasutaja sessioonid kasutavad globaalset monteerimise nimeruumi</string>
<string name="requester_summary">Juurkasutaja sessioonid võtavad üle selle taotleja nimeruumi</string>
<string name="isolate_summary">Iga juurkasutaja sessioon saab oma isoleeritud nimeruumi</string>
<string name="android_o_not_support">Pole toetatud Androidi versioonis 8.0+</string>
<!--Superuser-->
<string name="su_request_title">Superkasutaja taotlus</string>
<string name="deny_with_str">Keela %1$s</string>
<string name="deny">Keela</string>
<string name="prompt">Küsi</string>
<string name="grant">Luba</string>
<string name="su_warning">Annab täieliku ligipääsu sinu seadmele.\n
Keela, kui sa pole kindel!</string>
<string name="forever">Igavesti</string>
<string name="once">Üks kord</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">Rakendusele %1$s anti superkasutaja õigused</string>
<string name="su_deny_toast">Rakendusel %1$s keelati superkasutaja õigused</string>
<string name="no_apps_found">Rakendusi ei leitud</string>
<string name="su_snack_grant">Superkasutaja õigused antud rakendusele %1$s</string>
<string name="su_snack_deny">Superkasutaja õigused keelatud rakendusele %1$s</string>
<string name="su_snack_notif_on">Teated lubatud rakendusele %1$s</string>
<string name="su_snack_notif_off">Teated keelatud rakendusele %1$s</string>
<string name="su_snack_log_on">Logimine lubatud rakendusele %1$s</string>
<string name="su_snack_log_off">Logimine keelatud rakendusele %1$s</string>
<string name="su_snack_revoke">Rakenduse %1$s õigused on eemaldatud</string>
<string name="su_revoke_title">Eemaldad?</string>
<string name="su_revoke_msg">Kinnitad rakenduse %1$s õiguste eemaldamise?</string>
<string name="toast">Hüpik</string>
<string name="none">Puudub</string>
<string name="auth_fail">Autentimine ebaõnnestus</string>
<!--Superuser logs-->
<string name="pid">PID:\\u0020</string>
<string name="target_uid">Siht-UID:\\u0020</string>
<string name="command">Käsklus:\\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Téléchargements</string>
<string name="superuser">Superuser</string>
<string name="log">Journal</string>
<string name="settings">Paramètres</string>
<string name="install">Installer</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk n\'est pas installé</string>
<string name="checking_for_updates">Vérification des mises à jours…</string>
<string name="magisk_update_available">Magisk v%1$s disponible !</string>
<string name="invalid_update_channel">Canal de mise à jour invalide</string>
<string name="safetyNet_check_text">Appuyer pour lancer le contrôle SafetyNet</string>
<string name="checking_safetyNet_status">Vérification de l\'état SafetyNet…</string>
<string name="safetyNet_check_success">Contrôle SafetyNet passé avec succès</string>
<string name="safetyNet_api_error">Erreur d\'API SafetyNet</string>
<string name="safetyNet_network_loss">Connexion réseau indisponible</string>
<string name="safetyNet_service_disconnected">Le service a été tué</string>
<string name="safetyNet_res_invalid">La réponse est invalide</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Paramètres avancés</string>
<string name="keep_force_encryption">Garder le chiffrement forcé</string>
<string name="keep_dm_verity">Garder AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Version installée : %1$s</string>
<string name="install_magisk_title">Dernière Magisk : %1$s</string>
<string name="uninstall">Désinstaller</string>
<string name="uninstall_magisk_title">Désinstaller Magisk</string>
<string name="uninstall_magisk_msg">Tous les modules seront désactivés/effacés. Le root sera enlevé et vos données seront potentiellement chiffrées si elles ne le sont pas actuellement</string>
<string name="update">Mise à jour %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Aucune information transmise)</string>
<string name="no_modules_found">Aucun module trouvé</string>
<string name="update_file_created">Le module va être mis à jour au prochain redémarrage</string>
<string name="remove_file_created">Le module va être supprimé au prochain redémarrage</string>
<string name="remove_file_deleted">Le module ne sera pas supprimé au prochain redémarrage</string>
<string name="disable_file_created">Le module va être désactivé au prochain redémarrage</string>
<string name="disable_file_removed">Le module va être activé au prochain redémarrage</string>
<string name="author">Créé par %1$s</string>
<string name="reboot_recovery">Redémarrer en récupération</string>
<string name="reboot_bootloader">Redémarrer en chargement démarrage</string>
<string name="reboot_download">Redémarrer en téléchargement</string>
<!--Repo Fragment-->
<string name="update_available">Mise à jour disponible</string>
<string name="installed">Installé</string>
<string name="not_installed">Non installé</string>
<string name="updated_on">Mis à jour le: %1$s</string>
<string name="sorting_order">Mode de tri</string>
<string name="sort_by_name">Trier par nom</string>
<string name="sort_by_update">Trier par dernière mis à jour</string>
<!--Log Fragment-->
<string name="menuSaveLog">Enregistrer journal</string>
<string name="menuReload">Actualiser</string>
<string name="menuClearLog">Effacer le journal maintenant</string>
<string name="logs_cleared">Journal effacé avec succès</string>
<string name="log_is_empty">Journal vide</string>
<!--About Activity-->
<string name="about">À propos</string>
<string name="app_changelog">Journal</string>
<string name="translators">Rom</string>
<string name="app_version">Version</string>
<string name="app_source_code">Code source</string>
<string name="donation">Dons</string>
<string name="app_translators">Traducteurs de l\'application</string>
<string name="support_thread">Fil d\'assistance</string>
<!--Toasts, Dialogs-->
<string name="close">Fermer</string>
<string name="repo_install_title">Installer %1$s</string>
<string name="repo_install_msg">Voulez-vous installer %1$s maintenant ?</string>
<string name="download">Télécharger</string>
<string name="reboot">Redémarrer</string>
<string name="magisk_update_title">Nouvelle mis à jour Magisk disponible!</string>
<string name="settings_reboot_toast">Redémarrer afin d\'appliquer les réglages</string>
<string name="release_notes">Notes de version</string>
<string name="repo_cache_cleared">Cache du dépôt éffacé</string>
<string name="process_error">Erreur du processus</string>
<string name="internal_storage">Le zip est enregistré dans:\n[Stockage Interne]%1$s</string>
<string name="zip_download_title">Téléchargement</string>
<string name="zip_download_msg">Téléchargement du fichier zip (%1$d%%) …</string>
<string name="zip_process_title">Tritement en cours</string>
<string name="zip_process_msg">Traitement du fichier zip…</string>
<string name="manager_update_title">Nouvelle mise à jour du Gestionnaire Magisk disponible!</string>
<string name="manager_download_install">Appuyer pour télécharger et installer</string>
<string name="dtbo_patched_title">DTBO a été patché!</string>
<string name="dtbo_patched_reboot">Le Gestionnaire Magisk a vient de patcher dtbo.img, merci de redémarrer</string>
<string name="magisk_updates">Mises à jours Magisk</string>
<string name="flashing">Flahage</string>
<string name="hide_manager_toast">Masquage du Gestionnaire Magisk…</string>
<string name="hide_manager_toast2">Cela pourrait prendre un certain temps …</string>
<string name="hide_manager_fail_toast">Masquage du Gestionnaire Magisk échoué…</string>
<string name="download_zip_only">Uniquement télécharger le zip</string>
<string name="patch_boot_file">Patch Fichier Image Démarrage</string>
<string name="direct_install">Installation directe (Recommendée)</string>
<string name="install_second_slot">Installer dans le second Slot (Après OTA)</string>
<string name="select_method">Sélectionner le méthode</string>
<string name="no_boot_file_patch_support">La version cible de Magisk ne prend pas en charge la correction de fichier image de démarrage</string>
<string name="boot_file_patch_msg">Sélectionnez l\'image par défaut de démarrage stockée au format .img ou .img.tar</string>
<string name="complete_uninstall">Désinstallation terminée</string>
<string name="restore_img">Restauration des images</string>
<string name="restore_img_msg">Restauration…</string>
<string name="restore_done">Restauration terminée!</string>
<string name="restore_fail">Le sauvegarde par défaut n\'existe pas!</string>
<string name="proprietary_title">Télécharger Code Propriétaire</string>
<string name="proprietary_notice">Magisk Manager est Libre, il ne contient pas le code API SafetyNet propriétaire de Google. \ N \ nAutorisez vous le Gestionnaire Magisk à télécharger une extension (contenant GoogleApiClient) pour les contrôles SafetyNet? </string>
<string name = "su_db_corrupt"> La base de données SU est corrompue, une nouvelle base de donnée va être re-créé</string>
<string name="cannot_check_sn_title">Vérification SafetyNet impossible</string>
<string name="cannot_check_sn_notice">En raison de certains changements dans les services Google Play, il n\'est pas possible de vérifier SafetyNet via Magisk Manager reconstruit</string>
<string name="setup_done">Installation terminée</string>
<string name="setup_fail">Échec de l\'installation</string>
<string name="env_fix_title">Installation additionnelle requise</string>
<string name="env_fix_msg">Votre appareil a besoin d\'une configuration supplémentaire pour que Magisk fonctionne correctement. Il téléchargera le zip d\'installation de Magisk, voulez-vous procéder maintenant ?</string>
<string name="setup_title">Installation Additionnel</string>
<string name="setup_msg">Démarrer l\'installation de l\'environnement…</string>
<!--Settings Activity -->
<string name="settings_general_category">Général</string>
<string name="settings_dark_theme_title">Thème sombre</string>
<string name="settings_dark_theme_summary">Activer le thème sombre</string>
<string name="settings_clear_cache_title">Effacer le cache du dépot</string>
<string name="settings_clear_cache_summary">Effacer les informations de cache pour les dépots en ligne, Forcer l\'appli à se rafraichir en ligne</string>
<string name="settings_hide_manager_title">Masquer le Gestionnaire Magisk</string>
<string name="settings_hide_manager_summary">Reconstruire le Gestionnaire Magisk avec un nom de paquet aléatoire</string>
<string name="settings_restore_manager_title">Restaurer le Gestionnaire Magisk</string>
<string name="settings_restore_manager_summary">Restaurer le Gestionnaire Magisk avec le paquet originel</string>
<string name="language">Language</string>
<string name="system_default">(Système par Défaut)</string>
<string name="settings_update">Mis à jour des réglages</string>
<string name="settings_check_update_title">Vérification des mises à jours</string>
<string name="settings_check_update_summary">Vérifier l\'éxistance de mise à jour en tâche de fond de façon périodique</string>
<string name="settings_update_channel_title">Mis à jour du canal</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Béta</string>
<string name="settings_update_custom">Personalisé</string>
<string name="settings_update_custom_msg">Insérer une URL personalisée</string>
<string name="settings_boot_format_title">Patcher Format Fichier Démarrage</string>
<string name="settings_boot_format_summary">Sélectioner le format de sortie de l\'image de boot.\nChoisir .img pour flasher à traver le mode démarrage rapide/téléchargement; choisir .img.tar pour flasher via ODIN.</string>
<string name="settings_core_only_title">Mode Magisk Core uniquement</string>
<string name="settings_core_only_summary">Activer uniquement les fonctionnalités de base, tous les modules ne seront pas chargés. MagiskSU, MagiskHide et les hosts systemless restent activés</string>
<string name="settings_magiskhide_summary">Masquer Magisk de diverses détections</string>
<string name="settings_hosts_title">Hosts systemless</string>
<string name="settings_hosts_summary">Support hosts systemless pour les applications type Adblock</string>
<string name="settings_su_app_adb">Applis et ADB</string>
<string name="settings_su_app">Applications uniquement</string>
<string name="settings_su_adb">ADB uniquement</string>
<string name="settings_su_disable">Désactivé</string>
<string name="settings_su_request_10">10 secondes</string>
<string name="settings_su_request_20">20 secondes</string>
<string name="settings_su_request_30">30 secondes</string>
<string name="settings_su_request_60">60 secondes</string>
<string name="superuser_access">Accès Superuser</string>
<string name="auto_response">Réponse automatique</string>
<string name="request_timeout">Délai de requête</string>
<string name="superuser_notification">Notification Superuser</string>
<string name="request_timeout_summary">%1$s secondes</string>
<string name="settings_su_reauth_title">Ré-authentifier après la mise à niveau</string>
<string name="settings_su_reauth_summary">Réauthentifier les autorisations de superutilisateur après une mise à niveau d\'application</string>
<string name="settings_su_fingerprint_title">Activer l\'authentification par empreinte digitale</string>
<string name="settings_su_fingerprint_summary">Utiliser un scanner d\'empreintes digitales pour autoriser les demandes superutilisateur</string>
<string name="multiuser_mode">Mode Multi-utilisateurs</string>
<string name="settings_owner_only">Propriétaire de l\'appareil uniquement</string>
<string name="settings_owner_manage">Propriétaire de l\'appareil géré</string>
<string name="settings_user_independent">Utilisateur indépendant</string>
<string name="owner_only_summary">Seul le propriétaire a un accès root</string>
<string name="owner_manage_summary">Seul le propriétaire peut gérer l\'accès root et recevoir des demandes de requêtes</string>
<string name="user_indepenent_summary">Chaque utilisateur a ses propres règles de root séparées</string>
<string name="multiuser_hint_owner_request">Une requête a été envoyée au propriétaire du périphérique. Merci de basculer en propriétaire et d\'accepter les permissions requises</string>
<string name="mount_namespace_mode">Mode Montage Espace de Noms</string>
<string name="settings_ns_global">Espace de Nom Global</string>
<string name="settings_ns_requester">Hériter de l\'espace de noms</string>
<string name="settings_ns_isolate">Espace de noms isolé</string>
<string name="global_summary">Toutes les sessions racines utilisent l\'espace de noms de montage global</string>
<string name="requester_summary">Les sessions racines hériteront de l\'espace de noms de son demandeur</string>
<string name="isolate_summary">Chaque session racine aura son propre espace de noms isolé</string>
<string name="android_o_not_support">Android 8.0+ n\'est pas supporté</string>
<string name="disable_fingerprint">Aucune empreinte digitale n\'a été définie ou aucun support de périphérique</string>
<!--Superuser-->
<string name="su_request_title">Requête Superuser</string>
<string name="deny_with_str">Refuser%1$s</string>
<string name="deny">Refuser</string>
<string name="prompt">Demander</string>
<string name="grant">Accepter</string>
<string name="su_warning">Accepter un accès complet à votre appareil.\nRefuser si vous n\'êtes pas sûr !</string>
<string name="forever">Toujours</string>
<string name="once">Une fois</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 a obtenu les droits Superuser</string>
<string name="su_deny_toast">%1$s n\'a pas obtenu les droits Superuser</string>
<string name="no_apps_found">Aucune application trouvée</string>
<string name="su_snack_grant">Les droits Superuser de %1$s sont accordés</string>
<string name="su_snack_deny">Les droits Superuser de %1$s sont refusés</string>
<string name="su_snack_notif_on">Les notifications pour %1$s sont activées</string>
<string name="su_snack_notif_off">Les notifications pour %1$s sont désactivées</string>
<string name="su_snack_log_on">La journalisation pour %1$s est activée</string>
<string name="su_snack_log_off">La journalisation pour %1$s est désactivée</string>
<string name="su_snack_revoke">Les droits de %1$s sont annulés</string>
<string name="su_revoke_title">Annuler ?</string>
<string name="su_revoke_msg">Vous confirmez l\'annulation des droits pour %1$s ?</string>
<string name="toast">Toast</string>
<string name="none">Aucun</string>
<string name="auth_fail">Authentication Échouée</string>
<!--Superuser logs-->
<string name="pid">PID :\u0020</string>
<string name="target_uid">UID cible :\\u0020</string>
<string name="command">Commande :\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moduli</string>
<string name="downloads">Preuzimanja</string>
<string name="superuser">Superuser</string>
<string name="log">Zapisnik događaja</string>
<string name="settings">Postavke</string>
<string name="install">Instaliranje</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk nije instaliran</string>
<string name="checking_for_updates">Provjera ažuriranja…</string>
<string name="magisk_update_available">Dostupna je Maigsk inačica v%1$s!</string>
<string name="safetyNet_check_text">Dodirni za SafetyNet provjeru</string>
<string name="checking_safetyNet_status">Provjera SafetyNet statusa</string>
<string name="safetyNet_check_success">SafetyNet provjera uspješna</string>
<string name="safetyNet_api_error">SafetyNet API greška</string>
<string name="safetyNet_network_loss">Mrežna veza nije dostupna</string>
<string name="safetyNet_service_disconnected">Usluga je ubijena</string>
<string name="safetyNet_res_invalid">Odgovor je nevažeći</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Napredne postavke</string>
<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="current_magisk_title">Instalirana inačica: %1$s</string>
<string name="install_magisk_title">Najnovija inačica: %1$s</string>
<string name="uninstall">Deinstaliraj</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 %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nema podataka)</string>
<string name="no_modules_found">Nijedan modul nije pronađen</string>
<string name="update_file_created">Modul će se ažurirati pri sljedećem ponovnom pokretanju</string>
<string name="remove_file_created">Modul će biti uklonjen pri sljedećem ponovnom pokretanju</string>
<string name="remove_file_deleted">Modul neće biti uklonjen pri sljedećem ponovnom pokretanju</string>
<string name="disable_file_created">Modul će biti onemogućen pri sljedećem ponovnom pokretanju</string>
<string name="disable_file_removed">Modul će biti omogućen pri sljedećem ponovnom pokretanju</string>
<string name="author">Napravio %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Ažuriranje dostupno</string>
<string name="installed">Instalirano</string>
<string name="not_installed">Nije instalirano</string>
<!--Log Fragment-->
<string name="menuSaveLog">"Spremi zapisnik "</string>
<string name="menuReload">Ponovno učitaj</string>
<string name="menuClearLog">Očisti zapisnik sada</string>
<string name="logs_cleared">Zapisnik je uspješno izbrisan</string>
<string name="log_is_empty">Zapisnik je prazan</string>
<!--About Activity-->
<string name="about">O aplikaciji</string>
<string name="app_changelog">Popis izmjena aplikacije</string>
<string name="translators" />
<string name="app_version">Verzija aplikacije</string>
<string name="app_source_code">Izvorni kod</string>
<string name="donation">Donacija</string>
<string name="app_translators">Prevoditelji aplikacije</string>
<string name="support_thread">Tema podrške</string>
<!--Toasts, Dialogs-->
<string name="close">Zatvori</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 podizanje sustava</string>
<string name="magisk_update_title">Dostupno je novo Magisk ažuriranje!</string>
<string name="settings_reboot_toast">Ponovno pokrenite kako biste primjenili postavke</string>
<string name="release_notes">Bilješke o izdavanju aplikacije</string>
<string name="repo_cache_cleared">Predmemorija repozitorija izbrisana</string>
<string name="process_error">Pogreška u procesu</string>
<string name="internal_storage">Zip je pohranjen u:\n[Unutarnja pohrana]%1$s</string>
<string name="zip_download_title">Preuzimanje</string>
<string name="zip_download_msg">Preuzimanje zip datoteke (%1$d%%) …</string>
<string name="zip_process_title">Obrada</string>
<string name="zip_process_msg">Obrada zip datoteke …</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="magisk_updates">Magisk ažuriranja</string>
<string name="flashing">Apliciranje</string>
<string name="hide_manager_toast">Skrivanje Magisk Manager aplikacije…</string>
<string name="hide_manager_fail_toast">Skrivanje Magisk Manager nije uspjelo</string>
<string name="download_zip_only">Preuzmi samo zip</string>
<string name="patch_boot_file">Zakrpa datoteke za podizanje sustava</string>
<string name="direct_install">Izravna instalacija (preporuča se)</string>
<string name="install_second_slot">Instalirajte na drugo mjesto (nakon OTA-e)</string>
<string name="select_method">Odaberite metodu</string>
<string name="no_boot_file_patch_support">Ciljana verzija Magiska ne podržava zakrpu datoteke za podizanje sustava</string>
<string name="boot_file_patch_msg">Odaberite standardnu datoteku za podizanje sustava u .img ili .img.tar formatu</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>
<!--Settings Activity -->
<string name="settings_general_category">Općenito</string>
<string name="settings_dark_theme_title">Tamna tema</string>
<string name="settings_dark_theme_summary">Omogući tamnu temu</string>
<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">Ažuriraj postavke</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_boot_format_title">Izlazni format datoteke za podizanje sustava nakon zakrpe</string>
<string name="settings_boot_format_summary">Odaberite izlazni format datoteke za podizanje sustava nakon zakrpe.\nOdaberite .img da biste aplicirali putem brzog pokretanja(fastboota)/preuzimanja(downloada); odaberite .img.tar da biste aplicirali putem ODIN-a.</string>
<string name="settings_core_only_title">Samo Magisk Core način rada</string>
<string name="settings_core_only_summary">Omogućite samo osnovne značajke, svi se moduli neće učitati. MagiskSU, MagiskHide i systemless hostovi će i dalje biti omogućeni</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_20">20 sekundi</string>
<string name="settings_su_request_30">30 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="request_timeout_summary">%1$s sekundi</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="multiuser_hint_owner_request">Zahtjev je poslan vlasniku uređaja. Prebacite se na vlasnika i odobrite dopuštenje</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>
<!--Superuser-->
<string name="su_request_title">Superuser zahtjev</string>
<string name="deny_with_str">Odbij%1$s</string>
<string name="deny">Odbij</string>
<string name="prompt">Upitaj</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="forever">Zauvijek</string>
<string name="once">Jednom</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 su dodijeljena Superuser prava</string>
<string name="su_deny_toast">%1$s su odbijena Superuser prava</string>
<string name="no_apps_found">Nisu pronađene aplikacije</string>
<string name="su_snack_grant">Superuser prava su dodijeljena za %1$s</string>
<string name="su_snack_deny">Superuser prava su odbijena za %1$s</string>
<string name="su_snack_notif_on">Obavijesti za %1$s su odobrene</string>
<string name="su_snack_notif_off">Obavijesti za %1$s su odbijene</string>
<string name="su_snack_log_on">Zapisnik događaja omogućen je za %1$s</string>
<string name="su_snack_log_off">Zapisnik događaja onemogućen je za %1$s</string>
<string name="su_snack_revoke">Opozvana su prava za %1$s</string>
<string name="su_revoke_title">Opozvati?</string>
<string name="su_revoke_msg">Potvrdite da biste opozvali prava za %1$s?</string>
<string name="toast">Pop-up</string>
<string name="none">Nijedan</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Ciljani UID:\u0020</string>
<string name="command">Naredba:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Modul</string>
<string name="downloads">Unduhan</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Pengaturan</string>
<string name="install">Pasang</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk tidak terpasang</string>
<string name="checking_for_updates">Memeriksa pembaruan…</string>
<string name="magisk_update_available">Magisk v%1$s tersedia!</string>
<string name="invalid_update_channel">Kanal Pembaruan tidak valid!</string>
<string name="safetyNet_check_text">Ketuk untuk memulai pemeriksaan SafetyNet</string>
<string name="checking_safetyNet_status">Memeriksa status SafetyNet…</string>
<string name="safetyNet_check_success">Pemeriksaan SafetyNet Berhasil</string>
<string name="safetyNet_api_error">Kesalahan pada API SafetyNet</string>
<string name="safetyNet_network_loss">Koneksi jaringan tidak tersedia</string>
<string name="safetyNet_service_disconnected">Layanan telah dimatikan</string>
<string name="safetyNet_res_invalid">Tanggapan tidak valid</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Pengaturan Lanjutan</string>
<string name="keep_force_encryption">Pertahankan enkripsi paksa</string>
<string name="keep_dm_verity">Pertahankan AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versi yang Terpasang: %1$s</string>
<string name="install_magisk_title">Versi Terbaru: %1$s</string>
<string name="uninstall">Copot</string>
<string name="uninstall_magisk_title">Copot Magisk</string>
<string name="uninstall_magisk_msg">Semua modul akan dinonaktifkan/dihapus. Root akan dihapus, dan berpotensi mengenkripsi data Anda jika tidak terenkripsi saat ini.</string>
<string name="update">Perbarui %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Tidak ada info tersedia)</string>
<string name="no_modules_found">Tidak ada modul ditemukan</string>
<string name="update_file_created">Modul akan diperbarui pada reboot berikutnya</string>
<string name="remove_file_created">Modul akan dihapus pada reboot berikutnya</string>
<string name="remove_file_deleted">Modul tidak akan dihapus pada reboot berikutnya</string>
<string name="disable_file_created">Modul akan dinonaktifkan pada reboot berikutnya</string>
<string name="disable_file_removed">Modul akan diaktifkan pada reboot berikutnya</string>
<string name="author">Dibuat oleh %1$s</string>
<string name="reboot_recovery">Reboot ke Recovery</string>
<string name="reboot_bootloader">Reboot ke Bootloader</string>
<string name="reboot_download">Reboot ke Download</string>
<!--Repo Fragment-->
<string name="update_available">Pembaruan Tersedia</string>
<string name="installed">Terpasang</string>
<string name="not_installed">Tidak Terpasang</string>
<string name="updated_on">Diperbarui pada: %1$s</string>
<string name="sorting_order">Urutkan Susunan</string>
<string name="sort_by_name">Urut berdasarkan nama</string>
<string name="sort_by_update">Urut berdasarkan pembaruan terakhir</string>
<!--Log Fragment-->
<string name="menuSaveLog">Simpan log</string>
<string name="menuReload">Muat ulang</string>
<string name="menuClearLog">Bersihkan log sekarang</string>
<string name="logs_cleared">Log berhasil dibersihkan</string>
<string name="log_is_empty">Log kosong</string>
<!--About Activity-->
<string name="about">Tentang</string>
<string name="app_changelog">Log pembaruan</string>
<string name="translators">Albert I (krasCGQ)</string>
<string name="app_version">Versi</string>
<string name="app_source_code">Kode sumber</string>
<string name="donation">Donasi</string>
<string name="app_translators">Penerjemah</string>
<string name="support_thread">Thread dukungan</string>
<!--Toasts, Dialogs-->
<string name="close">Tutup</string>
<string name="repo_install_title">Pasang %1$s</string>
<string name="repo_install_msg">Apakah Anda ingin memasang %1$s sekarang?</string>
<string name="download">Unduh</string>
<string name="reboot">Reboot</string>
<string name="magisk_update_title">Pembaruan Magisk Tersedia!</string>
<string name="settings_reboot_toast">Reboot untuk menerapkan pengaturan</string>
<string name="release_notes">Catatan rilis</string>
<string name="repo_cache_cleared">Cache repo dibersihkan</string>
<string name="process_error">Kesalahan proses</string>
<string name="internal_storage">Zip disimpan di:\n[Penyimpanan Internal]%1$s</string>
<string name="zip_download_title">Mengunduh</string>
<string name="zip_download_msg">Mengunduh file zip (%1$d%%) …</string>
<string name="zip_process_title">Memproses</string>
<string name="zip_process_msg">Memproses file zip …</string>
<string name="manager_update_title">Pembaruan Magisk Manager Tersedia!</string>
<string name="manager_download_install">Tekan untuk unduh dan pasang</string>
<string name="dtbo_patched_title">DTBO telah ditambal!</string>
<string name="dtbo_patched_reboot">Magisk Manager telah menambal dtbo.img, silahkan reboot</string>
<string name="magisk_updates">Pembaruan Magisk</string>
<string name="flashing">Flashing</string>
<string name="hide_manager_toast">Menyembunyikan Magisk Manager…</string>
<string name="hide_manager_toast2">Ini mungkin membutuhkan beberapa saat…</string>
<string name="hide_manager_fail_toast">Kesalahan menyembunyikan Magisk Manager…</string>
<string name="download_zip_only">Unduh Zip Saja</string>
<string name="patch_boot_file">Tambal File Boot Image</string>
<string name="direct_install">Pasang Langsung (Direkomendasikan)</string>
<string name="install_second_slot">Pasang ke Slot Kedua (Setelah OTA)</string>
<string name="select_method">Pilih Metode</string>
<string name="no_boot_file_patch_support">Versi target Magisk tidak mendukung penambalan file boot image</string>
<string name="boot_file_patch_msg">Pilih stock boot image dump dalam format .img atau .img.tar</string>
<string name="restore_img">Pulihkan Image</string>
<string name="complete_uninstall">Copot Total</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">Unduh Kode Proprieter</string>
<string name="proprietary_notice">Magisk Manager adalah aplikasi FOSS, yang tidak menyertakan kode API proprieter Google SafetyNet.\n\nApakah Anda mengizinkan Magisk Manager untuk mengunduh sebuah ekstensi (berisi GoogleApiClient) untuk pemeriksaan SafetyNet?</string>
<string name="su_db_corrupt">Database SU rusak, akan membuat db baru</string>
<string name="cannot_check_sn_title">Tidak dapat memeriksa SafetyNet</string>
<string name="cannot_check_sn_notice">Karena beberapa perubahan dalam Layanan Google Play, adalah tidak mungkin untuk memeriksa SafetyNet di Magisk Manager yang dipak ulang</string>
<string name="setup_done">Penyiapan selesai</string>
<string name="setup_fail">Penyiapan gagal</string>
<string name="env_fix_title">Memerlukan Penyiapan Tambahan</string>
<string name="env_fix_msg">Perangkat Anda memerlukan penyiapan tambahan untuk Magisk dapat bekerja dengan baik. Ia akan mengunduh zip penyiapan Magisk, apakah Anda ingin melanjutkan sekarang?</string>
<string name="setup_title">Penyiapan Tambahan</string>
<string name="setup_msg">Menjalankan penyiapan lingkungan…</string>
<!--Settings Activity -->
<string name="settings_general_category">Umum</string>
<string name="settings_dark_theme_title">Tema Gelap</string>
<string name="settings_dark_theme_summary">Aktifkan tema gelap</string>
<string name="settings_clear_cache_title">Bersihkan Cache Repo</string>
<string name="settings_clear_cache_summary">Bersihkan informasi ter-cache untuk repo online, memaksa apl untuk menyegarkan online</string>
<string name="settings_hide_manager_title">Sembunyikan Magisk Manager</string>
<string name="settings_hide_manager_summary">Pak ulang Magisk Manager dengan nama paket acak</string>
<string name="settings_restore_manager_title">Pulihkan Magisk Manager</string>
<string name="settings_restore_manager_summary">Pulihkan Magisk Manager dengan paket asli</string>
<string name="language">Bahasa</string>
<string name="system_default">(Default Sistem)</string>
<string name="settings_update">Pengaturan Pembaruan</string>
<string name="settings_update_channel_title">Kanal Pembaruan</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Kustom</string>
<string name="settings_update_custom_msg">Masukkan sebuah URL kustom</string>
<string name="settings_boot_format_title">Format Keluaran Boot yang Ditambal</string>
<string name="settings_boot_format_summary">Pilih format keluaran boot image yang ditambal.\nPilih .img untuk flash melalui mode recovery/download; pilih .img.tar untuk flash melalui ODIN.</string>
<string name="settings_core_only_title">Magisk Mode Inti Saja</string>
<string name="settings_core_only_summary">Aktifkan fitur inti saja. MagiskSU, MagiskHide, dan host tanpa sistem akan tetap diaktifkan</string>
<string name="settings_magiskhide_summary">Sembunyikan Magisk dari berbagai pendeteksian</string>
<string name="settings_hosts_title">Host tanpa sistem</string>
<string name="settings_hosts_summary">Dukungan host tanpa sistem untuk apl pemblokir iklan</string>
<string name="settings_su_app_adb">Apl dan ADB</string>
<string name="settings_su_app">Apl saja</string>
<string name="settings_su_adb">ADB saja</string>
<string name="settings_su_disable">Nonaktif</string>
<string name="settings_su_request_10">10 detik</string>
<string name="settings_su_request_20">20 detik</string>
<string name="settings_su_request_30">30 detik</string>
<string name="settings_su_request_60">60 detik</string>
<string name="superuser_access">Akses Superuser</string>
<string name="auto_response">Tanggapan Otomatis</string>
<string name="request_timeout">Batas Waktu Permintaan</string>
<string name="superuser_notification">Notifikasi Superuser</string>
<string name="request_timeout_summary">%1$s detik</string>
<string name="settings_su_reauth_title">Otentikasi ulang setelah pembaruan</string>
<string name="settings_su_reauth_summary">Otentikasi ulang izin superuser setelah pembaruan sebuah aplikasi</string>
<string name="settings_su_fingerprint_title">Aktifkan Otentikasi Sidik Jari</string>
<string name="settings_su_fingerprint_summary">Gunakan pemindai sidik jari untuk mengizinkan permintaan superuser</string>
<string name="multiuser_mode">Mode Multipengguna</string>
<string name="settings_owner_only">Pemilik Perangkat Saja</string>
<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 permintaan</string>
<string name="user_indepenent_summary">Setiap pengguna memiliki aturan root tersendiri</string>
<string name="multiuser_hint_owner_request">Permintaan telah dikirim kepada pemilik perangkat. Silakan beralih ke pemilik dan berikan izin yang diperlukan</string>
<string name="mount_namespace_mode">Mode Mount Ruang Nama</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 Terisolasi</string>
<string name="global_summary">Semua sesi root menggunakan mount ruang nama global</string>
<string name="requester_summary">Sesi root akan mewarisi ruang nama pemintanya</string>
<string name="isolate_summary">Setiap sesi root akan memiliki ruang nama tersendiri</string>
<string name="android_o_not_support">Tidak mendukung Android 8.0+</string>
<string name="disable_fingerprint">Tidak ada sidik jari diatur atau tidak ada dukungan perangkat</string>
<!--Superuser-->
<string name="su_request_title">Permintaan Superuser</string>
<string name="deny_with_str">Tolak%1$s</string>
<string name="deny">Tolak</string>
<string name="prompt">Beritahu</string>
<string name="grant">Izinkan</string>
<string name="su_warning">Mengizinkan akses penuh ke perangkat Anda.\nTolak jika Anda tidak yakin!</string>
<string name="forever">Selamanya</string>
<string name="once">Sekali</string>
<string name="tenmin">10 mnt</string>
<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 diizinkan akses Superuser</string>
<string name="su_deny_toast">%1$s ditolak akses Superuser</string>
<string name="no_apps_found">Tidak ada apl ditemukan</string>
<string name="su_snack_grant">Akses Superuser dari %1$s diizinkan</string>
<string name="su_snack_deny">Akses Superuser dari %1$s ditolak</string>
<string name="su_snack_notif_on">Notifikasi dari %1$s diaktifkan</string>
<string name="su_snack_notif_off">Notifikasi dari %1$s dinonaktifkan</string>
<string name="su_snack_log_on">Logging dari %1$s diaktifkan</string>
<string name="su_snack_log_off">Logging dari %1$s dinonaktifkan</string>
<string name="su_snack_revoke">Akses %1$s dicabut</string>
<string name="su_revoke_title">Cabut?</string>
<string name="su_revoke_msg">Konfirmasi untuk mencabut akses %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Tidak ada</string>
<string name="auth_fail">Otentikasi Gagal</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID target:\u0020</string>
<string name="command">Perintah:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moduli</string>
<string name="downloads">Download</string>
<string name="superuser">Superuser</string>
<string name="log">Registro eventi</string>
<string name="settings">Impostazioni</string>
<string name="install">Installa</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk non è installato</string>
<string name="checking_for_updates">Controllo aggiornamenti…</string>
<string name="magisk_update_available">È disponibile Magisk v%1$s!</string>
<string name="invalid_update_channel">Canale di aggiornamento non valido</string>
<string name="safetyNet_check_text">Tocca per controllare SafetyNet</string>
<string name="checking_safetyNet_status">Controllo stato SafetyNet…</string>
<string name="safetyNet_check_success">Controllo SafetyNet OK</string>
<string name="safetyNet_api_error">Errore API SafetyNet</string>
<string name="safetyNet_network_loss">Connessione di rete persa</string>
<string name="safetyNet_service_disconnected">Il servizio è stato terminato</string>
<string name="safetyNet_res_invalid">La risposta non è valida</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Impostazioni avanzate</string>
<string name="keep_force_encryption">Mantieni crittografia forzata</string>
<string name="keep_dm_verity">Mantieni AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versione installata: %1$s</string>
<string name="install_magisk_title">Ultima versione disponibile: %1$s</string>
<string name="uninstall">Disinstalla</string>
<string name="uninstall_magisk_title">Disinstalla Magisk</string>
<string name="uninstall_magisk_msg">Tutti i moduli verranno disabilitati/rimossi. Il root verrà rimosso e se il dispositivo non è crittografato è possibile che tutti i dati vengano crittografati</string>
<string name="update">Aggiorna %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nessuna informazione)</string>
<string name="no_modules_found">Nessun modulo trovato</string>
<string name="update_file_created">Il modulo sarà aggiornato al prossimo riavvio</string>
<string name="remove_file_created">Il modulo sarà rimosso al prossimo riavvio</string>
<string name="remove_file_deleted">Il modulo non sarà rimosso al prossimo riavvio</string>
<string name="disable_file_created">Il modulo sarà disabilitato al prossimo riavvio</string>
<string name="disable_file_removed">Il modulo sarà abilitato al prossimo riavvio</string>
<string name="author">Creato da: %1$s</string>
<string name="reboot_recovery">Riavvia in Recovery</string>
<string name="reboot_bootloader">Riavvia in Bootloader</string>
<string name="reboot_download">Riavvia in Download Mode</string>
<!--Repo Fragment-->
<string name="update_available">Aggiornamento disponibile</string>
<string name="installed">Installato</string>
<string name="not_installed">Non installato</string>
<string name="updated_on">Aggiornato il: %1$s</string>
<string name="sorting_order">Ordinamento</string>
<string name="sort_by_name">Ordina per nome</string>
<string name="sort_by_update">Ordina per ultimo aggiornamento</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salva registro eventi</string>
<string name="menuReload">Ricarica</string>
<string name="menuClearLog">Svuota il registro eventi</string>
<string name="logs_cleared">Registro eventi svuotato correttamente</string>
<string name="log_is_empty">Il registro eventi è vuoto</string>
<!--About Activity-->
<string name="about">Informazioni</string>
<string name="app_changelog">Novità</string>
<string name="translators">Auanasgheps | Fabb2303 | bovirus</string>
<string name="app_version">Versione</string>
<string name="app_source_code">Codice sorgente</string>
<string name="donation">Dona</string>
<string name="app_translators">Traduttori</string>
<string name="support_thread">Thread di supporto</string>
<!--Toasts, Dialogs-->
<string name="close">Chiudi</string>
<string name="repo_install_title">Installazione di %1$s</string>
<string name="repo_install_msg">Vuoi installare %1$s?</string>
<string name="download">Download</string>
<string name="reboot">Riavvia</string>
<string name="magisk_update_title">È disponibile un nuovo aggiornamento di Magisk!</string>
<string name="settings_reboot_toast">Riavvia per applicare</string>
<string name="release_notes">Note di rilascio</string>
<string name="repo_cache_cleared">La cache delle repository è stata svuotata</string>
<string name="process_error">Errore di elaborazione</string>
<string name="internal_storage">Il file zip si trova in:\n[Memoria Interna]%1$s</string>
<string name="zip_download_title">Download in corso</string>
<string name="zip_download_msg">Download del file zip (%1$d%%) …</string>
<string name="zip_process_title">Elaborazione</string>
<string name="zip_process_msg">Elaborazione del file zip…</string>
<string name="manager_update_title">È disponibile un nuovo aggiornamento di Magisk Manager!</string>
<string name="manager_download_install">Premere per scaricare e installare</string>
<string name="dtbo_patched_title">DTBO è stato aggiornato!</string>
<string name="dtbo_patched_reboot">Magisk Manager ha aggiornato dtbo.img, riavvia per completare</string>
<string name="magisk_updates">Aggiornamenti di Magisk</string>
<string name="flashing">Flash in corso…</string>
<string name="hide_manager_toast">Nascondendo Magisk Manager…</string>
<string name="hide_manager_toast2">Potrebbe volerci un po\'…</string>
<string name="hide_manager_fail_toast">Non è stato possibile nascondere Magisk Manager</string>
<string name="download_zip_only">Scarica solo il file zip</string>
<string name="patch_boot_file">Aggiorna l\'immagine di boot</string>
<string name="direct_install">Installazione diretta (raccomandata)</string>
<string name="install_second_slot">Installa nel secondo slot (dopo OTA)</string>
<string name="select_method">Seleziona un metodo</string>
<string name="no_boot_file_patch_support">La versione Magisk di destinazione non supporta l\'aggiornamento dell\'immagine di boot</string>
<string name="boot_file_patch_msg">Seleziona l\'immagine originale di boot in formato .img o img.tar</string>
<string name="complete_uninstall">Disinstallazione completa</string>
<string name="restore_img">Ripristina Immagini</string>
<string name="restore_img_msg">Ripristino…</string>
<string name="restore_done">Ripristino completato!</string>
<string name="restore_fail">Non esiste un\'immagine originale di boot!</string>
<string name="proprietary_title">Scarica codice proprietario</string>
<string name="proprietary_notice">Magisk Manager è FOSS, quindi non contiene codice proprietario delle API Google SafetyNet.\n\nVuoi permettere il download di un\'estensione (che contiene GoogleApiClient) per controllare lo stato di SafetyNet?</string>
<string name="su_db_corrupt">Il database SU è corrotto, un nuovo DB verrà ricreato</string>
<string name="cannot_check_sn_title">Impossibile controllare SafetyNet</string>
<string name="cannot_check_sn_notice">In seguito a dei cambiamenti in Google Play Services, non è possibile controllare SafetyNet quando Magisk Manager è nascosto</string>
<string name="setup_done">Configurazione completata</string>
<string name="setup_fail">Configurazione fallita</string>
<string name="env_fix_title">Richiedi configurazione aggiuntiva</string>
<string name="env_fix_msg">Il tuo dispositivo necessita di una configurazione aggiuntiva per far funzionare Magisk correttamente. Verrà scaricato il file zip di Magisk, vuoi procedere ora?</string>
<string name="setup_title">Configurazione aggiuntiva</string>
<string name="setup_msg">Configurazione dell\'ambiente in corso…</string>
<!--Settings Activity -->
<string name="settings_general_category">Generale</string>
<string name="settings_dark_theme_title">Tema scuro</string>
<string name="settings_dark_theme_summary">Abilita il tema scuro</string>
<string name="settings_clear_cache_title">Svuota cache repository</string>
<string name="settings_clear_cache_summary">Svuota la cache delle repository e forza l\'aggiornamento online dell\'app</string>
<string name="settings_hide_manager_title">Nascondi Magisk Manager</string>
<string name="settings_hide_manager_summary">Reinstalla Magisk Manager con un nome pacchetto casuale</string>
<string name="settings_restore_manager_title">Ripristina Magisk Manager</string>
<string name="settings_restore_manager_summary">Ripristina Magisk Manager con il nome pacchetto originale</string>
<string name="language">Lingua</string>
<string name="system_default">(Sistema)</string>
<string name="settings_update">Impostazioni aggiornamento</string>
<string name="settings_check_update_title">Controlla aggiornamenti</string>
<string name="settings_check_update_summary">Controlla automaticamente gli aggiornamenti in background</string>
<string name="settings_update_channel_title">Canale di aggiornamento</string>
<string name="settings_update_stable">Stabile</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Personalizzato</string>
<string name="settings_update_custom_msg">Inserisci un URL personalizzato</string>
<string name="settings_boot_format_title">Formato dell\'immagine di boot aggiornata</string>
<string name="settings_boot_format_summary">Seleziona il formato nel quale l\'immagine di boot verrà salvata.\nSeleziona .img per il flash in Fastboot/Download Mode; Seleziona .img.tar per il flash con Odin.</string>
<string name="settings_core_only_title">Modalità Magisk Core</string>
<string name="settings_core_only_summary">Abilita solo le funzioni principali. Nessun modulo verrà caricato. MagiskSU, MagiskHide e host systemless rimarranno abilitati</string>
<string name="settings_magiskhide_summary">Nasconde Magisk da numerose rilevazioni</string>
<string name="settings_hosts_title">Host systemless</string>
<string name="settings_hosts_summary">Supporto a host systemless per le app che bloccano le pubblicità</string>
<string name="settings_su_app_adb">App e ADB</string>
<string name="settings_su_app">Solo app</string>
<string name="settings_su_adb">Solo ADB</string>
<string name="settings_su_disable">Disabilitato</string>
<string name="settings_su_request_10">10 secondi</string>
<string name="settings_su_request_20">20 secondi</string>
<string name="settings_su_request_30">30 secondi</string>
<string name="settings_su_request_60">60 secondi</string>
<string name="superuser_access">Accesso Superuser</string>
<string name="auto_response">Accesso predefinito</string>
<string name="request_timeout">Timeout richiesta</string>
<string name="superuser_notification">Notifica Superuser</string>
<string name="request_timeout_summary">%1$s secondi</string>
<string name="settings_su_reauth_title">Ri-autentica dopo aggiornamento</string>
<string name="settings_su_reauth_summary">Ri-autentica i permessi Superuser dopo un aggiornamento dell\'app</string>
<string name="settings_su_fingerprint_title">Abilita autenticazione impronta</string>
<string name="settings_su_fingerprint_summary">Utilizza il sensore di impronte per accettare le richieste Superuser</string>
<string name="multiuser_mode">Modalità multiutente</string>
<string name="settings_owner_only">Solo proprietario del dispositivo</string>
<string name="settings_owner_manage">Gestito dal proprietario utente</string>
<string name="settings_user_independent">Utente indipendente</string>
<string name="owner_only_summary">Solo il proprietario ha i permessi di root</string>
<string name="owner_manage_summary">Solo il proprietario può gestire accesso root e ricevere richieste</string>
<string name="user_indepenent_summary">Ogni utente ha le sue regole di root separate</string>
<string name="multiuser_hint_owner_request">Una richiesta è stata inviata al proprietario del dispositivo. Accedi come proprietario dispositivo e concedi i permessi.</string>
<string name="mount_namespace_mode">Modalità mount namespace</string>
<string name="settings_ns_global">Namespace globale</string>
<string name="settings_ns_requester">Namespace ereditato</string>
<string name="settings_ns_isolate">Namespace isolato</string>
<string name="global_summary">Tutte le sessioni di root erediteranno il namespace globale</string>
<string name="requester_summary">Le sessioni di root erediteranno il namespace del loro richiedente</string>
<string name="isolate_summary">Ogni sessione di root avrà il suo namespace isolato</string>
<string name="android_o_not_support">Non è supportato da Android 8.0+</string>
<string name="disable_fingerprint">Non è presente alcuna impronta o il dispositivo non è supportato</string>
<!--Superuser-->
<string name="su_request_title">Richiesta Superuser</string>
<string name="deny_with_str">Nega %1$s</string>
<string name="deny">Nega</string>
<string name="prompt">Chiedi</string>
<string name="grant">Concedi</string>
<string name="su_warning">Concede il pieno accesso al dispositivo.\nNega se non sei sicuro</string>
<string name="forever">Sempre</string>
<string name="once">Una volta</string>
<string name="tenmin">10 minuti</string>
<string name="twentymin">20 minuti</string>
<string name="thirtymin">30 minuti</string>
<string name="sixtymin">60 minuti</string>
<string name="su_allow_toast">%1$s ha ottenuto i permessi Superuser</string>
<string name="su_deny_toast">%1$s non ha ottenuto i permessi Superuser</string>
<string name="no_apps_found">Nessuna app trovata</string>
<string name="su_snack_grant"> %1$s ha ottenuto i permessi Superuser</string>
<string name="su_snack_deny"> %1$s non ha ottenuto i permessi Superuser</string>
<string name="su_snack_notif_on">Notifiche per %1$s abilitate</string>
<string name="su_snack_notif_off">Notifiche per %1$s disabilitate</string>
<string name="su_snack_log_on">Registro eventi abilitato per %1$s</string>
<string name="su_snack_log_off">Registro eventi non abilitato per %1$s</string>
<string name="su_snack_revoke">I diritti di %1$s sono stati revocati</string>
<string name="su_revoke_title">Vuoi revocare?</string>
<string name="su_revoke_msg">Confermi la revoca dei diritti di %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Nessuno</string>
<string name="auth_fail">Autenticatione fallita</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID destinazione:\u0020</string>
<string name="command">Comando:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">モジュール</string>
<string name="downloads">ダウンロード</string>
<string name="superuser">スーパーユーザー</string>
<string name="log">ログ</string>
<string name="settings">設定</string>
<string name="install">インストール</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magiskがインストールされていません</string>
<string name="checking_for_updates">更新を確認中…</string>
<string name="magisk_update_available">Magisk v%1$s が利用可能です!</string>
<string name="invalid_update_channel">不正な更新チャンネルです</string>
<string name="safetyNet_check_text">タップしてSafetyNetチェックを開始</string>
<string name="checking_safetyNet_status">SafetyNetの状態をチェック中…</string>
<string name="safetyNet_check_success">SafetyNetチェック成功</string>
<string name="safetyNet_api_error">SafetyNet APIエラー</string>
<string name="safetyNet_network_loss">ネットワーク接続がありません</string>
<string name="safetyNet_service_disconnected">サービスが終了されました</string>
<string name="safetyNet_res_invalid">応答が不正です</string>
<!--Install Fragment-->
<string name="advanced_settings_title">高度な設定</string>
<string name="keep_force_encryption">強制的な暗号化を維持する</string>
<string name="keep_dm_verity">AVB 2.0/dm-verityを維持する</string>
<string name="current_magisk_title">インストール済: %1$s</string>
<string name="install_magisk_title">最新: %1$s</string>
<string name="uninstall">アンインストール</string>
<string name="uninstall_magisk_title">Magiskのアンインストール</string>
<string name="uninstall_magisk_msg">すべてのモジュールが無効化/削除されます。Rootも無効化され、ストレージが暗号化されていない場合、暗号化される場合があります</string>
<string name="update">%1$sの更新</string>
<!--Module Fragment-->
<string name="no_info_provided">(情報がありません)</string>
<string name="no_modules_found">モジュールが見つかりません</string>
<string name="update_file_created">次の再起動時にモジュールを更新する</string>
<string name="remove_file_created">次の再起動時にモジュールを削除する</string>
<string name="remove_file_deleted">次の再起動時にモジュールを削除しない</string>
<string name="disable_file_created">次の再起動時にモジュールを無効にする</string>
<string name="disable_file_removed">次の再起動時にモジュールを有効にする</string>
<string name="author">開発者: %1$s</string>
<string name="reboot_recovery">リカバリへ再起動</string>
<string name="reboot_bootloader">Bootloaderへ再起動</string>
<string name="reboot_download">Downloadへ再起動</string>
<!--Repo Fragment-->
<string name="update_available">更新あり</string>
<string name="installed">インストール済</string>
<string name="not_installed">未インストール</string>
<string name="updated_on">更新日: %1$s</string>
<string name="sorting_order">並び順</string>
<string name="sort_by_name">名前順</string>
<string name="sort_by_update">最終更新日順</string>
<!--Log Fragment-->
<string name="menuSaveLog">ログの保存</string>
<string name="menuReload">再読み込み</string>
<string name="menuClearLog">ログの消去</string>
<string name="logs_cleared">ログを消去しました</string>
<string name="log_is_empty">ログは空です</string>
<!--About Activity-->
<string name="about">このアプリについて</string>
<string name="app_changelog">アプリの更新履歴</string>
<string name="translators">神楽坂桜(Sakura_Sa233#Twitter)/ hota (@lindwurm) / AndroPlus (@AndroPlus_org)</string>
<string name="app_version">アプリのバージョン</string>
<string name="app_source_code">ソースコード</string>
<string name="donation">寄付</string>
<string name="app_translators">アプリの翻訳者</string>
<string name="support_thread">サポートスレッド</string>
<!--Toasts, Dialogs-->
<string name="close">閉じる</string>
<string name="repo_install_title">%1$s をインストール</string>
<string name="repo_install_msg">%1$s をインストールしますか?</string>
<string name="download">ダウンロード</string>
<string name="reboot">再起動</string>
<string name="magisk_update_title">新しいMagiskの更新が利用可能です!</string>
<string name="settings_reboot_toast">再起動して設定を適用する</string>
<string name="release_notes">更新履歴</string>
<string name="repo_cache_cleared">リポジトリキャッシュを消去しました</string>
<string name="process_error">プロセスエラー</string>
<string name="internal_storage">ZIPは\n[内部ストレージ]%1$sに保存されます</string>
<string name="zip_download_title">ダウンロード中</string>
<string name="zip_download_msg">ZIPファイルのダウンロード中 (%1$d%%) …</string>
<string name="zip_process_title">処理</string>
<string name="zip_process_msg">ZIPファイルの処理中…</string>
<string name="manager_update_title">Magisk Managerの更新があります!</string>
<string name="manager_download_install">タップでダウンロードしてインストールします</string>
<string name="dtbo_patched_title">DTBOをパッチしました!</string>
<string name="dtbo_patched_reboot">Magisk Managerはdtbo.imgをパッチしました。再起動してください</string>
<string name="magisk_updates">Magiskの更新</string>
<string name="flashing">書き込み中</string>
<string name="hide_manager_toast">Magisk Managerを隠しています…</string>
<string name="hide_manager_toast2">しばらくお待ちください…</string>
<string name="hide_manager_fail_toast">Magisk Managerを隠せませんでした…</string>
<string name="download_zip_only">ZIPのみダウンロード</string>
<string name="patch_boot_file">Bootイメージのパッチ</string>
<string name="direct_install">直接インストール (推奨)</string>
<string name="install_second_slot">第2スロットへインストール (OTA後)</string>
<string name="select_method">方法の選択</string>
<string name="no_boot_file_patch_support">指定されたMagiskバージョンはBootイメージのパッチに対応していません</string>
<string name="boot_file_patch_msg">StockのBootイメージ (.img または .img.tar形式) を選択してください</string>
<string name="complete_uninstall">完全にアンインストール</string>
<string name="restore_img">イメージのリストア</string>
<string name="restore_done">リストア完了!</string>
<string name="restore_fail">Stockのバックアップがありません!</string>
<string name="proprietary_title">プロプライエタリコードのダウンロード</string>
<string name="proprietary_notice">Magisk ManagerはFOSSのため、GoogleのプロプライエタリなSafetyNet APIコードを含んでいません。\n\nMagisk ManagerがSafetyNetチェックのための拡張機能 (GoogleApiClientを含む) をダウンロードすることを許可しますか?</string>
<string name="su_db_corrupt">SUデータベースが壊れています。DBを再生成します</string>
<!--Settings Activity -->
<string name="settings_general_category">一般</string>
<string name="settings_dark_theme_title">ダークテーマ</string>
<string name="settings_dark_theme_summary">ダークテーマを有効化します</string>
<string name="settings_clear_cache_title">キャッシュを消去</string>
<string name="settings_clear_cache_summary">オンラインリポジトリのキャッシュされた情報を消去し、アプリをオンラインで更新します</string>
<string name="settings_hide_manager_title">Magisk Managerを隠す</string>
<string name="settings_hide_manager_summary">Magisk Managerをランダムなパッケージ名で再パックします</string>
<string name="language">Language</string>
<string name="system_default">(システム標準)</string>
<string name="settings_update">更新設定</string>
<string name="settings_update_channel_title">更新チャンネル</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">カスタム</string>
<string name="settings_update_custom_msg">カスタムURLを入力</string>
<string name="settings_boot_format_title">パッチしたBootの出力形式</string>
<string name="settings_boot_format_summary">パッチしたBootイメージの出力形式を選択してください。\nfastboot/download modeでインストールするには .img を、ODINでインストールするには .img.tar を選択してください</string>
<string name="settings_core_only_title">Magisk コアモード</string>
<string name="settings_core_only_summary">コア機能のみを有効にします。すべてのモジュールが読み込まれなくなります。 MagiskSU、MagiskHide、systemless hostsは引き続き有効になります</string>
<string name="settings_magiskhide_summary">さまざまな検出からMagiskを隠します</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">広告ブロックアプリのためのSystemless hostsサポートを有効化します</string>
<string name="settings_su_app_adb">アプリとADB</string>
<string name="settings_su_app">アプリのみ</string>
<string name="settings_su_adb">ADBのみ</string>
<string name="settings_su_disable">無効</string>
<string name="settings_su_request_10">10秒</string>
<string name="settings_su_request_20">20秒</string>
<string name="settings_su_request_30">30秒</string>
<string name="settings_su_request_60">60秒</string>
<string name="superuser_access">スーパーユーザーアクセス</string>
<string name="auto_response">自動応答</string>
<string name="request_timeout">リクエストタイムアウト</string>
<string name="superuser_notification">スーパーユーザー通知</string>
<string name="request_timeout_summary">%1$s秒</string>
<string name="settings_su_reauth_title">アップグレード後の再認証</string>
<string name="settings_su_reauth_summary">アプリのアップグレード後にスーパーユーザー権限を再認証します</string>
<string name="settings_su_fingerprint_title">指紋認証の有効化</string>
<string name="settings_su_fingerprint_summary">スーパーユーザー権限のリクエストの許可に指紋認証を使います</string>
<string name="multiuser_mode">マルチユーザーモード</string>
<string name="settings_owner_only">端末の管理者のみ</string>
<string name="settings_owner_manage">端末の管理者が管理</string>
<string name="settings_user_independent">ユーザー毎</string>
<string name="owner_only_summary">端末の管理者のみスーパーユーザー権限を利用できます</string>
<string name="owner_manage_summary">端末の管理者のみがスーパーユーザー権限を管理し、リクエストを受け付けられます</string>
<string name="user_indepenent_summary">ユーザー毎にそれぞれスーパーユーザー権限を設定できます</string>
<string name="multiuser_hint_owner_request">端末の管理者にリクエストを送信しました。管理者に切り替えて権限を許可してください</string>
<string name="mount_namespace_mode">名前空間のマウントモード</string>
<string name="settings_ns_global">グローバル名前空間</string>
<string name="settings_ns_requester">継承された名前空間</string>
<string name="settings_ns_isolate">分離された名前空間</string>
<string name="global_summary">すべてのrootセッションがグローバル名前空間を使用します</string>
<string name="requester_summary">rootセッションはリクエスト者の名前空間を継承します</string>
<string name="isolate_summary">rootセッション毎に分離された名前空間を使用します</string>
<string name="android_o_not_support">Android 8.0以降では対応していません</string>
<!--Superuser-->
<string name="su_request_title">スーパーユーザーリクエスト</string>
<string name="deny_with_str">拒否 %1$s</string>
<string name="deny">拒否</string>
<string name="prompt">プロンプト</string>
<string name="grant">許可</string>
<string name="su_warning">端末への完全なアクセスを許可します。\nもし確信が持てなければ拒否してください!</string>
<string name="forever">今後も</string>
<string name="once">一度だけ</string>
<string name="tenmin">10分</string>
<string name="twentymin">20分</string>
<string name="thirtymin">30分</string>
<string name="sixtymin">60分</string>
<string name="su_allow_toast">%1$s はスーパーユーザー権限を許可されました</string>
<string name="su_deny_toast">%1$s はスーパーユーザー権限を拒否されました</string>
<string name="no_apps_found">アプリが見つかりません</string>
<string name="su_snack_grant">%1$s のスーパーユーザー権限が許可されました</string>
<string name="su_snack_deny">%1$s のスーパーユーザー権限は拒否されました</string>
<string name="su_snack_notif_on">%1$s の通知は有効です</string>
<string name="su_snack_notif_off">%1$s の通知は無効です</string>
<string name="su_snack_log_on">%1$s のログは有効です</string>
<string name="su_snack_log_off">%1$s のログは無効です</string>
<string name="su_snack_revoke">%1$s の権限は取り消されました</string>
<string name="su_revoke_title">確認</string>
<string name="su_revoke_msg">%1$s の権限を取り消しますか?</string>
<string name="toast">トースト通知</string>
<string name="none">なし</string>
<string name="auth_fail">認証に失敗しました</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">ターゲット UID:\u0020</string>
<string name="command">コマンド:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">모듈</string>
<string name="downloads">다운로드</string>
<string name="superuser">슈퍼유저</string>
<string name="log">로그</string>
<string name="settings">설정</string>
<string name="install">설치</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk가 설치되지 않음</string>
<string name="checking_for_updates">업데이트 확인 중…</string>
<string name="magisk_update_available">Magisk v%1$s 사용 가능!</string>
<string name="safetyNet_check_text">SafetyNet 체크를 시작하려면 누르기</string>
<string name="checking_safetyNet_status">SafetyNet 상태 확인 중…</string>
<!--Install Fragment-->
<string name="advanced_settings_title">고급 설정</string>
<string name="keep_force_encryption">강제 암호화 유지</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity 유지</string>
<string name="current_magisk_title">설치된버전: %1$s</string>
<string name="install_magisk_title">최신버전: %1$s</string>
<string name="uninstall">제거</string>
<string name="uninstall_magisk_title">Magisk 제거</string>
<!--Module Fragment-->
<string name="no_info_provided">(제공된 정보 없음)</string>
<string name="no_modules_found">검색된 모듈 없음</string>
<string name="update_file_created">모듈이 다음 다시 시작 시 업데이트됨</string>
<string name="remove_file_created">모듈이 다음 다시 시작 시 제거됨</string>
<string name="remove_file_deleted">모듈이 다음 다시 시작 시 제거되지 않음</string>
<string name="disable_file_created">모듈이 다음 다시 시작 시 비활성화됨</string>
<string name="disable_file_removed">모듈이 다음 다시 시작 시 활성화됨</string>
<string name="author">제작: %1$s</string>
<!--Repo Fragment-->
<string name="update_available">업데이트 있음</string>
<string name="installed">설치됨</string>
<string name="not_installed">설치되지 않음</string>
<!--Log Fragment-->
<string name="menuSaveLog">저장 로그</string>
<string name="menuReload">다시 불러오기</string>
<string name="menuClearLog">지금 로그 비우기</string>
<string name="logs_cleared">로그가 성공적으로 비워짐</string>
<string name="log_is_empty">로그가 비어 있음</string>
<!--About Activity-->
<string name="about">정보</string>
<string name="app_changelog">앱 변경 사항</string>
<string name="translators">lilymaniac</string>
<string name="app_version">앱 버전</string>
<string name="app_source_code">소스 코드</string>
<string name="donation">기부</string>
<string name="app_translators">앱 번역자</string>
<string name="support_thread">지원 스레드</string>
<!--Toasts, Dialogs-->
<string name="close">닫기</string>
<string name="repo_install_title">%1$s 설치</string>
<string name="repo_install_msg">정말 %1$s을(를) 설치하시겠습니까?</string>
<string name="reboot">다시 시작</string>
<string name="zip_process_msg">zip 파일 처리 중…</string>
<string name="magisk_update_title">새 버전의 Magisk를 사용할 수 있습니다!</string>
<string name="settings_reboot_toast">기기를 다시 시작하면 설정이 적용됩니다.</string>
<string name="release_notes">릴리즈 노트</string>
<string name="repo_cache_cleared">저장소 캐시 비워짐</string>
<string name="process_error">처리 오류</string>
<string name="internal_storage">zip 파일이 다음 위치에 저장됨:\n[내부 저장소]%1$s</string>
<string name="zip_process_title">처리 중</string>
<!--Settings Activity -->
<string name="settings_general_category">일반</string>
<string name="settings_dark_theme_title">어두운 테마</string>
<string name="settings_dark_theme_summary">어두운 테마 사용</string>
<string name="settings_clear_cache_title">저장소 캐시 비우기</string>
<string name="settings_clear_cache_summary">온라인 저장소에 대해 캐시된 정보를 지우고, 온라인에서 정보를 강제로 새로 고칩니다.</string>
<string name="settings_core_only_title">Magisk 핵심 기능 모드</string>
<string name="settings_core_only_summary">핵심 기능만 사용합니다. 모든 모듈은 로드하지 않습니다. MagiskSU, MagiskHide 및 systemless hosts 는 계속 사용할 수 있습니다.</string>
<string name="settings_magiskhide_summary">다양한 감지로부터 Magisk를 숨깁니다.</string>
<string name="settings_hosts_title">systemless hosts</string>
<string name="settings_hosts_summary">광고 차단 앱에서 사용하는 systemless hosts를 지원합니다.</string>
<string name="settings_su_app_adb">앱 및 ADB</string>
<string name="settings_su_app">앱만</string>
<string name="settings_su_adb">ADB만</string>
<string name="settings_su_disable">사용 안 함</string>
<string name="settings_su_request_10">10초</string>
<string name="settings_su_request_20">20초</string>
<string name="settings_su_request_30">30초</string>
<string name="settings_su_request_60">60초</string>
<string name="superuser_access">슈퍼유저 액세스</string>
<string name="auto_response">자동 응답</string>
<string name="request_timeout">요청 시간 제한</string>
<string name="superuser_notification">슈퍼유저 알림</string>
<string name="request_timeout_summary">%1$s초</string>
<!--Superuser-->
<string name="su_request_title">슈퍼유저 요청</string>
<string name="deny_with_str">거부%1$s</string>
<string name="deny">거부</string>
<string name="prompt">메시지</string>
<string name="grant">허용</string>
<string name="su_warning">기기에 대한 전체 액세스 권한을 부여합니다.\n확실하지 않은 경우 거부하세요!</string>
<string name="forever">영구적으로</string>
<string name="once">한 번만</string>
<string name="tenmin">10분</string>
<string name="twentymin">20분</string>
<string name="thirtymin">30분</string>
<string name="sixtymin">60분</string>
<string name="su_allow_toast">%1$s에 슈퍼유저 권한이 허용됨</string>
<string name="su_deny_toast">%1$s에 슈퍼유저 권한이 거부됨</string>
<string name="no_apps_found">검색된 앱 없음</string>
<string name="su_snack_grant">%1$s의 슈퍼유저 권한이 허용됨</string>
<string name="su_snack_deny">%1$s의 슈퍼유저 권한이 거부됨</string>
<string name="su_snack_notif_on">%1$s의 알림이 활성화됨</string>
<string name="su_snack_notif_off">%1$s의 알림이 비활성화됨</string>
<string name="su_snack_log_on">%1$s의 로깅이 활성화됨</string>
<string name="su_snack_log_off">%1$s의 로깅이 비활성화됨</string>
<string name="su_snack_revoke">%1$s의 권한이 취소됨</string>
<string name="su_revoke_title">취소하시겠습니까?</string>
<string name="su_revoke_msg">정말 %1$s의 권한을 취소하시겠습니까?</string>
<string name="toast">토스트</string>
<string name="none">없음</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">대상 UID:\u0020</string>
<string name="command">명령:\u0020</string>
<string name="download">다운로드</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Papildiniai</string>
<string name="downloads">Papildinių parduotuvė</string>
<string name="superuser">Supervartotojas</string>
<string name="log">Įvykių sąrašas</string>
<string name="settings">Nustatymai</string>
<string name="install">Instaliuoti</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk yra neinstaliuotas</string>
<string name="checking_for_updates">Ieškoma atnaujinimų…</string>
<string name="magisk_update_available">Magisk v%1$s yra galima!</string>
<string name="invalid_update_channel">Neteisingas atnaujinimų nustatymas</string>
<string name="safetyNet_check_text">Paspauskite SafetyNet paieškai</string>
<string name="checking_safetyNet_status">Ieškomas SafetyNet statusas…</string>
<string name="safetyNet_check_success">SafetyNet Paieška sėkminga</string>
<string name="safetyNet_api_error">SafetyNet API Klaida</string>
<string name="safetyNet_network_loss">Nėra prieigos prie interneto</string>
<string name="safetyNet_service_disconnected">Paslauga atjungta</string>
<string name="safetyNet_res_invalid">Gautas neteisingas atsakymas</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Išplėstiniai nustatymai</string>
<string name="keep_force_encryption">Palikti priverstinį šifravimą</string>
<string name="keep_dm_verity">Palikti dm-verity</string>
<string name="current_magisk_title">Instaliuota versija: %1$s</string>
<string name="install_magisk_title">Naujausia versija: %1$s</string>
<string name="uninstall">Pašalinti</string>
<string name="uninstall_magisk_title">Pašalinti Magisk</string>
<string name="uninstall_magisk_msg">Visi papildiniai bus išjungti/pašalinti. Root bus panaikintas. Yra galimybė, kad duomenys bus užšifruoti…</string>
<string name="update">Atnaujinti %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nėra informacijos)</string>
<string name="no_modules_found">Papildinių nesurasta</string>
<string name="update_file_created">Perkrovus sistemą papildinys bus atnaujintas</string>
<string name="remove_file_created">Perkrovus sistemą papildinys bus panaikintas</string>
<string name="remove_file_deleted">Perkrovus sistemą papildinys nebus panaikintas</string>
<string name="disable_file_created">Perkrovus sistemą papildinys bus išjungtas, tačiau nepanaikintas</string>
<string name="disable_file_removed">Perkrovus sistemą papildinys bus įjungtas</string>
<string name="author">Sukūrė %1$s</string>
<string name="reboot_recovery">Perkrauti į Recovery</string>
<string name="reboot_bootloader">Perkrauti į Bootloader</string>
<string name="reboot_download">Perkrauti į Download režimą</string>
<!--Repo Fragment-->
<string name="update_available">Galimas atnaujinimas</string>
<string name="installed">Instaliuota</string>
<string name="not_installed">Neinstaliuota</string>
<string name="updated_on">Atnaujinta: %1$s</string>
<string name="sorting_order">Išdėliojimo tvarka</string>
<string name="sort_by_name">Išdėlioti pagal pavadinimą (A-Z)</string>
<string name="sort_by_update">Išdėlioti pagal atnaujinimo datą (Naujausi-Seniausi)</string>
<!--Log Fragment-->
<string name="menuSaveLog">Išsaugoti įvykių sąrašą</string>
<string name="menuReload">Įvykių sąrašo atnaujinmas</string>
<string name="menuClearLog">Išvalyti įvykių sąrašą</string>
<string name="logs_cleared">Įvykių sąrašas pašalintas</string>
<string name="log_is_empty">Įvykių sąrašas tuščias</string>
<!--About Activity-->
<string name="about">Apie</string>
<string name="app_changelog">Pakeitimų sąrašas</string>
<string name="translators">Vv2233Bb</string>
<string name="app_version">Versija</string>
<string name="app_source_code">Prisidėkite</string>
<string name="donation">Paaukoti</string>
<string name="app_translators">Vertėjai</string>
<string name="support_thread">Mūsų XDA puslapis</string>
<!--Toasts, Dialogs-->
<string name="close">Uždaryti</string>
<string name="repo_install_title">Instaliuoti %1$s</string>
<string name="repo_install_msg">Ar jūs norite instaliuoti %1$s?</string>
<string name="download">Atsisiųsti</string>
<string name="reboot">Perkrauti</string>
<string name="magisk_update_title">Atsirado nauja Magisk versija!</string>
<string name="settings_reboot_toast">Nustatymų įgalinimui prašome perkrauti telefoną</string>
<string name="release_notes">Pakeitimai</string>
<string name="repo_cache_cleared">Repo failai išvalyti</string>
<string name="process_error">Proceso klaida</string>
<string name="internal_storage">Zip failas yra saugomas:\n[Internal Storage]%1$s</string>
<string name="zip_download_title">Atsisiunčiama</string>
<string name="zip_download_msg">Atsiunčiamas zip failas(%1$d%%)…</string>
<string name="zip_process_title">Vyksta procesas</string>
<string name="zip_process_msg">Zip failas apdorojamas…</string>
<string name="manager_update_title">Atsirado naujas Magisk Manager atnaujinimas!</string>
<string name="manager_download_install">Paspauskite, kad atsisiųstumėte ir instaliuotumėte</string>
<string name="dtbo_patched_title">DTBO buvo ištaisytas!</string>
<string name="dtbo_patched_reboot">Magisk Manager ištaisė dtbo.img, prašome perkrauti telefoną</string>
<string name="magisk_updates">Magisk Atnaujinimai</string>
<string name="flashing">Instaliuojama</string>
<string name="hide_manager_toast">Magisk Manager paslėpiamas…</string>
<string name="hide_manager_toast2">Tai užtruks sekundėlę…</string>
<string name="hide_manager_fail_toast">Magisk Manager paslėpimas žlugo…</string>
<string name="download_zip_only">Atsisiųsti zip failą</string>
<string name="patch_boot_file">Ištaisyti boot failą</string>
<string name="direct_install">Tiesioginis instaliavimas (Rekomenduojamas)</string>
<string name="install_second_slot">Instaliuoti į antrą vietą (Po OTA)</string>
<string name="select_method">Pasirinkite metodą</string>
<string name="no_boot_file_patch_support">Pasirinkta Magisk versija nepalaiko pakeitimų boot faile</string>
<string name="boot_file_patch_msg">Pasirinkti boot failą .img ar .img.tar formate</string>
<string name="complete_uninstall">Pilnas pašalinimas</string>
<string name="restore_img">Atstatyti boot failą</string>
<string name="restore_img_msg">Atstatome…</string>
<string name="restore_done">Atstatymas įvykdytas!</string>
<string name="restore_fail">Gamyklinis atstatymo failas neegzistuoja!</string>
<string name="proprietary_title">Atsisiųsti patentuotą kodą</string>
<string name="proprietary_notice">Magisk Manager yra FOSS todėl neturi Google patentuoto SafetyNet API kodo.\n\nAr jūs leidžiate Magisk Manager atsisiųsti papildinį (turintį GoogleApiClient) SafetyNet paieškai?</string>
<string name="su_db_corrupt">Supervartotojo duomenų bazė yra sugadinta, perkursime naują duomenų bazę</string>
<string name="cannot_check_sn_title">Negalime surasti SafetyNet</string>
<string name="cannot_check_sn_notice">Dėl Google Play Services pakeitimų, SafetyNet suradimas perpakuotame Magisk Manager yra neįmanomas</string>
<string name="setup_done">Pasiruošimas baigtas</string>
<string name="setup_fail">Pasiruošimas nesėkmingas</string>
<string name="env_fix_title">Reikalingas papildomas pasiruošimas</string>
<string name="env_fix_msg">Kad Magisk veiktų tinkamai, jūsų įrenginiui reikia papildomo paruošimo. Tai atsisiųs papildomą Magisk zip failą, ar norite tęsti?</string>
<string name="setup_title">Papildomas pasiruošimas</string>
<string name="setup_msg">Paruošiama aplinka…</string>
<!--Settings Activity -->
<string name="settings_general_category">Pagrininiai</string>
<string name="settings_dark_theme_title">Tamsi tema</string>
<string name="settings_dark_theme_summary">Įjungti tamsią temą</string>
<string name="settings_clear_cache_title">Išvalyti nereikalingus saugyklos failus</string>
<string name="settings_clear_cache_summary">Išvalyti patalpintą informaciją talpykloms internete, priverčia perkrauti interneto jungtį</string>
<string name="settings_hide_manager_title">Paslėpti Magisk Manager</string>
<string name="settings_hide_manager_summary">Perpakuoti Magisk Manager su atsitiktiniu pakuotės pavadinimu</string>
<string name="settings_restore_manager_title">Grąžinti Magisk Manager</string>
<string name="settings_restore_manager_summary">Grąžinti Magisk Manager su orginalia pakuote</string>
<string name="language">Kalba</string>
<string name="system_default">(Sistemos)</string>
<string name="settings_update">Atnaujinimų nustatymai</string>
<string name="settings_check_update_title">Automatiškas atnaujinimų ieškojimas</string>
<string name="settings_check_update_summary">Automatiškai ieškoti Magisk ir Magisk Manager atnaujinimų</string>
<string name="settings_update_channel_title">Atnaujinimų tipai</string>
<string name="settings_update_stable">Stabilūs</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Pasirinktiniai</string>
<string name="settings_update_custom_msg">Įvesti pasirinktinį URL</string>
<string name="settings_boot_format_title">Boot failo formatas</string>
<string name="settings_boot_format_summary">Pasirinkti boot failo formatą.\n.img naudojamas įdiegimui per fastboot/download; .img.tar naudojamas įdiegimui per ODIN</string>
<string name="settings_core_only_title">Pagrindinis Magisk režimas</string>
<string name="settings_core_only_summary">Įgalinti tik pagrindines funkcijas, išjungti visus papildinius. MagiskSU, Magisk Hide ir Sistemos pedejėjai liks įgalinti</string>
<string name="settings_magiskhide_summary">Paslėpti Magisk nuo įvairių susekimų</string>
<string name="settings_hosts_title">Sistemos padejėjai</string>
<string name="settings_hosts_summary">Įgalinti sistemos padejėjus Adblock programėlėms</string>
<string name="settings_su_app_adb">Programėlėms ir ADB</string>
<string name="settings_su_app">Tik programėlėms</string>
<string name="settings_su_adb">Tik ADB</string>
<string name="settings_su_disable">Išjungta</string>
<string name="settings_su_request_10">10 sekundžių</string>
<string name="settings_su_request_20">20 sekundžių</string>
<string name="settings_su_request_30">30 sekundžių</string>
<string name="settings_su_request_60">60 sekundžių</string>
<string name="superuser_access">Supervartotojo prieiga</string>
<string name="auto_response">Automatinis atsakymas</string>
<string name="request_timeout">Prašymo laikas baigiasi po</string>
<string name="superuser_notification">Supervartotojo pranešimai</string>
<string name="request_timeout_summary">%1$s sekundžių</string>
<string name="settings_su_reauth_title">Pakartotinai patvirtinti po atnaujinimo</string>
<string name="settings_su_reauth_summary">Pakartotinai patvirtinti supervartotojo leidimus po programėlės atnaujinimo</string>
<string name="settings_su_fingerprint_title">Įgalinti patvirtinimą piršto antspaudu</string>
<string name="settings_su_fingerprint_summary">Naudoti piršto antspaudą supervartotojo leidimo prašymų atsakymui</string>
<string name="multiuser_mode">Daugialypio vartotojo režimas</string>
<string name="settings_owner_only">Tik įrenginio savininkas</string>
<string name="settings_owner_manage">Įrenginio savininko valdomas</string>
<string name="settings_user_independent">Visų</string>
<string name="owner_only_summary">Tik įrenginio savininkas turi root prieigą</string>
<string name="owner_manage_summary">Tik įrenginio savinkas gali tvarkyti root prieigą ir gauti lenteles prašančias root prieigos</string>
<string name="user_indepenent_summary">Kiekvienas vartotojas turi savo atskiras root taisykles</string>
<string name="multiuser_hint_owner_request">Prašymas buvo nusiųstas savininkui. Prašome tapti savininku ir suteikite leidimą</string>
<string name="mount_namespace_mode">Root sesijos vardų srities režimas</string>
<string name="settings_ns_global">Globali vardų sritis</string>
<string name="settings_ns_requester">Paveldima vardų sritis</string>
<string name="settings_ns_isolate">Izoliuota vardų sritis</string>
<string name="global_summary">Visos root sesijos naudoja globalią vardų sritį</string>
<string name="requester_summary">Root sesijos paveldi jos išprašytojo/s vardų sritį</string>
<string name="isolate_summary">Kiekviena root sesija turi savo izoliuotą vardų sritį</string>
<string name="android_o_not_support">Įrenginiai su Android 8.0+ nepalaiko šio nustatymo</string>
<string name="disable_fingerprint">Jūsų įrenginyje nebuvo surasta pirštų antspaudų arba jūsų įrenginys neturi pirštų antspaudų skaitytuvo</string>
<!--Superuser-->
<string name="su_request_title">Supervartotojo prašymas</string>
<string name="deny_with_str">Atmesti%1$s</string>
<string name="deny">Atmesti</string>
<string name="prompt">Klausti</string>
<string name="grant">Suteikti(a)</string>
<string name="su_warning">Supervartotojo prieiga suteikia pilną prieigą prie jūsų įrenginio\nAtmeskite jei neesate tikri dėl programėlės patikimumo!</string>
<string name="forever">Visados</string>
<string name="once">Vieną kartą</string>
<string name="tenmin">10 min</string>
<string name="twentymin">20 min</string>
<string name="thirtymin">30 min</string>
<string name="sixtymin">60 min</string>
<string name="su_allow_toast">%1$s gavo supervartotojo teises</string>
<string name="su_deny_toast">%1$s negavo supervartotojo teisių</string>
<string name="no_apps_found">Nėra surastų programėlių</string>
<string name="su_snack_grant">%1$s supervartotojo teisių prašymas buvo atsakytas teigiamai</string>
<string name="su_snack_deny">%1$s supervartotojo teisių prašymas buvo atmestas</string>
<string name="su_snack_notif_on">Buvo įjungta %1$s pranešimai</string>
<string name="su_snack_notif_off">Buvo išjungta %1$s pranešimai</string>
<string name="su_snack_log_on">%1$s įvykių surašymas yra įgalintas</string>
<string name="su_snack_log_off">%1$s įvykių surašymas yra išjungtas</string>
<string name="su_snack_revoke">%1$s supervartotojo teisės atimtos</string>
<string name="su_revoke_title">Neleisti?</string>
<string name="su_revoke_msg">Neleisti %1$s naudotis supervartotojo teisėmis?</string>
<string name="toast">Išmesti</string>
<string name="none">Nėra</string>
<string name="auth_fail">Patvirtinimas žlugo</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Target UID:\u0020</string>
<string name="command">Komanda:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Downloads</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Instellingen</string>
<string name="install">Installeren</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk niet geïnstalleerd</string>
<string name="checking_for_updates">Controleren op updates…</string>
<string name="magisk_update_available">Magisk v%1$s beschikbaar!</string>
<string name="invalid_update_channel">Ongeldig bijwerkkanaal</string>
<string name="safetyNet_check_text">Tik om SafetyNet controle te starten</string>
<string name="checking_safetyNet_status">SafetyNet status controleren…</string>
<string name="safetyNet_check_success">SafetyNet controle succesvol</string>
<string name="safetyNet_api_error">SafetyNet API fout</string>
<string name="safetyNet_network_loss">Netwerkverbinding verloren</string>
<string name="safetyNet_service_disconnected">Service is beëindigd</string>
<string name="safetyNet_res_invalid">Reactie is ongeldig</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Geavanceerde instellingen</string>
<string name="keep_force_encryption">Behoud afgedwongen versleuteling</string>
<string name="keep_dm_verity">Behoud AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Geïnstalleerde versie: %1$s</string>
<string name="install_magisk_title">Recentste versie: %1$s</string>
<string name="uninstall">Deïnstalleren</string>
<string name="uninstall_magisk_title">Magisk deïnstalleren</string>
<string name="uninstall_magisk_msg">Alle modules worden uitgeschakeld/verwijderd. Root wordt verwijderd, en je data wordt mogelijk versleuteld als deze dat momenteel niet is</string>
<string name="update">Bijwerken %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Geen info verstrekt)</string>
<string name="no_modules_found">Geen modules gevonden</string>
<string name="update_file_created">Module wordt bijgewerkt bij volgende herstart</string>
<string name="remove_file_created">Module wordt verwijderd bij volgende herstart</string>
<string name="remove_file_deleted">Module wordt niet verwijderd bij volgende herstart</string>
<string name="disable_file_created">Module wordt uitgeschakeld bij volgende herstart</string>
<string name="disable_file_removed">Module wordt ingeschakeld bij volgende herstart</string>
<string name="author">Gemaakt door %1$s</string>
<string name="reboot_recovery">Herstart naar Recovery</string>
<string name="reboot_bootloader">Herstart naar Bootloader</string>
<string name="reboot_download">Herstart naar Download</string>
<!--Repo Fragment-->
<string name="update_available">Update beschikbaar</string>
<string name="installed">Geïnstalleerd</string>
<string name="not_installed">Niet geïnstalleerd</string>
<string name="updated_on">Bijgewerkt op: %1$s</string>
<string name="sorting_order">Sorteervolgorde</string>
<string name="sort_by_name">Sorteren op naam</string>
<string name="sort_by_update">Sorteren op laatste update</string>
<!--Log Fragment-->
<string name="menuSaveLog">Opslaan log</string>
<string name="menuReload">Herladen</string>
<string name="menuClearLog">Log nu wissen</string>
<string name="logs_cleared">Log succesvol gewist</string>
<string name="log_is_empty">Log is leeg</string>
<!--About Activity-->
<string name="about">Over</string>
<string name="app_changelog">App\'s changelog</string>
<string name="translators" />
<string name="app_version">App\'s versie</string>
<string name="app_source_code">Broncode</string>
<string name="donation">Donatie</string>
<string name="app_translators">App\'s vertalers</string>
<string name="support_thread">Hulp thread</string>
<!--Toasts, Dialogs-->
<string name="close">Sluiten</string>
<string name="repo_install_title">%1$s installeren</string>
<string name="repo_install_msg">Zeker weten %1$s installeren?</string>
<string name="download">Downloaden</string>
<string name="reboot">Herstarten</string>
<string name="magisk_update_title">Nieuwe Magisk update beschikbaar!</string>
<string name="settings_reboot_toast">Herstarten om instellingen toe te passen</string>
<string name="release_notes">Publicatie notities</string>
<string name="repo_cache_cleared">Opslagcache gewist</string>
<string name="process_error">Verwerkingsfout</string>
<string name="internal_storage">De zip is opgeslagen in:\n[Interne opslag]%1$s</string>
<string name="zip_download_title">Downloaden</string>
<string name="zip_download_msg">Zip-bestand downloaden (%1$d%%) …</string>
<string name="zip_process_title">Verwerken</string>
<string name="zip_process_msg">Zip-bestand verwerken…</string>
<string name="manager_update_title">Nieuwe Magisk Manager update beschikbaar!</string>
<string name="manager_download_install">Tik om te downloaden en installeren</string>
<string name="dtbo_patched_title">DTBO is gepatched!</string>
<string name="dtbo_patched_reboot">Magisk Manager heeft dtbo.img gepatched, herstarten a.u.b.</string>
<string name="magisk_updates">Magisk updates</string>
<string name="flashing">Flashen</string>
<string name="hide_manager_toast">Magisk Manager verbergen…</string>
<string name="hide_manager_toast2">Dit kan even duren…</string>
<string name="hide_manager_fail_toast">Magisk Manager verbergen mislukt…</string>
<string name="download_zip_only">Alleen zip downloaden</string>
<string name="patch_boot_file">Boot image-bestand patchen</string>
<string name="direct_install">Direct installeren (aangeraden)</string>
<string name="install_second_slot">Op tweede positie installeren (na OTA)</string>
<string name="select_method">Methode kiezen</string>
<string name="no_boot_file_patch_support">Magisk versie ondersteund geen boot image-bestand patchen</string>
<string name="boot_file_patch_msg">Kies originele boot image-dump in .img- of .img.tar-formaat</string>
<string name="complete_uninstall">Compleet deïnstalleren</string>
<string name="restore_img">Images herstellen</string>
<string name="restore_done">Herstel voltooid!</string>
<string name="restore_fail">Originele back-up bestaat niet!</string>
<string name="proprietary_title">Google\'s code downloaden</string>
<string name="proprietary_notice">Magisk Manager is FOSS, dus bevat geen SafetyNet API code van Google.\n\nSta je Magisk Manager toe om een extensie te downloaden (bevat GoogleApiClient) voor SafetyNet controles?</string>
<string name="su_db_corrupt">SU database is corrupt, nieuwe db maken…</string>
<string name="cannot_check_sn_title">Kan SafetyNet niet controleren</string>
<string name="cannot_check_sn_notice">Door wijzigingen in Google Play Services is het niet mogelijk om SafetyNet te controleren met een opnieuw ingepakte Magisk Manager</string>
<!--Settings Activity -->
<string name="settings_general_category">Algemeen</string>
<string name="settings_dark_theme_title">Donker thema</string>
<string name="settings_dark_theme_summary">Donker thema inschakelen</string>
<string name="settings_clear_cache_title">Opslagcache wissen</string>
<string name="settings_clear_cache_summary">Wis de gecachte informatie voor online opslagplaatsen. Dit dwingt de app om online te verversen</string>
<string name="settings_hide_manager_title">Magisk Manager verbergen</string>
<string name="settings_hide_manager_summary">Magisk Manager opnieuw inpakken met een willekeurige pakketnaam</string>
<string name="settings_restore_manager_title">Magisk Manager herstellen</string>
<string name="settings_restore_manager_summary">Magisk Manager met oorspronkelijk pakket herstellen</string>
<string name="language">Taal</string>
<string name="system_default">(Systeem standaard)</string>
<string name="settings_update">Instellingen bijwerken</string>
<string name="settings_check_update_title">Updates controleren</string>
<string name="settings_check_update_summary">Periodiek op updates controleren in de achtergrond</string>
<string name="settings_update_channel_title">Update-kanaal</string>
<string name="settings_update_stable">Stabiel</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Aangepast</string>
<string name="settings_update_custom_msg">Aangepaste URL invoeren</string>
<string name="settings_boot_format_title">Gepatchte boot uitvoerformaat</string>
<string name="settings_boot_format_summary">Kies het formaat van de boot image uitvoer.\nKies .img om via fastboot/downloadmodus te flashen; kies .img.tar om via ODIN te flashen.</string>
<string name="settings_core_only_title">Magisk basismodus</string>
<string name="settings_core_only_summary">Alleen kernfuncties inschakelen. Alle modules worden niet geladen. MagiskSU, MagiskHide, en systeemloze hosts blijven ingeschakeld</string>
<string name="settings_magiskhide_summary">Magisk van verschillende detecties verbergen</string>
<string name="settings_hosts_title">Systeemloze hosts</string>
<string name="settings_hosts_summary">Systemloze hosts ondersteuning voor Adblock apps</string>
<string name="settings_su_app_adb">Apps en ADB</string>
<string name="settings_su_app">Alleen apps</string>
<string name="settings_su_adb">Alleen ADB</string>
<string name="settings_su_disable">Uitgeschakeld</string>
<string name="settings_su_request_10">10 seconden</string>
<string name="settings_su_request_20">20 seconden</string>
<string name="settings_su_request_30">30 seconden</string>
<string name="settings_su_request_60">60 seconden</string>
<string name="superuser_access">Superuser toegang</string>
<string name="auto_response">Automatisch antwoord</string>
<string name="request_timeout">Verzoek time-out</string>
<string name="superuser_notification">Superuser melding</string>
<string name="request_timeout_summary">%1$s seconden</string>
<string name="settings_su_reauth_title">Opnieuw verzoeken na bijwerken</string>
<string name="settings_su_reauth_summary">Superuser rechten opnieuw opvragen na bijwerken applicatie</string>
<string name="settings_su_fingerprint_title">Vingerafdruk authenticatie inschakelen</string>
<string name="settings_su_fingerprint_summary">Vingerafdruk gebruiken om superuser verzoeken toe te staan</string>
<string name="multiuser_mode">Multi-gebruiker modus</string>
<string name="settings_owner_only">Alleen apparaateigenaar</string>
<string name="settings_owner_manage">Beheerd door apparaateigenaar</string>
<string name="settings_user_independent">Gebruiker onafhankelijk</string>
<string name="owner_only_summary">Alleen eigenaar heeft roottoegang</string>
<string name="owner_manage_summary">Alleen eigenaar kan roottoegang beheren en prompt verzoeken ontvangen</string>
<string name="user_indepenent_summary">Iedere gebruiker heeft eigen afzonderlijke rootregels</string>
<string name="multiuser_hint_owner_request">Een verzoek is naar de apparaateigenaar verstuurd. Wissel van gebruiker en sta de rechten toe</string>
<string name="mount_namespace_mode">Naamruimte-mount modus</string>
<string name="settings_ns_global">Globale naamruimte</string>
<string name="settings_ns_requester">Verkrijg naamruimte</string>
<string name="settings_ns_isolate">Geïsoleerde naamruimte</string>
<string name="global_summary">Alle rootsessies gebruiken de globale naamruimte</string>
<string name="requester_summary">Rootsessies verkrijgen de verzoeker\'s naamruimte</string>
<string name="isolate_summary">Iedere rootsessie heeft een eigen geïsoleerde naamruimte</string>
<string name="android_o_not_support">Ondersteunt geen Android 8.0+</string>
<string name="disable_fingerprint">Geen vingerafdrukken ingesteld, of geen apparaatondersteuning</string>
<!--Superuser-->
<string name="su_request_title">Superuser verzoek</string>
<string name="deny_with_str">Weigeren %1$s</string>
<string name="deny">Weigeren</string>
<string name="prompt">Prompt</string>
<string name="grant">Toestaan</string>
<string name="su_warning">Verleent volledige toegang tot je apparaat.\nWeigeren als je het niet zeker weet!</string>
<string name="forever">Altijd</string>
<string name="once">Eénmalig</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">Superuser rechten voor %1$s toegestaan</string>
<string name="su_deny_toast">Superuser rechten voor %1$s geweigerd</string>
<string name="no_apps_found">Geen apps gevonden</string>
<string name="su_snack_grant">Superuser rechten van %1$s toegestaan</string>
<string name="su_snack_deny">Superuser rechten van %1$s geweigerd</string>
<string name="su_snack_notif_on">Meldingen van %1$s ingeschakeld</string>
<string name="su_snack_notif_off">Meldingen van %1$s uitgeschakeld</string>
<string name="su_snack_log_on">Loggen van %1$s ingeschakeld</string>
<string name="su_snack_log_off">Loggen of %1$s uitgeschakeld</string>
<string name="su_snack_revoke">%1$s rechten zijn ingetrokken</string>
<string name="su_revoke_title">Intrekken?</string>
<string name="su_revoke_msg">De rechten van %1$s intrekken?</string>
<string name="toast">Toast</string>
<string name="none">Geen</string>
<string name="auth_fail">Authenticatie mislukt</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Doel UID:\u0020</string>
<string name="command">Opdracht:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Moduły</string>
<string name="downloads">Pobieranie</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Ustawienia</string>
<string name="install">Instalacja</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk nie jest zainstalowany</string>
<string name="checking_for_updates">Sprawdzanie aktualizacji…</string>
<string name="magisk_update_available">Magisk v%1$s dostępny!</string>
<string name="invalid_update_channel">Nieprawidłowy Kanał Aktualizacji</string>
<string name="safetyNet_check_text">Dotknij aby sprawdzić SafetyNet</string>
<string name="checking_safetyNet_status">Sprawdzanie statusu SafetyNet…</string>
<string name="safetyNet_check_success">SafetyNet Poprawny</string>
<string name="safetyNet_api_error">SafetyNet Błędny</string>
<string name="safetyNet_network_loss">Brak połączenia z internetem</string>
<string name="safetyNet_service_disconnected">Usługa została zamknięta</string>
<string name="safetyNet_res_invalid">Usługa nie odpowiada</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Zaawansowane Ustawienia</string>
<string name="keep_force_encryption">Zachowaj force encryption</string>
<string name="keep_dm_verity">Zachowaj AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Zainstalowana Wersja: %1$s</string>
<string name="install_magisk_title">Ostatnia Wersja: %1$s</string>
<string name="uninstall">Odinstaluj</string>
<string name="uninstall_magisk_title">Odinstaluj Magisk</string>
<string name="uninstall_magisk_msg">Wszystkie moduły będą wyłączone/usunięte. Root zostanie usunięty i przywrócone szyfrowanie danych, jeśli nie są te dane obecnie szyfrowane</string>
<string name="update">Aktualizacja %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nie umieszczono informacji)</string>
<string name="no_modules_found">Nie znaleziono modułów</string>
<string name="update_file_created">Moduł zostanie zaktualizowany przy następnym restarcie</string>
<string name="remove_file_created">Moduł zostanie usunięty przy następnym uruchomieniu</string>
<string name="remove_file_deleted">Moduł nie zostanie usunięty podczas następnego restartu</string>
<string name="disable_file_created">Moduł zostanie wyłączony przy następnym restarcie</string>
<string name="disable_file_removed">Moduł zostanie włączony przy następnym restarcie</string>
<string name="author">Autor: %1$s</string>
<string name="reboot_recovery">Restart do Recovery</string>
<string name="reboot_bootloader">Restart do Bootloadera</string>
<string name="reboot_download">Restart do Download</string>
<!--Repo Fragment-->
<string name="update_available">Aktualizacja jest dostępna</string>
<string name="installed">Zainstalowany</string>
<string name="not_installed">Nie zainstalowany</string>
<string name="updated_on">Zaktualizowano: %1$s</string>
<string name="sorting_order">Kolejność Sortowania</string>
<string name="sort_by_name">Sortuj po nazwie</string>
<string name="sort_by_update">Sortuj po ostatniej aktualizacji</string>
<!--Log Fragment-->
<string name="menuSaveLog">Zapisz log</string>
<string name="menuReload">Załaduj ponownie</string>
<string name="menuClearLog">Wyczyść Log</string>
<string name="logs_cleared">Log wyczyszczony</string>
<string name="log_is_empty">Log jest pusty</string>
<!--About Activity-->
<string name="about">O Aplikacji</string>
<string name="app_changelog">Zmiany w Aplikacji</string>
<string name="translators" />
<string name="app_version">Wersja Aplikacji</string>
<string name="app_source_code">Kod Źródłowy</string>
<string name="donation">Dotacja</string>
<string name="app_translators">Tłumacze Aplikacji</string>
<string name="support_thread">Strona Wsparcia</string>
<!--Toasts, Dialogs-->
<string name="close">Zamknij</string>
<string name="repo_install_title">Zainstaluj %1$s</string>
<string name="repo_install_msg">Czy chcesz zainstalować %1$s ?</string>
<string name="download">Pobierz</string>
<string name="reboot">Restart</string>
<string name="magisk_update_title">Nowa Wersja Magisk Dostępna!</string>
<string name="settings_reboot_toast">Uruchom ponownie, aby zastosować ustawienia</string>
<string name="release_notes">Zmiany</string>
<string name="repo_cache_cleared">Cache repozytorium wyczyszczone</string>
<string name="process_error">Błąd procesu</string>
<string name="internal_storage">Zip jest przechowywany w:\n[Pamięć Wewnętrzna]%1$s</string>
<string name="zip_download_title">Pobieranie</string>
<string name="zip_download_msg">Pobieranie pliku zip (%1$d%%) …</string>
<string name="zip_process_title">Przetwarzanie</string>
<string name="zip_process_msg">Przetwarzanie pliku zip …</string>
<string name="manager_update_title">Nowa Wersja Magisk Manager Jest Dostępna!</string>
<string name="manager_download_install">Naciśnij aby pobrać i zainstalować</string>
<string name="dtbo_patched_title">DTBO został wgrany!</string>
<string name="dtbo_patched_reboot">Magisk Manager wgrał dtbo.img, uruchom ponownie</string>
<string name="magisk_updates">Aktualizacja Magisk</string>
<string name="flashing">Flashowanie</string>
<string name="hide_manager_toast">Ukryj Magisk Manager…</string>
<string name="hide_manager_toast2">To może chwilę potrwać…</string>
<string name="hide_manager_fail_toast">Błąd Ukrycia Magisk Managera</string>
<string name="download_zip_only">Pobierz Tylko Zip</string>
<string name="patch_boot_file">Patchowanie Pliku Boot Image</string>
<string name="direct_install">Bezpośrednia instalacja (Zalecane)</string>
<string name="install_second_slot">Zainstaluj na Drugim Slocie (Po OTA)</string>
<string name="select_method">Wybierz Metodę</string>
<string name="no_boot_file_patch_support">Wersja docelowa programu Magisk nie obsługuje ładowania pliku boot image</string>
<string name="boot_file_patch_msg">Wybierz stock boot image w formacie .img lub .img.tar</string>
<string name="complete_uninstall">Odinstalowywanie Zakończone</string>
<string name="restore_img">Przywróć Obraz</string>
<string name="restore_done">Przywracanie zakończone!</string>
<string name="restore_fail">Stock backup nie istnieje!</string>
<string name="proprietary_title">Pobierz Kod</string>
<string name="proprietary_notice">Magisk Manager to FOSS, więc nie zawiera zastrzeżonego kodu API SafetyNet. \n\nCzy zezwolić Magisk Managerowi na pobranie rozszerzenia (zawierającego GoogleApiClient) do sprawdzenia SafetyNet?</string>
<string name="su_db_corrupt">Baza danych SU jest uszkodzona, odtworzy nową bazę danych</string>
<string name="cannot_check_sn_title">Nie mogę sprawdzić SafetyNet</string>
<string name="cannot_check_sn_notice">Z powodu pewnych zmian w Usługach Google Play nie jest możliwe sprawdzenie SafetyNet w przepakowanym Magisk Managerze</string>
<string name="setup_done">Konfiguracja gotowa</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 pliku instalacyjnego Magisk, czy chcesz kontynuować?</string>
<!--Settings Activity -->
<string name="settings_general_category">Ogólne</string>
<string name="settings_dark_theme_title">Ciemny Motyw</string>
<string name="settings_dark_theme_summary">Włącz ciemny motyw</string>
<string name="settings_clear_cache_title">Wyczyść Pamięć Repozytorium</string>
<string name="settings_clear_cache_summary">Wymusza na aplikacji odświeżenie online repozytorium</string>
<string name="settings_hide_manager_title">Ukryj Magisk Manager</string>
<string name="settings_hide_manager_summary">Przepakowanie Magisk Manager z losową nazwą pakietu</string>
<string name="settings_restore_manager_title">Przywróć Magisk Manager</string>
<string name="settings_restore_manager_summary">Przywróć oryginalną paczkę Magisk Manager</string>
<string name="language">Język</string>
<string name="system_default">(Domyślny Systemu)</string>
<string name="settings_update">Aktualizacja Ustawień</string>
<string name="settings_check_update_title">Sprawdź Aktualizację</string>
<string name="settings_check_update_summary">Regularnie sprawdzaj aktualizacje 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">Wstaw własny URL</string>
<string name="settings_boot_format_title">Poprawny format pliku rozruchowego</string>
<string name="settings_boot_format_summary">Wybierz format pliku boot image.\nWybierz .img dla wgrywania poprzez Fastboot/Download Mode. Wybierz .img.tar dla ODINA.</string>
<string name="settings_core_only_title">Tylko Podstawowy Tryb Magisk</string>
<string name="settings_core_only_summary">Włącz tylko podstawowe funkcje, wszystkie moduły nie zostaną załadowane. MagiskSU, MagiskHide i systemless hosts nadal będą włączone</string>
<string name="settings_magiskhide_summary">Włącz Magisk Hide dla wykrytych aplikacji</string>
<string name="settings_hosts_title">Włącz systemless hosts</string>
<string name="settings_hosts_summary">Wsparcie systemless dla aplikacji Adblock</string>
<string name="settings_su_app_adb">Aplikacje i ADB</string>
<string name="settings_su_app">Tylko Aplikacje</string>
<string name="settings_su_adb">Tylko ADB</string>
<string name="settings_su_disable">Wyłączone</string>
<string name="settings_su_request_10">10 sekund</string>
<string name="settings_su_request_20">20 sekund</string>
<string name="settings_su_request_30">30 sekund</string>
<string name="settings_su_request_60">60 sekund</string>
<string name="superuser_access">Dostęp Superuser</string>
<string name="auto_response">Automatyczna Odpowiedź</string>
<string name="request_timeout">Czas na decyzję</string>
<string name="superuser_notification">Powiadomienia Superusera</string>
<string name="request_timeout_summary">%1$s sekund</string>
<string name="settings_su_reauth_title">Ponowienie uwierzytelnienia po aktualizacji</string>
<string name="settings_su_reauth_summary">Ponowne uwierzytelnianie uprawnienia superużytkownika po aktualizacji aplikacji</string>
<string name="settings_su_fingerprint_title">Włącz Uwierzytelnienie Odciskiem Palca</string>
<string name="settings_su_fingerprint_summary">Użyj skanera linii papilarnych, aby zezwolić na żądania supersu</string>
<string name="multiuser_mode">Tryb Multiusera</string>
<string name="settings_owner_only">Tylko Właściciel Urządzenia</string>
<string name="settings_owner_manage">Zarządzanie Właścicielami Urządzenia</string>
<string name="settings_user_independent">Niezależny Użytkownik</string>
<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ć prawami dostępu użytkownika do roota iwyświetlać żądania dostępu</string>
<string name="user_indepenent_summary">Każdy użytkownik ma swoje własne odrębne ustawienia dostępu</string>
<string name="multiuser_hint_owner_request">Żądanie zostało wysłane do właściciela urządzenia. Proszę przejść do właściciela i udzielić pozwolenia</string>
<string name="mount_namespace_mode">Montuj Tryb Odstępu Nazw</string>
<string name="settings_ns_global">Globalna Nazwa</string>
<string name="settings_ns_requester">Dziedziczenie Nazw</string>
<string name="settings_ns_isolate">Izolacja Nazw</string>
<string name="global_summary">Wszystkie sesje root za pomocą globalnej przestrzeni montowań nazw</string>
<string name="requester_summary">Sesje Root będzie dziedziczyć prośby i nazwy</string>
<string name="isolate_summary">W każdej sesji root będzie miał własną odosobnioną nazwę</string>
<string name="android_o_not_support">Brak wsparcia dla Androida 8.0+</string>
<string name="disable_fingerprint">Nie ustawiono żadnych odcisków palców lub brak obsługi urządzenia</string>
<!--Superuser-->
<string name="su_request_title">Prośba o dostęp Superusera</string>
<string name="deny_with_str">Odmów%1$s</string>
<string name="deny">Odmów</string>
<string name="prompt">Zapytaj</string>
<string name="grant">Przyznaj</string>
<string name="su_warning">Udziela pełnego dostępu do urządzenia.\nOdmów jeśli nie jesteś pewien!</string>
<string name="forever">Zawsze</string>
<string name="once">Raz</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 ma przyznane uprawnienia Superusera</string>
<string name="su_deny_toast">%1$s ma odmówione uprawnienia Superusera</string>
<string name="no_apps_found">Nie znaleziono aplikacji</string>
<string name="su_snack_grant">Przyznano uprawnienia Superuser dla %1$s</string>
<string name="su_snack_deny">Odmówiono uprawnień Superuser dla %1$s</string>
<string name="su_snack_notif_on">Powiadomienia dla %1$s są włączone</string>
<string name="su_snack_notif_off">Powiadomienia dla %1$s są wyłączone</string>
<string name="su_snack_log_on">Logowanie dla %1$s jest włączone</string>
<string name="su_snack_log_off">Logowanie dla %1$s jest wyłączone</string>
<string name="su_snack_revoke">%1$s uprawnienia są odwołane</string>
<string name="su_revoke_title">Odwołać?</string>
<string name="su_revoke_msg">Potwierdzasz odwołanie uprawnień %1$s?</string>
<string name="toast">Powiadomienie</string>
<string name="none">Brak</string>
<string name="auth_fail">Uwierzytelnienie Nieudane</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Identyfikator UID:\u0020</string>
<string name="command">Komenda:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Módulos</string>
<string name="downloads">Downloads</string>
<string name="superuser">Superusuário</string>
<string name="log">Registro</string>
<string name="settings">Definições</string>
<string name="install">Instalar</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk não está instalado</string>
<string name="checking_for_updates">Verificando por atualizações…</string>
<string name="magisk_update_available">Magisk v%1$s está disponível!</string>
<string name="invalid_update_channel">Canal de Atualização Inválido</string>
<string name="safetyNet_check_text">Verificar SafetyNet</string>
<string name="checking_safetyNet_status">Verificando status de SafetyNet…</string>
<string name="safetyNet_check_success">SafetyNet Verificado Com Sucesso</string>
<string name="safetyNet_api_error">Erro de SafetyNet API</string>
<string name="safetyNet_network_loss">Conexão de rede indisponível</string>
<string name="safetyNet_service_disconnected">Serviço foi morto</string>
<string name="safetyNet_res_invalid">A resposta é inválida</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Definições Avançadas</string>
<string name="keep_force_encryption">Preservar criptografia forçada</string>
<string name="keep_dm_verity">Preservar AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versão Instalada: %1$s</string>
<string name="install_magisk_title">Última Versão: %1$s</string>
<string name="uninstall">Desinstalar</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="uninstall_magisk_msg">Todos os módulos serão desativados/removidos. O root será removido, e potencialmente criptografará seus dados se seus dados não estiverem atualmente criptografados</string>
<string name="update">Atualizar %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nenhuma informação fornecida)</string>
<string name="no_modules_found">Nenhum módulo encontrado</string>
<string name="update_file_created">Módulo será atualizado na próxima reinicialização</string>
<string name="remove_file_created">Módulo será removido na próxima reinicialização</string>
<string name="remove_file_deleted">Módulo não será removido na próxima reinicialização</string>
<string name="disable_file_created">Módulo será desativado na próxima reinicialização</string>
<string name="disable_file_removed">Módulo será ativado na próxima reinicialização</string>
<string name="author">Criado por %1$s</string>
<string name="reboot_recovery">Reiniciar na Recuperação</string>
<string name="reboot_bootloader">Reiniciar no Bootloader</string>
<string name="reboot_download">Reiniciar no Download</string>
<!--Repo Fragment-->
<string name="update_available">Atualização Disponível</string>
<string name="installed">Instalado</string>
<string name="not_installed">Não Instalado</string>
<string name="updated_on">Atualizado em: %1$s</string>
<string name="sorting_order">Ordenar</string>
<string name="sort_by_name">Ordenar por nome</string>
<string name="sort_by_update">Ordenar por última atualização</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salvar registro</string>
<string name="menuReload">Recarregar</string>
<string name="menuClearLog">Limpar registro agora</string>
<string name="logs_cleared">Registro limpo com sucesso</string>
<string name="log_is_empty">Registro está vazio</string>
<!--About Activity-->
<string name="about">Sobre</string>
<string name="app_changelog">Registro de mudanças</string>
<string name="translators" />
<string name="app_version">Versão</string>
<string name="app_source_code">Código fonte</string>
<string name="donation">Doação</string>
<string name="app_translators">Tradutores</string>
<string name="support_thread">Tópico de suporte</string>
<!--Toasts, Dialogs-->
<string name="close">Fechar</string>
<string name="repo_install_title">Instalar %1$s</string>
<string name="repo_install_msg">Instalar %1$s agora?</string>
<string name="download">Baixar</string>
<string name="reboot">Reiniciar</string>
<string name="magisk_update_title">Nova Atualização do Magisk Disponível!</string>
<string name="settings_reboot_toast">Reinicie para aplicar as definições</string>
<string name="release_notes">Notas de lançamento</string>
<string name="repo_cache_cleared">Cache de repositório limpado</string>
<string name="process_error">Erro de processo</string>
<string name="internal_storage">O zip está armazenado em:\n[Armazenamento Interno]%1$s</string>
<string name="zip_download_title">Baixando</string>
<string name="zip_download_msg">Baixando arquivo zip (%1$d%%) …</string>
<string name="zip_process_title">Processando</string>
<string name="zip_process_msg">Processando arquivo zip …</string>
<string name="manager_update_title">Nova Atualização do Magisk Manager Disponível!</string>
<string name="manager_download_install">Toque para baixar e instalar</string>
<string name="dtbo_patched_title">DTBO foi emendado!</string>
<string name="dtbo_patched_reboot">Magisk Manager emendou dtbo.img, reinicie</string>
<string name="magisk_updates">Atualizações do Magisk</string>
<string name="flashing">Gravando</string>
<string name="hide_manager_toast">Ocultando Magisk Manager…</string>
<string name="hide_manager_toast2">Isto pode demorar um pouco…</string>
<string name="hide_manager_fail_toast">Falha ao ocultar Magisk Manager…</string>
<string name="download_zip_only">Baixar Zip Apenas</string>
<string name="patch_boot_file">Emendar Arquivo de Imagem de Inicialização</string>
<string name="direct_install">Instalação Direta (Recomendado)</string>
<string name="install_second_slot">Instalar no Segundo Slot (Após OTA)</string>
<string name="select_method">Selecionar Método</string>
<string name="no_boot_file_patch_support">A versão alvo do Magisk não suporta emendamento de imagem de inicialização</string>
<string name="boot_file_patch_msg">Selecionar depósito de imagem de inicialização de fábrica no formato .img ou .img.tar</string>
<string name="complete_uninstall">Completar Desinstalação</string>
<string name="restore_img">Restaurar Imagens</string>
<string name="restore_done">Restauração concluída!</string>
<string name="restore_fail">Backup de fábrica não existe!</string>
<string name="proprietary_title">Baixar Código de Propriedade</string>
<string name="proprietary_notice">Magisk Manager é FOSS, que não contém o código de propriedade de SafetyNet API da Google.\n\nPermitir ao Magisk Manager baixar uma extensão (que contém a GoogleApiClient) para verificação de SafetyNet?</string>
<string name="su_db_corrupt">Banco de dados do SU está corrompido, será recriado novo db</string>
<!--Settings Activity -->
<string name="settings_general_category">Geral</string>
<string name="settings_dark_theme_title">Tema Escuro</string>
<string name="settings_dark_theme_summary">Ativar tema escuro</string>
<string name="settings_clear_cache_title">Limpar Cache de Repositório</string>
<string name="settings_clear_cache_summary">Limpar as informações no cache para repositórios onlines, força o app a reatualizar online</string>
<string name="settings_hide_manager_title">Ocultar Magisk Manager</string>
<string name="settings_hide_manager_summary">Reempacotar Magisk Manager com nome de pacote aleatório</string>
<string name="settings_restore_manager_title">Restaurar Magisk Manager</string>
<string name="settings_restore_manager_summary">Restaurar Magisk Manager com pacote original</string>
<string name="language">Idioma</string>
<string name="system_default">(Padrão do Sistema)</string>
<string name="settings_update">Definições de Atualizações</string>
<string name="settings_check_update_title">Verificar Atualizações</string>
<string name="settings_check_update_summary">Verificar atualizações em segundo plano periodicamente</string>
<string name="settings_update_channel_title">Canal de Atualização</string>
<string name="settings_update_stable">Estável</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Personalizado</string>
<string name="settings_update_custom_msg">Inserir uma URL personalizada</string>
<string name="settings_boot_format_title">Formato de Saída de Inicialização Emendada</string>
<string name="settings_boot_format_summary">Selecionar formato de saída de imagem de inicialização emendada.\nEscolha .img para gravar através do modo fastboot/download; escolha .img.tar para gravar com ODIN.</string>
<string name="settings_core_only_title">Modo Magisk de Núcleo Apenas</string>
<string name="settings_core_only_summary">Ativar apenas recursos de núcleo. MagiskSU, MagiskHide e hosts sem sistema ainda serão ativados, mas nenhum módulo será carregado.</string>
<string name="settings_magiskhide_summary">Ocultar Magisk de várias detecções</string>
<string name="settings_hosts_title">Hosts sem sistema</string>
<string name="settings_hosts_summary">Suporte de hosts sem sistema para apps de Adblock</string>
<string name="settings_su_app_adb">Apps e ADB</string>
<string name="settings_su_app">Apps apenas</string>
<string name="settings_su_adb">ADB apenas</string>
<string name="settings_su_disable">Desativado</string>
<string name="settings_su_request_10">10 segundos</string>
<string name="settings_su_request_20">20 segundos</string>
<string name="settings_su_request_30">30 segundos</string>
<string name="settings_su_request_60">60 segundos</string>
<string name="superuser_access">Acesso de Superusuário</string>
<string name="auto_response">Resposta Automática</string>
<string name="request_timeout">Tempo Limite de Solicitação</string>
<string name="superuser_notification">Notificação de Superusuário</string>
<string name="request_timeout_summary">%1$s segundos</string>
<string name="settings_su_reauth_title">Reautenticar após atualizar</string>
<string name="settings_su_reauth_summary">Reautenticar permissões de superusuário após um app atualizar</string>
<string name="settings_su_fingerprint_title">Ativar Autenticação de Impressão Digital</string>
<string name="settings_su_fingerprint_summary">Usar escaneador de impressão digital para permitir solicitações de superusuário</string>
<string name="multiuser_mode">Modo de Multiusuário</string>
<string name="settings_owner_only">Proprietário do Dispositivo Apenas</string>
<string name="settings_owner_manage">Proprietário do Dispositivo Gerenciado</string>
<string name="settings_user_independent">Usuário Independente</string>
<string name="owner_only_summary">Apenas proprietário tem acesso root</string>
<string name="owner_manage_summary">Apenas proprietário pode gerenciar acesso root e receber expedições de solicitações</string>
<string name="user_indepenent_summary">Cada usuário tem suas próprias regras root separadas</string>
<string name="multiuser_hint_owner_request">Uma solicitação foi enviada ao proprietário do dispositivo. Mude para proprietário e conceda as permissões requeridas</string>
<string name="mount_namespace_mode">Montar Modo de Espaço de Nome</string>
<string name="settings_ns_global">Espaço de Nome Global</string>
<string name="settings_ns_requester">Espaço de Nome Herdado</string>
<string name="settings_ns_isolate">Espaço de Nome Isolado</string>
<string name="global_summary">Todas as sessões root usam montagem de espaço de nome global</string>
<string name="requester_summary">As sessões root herdarão espaço de nome de seu solicitante</string>
<string name="isolate_summary">Cada sessão root terá seu próprio espaço de nome isolado</string>
<string name="android_o_not_support">Não suporta Android 8.0+</string>
<string name="disable_fingerprint">Nenhuma impressão digital foi definida ou dispostivo sem suporte</string>
<!--Superuser-->
<string name="su_request_title">Solicitação de Superusuário</string>
<string name="deny_with_str">Negar%1$s</string>
<string name="deny">Negar</string>
<string name="prompt">Solicitar</string>
<string name="grant">Conceder</string>
<string name="su_warning">Concede acesso total ao seu dispositivo.\nNegue se você não tem certeza!</string>
<string name="forever">Sempre</string>
<string name="once">Uma Vez</string>
<string name="tenmin">10 mins</string>
<string name="twentymin">20 mins</string>
<string name="thirtymin">30 mins</string>
<string name="sixtymin">60 mins</string>
<string name="su_allow_toast">%1$s teve concedido direitos de Superusuário</string>
<string name="su_deny_toast">%1$s teve negado direitos de Superusuário</string>
<string name="no_apps_found">Nenhum app encontrado</string>
<string name="su_snack_grant">Direitos de Superusuário de %1$s estão concedidos</string>
<string name="su_snack_deny">Direitos de Superusuário de %1$s estão negados</string>
<string name="su_snack_notif_on">Notificações de %1$s estão ativadas</string>
<string name="su_snack_notif_off">Notificações de %1$s estão desativadas</string>
<string name="su_snack_log_on">Registração de %1$s está ativada</string>
<string name="su_snack_log_off">Registração de %1$s está desativada</string>
<string name="su_snack_revoke">Direitos de %1$s estão revogados</string>
<string name="su_revoke_title">Revogar?</string>
<string name="su_revoke_msg">Revogar os direitos de %1$s?</string>
<string name="toast">Torrada</string>
<string name="none">Nenhuma</string>
<string name="auth_fail">Falha de Autenticação</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Alvo UID:\u0020</string>
<string name="command">Comando:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Módulos</string>
<string name="downloads">Transferir</string>
<string name="superuser">root</string>
<string name="log">Registo</string>
<string name="settings">Definições</string>
<string name="install">Instalar</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk não instalado</string>
<string name="checking_for_updates">A procurar por atualizações…</string>
<string name="magisk_update_available">Magisk v%1$s disponível!</string>
<string name="safetyNet_check_text">Pressione para verificar SafetyNet</string>
<string name="checking_safetyNet_status">A verificar o estado do SafetyNet…</string>
<string name="safetyNet_check_success">SafetyNet verificado com sucesso</string>
<string name="safetyNet_api_error">Erro na API SafetyNet</string>
<string name="safetyNet_network_loss">Perda de ligação</string>
<string name="safetyNet_service_disconnected">Serviço foi interrompido</string>
<string name="safetyNet_res_invalid">A resposta é inválida</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Definições avançadas</string>
<string name="keep_force_encryption">Manter encriptação forçada</string>
<string name="keep_dm_verity">Manter AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versão instalada: %1$s</string>
<string name="install_magisk_title">Última versão: %1$s</string>
<string name="uninstall">Desinstalar</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="update">Atualizar %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nenhuma informação fornecida)</string>
<string name="no_modules_found">Nenhum módulo encontrado</string>
<string name="update_file_created">Módulo será atualizado depois de reiniciar</string>
<string name="remove_file_created">Módulo será removido depois de reiniciar</string>
<string name="remove_file_deleted">Módulo não será removido ao reiniciar</string>
<string name="disable_file_created">Módulo será desativado depois de reiniciar</string>
<string name="disable_file_removed">Módulo será ativado depois de reiniciar</string>
<string name="author">Criado por %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Atualização disponível</string>
<string name="installed">Instalado</string>
<string name="not_installed">Não Instalado</string>
<!--Log Fragment-->
<string name="menuSaveLog">Gravar registo</string>
<string name="menuReload">Recarregar</string>
<string name="menuClearLog">Limpar registo agora</string>
<string name="logs_cleared">Registo limpo com sucesso</string>
<string name="log_is_empty">Registo está vazio</string>
<!--About Activity-->
<string name="about">Sobre</string>
<string name="app_changelog">Lista de alterações da aplicação</string>
<string name="app_version">Versão do aplicação</string>
<string name="app_source_code">Código fonte</string>
<string name="donation">Doar</string>
<string name="app_translators">Tradutores da Aplicação</string>
<string name="support_thread">Suporte</string>
<!--Toasts, Dialogs-->
<string name="close">Fechar</string>
<string name="repo_install_title">Instalar %1$s</string>
<string name="repo_install_msg">Deseja instalar%1$s agora?</string>
<string name="download">Transferir</string>
<string name="reboot">Reiniciar</string>
<string name="magisk_update_title">Nova atualização do Magisk disponível!</string>
<string name="settings_reboot_toast">Reinicie para aplicar definições</string>
<string name="release_notes">Notas da atualização</string>
<string name="repo_cache_cleared">Cache do repositório apagado</string>
<string name="process_error">Erro no processo</string>
<string name="internal_storage">O zip foi guardado em:
\n[Armazenamento interno]%1$s</string>
<string name="zip_download_msg">A transferir ficheiro zip (%1$d%%) …</string>
<string name="zip_process_title">A processar</string>
<string name="zip_process_msg">A processar ficheiro zip …</string>
<string name="manager_update_title">Nova atualização do Magisk Manager disponível!</string>
<string name="manager_download_install">Pressione para transferir e instalar</string>
<string name="magisk_updates">Atualizações do Magisk</string>
<string name="flashing">A instalar</string>
<string name="hide_manager_toast">A esconder Magisk Manager…</string>
<string name="hide_manager_toast2">Isto pode demorar algum tempo...</string>
<string name="hide_manager_fail_toast">Falha ao esconder Magisk Manager…</string>
<string name="download_zip_only">Transferir Apenas Ficheiro Zip</string>
<string name="patch_boot_file">Patch a Imagem de Arranque</string>
<string name="direct_install">Instalar Diretamente (Recomendado)</string>
<string name="select_method">Selecionar Método</string>
<string name="complete_uninstall">Desinstalação Completa</string>
<string name="restore_done">Restauração feita!</string>
<!--Settings Activity -->
<string name="settings_general_category">Geral</string>
<string name="settings_dark_theme_title">Tema escuro</string>
<string name="settings_dark_theme_summary">Ativa o tema escuro</string>
<string name="settings_clear_cache_title">Apagar Cache de Repositório</string>
<string name="settings_clear_cache_summary">Apaga a informação cache de repositórios online. online, forçando a aplicação a atualizar online</string>
<string name="settings_hide_manager_title">Esconder Magisk Manager</string>
<string name="language">Língua</string>
<string name="system_default">(Padrão do Sistema)</string>
<string name="settings_update_stable">Estável</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_core_only_title">Magisk somente em Modo Core</string>
<string name="settings_core_only_summary">Ativar somente funcionalidades principais, todos os módulos não serão carregados. MagiskSU, MagiskHide, e systemless hosts ainda estará ativado</string>
<string name="settings_magiskhide_summary">Oculta Magisk de várias deteções</string>
<string name="settings_hosts_title">Ativar systemless hosts</string>
<string name="settings_hosts_summary">Suporte de systemless para aplicações Adblock</string>
<string name="settings_su_app_adb">Aplicações e ADB</string>
<string name="settings_su_app">Somente Aplicações</string>
<string name="settings_su_adb">Somente ADB</string>
<string name="settings_su_disable">Desativado</string>
<string name="settings_su_request_10">10 segundos</string>
<string name="settings_su_request_20">20 segundos</string>
<string name="settings_su_request_30">30 segundos</string>
<string name="settings_su_request_60">60 segundos</string>
<string name="superuser_access">Acesso de root</string>
<string name="auto_response">Resposta Automática</string>
<string name="request_timeout">Tempo limite de solicitação</string>
<string name="superuser_notification">Notificação de root</string>
<string name="request_timeout_summary">%1$s segundos</string>
<string name="settings_su_reauth_title">Autenticar novamente após atualizar</string>
<string name="settings_su_reauth_summary">Autenticar novamente permissões de root após atualizar aplicações</string>
<string name="multiuser_mode">Modo Multi-Utilizador</string>
<string name="settings_owner_only">Apenas Proprietário de Dispositivo</string>
<string name="settings_owner_manage">Gerido Proprietário do Dispositivo</string>
<string name="settings_user_independent">Independente de Utilizadores</string>
<string name="owner_only_summary">Apenas o proprietário tem acesso a root</string>
<string name="owner_manage_summary">Apenas o proprietário pode gerir acesso root e receber pedidos</string>
<string name="user_indepenent_summary">Cada utilizador tem suas próprias regras de root separadas</string>
<string name="multiuser_hint_owner_request">Um pedido foi enviado ao proprietário do dispositivo. Mude para o proprietário e conceda a permissão</string>
<string name="mount_namespace_mode">Cada sessão root terá sua própria identificação isolada</string>
<string name="settings_ns_global">Identificação Global</string>
<string name="settings_ns_requester">Herdar Identificação</string>
<string name="settings_ns_isolate">Identificação Isolada</string>
<string name="global_summary">Todas as sessões root usam a identificação de montagem global</string>
<string name="requester_summary">As sessões de root herdarão a identificação do seu solicitante</string>
<string name="isolate_summary">Cada sessão root terá sua própria identificação isolada</string>
<!--Superuser-->
<string name="su_request_title">Pedido de root</string>
<string name="deny_with_str">Negar%1$s</string>
<string name="deny">Negar</string>
<string name="prompt">Perguntar</string>
<string name="grant">Permitir</string>
<string name="su_warning">Concede acesso total ao seu dispositivo.
\nNegue se não tiver certeza!</string>
<string name="forever">Sempre</string>
<string name="once">Uma vez</string>
<string name="tenmin">10 minutos</string>
<string name="twentymin">20 minutos</string>
<string name="thirtymin">30 minutos</string>
<string name="sixtymin">60 minutos</string>
<string name="su_allow_toast">%1$s foi permitido o acesso de root</string>
<string name="su_deny_toast">%1$s foi negado o acesso de root</string>
<string name="no_apps_found">Não foram encontrados aplicações</string>
<string name="su_snack_grant">Acesso de root a %1$s foi permitido</string>
<string name="su_snack_deny">Acesso de root a %1$s foi negado</string>
<string name="su_snack_notif_on">Notificações de %1$s está ativado</string>
<string name="su_snack_notif_off">Notificações da %1$s está desativado</string>
<string name="su_snack_log_on">Registo de %1$s está ativado</string>
<string name="su_snack_log_off">Registo de %1$s está desativado</string>
<string name="su_snack_revoke">%1$s direitos foram revogados</string>
<string name="su_revoke_title">Revogar?</string>
<string name="su_revoke_msg">Revogar os diretos do %1$s, Confirmar?</string>
<string name="toast">Notificação(pop-up)</string>
<string name="none">Nenhum</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Alvo UID:\u0020</string>
<string name="command">Comando:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Module</string>
<string name="downloads">Descărcări</string>
<string name="superuser">Superuser</string>
<string name="log">Jurnal</string>
<string name="settings">Setări</string>
<string name="install">Instalare</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk nu este instalat</string>
<string name="checking_for_updates">Verificare actualizări…</string>
<string name="magisk_update_available">Magisk v%1$s disponibil!</string>
<string name="invalid_update_channel">Canal de actualizare nevalid</string>
<string name="safetyNet_check_text">Verificare SafetyNet</string>
<string name="checking_safetyNet_status">Verificarea stării SafetyNet…</string>
<string name="safetyNet_check_success">Verificare SafetyNet cu succes</string>
<string name="safetyNet_api_error">Eroare API SafetyNet</string>
<string name="safetyNet_network_loss">Conexiunea la rețea nu este disponibilă</string>
<string name="safetyNet_service_disconnected">Serviciul a fost oprit</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Setări avansate</string>
<string name="keep_force_encryption">Păstrare criptare forţată</string>
<string name="keep_dm_verity">Păstrare AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Versiune instalată: %1$s</string>
<string name="install_magisk_title">Ultima versiune: %1$s</string>
<string name="uninstall">Dezinstalare</string>
<string name="uninstall_magisk_title">Dezinstalare Magisk</string>
<string name="uninstall_magisk_msg">Toate modulele vor fi dezactivate/eliminate. Accesul la Root va fi eliminat și potențial se vor cripta datele dacă nu sunt în prezent criptate</string>
<string name="update">Actualizare %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nu sunt furnizate informații)</string>
<string name="no_modules_found">Niciun modul</string>
<string name="update_file_created">Modulul va fi actualizat la următoarea repornire</string>
<string name="remove_file_created">Modulul va fi eliminat la următoarea repornire</string>
<string name="remove_file_deleted">Modulul nu va fi eliminat la următoarea repornire</string>
<string name="disable_file_created">Modulul va fi dezactivat la următoarea repornire</string>
<string name="disable_file_removed">Modulul va fi activat la următoarea repornire</string>
<string name="author">Creat de %1$s</string>
<string name="reboot_recovery">Repornire în Recovery</string>
<string name="reboot_bootloader">Repornire în Bootloader</string>
<string name="reboot_download">Repornire în Download</string>
<!--Repo Fragment-->
<string name="update_available">Actualizare disponibilă</string>
<string name="installed">Instalat</string>
<string name="not_installed">Nu este instalat</string>
<!--Log Fragment-->
<string name="menuSaveLog">Salvare jurnal</string>
<string name="menuReload">Reîncărcare</string>
<string name="menuClearLog">Șterge jurnal acum</string>
<string name="logs_cleared">Jurnal şters</string>
<string name="log_is_empty">Jurnal gol</string>
<!--About Activity-->
<string name="about">Despre</string>
<string name="app_changelog">Lista modificărilor</string>
<string name="translators" />
<string name="app_version">Versiune</string>
<string name="app_source_code">Cod sursă</string>
<string name="donation">Donaţie</string>
<string name="app_translators">Traducători</string>
<string name="support_thread">Pagina de suport</string>
<!--Toasts, Dialogs-->
<string name="close">Închide</string>
<string name="repo_install_title">Instalare %1$s</string>
<string name="repo_install_msg">Instalaţi %1$s?</string>
<string name="download">Descărcare</string>
<string name="reboot">Repornire</string>
<string name="magisk_update_title">O nouă actualizare Magisk este disponibilă!</string>
<string name="settings_reboot_toast">Reporniți pentru a aplica setările</string>
<string name="release_notes">Note de lansare</string>
<string name="repo_cache_cleared">Arhive cache eliminate</string>
<string name="process_error">Eroare de proces</string>
<string name="internal_storage">Zip stocat în:\n[Stocare internă]%1$s</string>
<string name="zip_download_title">Descărcare</string>
<string name="zip_download_msg">Descărcare fişier zip (%1$d%%)…</string>
<string name="zip_process_title">Procesare</string>
<string name="zip_process_msg">Procesare fişier zip…</string>
<string name="manager_update_title">O nouă actualizare pentru Magisk Manager este disponibilă!</string>
<string name="manager_download_install">Apăsați pentru a descărca și instala</string>
<string name="dtbo_patched_title">DTBO a fost modificat!</string>
<string name="dtbo_patched_reboot">Magisk Manager a modificat dtbo.img, reporniţi</string>
<string name="magisk_updates">Actualizări Magisk</string>
<string name="flashing">Flashing</string>
<string name="hide_manager_toast">Ascundere Magisk Manager…</string>
<string name="hide_manager_toast2">Ar putea dura ceva timp…</string>
<string name="hide_manager_fail_toast">Ascunderea Magisk Manager a eşuat</string>
<string name="download_zip_only">Doar descărcare fişier Zip</string>
<string name="patch_boot_file">Modificare fişier imagine Boot</string>
<string name="direct_install">Instalare directă (Recomandat)</string>
<string name="install_second_slot">Instalare în slotul secund (După OTA)</string>
<string name="select_method">Selectaţi metoda</string>
<string name="no_boot_file_patch_support">Versiunea Magisk nu acceptă modificarea imaginii de Boot</string>
<string name="boot_file_patch_msg">Selectaţi formatul .img sau .img.tar pentru imaginea de Boot stoc</string>
<string name="complete_uninstall">Dezinstalare totală</string>
<string name="restore_done">Restabilire finalizată!</string>
<string name="restore_fail">Backup stoc nu există!</string>
<string name="proprietary_title">Descărcare cod proprietar</string>
<string name="proprietary_notice">Magisk Manager este FOSS așa că nu conține codul API SafetyNet de la Google.\n\nPermiteți ca Magisk Manager să descarce o extensie (conține GoogleApiClient) pentru verificările SafetyNet?</string>
<string name="su_db_corrupt">Baza de date SU este defectă, va fi creată o bază nouă</string>
<!--Settings Activity -->
<string name="settings_general_category">General</string>
<string name="settings_dark_theme_title">Temă întunecată</string>
<string name="settings_dark_theme_summary">Activare temă întunecată</string>
<string name="settings_clear_cache_title">Eliminare cache</string>
<string name="settings_clear_cache_summary">Ștergeți informațiile memorate în cache, forțează actualizarea aplicației online</string>
<string name="settings_hide_manager_title">Ascundeţi Magisk Manager</string>
<string name="settings_hide_manager_summary">Reîmpachetare Magisk Manager cu nume de pachet aleatoriu</string>
<string name="settings_restore_manager_title">Restabilire Magisk Manager</string>
<string name="settings_restore_manager_summary">Restabilire Magisk Manager cu pachetul original</string>
<string name="language">Limbă</string>
<string name="system_default">(Implicit)</string>
<string name="settings_update">Setări actualizare</string>
<string name="settings_check_update_title">Verificare actualizări</string>
<string name="settings_check_update_summary">Se verifică periodic în fundal dacă există actualizări</string>
<string name="settings_update_channel_title">Canal de actualizare</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Personalizat</string>
<string name="settings_update_custom_msg">Introduceți un URL personalizat</string>
<string name="settings_boot_format_title">Formatul Boot-ului modificat</string>
<string name="settings_boot_format_summary">Selectați formatul fișierului imaginii de Boot modificată.\nAlegeţi .img pentru flash prin modul fastboot/download; alegeţi .img.tar pentru flash prin ODIN.</string>
<string name="settings_core_only_title">Mod de bază</string>
<string name="settings_core_only_summary">Se activează numai caracteristicile principale, toate modulele nu vor fi încărcate. MagiskSU, MagiskHide şi systemless hosts vor fi în continuare activate</string>
<string name="settings_magiskhide_summary">Ascundeţi Magisk de la diferite detectări</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Systemless hosts suport pentru aplicațiile Adblock</string>
<string name="settings_su_app_adb">Aplicaţii şi ADB</string>
<string name="settings_su_app">Doar aplicaţii</string>
<string name="settings_su_adb">Doar ADB</string>
<string name="settings_su_disable">Dezactivat</string>
<string name="settings_su_request_10">10 secunde</string>
<string name="settings_su_request_20">20 de secunde</string>
<string name="settings_su_request_30">30 de secunde</string>
<string name="settings_su_request_60">60 de secunde</string>
<string name="superuser_access">Acces Superuser</string>
<string name="auto_response">Răspuns automat</string>
<string name="request_timeout">Expirare</string>
<string name="superuser_notification">Notificare Superuser</string>
<string name="request_timeout_summary">%1$s secunde</string>
<string name="settings_su_reauth_title">Reautentificare după actualizare</string>
<string name="settings_su_reauth_summary">Reautentificare permisiuni pentru superuser după o actualizare a aplicației</string>
<string name="settings_su_fingerprint_title">Activați autentificarea cu amprenta digitală</string>
<string name="settings_su_fingerprint_summary">Utilizați scanerul de amprentă pentru a permite solicitările superuser</string>
<string name="multiuser_mode">Mod Multiutilizator</string>
<string name="settings_owner_only">Numai proprietarul dispozitivului</string>
<string name="settings_owner_manage">Gestionat de proprietarul dispozitivului</string>
<string name="settings_user_independent">Utilizator independent</string>
<string name="owner_only_summary">Numai proprietarul are acces la root</string>
<string name="owner_manage_summary">Numai proprietarul poate gestiona accesul la root și să primească solicitări</string>
<string name="user_indepenent_summary">Fiecare utilizator are propriile reguli de acces la root</string>
<string name="multiuser_hint_owner_request">A fost trimisă o solicitare proprietarului dispozitivului. Comutaţi la proprietar și acordați permisiunea</string>
<string name="mount_namespace_mode">Mod montare spaţiu de nume</string>
<string name="settings_ns_global">Spaţiu de nume global</string>
<string name="settings_ns_requester">Spaţiu de nume moştenit</string>
<string name="settings_ns_isolate">Spațiu de nume izolat</string>
<string name="global_summary">Toate sesiunile de root utilizează spațiul de nume global</string>
<string name="requester_summary">Sesiunile de root vor moșteni spațiul de nume al solicitantului</string>
<string name="isolate_summary">Fiecare sesiune de root va avea propriul spațiu de nume izolat</string>
<string name="android_o_not_support">Nu se acceptă pe Android 8.0+</string>
<string name="disable_fingerprint">Nu au fost setate amprente sau scanerul de apmrentă lipseşte</string>
<!--Superuser-->
<string name="su_request_title">Solicitare Superuser</string>
<string name="deny_with_str">Refuzaţi %1$s</string>
<string name="deny">Refuzaţi</string>
<string name="prompt">Solicitare</string>
<string name="grant">Permiteţi</string>
<string name="su_warning">Acordă acces complet la dispozitivul dvs..\nRefuzaţi dacă nu sunteţi sigur!</string>
<string name="forever">Pentru totdeauna</string>
<string name="once">O singura dată</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 i-au fost acordate drepturi Superuser</string>
<string name="su_deny_toast">%1$s i-au fost refuzate drepturi Superuser</string>
<string name="no_apps_found">Nicio aplicaţie</string>
<string name="su_snack_grant">Drepturile Superuser pentru %1$s au fost acordate</string>
<string name="su_snack_deny">Drepturile Superuser pentru %1$s au fost refuzate</string>
<string name="su_snack_notif_on">Notificările pentru %1$s au fost acordate</string>
<string name="su_snack_notif_off">Notificările pentru %1$s au fost refuzate</string>
<string name="su_snack_log_on">Logarea pentru %1$s a fost activată</string>
<string name="su_snack_log_off">Logarea pentru %1$s a fost dezactivată</string>
<string name="su_snack_revoke">Drepturile pentru %1$s sunt revocate</string>
<string name="su_revoke_title">Revocaţi?</string>
<string name="su_revoke_msg">Confirmați revocarea drepturilor pentru %1$s?</string>
<string name="toast">Mesaj</string>
<string name="none">Nimic</string>
<string name="auth_fail">Autentificare eşuată</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID:\u0020</string>
<string name="command">Comandă:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Модули</string>
<string name="downloads">Репозиторий</string>
<string name="superuser">Суперпользователь</string>
<string name="log">Логи</string>
<string name="settings">Настройки</string>
<string name="install">Установка</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk не установлен</string>
<string name="checking_for_updates">Проверка обновлений…</string>
<string name="magisk_update_available">Доступен Magisk v%1$s!</string>
<string name="invalid_update_channel">Некорректный канал обновлений</string>
<string name="safetyNet_check_text">Проверить статус SafetyNet</string>
<string name="checking_safetyNet_status">Проверка статуса SafetyNet…</string>
<string name="safetyNet_check_success">Результат проверки SafetyNet</string>
<string name="safetyNet_api_error">Ошибка SafetyNet API</string>
<string name="safetyNet_network_loss">Нет подключения к сети</string>
<string name="safetyNet_service_disconnected">Служба была остановлена</string>
<string name="safetyNet_res_invalid">Некорректный ответ</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Расширенные опции</string>
<string name="keep_force_encryption">Сохранить шифрование</string>
<string name="keep_dm_verity">Сохранить AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Установлена версия: %1$s</string>
<string name="install_magisk_title">Последняя версия: %1$s</string>
<string name="uninstall">Удаление</string>
<string name="uninstall_magisk_title">Удаление Magisk</string>
<string name="uninstall_magisk_msg">Все модули будут отключены/удалены. Root-права будут удалены. Шифрование будет активировано.</string>
<string name="update">Обновить %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Нет информации)</string>
<string name="no_modules_found">Модули не найдены</string>
<string name="update_file_created">Модуль будет обновлен после перезагрузки</string>
<string name="remove_file_created">Модуль будет удален после перезагрузки</string>
<string name="remove_file_deleted">Модуль не будет удален после перезагрузки</string>
<string name="disable_file_created">Модуль будет отключен после перезагрузки</string>
<string name="disable_file_removed">Модуль будет активирован после перезагрузки</string>
<string name="author">Автор: %1$s</string>
<string name="reboot_recovery">Перезагрузка в Recovery</string>
<string name="reboot_bootloader">Перезагрузка в Bootloader</string>
<string name="reboot_download">Перезагрузка в Download</string>
<!--Repo Fragment-->
<string name="update_available">Доступно обновление</string>
<string name="installed">Установлены</string>
<string name="not_installed">Не установлены</string>
<string name="updated_on">Обновлено: %1$s</string>
<string name="sorting_order">Сортировка</string>
<string name="sort_by_name">По имени</string>
<string name="sort_by_update">По дате обновления</string>
<!--Log Fragment-->
<string name="menuSaveLog">Сохранить лог</string>
<string name="menuReload">Обновить</string>
<string name="menuClearLog">Очистить лог</string>
<string name="logs_cleared">Лог успешно очищен</string>
<string name="log_is_empty">Лог пуст</string>
<!--About Activity-->
<string name="about">О приложении</string>
<string name="app_changelog">Список изменений</string>
<string name="translators">Displax [4PDA]</string>
<string name="app_version">Версия</string>
<string name="app_source_code">Исходный код</string>
<string name="donation">Поддержать проект</string>
<string name="app_translators">Переводчики</string>
<string name="support_thread">Домашняя страница</string>
<!--Toasts, Dialogs-->
<string name="close">Закрыть</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="magisk_update_title">Доступно обновление Magisk!</string>
<string name="settings_reboot_toast">Для применения настроек перезагрузите устройство</string>
<string name="release_notes">О версии</string>
<string name="repo_cache_cleared">Кэш репозитория очищен</string>
<string name="process_error">Ошибка обработки</string>
<string name="internal_storage">Расположение архива:\n[Внутреннее Хранилище]%1$s</string>
<string name="zip_download_title">Загрузка</string>
<string name="zip_download_msg">Загрузка архива (%1$d%%) …</string>
<string name="zip_process_title">Обработка</string>
<string name="zip_process_msg">Обработка архива…</string>
<string name="manager_update_title">Доступно обновление Magisk Manager!</string>
<string name="manager_download_install">Нажмите для установки</string>
<string name="dtbo_patched_title">DTBO пропатчен!</string>
<string name="dtbo_patched_reboot">Magisk Manager пропатчил dtbo.img. Перезагрузите устройство.</string>
<string name="magisk_updates">Обновления Magisk</string>
<string name="flashing">Прошивка…</string>
<string name="hide_manager_toast">Скрытие Magisk Manager…</string>
<string name="hide_manager_toast2">Может занять некоторое время…</string>
<string name="hide_manager_fail_toast">Скрытие Magisk Manager неудачно!</string>
<string name="download_zip_only">Загрузка установочного ZIP</string>
<string name="patch_boot_file">Пропатчить образ ядра (boot.img)</string>
<string name="direct_install">Прямая установка (Рекомендуется)</string>
<string name="install_second_slot">Установка во Второй Слот (После OTA)</string>
<string name="select_method">Выбор способа</string>
<string name="no_boot_file_patch_support">Целевая версия Magisk не поддерживает патчинг boot-образов</string>
<string name="boot_file_patch_msg">Выберите файл ядра (boot) - *.img или *.img.tar</string>
<string name="complete_uninstall">Полное удаление</string>
<string name="restore_img">Восстановить разделы</string>
<string name="restore_img_msg">Восстановление…</string>
<string name="restore_done">Восстановление завершено!</string>
<string name="restore_fail">Резервная копия отсутствует!</string>
<string name="proprietary_title">Загрузка SafetyNet</string>
<string name="proprietary_notice">Magisk Manager — свободно распространяемый продукт, он не содержит собственный код SafetyNet API от Google.\n\nРазрешить Magisk Manager загрузить расширение для проверки SafetyNet? (содержит GoogleApiClient)</string>
<string name="su_db_corrupt">База данных SU повреждена, будет создана новая</string>
<string name="cannot_check_sn_title">Невозможно проверить SafetyNet</string>
<string name="cannot_check_sn_notice">В связи с изменениями в сервисах Google Play, невозможно выполнить проверку статуса SafetyNet с пересобранным Magisk Manager</string>
<string name="setup_done">Установка завершена</string>
<string name="setup_fail">Ошибка установки</string>
<string name="env_fix_title">Требуется дополнительная установка</string>
<string name="env_fix_msg">Вашему устройству требуется дополнительная установка Magisk для корректной работы. Будет загружен установочный ZIP Magisk, продолжить?</string>
<string name="setup_title">Дополнительная установка</string>
<string name="setup_msg">Настройка рабочей среды…</string>
<!--Settings Activity -->
<string name="settings_general_category">Основные</string>
<string name="settings_dark_theme_title">Тёмная тема</string>
<string name="settings_dark_theme_summary">Включить темное оформление</string>
<string name="settings_clear_cache_title">Очистка кэша репозитория</string>
<string name="settings_clear_cache_summary">Очистить сохранённую информацию о репозитории. Будет обновлено принудительно</string>
<string name="settings_hide_manager_title">Скрытие Magisk Manager</string>
<string name="settings_hide_manager_summary">Пересобрать Magisk Manager со случайным именем пакета</string>
<string name="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_update">Настройки обновлений</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">Beta канал</string>
<string name="settings_update_custom">Сторонний канал</string>
<string name="settings_update_custom_msg">Укажите ссылку</string>
<string name="settings_boot_format_title">Тип образа ядра</string>
<string name="settings_boot_format_summary">Выберите тип патченого образа ядра:\n*.img - для прошивки через fastboot/download режимы\n*.img.tar - для прошивки через ODIN (Samsung)</string>
<string name="settings_core_only_title">Magisk Core режим</string>
<string name="settings_core_only_summary">Включить только основные (Core) возможности. Модули не будут загружены. MagiskSU, MagiskHide и внесистемные хосты останутся активными</string>
<string name="settings_magiskhide_summary">Скрывать Magisk от различных проверок</string>
<string name="settings_hosts_title">Внесистемные хосты</string>
<string name="settings_hosts_summary">Поддержка внесистемных хостов для приложений, блокирующих рекламу</string>
<string name="settings_su_app_adb">Приложения и ADB</string>
<string name="settings_su_app">Только приложения</string>
<string name="settings_su_adb">Только ADB</string>
<string name="settings_su_disable">Отключен</string>
<string name="settings_su_request_10">10 секунд</string>
<string name="settings_su_request_20">20 секунд</string>
<string name="settings_su_request_30">30 секунд</string>
<string name="settings_su_request_60">60 секунд</string>
<string name="superuser_access">Уровень доступа</string>
<string name="auto_response">Автоматический ответ</string>
<string name="request_timeout">Ожидание ответа</string>
<string name="superuser_notification">Уведомления Суперпользователя</string>
<string name="request_timeout_summary">%1$s секунд</string>
<string name="settings_su_reauth_title">Повторная аутентификация</string>
<string name="settings_su_reauth_summary">Повторный запрос прав Суперпользователя после обновления приложений</string>
<string name="settings_su_fingerprint_title">Биометрическая аутентификация</string>
<string name="settings_su_fingerprint_summary">Использовать дактилоскопический сканер для подтверждения запросов Суперпользователя</string>
<string name="multiuser_mode">Многопользовательский режим</string>
<string name="settings_owner_only">Только владелец</string>
<string name="settings_owner_manage">Регулировка владельцем</string>
<string name="settings_user_independent">Правила пользователей</string>
<string name="owner_only_summary">Только владелец имеет Root-доступ</string>
<string name="owner_manage_summary">Только владелец управляет Root-доступом и обрабатывает запросы</string>
<string name="user_indepenent_summary">Каждый пользователь имеет свои собственные правила Root-доступа</string>
<string name="multiuser_hint_owner_request">Запрос отправлен владельцу устройства. Переключитесь в профиль владельца для обработки запроса</string>
<string name="mount_namespace_mode">Настройка именных пространств</string>
<string name="settings_ns_global">Общее именное пространство</string>
<string name="settings_ns_requester">Наследуемое именное пространство</string>
<string name="settings_ns_isolate">Изолированное именное пространство</string>
<string name="global_summary">Сессии Суперпользователя используют общее именное пространство</string>
<string name="requester_summary">Сессии Суперпользователя наследуют именное пространство запрашивающего</string>
<string name="isolate_summary">Сессии Суперпользователя используют изолированные именные пространства</string>
<string name="android_o_not_support">Не поддерживается в Android 8.0+</string>
<string name="disable_fingerprint">Не поддерживается устройством или не заданы отпечатки</string>
<!--Superuser-->
<string name="su_request_title">Запрос прав Суперпользователя</string>
<string name="deny_with_str">Отказать %1$s</string>
<string name="deny">Отказать</string>
<string name="prompt">Запрос</string>
<string name="grant">Предоставить</string>
<string name="su_warning">Предоставить полный доступ к устройству.\nЕсли не уверены, что желаете продолжить, отклоните данное действие!</string>
<string name="forever">Навсегда</string>
<string name="once">Сейчас</string>
<string name="tenmin">10 мин.</string>
<string name="twentymin">20 мин.</string>
<string name="thirtymin">30 мин.</string>
<string name="sixtymin">60 мин.</string>
<string name="su_allow_toast">%1$s предоставлены права Суперпользователя</string>
<string name="su_deny_toast">%1$s отказано в правах Суперпользователя</string>
<string name="no_apps_found">Приложения не обнаружены</string>
<string name="su_snack_grant">%1$s предоставлены права Суперпользователя</string>
<string name="su_snack_deny">%1$s отказано в правах Суперпользователя</string>
<string name="su_snack_notif_on">Уведомления для %1$s включены</string>
<string name="su_snack_notif_off">Уведомления для %1$s отключены</string>
<string name="su_snack_log_on">Логирование для %1$s включено</string>
<string name="su_snack_log_off">Логирование для %1$s отключено</string>
<string name="su_snack_revoke">Настройки для %1$s сброшены</string>
<string name="su_revoke_title">Сброс настроек</string>
<string name="su_revoke_msg">Сбросить настройки для %1$s?</string>
<string name="toast">Всплывающие уведомления</string>
<string name="none">Нет</string>
<string name="auth_fail">Ошибка аутентификации</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">UID:\u0020</string>
<string name="command">Команда:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Модули</string>
<string name="downloads">Преузимања</string>
<string name="superuser">Супер-корисник</string>
<string name="log">Дневник</string>
<string name="settings">Подешавања</string>
<string name="install">Инсталација</string>
<!--Status Fragment-->
<string name="magisk_version_error">Магиск није инсталиран</string>
<string name="checking_for_updates">Проверавам Ажурирања…</string>
<string name="magisk_update_available">Магиск v%1$s је доступан!</string>
<string name="invalid_update_channel">Непостојећи Канал Ажурирања</string>
<string name="safetyNet_check_text">Притисни да започнеш СигурнаМрежа проверу</string>
<string name="checking_safetyNet_status">Проверавам СигурнаМрежа статус…</string>
<string name="safetyNet_check_success">СигурнаМрежа Провера Успешна</string>
<string name="safetyNet_api_error">СигурнаМрежа АПИ Грешка</string>
<string name="safetyNet_network_loss">Интернет конекција недоступна</string>
<string name="safetyNet_service_disconnected">Сервис је елеминисан</string>
<string name="safetyNet_res_invalid">Одговор није валидан</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Напредна Подешавања</string>
<string name="keep_force_encryption">Задржи форсирану енкрипцију</string>
<string name="keep_dm_verity">Задржи AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Инсталирана верзија: %1$s</string>
<string name="install_magisk_title">Најновија верзија: %1$s</string>
<string name="uninstall">Унинсталирај</string>
<string name="uninstall_magisk_title">Унинсталирај Магиск</string>
<string name="uninstall_magisk_msg">Сви модули ће бити онеспособљени/уклоњени. Корен ће бити уклоњен, и потенцијално енкриптовати твоје податке уколико већ нису енкриптовани</string>
<string name="update">Ажурирање %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Без информација)</string>
<string name="no_modules_found">Нема пронађених модула</string>
<string name="update_file_created">Модул ће бити ажуриран после рестарта</string>
<string name="remove_file_created">Модул ће бити уклоњен после рестарта</string>
<string name="remove_file_deleted">Модул неће бити уклоњен после рестарта</string>
<string name="disable_file_created">Модул ће бити онеспособљен после рестарта</string>
<string name="disable_file_removed">Модул ће бити оспособљен после рестарта</string>
<string name="author">Креирао %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Ажурирање доступно</string>
<string name="installed">Инсталирано</string>
<string name="not_installed">Није инсталирано</string>
<!--Log Fragment-->
<string name="menuSaveLog">Сачувај дневник</string>
<string name="menuReload">Поново учитај</string>
<string name="menuClearLog">Обриши дневник</string>
<string name="logs_cleared">Дневник успешно креиран</string>
<string name="log_is_empty">Дневник је празан</string>
<!--About Activity-->
<string name="about">О апликацији</string>
<string name="app_changelog">Дневник промена апликације</string>
<string name="translators" />
<string name="app_version">Верзија апликације</string>
<string name="app_source_code">изворни код</string>
<string name="donation">Донације</string>
<string name="app_translators">Преводиоци апликације</string>
<string name="support_thread">Подршка</string>
<!--Toasts, Dialogs-->
<string name="close">Затвори</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="magisk_update_title">Нови Адбејт Магиска Доступан!</string>
<string name="settings_reboot_toast">Рестартуј да примениш подешавања</string>
<string name="release_notes">Белешке обљављивања</string>
<string name="repo_cache_cleared">Кеш спремишта обрисан</string>
<string name="process_error">Грешка у обради</string>
<string name="internal_storage">Зип је сачуван у:\n[Интерно складиште]%1$s</string>
<string name="zip_download_title">Преузимање</string>
<string name="zip_download_msg">Преузимање зип фајла (%1$d%%) …</string>
<string name="zip_process_title">Обрада</string>
<string name="zip_process_msg">Обрада зип фајла …</string>
<string name="manager_update_title">Ново Ажурирање Магиск Менаџера Доступно!</string>
<string name="manager_download_install">Притисни да преузмеш и инсталираш</string>
<string name="dtbo_patched_title">DTBO је закрпљен!</string>
<string name="dtbo_patched_reboot">Магиск Менаџер је закрпио dtbo.img, рестартујте телефон</string>
<string name="magisk_updates">Магиск Ажурирање</string>
<string name="flashing">Флешовање</string>
<string name="hide_manager_toast">Сакривам Магиск Менаџер…</string>
<string name="hide_manager_toast2">Ово може потрајати…</string>
<string name="hide_manager_fail_toast">Скривање Магиск Менаџера неуспешно…</string>
<string name="download_zip_only">Преузми само Зип</string>
<string name="patch_boot_file">Закрпи фајл слике покретања</string>
<string name="direct_install">Директна Инсталација (Препоручено)</string>
<string name="install_second_slot">Инсталирај у Други Слот (После ОТА)</string>
<string name="select_method">Изабери Методу</string>
<string name="no_boot_file_patch_support">Циљана Магиск верзија не подржава закрпу фајла слике покретања</string>
<string name="boot_file_patch_msg">Изабери испис фабричког фајла слике покретања у .img или img.tar формату</string>
<string name="complete_uninstall">Комплетна Унинсталација</string>
<string name="restore_done">Повратак успешан!</string>
<string name="restore_fail">Фабрички бекап не постоји!</string>
<string name="proprietary_title">Преузми Власнички Код</string>
<string name="proprietary_notice">Магиск Менаџер је \'FOSS\' што значи да не садржи Гуглов власнички код од СигурнаМрежа АПИ.\n\nДа ли дозвољавате да Магиск Менаџер преузме додатак (садржи GoogleApiClient) за СигурнаМрежа провере?</string>
<string name="su_db_corrupt">СК база података оштећена, креирам нову</string>
<!--Settings Activity -->
<string name="settings_general_category">Генерално</string>
<string name="settings_dark_theme_title">Црна тема</string>
<string name="settings_dark_theme_summary">Омогући црну тему</string>
<string name="settings_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="language">Језик</string>
<string name="system_default">(Фабрички Система)</string>
<string name="settings_update">Подешавања Ажурирања</string>
<string name="settings_update_channel_title">Канал Ажурирања</string>
<string name="settings_update_stable">Стабилан</string>
<string name="settings_update_beta">Бета</string>
<string name="settings_update_custom">По наруџби</string>
<string name="settings_update_custom_msg">Унеси наруџбени УРЛ</string>
<string name="settings_boot_format_title">Закрпљено Покретање Излазни Формат</string>
<string name="settings_boot_format_summary">Изабери формат излазних закрпљених слика покретања.\nИзаберите .img ако флешујете преко fastboot/download режима; Изаберите .img.tar ако флешујете уз ОДИН.</string>
<string name="settings_core_only_title">Магиск Основни Режим</string>
<string name="settings_core_only_summary">Омогућава само основне карактеристике, сви модули неће бити учитани. МагискСК, МагискСакриј, и без-системски домаћини ће бити омогућени</string>
<string name="settings_magiskhide_summary">Сакриј Магиск од разних детекција</string>
<string name="settings_hosts_title">Без-системски домаћини (hosts)</string>
<string name="settings_hosts_summary">Подршка без-системских домаћина за апликације за блокирање реклама</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_20">20 секунди</string>
<string name="settings_su_request_30">30 секунди</string>
<string name="settings_su_request_60">60 секунди</string>
<string name="superuser_access">Приступ Супер-кориснику</string>
<string name="auto_response">Аутоматски одговор</string>
<string name="request_timeout">Истек захтева</string>
<string name="superuser_notification">Нотификације Супер-корисника</string>
<string name="request_timeout_summary">%1$s секунди</string>
<string name="settings_su_reauth_title">Поново одобри после ажурирања</string>
<string name="settings_su_reauth_summary">Поново одобри дозволу Супер-корисника после ажурирања апликације</string>
<string name="multiuser_mode">Више-кориснички режим</string>
<string name="settings_owner_only">Власник уређаја само</string>
<string name="settings_owner_manage">Одређено од стране власника</string>
<string name="settings_user_independent">Независно од корисника</string>
<string name="owner_only_summary">Само власник има приступ корену</string>
<string name="owner_manage_summary">Само власник може да приступа корену и да прими захтеве за њега</string>
<string name="user_indepenent_summary">Сваки корисник има своја правила корена</string>
<string name="multiuser_hint_owner_request">Захтев је послат власнику уређаја. Молимо вас да на власниковом налогу прихватите захтев</string>
<string name="mount_namespace_mode">Постоље режима имена простора</string>
<string name="settings_ns_global">Глобално име простора</string>
<string name="settings_ns_requester">Наслеђено име простора</string>
<string name="settings_ns_isolate">Ограђено име простора</string>
<string name="global_summary">Све коренске сесије користе глобално име простора</string>
<string name="requester_summary">Коренске сесије ће наследити свој простор именовања</string>
<string name="isolate_summary">Свака коренска сесија ће имати свој изоловани простор именовања</string>
<!--Superuser-->
<string name="su_request_title">Супер-кориснички захтев</string>
<string name="deny_with_str">Забрани%1$s</string>
<string name="deny">Забрани</string>
<string name="prompt">Захтев</string>
<string name="grant">Дозволи</string>
<string name="su_warning">Пружа потпун приступ вашем уређају.\nЗабраните ако нисте сигурни!</string>
<string name="forever">Заувек</string>
<string name="once">Једном</string>
<string name="tenmin">10 мин</string>
<string name="twentymin">20 мин</string>
<string name="thirtymin">30 мин</string>
<string name="sixtymin">60 мин</string>
<string name="su_allow_toast">%1$s је добио права на Супер-корисника</string>
<string name="su_deny_toast">%1$s није добио права на Супер-корисника</string>
<string name="no_apps_found">Нема пронађених апликација</string>
<string name="su_snack_grant">Супер-корисничка права од %1$s су пружена</string>
<string name="su_snack_deny">Супер-корисничка права од %1$s су одбијена</string>
<string name="su_snack_notif_on">Нотификације од %1$s су омогућене</string>
<string name="su_snack_notif_off">Нотификације од %1$s су онемогућене</string>
<string name="su_snack_log_on">Записивање у дневник за %1$s је омогућено</string>
<string name="su_snack_log_off">Записивање у дневник за %1$s је онемогућено</string>
<string name="su_snack_revoke">%1$s права су опозвана </string>
<string name="su_revoke_title">Опозови?</string>
<string name="su_revoke_msg">Потврди да опозовеш права од %1$s?</string>
<string name="toast">Тост</string>
<string name="none">Ниједан</string>
<!--Superuser logs-->
<string name="pid">ПИД:\u0020</string>
<string name="target_uid">Циљани УИД:\u0020</string>
<string name="command">Команда:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Moduler</string>
<string name="downloads">Nerladdningar</string>
<string name="superuser">Superuser</string>
<string name="log">Logg</string>
<string name="settings">Inställningar</string>
<string name="install">Install</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk är inte installerad</string>
<string name="checking_for_updates">Söker efter uppdateringar…</string>
<string name="magisk_update_available">Magisk v%1$s tillgänglig!</string>
<string name="safetyNet_check_text">Tryck för att starta SafetyNet-kontroll</string>
<string name="checking_safetyNet_status">Kontrollerar SafetyNet-status…</string>
<string name="safetyNet_check_success">SafetyNet-kontroll lyckades</string>
<string name="safetyNet_network_loss">Tappade nätverksanslutningen</string>
<string name="safetyNet_service_disconnected">Tjänsten har dödats</string>
<string name="safetyNet_res_invalid">Svaret är ogiltigt</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Advancerade inställningar</string>
<string name="keep_force_encryption">Fortsätt tvinga kryptering</string>
<string name="keep_dm_verity">Behåll AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Installerad: %1$s</string>
<string name="install_magisk_title">Senaste: %1$s</string>
<string name="uninstall">Avinstallera</string>
<string name="uninstall_magisk_title">Avinstallera Magisk</string>
<string name="update">Uppdatera %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Ingen information tillhandahållen)</string>
<string name="no_modules_found">Hittade inga moduler</string>
<string name="update_file_created">Modulen kommer att uppdateras vid nästa omstart</string>
<string name="remove_file_created">Modulen kommer att tas bort vid nästa omstart</string>
<string name="remove_file_deleted">Modulen kommer att inte att tas bort vid nästa omstart</string>
<string name="disable_file_created">Modulen kommer att inaktiveras vid nästa omstart</string>
<string name="disable_file_removed">Modulen kommer att aktiveras vid nästa omstart</string>
<string name="author">Skapad av %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Uppdatering tillgänglig</string>
<string name="installed">Installerad</string>
<string name="not_installed">Inte installerad</string>
<!--Log Fragment-->
<string name="menuSaveLog">Spara loggen</string>
<string name="menuReload">Uppdatera</string>
<string name="menuClearLog">Rensa loggen</string>
<string name="logs_cleared">Loggen rensad</string>
<string name="log_is_empty">Loggen är tom</string>
<!--About Activity-->
<string name="about">Om</string>
<string name="app_changelog">Ändringslogg</string>
<string name="translators" />
<string name="app_version">Version</string>
<string name="app_source_code">Källkod</string>
<string name="donation">Donation</string>
<string name="app_translators">Översättare</string>
<string name="support_thread">Supporttråd</string>
<!--Toasts, Dialogs-->
<string name="close">Stäng</string>
<string name="repo_install_title">Installera %1$s</string>
<string name="repo_install_msg">Vill du installera %1$s ?</string>
<string name="download">Ladda ner</string>
<string name="reboot">Starta om</string>
<string name="zip_process_msg">Bearbetar ZIP-filen …</string>
<string name="magisk_update_title">En uppdatering av Magisk finns tillgänglig!</string>
<string name="settings_reboot_toast">Starta om för att tillämpa inställningar</string>
<string name="release_notes">Release notes</string>
<string name="repo_cache_cleared">Repo-cache rensad</string>
<string name="process_error">Processfel</string>
<string name="internal_storage">ZIP-filen är sparad i:\n[Internal Storage]%1$s</string>
<string name="zip_process_title">Arbetar</string>
<string name="manager_update_title">En uppdatering av Magisk maneger finns tillgänglig!</string>
<string name="manager_download_install">Tryck för att ladda ner och installera</string>
<string name="magisk_updates">Magiska uppdateringar</string>
<!--Settings Activity -->
<string name="settings_general_category">Allmän</string>
<string name="settings_dark_theme_title">Mörkt tema</string>
<string name="settings_dark_theme_summary">Aktivera mörkt tema</string>
<string name="settings_clear_cache_title">Rensa repo-cache</string>
<string name="settings_clear_cache_summary">Rensa den lagrade information för online-repos, tvingar appen att uppdatera online</string>
<string name="settings_core_only_title">Endast Magisk kärnläge</string>
<string name="settings_core_only_summary">Aktiverar endast kärnfunktioner, alla moduler laddas inte. MagiskSU, MagiskHide och systemless hosts kommer fortfarande att vara aktiverade</string>
<string name="settings_magiskhide_summary">Dölj Magisk från att bli upptäckt</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Systemless hosts-stöd för Adblock-appar</string>
<string name="settings_su_app_adb">Apps och ADB</string>
<string name="settings_su_app">Endast appar</string>
<string name="settings_su_adb">Endast ADB</string>
<string name="settings_su_disable">Inaktiverad</string>
<string name="settings_su_request_10">10 sekunder</string>
<string name="settings_su_request_20">20 sekunder</string>
<string name="settings_su_request_30">30 sekunder</string>
<string name="settings_su_request_60">60 sekunder</string>
<string name="superuser_access">Superuser-tillgång</string>
<string name="auto_response">Automatiskt svar</string>
<string name="request_timeout">Förfrågnings-timeout</string>
<string name="superuser_notification">Superuser-avisering</string>
<string name="request_timeout_summary">%1$s sekunder</string>
<string name="settings_su_reauth_title">Återautentisera efter uppdatering</string>
<string name="settings_su_reauth_summary">Återautentisera superuser-behörigheter efter en applikationsuppdatering</string>
<string name="multiuser_mode">Multianvändarläge</string>
<string name="settings_owner_only">Endast ägaren av enheten</string>
<string name="settings_owner_manage">Enhetsägarhantering</string>
<string name="settings_user_independent">Användaroberoende</string>
<string name="owner_only_summary">Endast ägaren har root-tillgång</string>
<string name="owner_manage_summary">Endast ägaren kan hantera root-åtkomst och få begärda förfrågningar</string>
<string name="user_indepenent_summary">Varje användare har sina egna separata root-regler</string>
<string name="multiuser_hint_owner_request">En förfrågan har skickats till enhetens ägaren. Byt till ägaren och bevilja behörigheten</string>
<string name="mount_namespace_mode">Montera namnrymdsläge</string>
<string name="settings_ns_global">Global namnrymd</string>
<string name="settings_ns_requester">Ärv namnrymden</string>
<string name="settings_ns_isolate">Isolerad namnrymd</string>
<string name="global_summary">Alla root-sessioner använder den globala monteringsnamnrymden</string>
<string name="requester_summary">Root-sessioner kommer att ärva den sökandes namnrymd</string>
<string name="isolate_summary">Varje root-session kommer att ha sin egen isolerade namnrymd</string>
<!--Superuser-->
<string name="su_request_title">Superuser-förfrågan</string>
<string name="deny_with_str">Neka%1$s</string>
<string name="deny">Neka</string>
<string name="prompt">Fråga</string>
<string name="grant">Bevilja</string>
<string name="su_warning">Beviljar full tillgång till din enhet.\nNeka om du är osäker!</string>
<string name="forever">För alltid</string>
<string name="once">En gång</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 är beviljad Superuser-rättigheter</string>
<string name="su_deny_toast">%1$s är nekad Superuser-rättigheter</string>
<string name="no_apps_found">Hittade inga appar</string>
<string name="su_snack_grant">Superuser-rättigheter av %1$s är beviljad</string>
<string name="su_snack_deny">Superuser-rättigheter av %1$s är nekad</string>
<string name="su_snack_notif_on">Aviseringar från %1$s är aktiverad</string>
<string name="su_snack_notif_off">Aviseringar från %1$s är inaktiverade</string>
<string name="su_snack_log_on">Loggning av %1$s är aktiverad</string>
<string name="su_snack_log_off">Loggning av %1$s är inaktiverad</string>
<string name="su_snack_revoke">%1$s rättigheter är upphävda</string>
<string name="su_revoke_title">Upphäv?</string>
<string name="su_revoke_msg">Bekräfta upphävning av %1$s rättigheter?</string>
<string name="toast">Toast-meddelande</string>
<string name="none">Inga</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Mål-UID:\u0020</string>
<string name="command">Kommando:\u0020</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="fab_padding">24dp</dimen>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme.StatusBar" parent="AppTheme">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="AppTheme.StatusBar.Dark" parent="AppTheme.Dark">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
\ No newline at end of file
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Modüller</string>
<string name="downloads">İndir</string>
<string name="superuser">Yetkili kullanıcı</string>
<string name="log">Günlük</string>
<string name="settings">Ayarlar</string>
<string name="install">Yükle</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk yüklü değil</string>
<string name="checking_for_updates">Güncelleştirmeler denetleniyor…</string>
<string name="magisk_update_available">Magisk v%1$s mevcut!</string>
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</string>
<string name="safetyNet_check_text">SafetyNet kontrolünü başlatmak için dokun</string>
<string name="checking_safetyNet_status">SafetyNet durumu kontrol ediliyor…</string>
<string name="safetyNet_check_success">SafetyNet Kontrolü Başarılı</string>
<string name="safetyNet_api_error">SafetyNet API Hatası</string>
<string name="safetyNet_network_loss">Ağ bağlantısı kullanılamıyor</string>
<string name="safetyNet_service_disconnected">Hizmet sonlandırıldı</string>
<string name="safetyNet_res_invalid">Yanıt geçersiz</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Gelişmiş Ayarlar</string>
<string name="keep_force_encryption">Şifrelemeyi zorlamayı sürdür</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'yi koru</string>
<string name="current_magisk_title">Yüklü Sürüm: %1$s</string>
<string name="install_magisk_title">Yeni Sürüm: %1$s</string>
<string name="uninstall">Kaldır</string>
<string name="uninstall_magisk_title">"Magisk\'i kaldır"</string>
<string name="uninstall_magisk_msg">Tüm modüller devre dışı bırakılacak/kaldırılacaktır. Kök erişimi kaldırılacak ve verileriniz şu anda şifrelenmemişse potansiyel olarak verileriniz şifrelenecek</string>
<string name="update">Güncelle %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Hiçbir açıklama sağlanmadı)</string>
<string name="no_modules_found">Modül yok</string>
<string name="update_file_created">Modül sonraki yeniden başlatmada güncellenecek</string>
<string name="remove_file_created">Modül sonraki yeniden başlatmada kaldırılacak</string>
<string name="remove_file_deleted">Modül sonraki yeniden başlatmada kaldırılmayacak</string>
<string name="disable_file_created">Modül sonraki yeniden başlatmada devre dışı bırakılacak</string>
<string name="disable_file_removed">Modül sonraki yeniden başlatmada etkinleştirilecek</string>
<string name="author">Yapımcı: %1$s</string>
<string name="reboot_recovery">Kurtarma modunda yeniden başlat</string>
<string name="reboot_bootloader">Önyükleyici modunda yeniden başlat</string>
<string name="reboot_download">Yükleme modunda yeniden başlat</string>
<!--Repo Fragment-->
<string name="update_available">Güncelleme Mevcut</string>
<string name="installed">Yüklenmiş</string>
<string name="not_installed">Yüklenmemiş</string>
<string name="updated_on">Güncelleme: %1$s</string>
<string name="sorting_order">Sıralama Düzeni</string>
<string name="sort_by_name">İsme göre sırala</string>
<string name="sort_by_update">Son güncellemeye göre sırala</string>
<!--Log Fragment-->
<string name="menuSaveLog">Günlüğü kaydet</string>
<string name="menuReload">Yenile</string>
<string name="menuClearLog">Günlüğü temizle</string>
<string name="logs_cleared">Günlük başarıyla temizlendi</string>
<string name="log_is_empty">Günlük boş</string>
<!--About Activity-->
<string name="about">Hakkında</string>
<string name="app_changelog">Uygulama değişiklikleri</string>
<string name="translators">Fatih FIRINCI - Mevlüt TOPÇU</string>
<string name="app_version">Uygulama sürümü</string>
<string name="app_source_code">Kaynak kodu</string>
<string name="donation">Bağış Yapın</string>
<string name="app_translators">Çevirmenler</string>
<string name="support_thread">Destek konusu</string>
<!--Toasts, Dialogs-->
<string name="close">Kapat</string>
<string name="repo_install_title">%1$s yükle</string>
<string name="repo_install_msg">%1$s yüklensin mi?</string>
<string name="download">İndir</string>
<string name="reboot">Yeniden başlat</string>
<string name="magisk_update_title">Yeni Magisk Güncellemesi Mevcut!</string>
<string name="settings_reboot_toast">Ayarları uygulamak için yeniden başlatın</string>
<string name="release_notes">Sürüm notları</string>
<string name="repo_cache_cleared">Repo önbelleği temizlendi</string>
<string name="process_error">İşlem hatası</string>
<string name="internal_storage">Zip şuraya depolandı:\n[Dahili Hafıza]%1$s</string>
<string name="zip_download_title">İndiriliyor</string>
<string name="zip_download_msg">Zip dosyası indiriliyor (%1$d%%) …</string>
<string name="zip_process_title">İşleniyor</string>
<string name="zip_process_msg">Zip dosyası işleniyor …</string>
<string name="manager_update_title">Yeni Magisk Manager Güncellemesi Mevcut!</string>
<string name="manager_download_install">İndirmek ve yüklemek için dokunun</string>
<string name="dtbo_patched_title">DTBO yamalandı!</string>
<string name="dtbo_patched_reboot">Magisk Manager dtbo.img\'yi yamaladı, lütfen yeniden başlatın</string>
<string name="magisk_updates">Magisk Güncellemeleri</string>
<string name="flashing">Yükleniyor</string>
<string name="hide_manager_toast">Magisk Manager Gizleniyor…</string>
<string name="hide_manager_toast2">Bu biraz zaman alabilir…</string>
<string name="hide_manager_fail_toast">Magisk Manager\'ı Gizleme başarısız oldu…</string>
<string name="download_zip_only">Yalnızca Zip Dosyasını İndir</string>
<string name="patch_boot_file">Önyükleme İmaj Dosyasını Yamala</string>
<string name="direct_install">Doğrudan Yükle (Önerilen)</string>
<string name="install_second_slot">İkinci Yuvaya Yükle (OTA\'dan sonra)</string>
<string name="select_method">Yöntem Seçin</string>
<string name="no_boot_file_patch_support">Hedef Magisk sürümü önyükleme imaj dosyasını yamalamayı desteklemiyor</string>
<string name="boot_file_patch_msg">.img veya .img.tar formatında stok önyükleme imajını seçin</string>
<string name="complete_uninstall">Tamamen Kaldır</string>
<string name="restore_img">Önyükleme İmajını Geri Yükle</string>
<string name="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 Google\'ın tescilli olduğu SafetyNet API kodunu içermez.\n\nMagisk Manager\'ın SafetyNet kontrolü için bir uzantıyı (GoogleApiClient içeriyor) indirmesine izin veriyor musunuz?</string>
<string name="su_db_corrupt">SU veritabanı bozuk, yeni db oluşturacak</string>
  <string name="cannot_check_sn_title">SafetyNet denetlenemiyor</string>
<string name="cannot_check_sn_notice">Google Play Hizmetleri\'ndeki bazı değişiklikler nedeniyle, yeniden paketlenmiş Magisk Manager\'da SafetyNet\'i denetlemek mümkün değildir</string>
<string name="setup_done">Kurulum tamamlandı</string>
<string name="setup_fail">Kurulum başarısız</string>
<string name="env_fix_title">Ek Kurulum İste</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>
<!--Settings Activity -->
<string name="settings_general_category">Genel</string>
<string name="settings_dark_theme_title">Karanlık Tema</string>
<string name="settings_dark_theme_summary">Karanlık temayı etkinleştir</string>
<string name="settings_clear_cache_title">Repo Önbelleğini Temizle</string>
<string name="settings_clear_cache_summary">Çevrimiçi repolar için önbellek bilgilerini temizle, uygulamayı çevrimiçi yenilemeye zorla</string>
<string name="settings_hide_manager_title">Magisk Manager\'ı Gizle</string>
<string name="settings_hide_manager_summary">Rastgele 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_update">Güncelleme Ayarları</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_beta">Beta</string>
<string name="settings_update_custom">Özel</string>
<string name="settings_update_custom_msg">Özel bir URL ekleyin</string>
<string name="settings_boot_format_title">Yamalı Önyükleme Formatı</string>
<string name="settings_boot_format_summary">Yamalı önyükleme imaj dosyasının formatını seçin\nFastboot/download modunda yüklemek için .img seçeneğini seçin; ODIN ile yüklemek için .img.tar\'ı seçin.</string>
<string name="settings_core_only_title">Magisk Sadece Çekirdek Modu</string>
<string name="settings_core_only_summary">Sadece temel özellikleri etkinleştirin, tüm modüller yüklenmez. MagiskSU, MagiskHide ve host yine de etkinleştirilecektir</string>
<string name="settings_magiskhide_summary">"Magisk\'i çeşitli algılamalardan gizle"</string>
<string name="settings_hosts_title">Sistemsiz host</string>
<string name="settings_hosts_summary">Reklam engelleme uygulamaları için sistemsiz host desteği</string>
<string name="settings_su_app_adb">Uygulamalar ve ADB</string>
<string name="settings_su_app">Sadece uygulamalar</string>
<string name="settings_su_adb">Sadece ADB</string>
<string name="settings_su_disable">Devre dışı</string>
<string name="settings_su_request_10">10 saniye</string>
<string name="settings_su_request_20">20 saniye</string>
<string name="settings_su_request_30">30 saniye</string>
<string name="settings_su_request_60">60 saniye</string>
<string name="superuser_access">Yetkili Kullanıcı Erişimi</string>
<string name="auto_response">Otomatik Yanıt</string>
<string name="request_timeout">İstek Zaman Aşımı</string>
<string name="superuser_notification">Yetkili Kullanıcı Bildirimi</string>
<string name="request_timeout_summary">%1$s saniye</string>
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrula</string>
<string name="settings_su_reauth_summary">Uygulama yükseltmeleri sonrasında yetkili kullanıcı izinlerini yeniden doğrula</string>
<string name="settings_su_fingerprint_title">Parmak İzi Kimlik Doğrulamayı Etkinleştir</string>
<string name="settings_su_fingerprint_summary">Yetkili kullanıcı isteklerine izin vermek için parmak izi tarayıcısını kullan</string>
<string name="multiuser_mode">Çok Kullanıcılı Mod</string>
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</string>
<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_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>
<string name="multiuser_hint_owner_request">Cihaz sahibine bir istek gönderilmiştir. Lütfen cihaz sahibi hesabına geçin ve izin verin</string>
<string name="mount_namespace_mode">Ad Alanı Modunu Doldur</string>
<string name="settings_ns_global">Global Ad Alanı</string>
<string name="settings_ns_requester">Inherit Ad Alanı</string>
<string name="settings_ns_isolate">Isolated Ad Alanı</string>
<string name="global_summary">Tüm kök oturumları genel bağlama ad alanını kullanır</string>
<string name="requester_summary">Kök oturumları, istekte bulunanın ad alanını devralır</string>
<string name="isolate_summary">Her bir kök oturumunun kendi izole ad alanı olacaktır</string>
<string name="android_o_not_support">Android 8.0 ve üzerinde desteklenmiyor</string>
<string name="disable_fingerprint">Parmak izi ayarlanmadı veya cihaz desteği yok</string>
<!--Superuser-->
<string name="su_request_title">Yetkili Kullanıcı İsteği</string>
<string name="deny_with_str">Reddet%1$s</string>
<string name="deny">Reddet</string>
<string name="prompt">Sor</string>
<string name="grant">İzin ver</string>
<string name="su_warning">Cihazınıza tam erişim izni verir.\nEmin değilseniz, reddedin!</string>
<string name="forever">Daima</string>
<string name="once">Bir kere</string>
   <string name="tenmin">10 dakika</string>
   <string name="twentymin">20 dakika</string>
   <string name="thirtymin">30 dakika</string>
   <string name="sixtymin">60 dakika</string>
<string name="su_allow_toast">%1$s için yetkili kullanıcı hakları verildi</string>
<string name="su_deny_toast">%1$s için yetkili kullanıcı hakları reddedildi</string>
<string name="no_apps_found">Hiçbir uygulama bulunamadı</string>
<string name="su_snack_grant">%1$s için yetkili kullanıcı hakları verildi</string>
<string name="su_snack_deny">%1$s için yetkili kullanıcı hakları reddedildi</string>
<string name="su_snack_notif_on">%1$s için bildirimler etkin</string>
<string name="su_snack_notif_off">%1$s için bildirimler devre dışı</string>
<string name="su_snack_log_on">%1$s için günlük etkin</string>
<string name="su_snack_log_off">%1$s için günlük devre dışı</string>
<string name="su_snack_revoke">%1$s hakları geri alındı</string>
<string name="su_revoke_title">Geri alınsın mı?</string>
<string name="su_revoke_msg">%1$s hakları geri alınsın mı?</string>
<string name="toast">Pencere</string>
<string name="none">Hiçbiri</string>
<string name="auth_fail">Kimlik Doğrulama Başarısız</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Hedef UID:\u0020</string>
<string name="command">Komut:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">Модулі</string>
<string name="downloads">Завантаження</string>
<string name="superuser">Суперкористувач</string>
<string name="log">Логи</string>
<string name="settings">Налаштування</string>
<string name="install">Встановлення</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk не встановлено</string>
<string name="checking_for_updates">Перевірка оновлень…</string>
<string name="magisk_update_available">Доступно Magisk v%1$s!</string>
<string name="invalid_update_channel">Неправильний канал оновлень</string>
<string name="safetyNet_check_text">Перевірити статус SafetyNet</string>
<string name="checking_safetyNet_status">Перевірка статусу SafetyNet…</string>
<string name="safetyNet_check_success">Результат перевірки SafetyNet</string>
<string name="safetyNet_api_error">Помилка в API SafetyNet</string>
<string name="safetyNet_network_loss">Підключення до інтернету втрачено</string>
<string name="safetyNet_service_disconnected">Службу зупинено</string>
<string name="safetyNet_res_invalid">Невірна відповідь</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Розширені налаштування</string>
<string name="keep_force_encryption">Залишити примусове шифрування</string>
<string name="keep_dm_verity">Залишити AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Поточна версія: %1$s</string>
<string name="install_magisk_title">Найновіша версія: %1$s</string>
<string name="uninstall">Видалити</string>
<string name="uninstall_magisk_title">Видалити Magisk</string>
<string name="uninstall_magisk_msg">Ця дія призведе до видалення всіх модулів, MagiskSU, і може зашифрувати дані, якщо вони не зашифровані.\nВпевнені, що бажаєте продовжити?</string>
<string name="update">Оновити %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(Немає наданої інформації)</string>
<string name="no_modules_found">Модулів не знайдено</string>
<string name="update_file_created">Модуль оновиться при перезавантаженні</string>
<string name="remove_file_created">Модуль видалиться при перезавантаженні</string>
<string name="remove_file_deleted">Модуль не видалиться при перезавантаженні</string>
<string name="disable_file_created">Модуль вимкнеться при перезавантаженні</string>
<string name="disable_file_removed">Модуль увімкнеться при перезавантаженні</string>
<string name="author">Автор: %1$s</string>
<string name="reboot_recovery">Перезавантаження в Recovery</string>
<string name="reboot_bootloader">Перезавантаження в Bootloader</string>
<string name="reboot_download">Перезавантаження в Download</string>
<!--Repo Fragment-->
<string name="update_available">Доступне оновлення</string>
<string name="installed">Встановлено</string>
<string name="not_installed">Не встановлено</string>
<string name="updated_on">Оновлено: %1$s</string>
<string name="sorting_order">Порядок сортування</string>
<string name="sort_by_name">Сортувати за назвою</string>
<string name="sort_by_update">Сортувати за оновленням</string>
<!--Log Fragment-->
<string name="menuSaveLog">Зберегти логи</string>
<string name="menuReload">Оновити</string>
<string name="menuClearLog">Очистити логи</string>
<string name="logs_cleared">Логи очищено</string>
<string name="log_is_empty">Логи пусті</string>
<!--About Activity-->
<string name="about">Про програму</string>
<string name="app_changelog">Перелік змін</string>
<string name="translators" />
<string name="app_version">Версія</string>
<string name="app_source_code">Вихідний код</string>
<string name="donation">Підтримати проект</string>
<string name="app_translators">Перекладачі</string>
<string name="support_thread">Сторінка підтримки</string>
<!--Toasts, Dialogs-->
<string name="close">Закрити</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="magisk_update_title">Доступне оновлення Magisk!</string>
<string name="settings_reboot_toast">Для застосування змін перезавантажте пристрій</string>
<string name="release_notes">Особливості версії</string>
<string name="repo_cache_cleared">Кеш репозиторію очищено</string>
<string name="process_error">Помилка опрацювання</string>
<string name="internal_storage">Архів розташований:\n[Внутрішнє Сховище]%1$s</string>
<string name="zip_download_title">Завантаження</string>
<string name="zip_download_msg">Завантаження zip файлу (%1$d%%) …</string>
<string name="zip_process_title">Опрацювання</string>
<string name="zip_process_msg">Опрацювання архіву …</string>
<string name="manager_update_title">Доступне оновлення Magisk Manager!</string>
<string name="manager_download_install">Натисніть, щоб завантажити і встановити</string>
<string name="dtbo_patched_title">DTBO пропатчено!</string>
<string name="dtbo_patched_reboot">Magisk Manager пропатчив dtbo.img, будь ласка, перезавантажте пристрій</string>
<string name="magisk_updates">Оновлення Magisk</string>
<string name="flashing">Прошивання</string>
<string name="hide_manager_toast">Приховування Magisk Manager…</string>
<string name="hide_manager_toast2">Це може зайняти деякий час…</string>
<string name="hide_manager_fail_toast">Не вдалося приховати Magisk Manager…</string>
<string name="download_zip_only">Тільки завантажити</string>
<string name="patch_boot_file">Пропатчити boot образ</string>
<string name="direct_install">Пряме встановлення (рекомендовано)</string>
<string name="install_second_slot">Встановити в Другий Слот (після OTA)</string>
<string name="select_method">Виберіть спосіб</string>
<string name="no_boot_file_patch_support">Цільова версія Magisk не підтримує пропатчування boot образу</string>
<string name="boot_file_patch_msg">Виберіть оригінальний дамп boot образу в форматі .img чи .img.tar</string>
<string name="complete_uninstall">Видалення виконано</string>
<string name="restore_img">Відновити образи</string>
<string name="restore_img_msg">Відновлення…</string>
<string name="restore_done">Відновлення завершено!</string>
<string name="restore_fail">Немає резервної копії оригінального boot образу</string>
<string name="proprietary_title">Завантажити пропрієтарний код</string>
<string name="proprietary_notice">Magisk Manager — це безкоштовний додаток з відкритим вихідним кодом, тому він не містить пропрієтарний код API SafetyNet від компанії Google.\n\nДозволити Magisk Manager завантажити розширення (яке містить GoogleApiClient) для перевірки SafetyNet?</string>
<string name="su_db_corrupt">База даних SU пошкоджена, буде створено нову БД</string>
<string name="cannot_check_sn_title">Неможливо перевірити SafetyNet</string>
<string name="cannot_check_sn_notice">Через деякі зміни в Сервісах Google Play, неможливо перевірити статус SafetyNet на перепакованому Magisk Manager</string>
<string name="setup_done">Налаштування завершено</string>
<string name="setup_fail">Не вдалося налаштувати</string>
<string name="env_fix_title">Потрібне додаткове налаштування</string>
<string name="env_fix_msg">Для правильної роботи Magisk, потрібне додаткове налаштування вашого пристрою. Буде завантажено zip-архів. Розпочати негайно?</string>
<string name="setup_title">Додаткове налаштування</string>
<string name="setup_msg">Налаштування робочого середовища…</string>
<!--Settings Activity -->
<string name="settings_general_category">Основні</string>
<string name="settings_dark_theme_title">Темна тема</string>
<string name="settings_dark_theme_summary">Увімкнути темне оформлення</string>
<string name="settings_clear_cache_title">Очищення кешу</string>
<string name="settings_clear_cache_summary">Очистити збережену інформацію про мережеві репозиторії, змушуючи програму примусово оновлюватися через Інтернет</string>
<string name="settings_hide_manager_title">Приховати Magisk Manager</string>
<string name="settings_hide_manager_summary">Перезібрати Magisk Manager з випадковим іменем пакету</string>
<string name="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_update">Налаштування оновлень</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_boot_format_title">Формат пропатченого образу</string>
<string name="settings_boot_format_summary">Виберіть формат вихідного пропатченого boot образу.\n.img - для прошивання через fastboot/download режим;\n.img.tar - для прошивання через ODIN.</string>
<string name="settings_core_only_title">Режим ядра Magisk</string>
<string name="settings_core_only_summary">Увімкнути тільки можливості ядра, всі модулі не будуть активними. MagiskSU, MagiskHide і позасистемні хости залишуться увімкненими</string>
<string name="settings_magiskhide_summary">Приховати Magisk від різних перевірок</string>
<string name="settings_hosts_title">Позасистемні хости</string>
<string name="settings_hosts_summary">Підтримка позасистемних хостів для програм блокування реклами</string>
<string name="settings_su_app_adb">Програми і ADB</string>
<string name="settings_su_app">Програми</string>
<string name="settings_su_adb">ADB</string>
<string name="settings_su_disable">Вимкнено</string>
<string name="settings_su_request_10">10 секунд</string>
<string name="settings_su_request_20">20 секунд</string>
<string name="settings_su_request_30">30 секунд</string>
<string name="settings_su_request_60">60 секунд</string>
<string name="superuser_access">Доступ суперкористувача</string>
<string name="auto_response">Автоматична відповідь</string>
<string name="request_timeout">Час запиту</string>
<string name="superuser_notification">Сповіщення суперкористувача</string>
<string name="request_timeout_summary">%1$s сек.</string>
<string name="settings_su_reauth_title">Повторна автентифікація</string>
<string name="settings_su_reauth_summary">Перевидача прав суперкористувача після оновлення програм</string>
<string name="settings_su_fingerprint_title">Автентифікація за відбитком</string>
<string name="settings_su_fingerprint_summary">Використовувати сканер відбитків пальців, щоб надавати дозвіл суперкористувача</string>
<string name="multiuser_mode">Багатокористувацький режим</string>
<string name="settings_owner_only">Тільки власник</string>
<string name="settings_owner_manage">Регулювання власником</string>
<string name="settings_user_independent">Незалежний користувач</string>
<string name="owner_only_summary">Тільки власник має root-доступ</string>
<string name="owner_manage_summary">Тільки власник може керувати root-доступом і опрацьовувати запити на надання доступу</string>
<string name="user_indepenent_summary">Кожен користувач має власні правила root-доступу</string>
<string name="multiuser_hint_owner_request">Запит відправлено власнику. Будь ласка, перейдіть на профіль власника і надайте дозвіл</string>
<string name="mount_namespace_mode">Режим монтування простору імен</string>
<string name="settings_ns_global">Глобальний простір імен</string>
<string name="settings_ns_requester">Наслідуваний простір імен</string>
<string name="settings_ns_isolate">Ізольований простір імен</string>
<string name="global_summary">Всі сеанси Суперкористувача використовують глобальний простір імен</string>
<string name="requester_summary">Сеанси Суперкористувача наслідують простір імен запитувача</string>
<string name="isolate_summary">Кожнен сеанс Суперкористувача має власний ізольований простір імен</string>
<string name="android_o_not_support">Не підтримує Android 8.0+</string>
<string name="disable_fingerprint">Немає відбитків пальців або пристрій не підтримується</string>
<!--Superuser-->
<string name="su_request_title">Запит прав Суперкористувача</string>
<string name="deny_with_str">Відмовити %1$s</string>
<string name="deny">Відмовити</string>
<string name="prompt">Запитувати</string>
<string name="grant">Надати</string>
<string name="su_warning">Надати повний доступ до пристрою.\nЯкщо не впевнені, що бажаєте продовжити, відхиліть дану дію.</string>
<string name="forever">Назавжди</string>
<string name="once">Одноразово</string>
<string name="tenmin">10 хв.</string>
<string name="twentymin">20 хв.</string>
<string name="thirtymin">30 хв.</string>
<string name="sixtymin">60 хв.</string>
<string name="su_allow_toast">%1$s надані права Суперкористувача</string>
<string name="su_deny_toast">%1$s відмовлено в правах Суперкористувача</string>
<string name="no_apps_found">Програм не виявлено</string>
<string name="su_snack_grant">%1$s надані права Суперкористувача</string>
<string name="su_snack_deny">%1$s відмовлено в правах Суперкористувача</string>
<string name="su_snack_notif_on">Сповіщення для %1$s увімкнено</string>
<string name="su_snack_notif_off">Сповіщення для %1$s вимкнено</string>
<string name="su_snack_log_on">Логи подій для %1$s увімкнено</string>
<string name="su_snack_log_off">Логи подій для %1$s вимкнено</string>
<string name="su_snack_revoke">Права для %1$s відкликані</string>
<string name="su_revoke_title">Відкликати?</string>
<string name="su_revoke_msg">Підтвердити відкликання прав для %1$s?</string>
<string name="toast">Спливаюче сповіщення</string>
<string name="none">Ні</string>
<string name="auth_fail">Помилка автентифікації</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Цільовий UID:\u0020</string>
<string name="command">Команда:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">Mô-đun</string>
<string name="downloads">Tải xuống</string>
<string name="superuser">Superuser</string>
<string name="log">Nhật ký</string>
<string name="settings">Thiết lập</string>
<string name="install">Cài đặt</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk chưa được cài đặt</string>
<string name="checking_for_updates">Đang kiểm tra cập nhật…</string>
<string name="magisk_update_available">Magisk v%1$s available!</string>
<string name="safetyNet_check_text">Chạm để bắt đầu kiểm tra SafetyNet</string>
<string name="checking_safetyNet_status">Đang kiểm tra trạng thái SafetyNet…</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Thiết lập nâng cao</string>
<string name="keep_force_encryption">Giữ bắt buộc mã hoá</string>
<string name="keep_dm_verity">Giữ AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Đã cài đặt phiên bản: %1$s</string>
<string name="install_magisk_title">Phiên bản mới nhất: %1$s</string>
<string name="uninstall">Gỡ bỏ</string>
<string name="uninstall_magisk_title">Gỡ bỏ Magisk</string>
<!--Module Fragment-->
<string name="no_info_provided">(Không có thông tin được cung cấp)</string>
<string name="no_modules_found">Không tìm thấy mô-đun</string>
<string name="update_file_created">Mô-đun sẽ được cập nhật ở lần khởi động lại kế tiếp</string>
<string name="remove_file_created">Mô-đun sẽ được xoá bỏ ở lần khởi động lại kế tiếp</string>
<string name="remove_file_deleted">Mô-đun sẽ không được xoá bỏ ở lần khởi động lại kế tiếp</string>
<string name="disable_file_created">Mô-đun sẽ bị vô hiệu ở lần khởi động lại kế tiếp</string>
<string name="disable_file_removed">Mô-đun sẽ được kích hoạt ở lần khởi động lại kế tiếp</string>
<string name="author">Tạo bởi %1$s</string>
<!--Repo Fragment-->
<string name="update_available">Có cập nhật mới</string>
<string name="installed">Đã được cài đặt</string>
<string name="not_installed">Chưa được cài đặt</string>
<!--Log Fragment-->
<string name="menuSaveLog">Lưu nhật ký</string>
<string name="menuReload">Tải lại</string>
<string name="menuClearLog">Xoá nhật ký ngay</string>
<string name="logs_cleared">Đã xoá nhật ký thành công</string>
<string name="log_is_empty">Nhật ký trống</string>
<!--About Activity-->
<string name="about">Thông tin</string>
<string name="app_changelog">Nhật ký thay đổi của ứng dụng</string>
<string name="translators"><![CDATA[<a href="https://github.com/thanhtai2009">thanhtai2009@tekcafe.vn</a>]]></string>
<string name="app_version">Phiên bản ứng dụng</string>
<string name="app_source_code">Mã nguồn</string>
<string name="donation">Ủng hộ</string>
<string name="app_translators">Người dịch ứng dụng</string>
<string name="support_thread">Chủ đề hỗ trợ</string>
<!--Toasts, Dialogs-->
<string name="close">Đóng</string>
<string name="repo_install_title">Cài đặt %1$s</string>
<string name="repo_install_msg">Bạn muốn cài đặt %1$s ?</string>
<string name="download">Tải xuống</string>
<string name="reboot">Khởi động lại</string>
<string name="zip_process_msg">Đang xử lý tập tin zip …</string>
<string name="magisk_update_title">Có cập nhật Magisk mới!</string>
<string name="settings_reboot_toast">Khởi động lại để áp dụng thiết lập</string>
<string name="release_notes">Ghi chú phát hành</string>
<string name="repo_cache_cleared">Đã xoá bộ đệm kho</string>
<string name="process_error">Lỗi xử lý</string>
<string name="internal_storage">Tập tin zip được lưu vào:\n[Bộ nhớ trong]%1$s</string>
<string name="zip_process_title">Đang xử lý</string>
<!--Settings Activity -->
<string name="settings_general_category">Chung</string>
<string name="settings_dark_theme_title">Chủ đề tối</string>
<string name="settings_dark_theme_summary">Dùng chủ đề tối</string>
<string name="settings_clear_cache_title">Xoá bộ đệm kho</string>
<string name="settings_clear_cache_summary">Xoá thông tin truy cập nhật về các kho mô-đun, buộc ứng dụng làm mới trực tuyến</string>
<string name="settings_magiskhide_summary">Ẩn Magisk khỏi nhiều phương thức phát hiện</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Systemless hosts hỗ trợ các ứng dụng chặn quảng cáo</string>
<string name="settings_su_app_adb">Ứng dụng và ADB</string>
<string name="settings_su_app">Chỉ ứng dụng</string>
<string name="settings_su_adb">Chỉ ADB</string>
<string name="settings_su_disable">Đã vô hiệu</string>
<string name="settings_su_request_10">10 giây</string>
<string name="settings_su_request_20">20 giây</string>
<string name="settings_su_request_30">30 giây</string>
<string name="settings_su_request_60">60 giây</string>
<string name="superuser_access">Truy nhập Superuser</string>
<string name="auto_response">Tự phản hồi</string>
<string name="request_timeout">Thời gian chờ yêu cầu</string>
<string name="superuser_notification">Thông báo Superuser</string>
<string name="request_timeout_summary">%1$s giây</string>
<!--Superuser-->
<string name="su_request_title">Yêu cầu Superuser</string>
<string name="deny_with_str">Từ chối%1$s</string>
<string name="deny">Từ chối</string>
<string name="prompt">Nhắc nhở</string>
<string name="grant">Cấp phép</string>
<string name="su_warning">Cấp toàn quyền truy cập thiết bị.\nTừ chối nếu bạn không chắc chắn!</string>
<string name="forever">Mãi mãi</string>
<string name="once">Một lần</string>
<string name="tenmin">10 phút</string>
<string name="twentymin">20 phút</string>
<string name="thirtymin">30 phút</string>
<string name="sixtymin">60 phút</string>
<string name="su_allow_toast">%1$s đã được cấp quyền Superuser</string>
<string name="su_deny_toast">Đã từ chối cấp quyền Superuser cho %1$s</string>
<string name="no_apps_found">Không tìm thấy ứng dụng</string>
<string name="su_snack_grant">Quyền Superuser của %1$s đã được cấp</string>
<string name="su_snack_deny">Quyền Superuser của %1$s đã bị từ chối</string>
<string name="su_snack_notif_on">Thông báo của %1$s đã được kích hoạt</string>
<string name="su_snack_notif_off">Thông báo của %1$s đã bị vô hiệu</string>
<string name="su_snack_log_on">Ghi nhận của %1$s đã được kích hoạt</string>
<string name="su_snack_log_off">Ghi nhận của %1$s đã bị vô hiệu</string>
<string name="su_snack_revoke">Quyền của %1$s đã được thu hồi</string>
<string name="su_revoke_title">Thu hồi?</string>
<string name="su_revoke_msg">Xác nhận thu hồi quyền của %1$s?</string>
<string name="toast">Thông báo ngắn</string>
<string name="none">Không có</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Target UID:\u0020</string>
<string name="command">Command:\u0020</string>
</resources>
<resources>
<!--Welcome Activity-->
<string name="modules">模块</string>
<string name="downloads">下载</string>
<string name="superuser">超级用户</string>
<string name="log">日志</string>
<string name="settings">设置</string>
<string name="install">安装</string>
<!--Status Fragment-->
<string name="magisk_version_error">未安装 Magisk</string>
<string name="checking_for_updates">正在检查更新…</string>
<string name="magisk_update_available">Magisk 可更新到 v%1$s!</string>
<string name="invalid_update_channel">无效的更新通道</string>
<string name="safetyNet_check_text">点按启动 SafetyNet 检查</string>
<string name="checking_safetyNet_status">正在检查 SafetyNet 状态…</string>
<string name="safetyNet_check_success">SafetyNet 检查成功</string>
<string name="safetyNet_api_error">SafetyNet API 错误</string>
<string name="safetyNet_network_loss">网络连接不可用</string>
<string name="safetyNet_service_disconnected">服务已被取消</string>
<string name="safetyNet_res_invalid">回传值无效</string>
<!--Install Fragment-->
<string name="advanced_settings_title">安装选项</string>
<string name="keep_force_encryption">保持强制加密</string>
<string name="keep_dm_verity">保留 AVB 2.0/dm-verity</string>
<string name="current_magisk_title">已安装版本:%1$s</string>
<string name="install_magisk_title">最新的版本:%1$s</string>
<string name="uninstall">卸载</string>
<string name="uninstall_magisk_title">卸载 Magisk</string>
<string name="uninstall_magisk_msg">所有模块将停用或删除,Root 会被移除。未加密的设备重启时可能会被进行加密。</string>
<string name="update">更新 %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(未提供信息)</string>
<string name="no_modules_found">未找到模块</string>
<string name="update_file_created">模块将在下次重启后更新</string>
<string name="remove_file_created">模块将在下次重启后移除</string>
<string name="remove_file_deleted">模块将不会在下次重启后移除</string>
<string name="disable_file_created">模块将在下次重启后禁用</string>
<string name="disable_file_removed">模块将在下次重启后启用</string>
<string name="author">作者:%1$s</string>
<string name="reboot_recovery">重启到 Recovery</string>
<string name="reboot_bootloader">重启到 Bootloader</string>
<string name="reboot_download">重启到 Download</string>
<!--Repo Fragment-->
<string name="update_available">可更新</string>
<string name="installed">已安装</string>
<string name="not_installed">未安装</string>
<string name="updated_on">更新于: %1$s</string>
<string name="sorting_order">排序方式</string>
<string name="sort_by_name">按名称排序</string>
<string name="sort_by_update">按更新时间排序</string>
<!--Log Fragment-->
<string name="menuSaveLog">保存日志</string>
<string name="menuReload">刷新</string>
<string name="menuClearLog">清除日志</string>
<string name="logs_cleared">日志已清除</string>
<string name="log_is_empty">日志为空</string>
<!--About Activity-->
<string name="about">关于</string>
<string name="app_changelog">应用更新日志</string>
<string name="translators">gh2923, vvb2060</string>
<string name="app_version">应用版本</string>
<string name="app_source_code">源代码</string>
<string name="donation">捐赠</string>
<string name="app_translators">翻译人员</string>
<string name="support_thread">支持主题</string>
<!--Toasts, Dialogs-->
<string name="close">关闭</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="magisk_update_title">Magisk 可更新!</string>
<string name="settings_reboot_toast">重启以应用设置</string>
<string name="release_notes">发布说明</string>
<string name="repo_cache_cleared">仓库缓存已清除</string>
<string name="process_error">处理失败</string>
<string name="internal_storage">Zip 已被储存到:\n[内部存储空间]%1$s</string>
<string name="zip_download_title">正在下载</string>
<string name="zip_download_msg">正在下载 Zip 文件(%1$d%%)…</string>
<string name="zip_process_title">正在处理</string>
<string name="zip_process_msg">正在处理 zip 文件…</string>
<string name="manager_update_title">Magisk Manager 有更新!</string>
<string name="manager_download_install">点按以下载并安装</string>
<string name="dtbo_patched_title">已修补 DTBO!</string>
<string name="dtbo_patched_reboot">Magisk Manager 为 dtbo 分区进行了修补,请立即重新启动</string>
<string name="magisk_updates">Magisk 更新</string>
<string name="flashing">正在刷入</string>
<string name="hide_manager_toast">正在隐藏 Magisk Manager…</string>
<string name="hide_manager_toast2">这可能需要一点时间…</string>
<string name="hide_manager_fail_toast">隐藏 Magisk Manager 失败…</string>
<string name="download_zip_only">仅下载 Zip</string>
<string name="patch_boot_file">修补 Boot 镜像文件</string>
<string name="direct_install">直接安装(推荐)</string>
<string name="install_second_slot">安装到第二分区(安装完OTA后)</string>
<string name="select_method">选择安装方法</string>
<string name="no_boot_file_patch_support">目标安装版本不支持修补 Boot 镜像文件</string>
<string name="boot_file_patch_msg">选择原厂 Boot 镜像备份;支持 .img 以及 .img.tar 格式</string>
<string name="complete_uninstall">完全卸载</string>
<string name="restore_img">还原原厂镜像</string>
<string name="restore_img_msg">还原中…</string>
<string name="restore_done">还原完成!</string>
<string name="restore_fail">原厂 Boot 镜像备份不存在!</string>
<string name="proprietary_title">下载专有代码</string>
<string name="proprietary_notice">Magisk Manager 是一个 100% 开源的应用,因此不会包含 Google 专有的 SafetyNet API 代码。\n\n允许 Magisk Manager 下载一个扩展(包含 GoogleApiClient)用于 SafetyNet 检查吗?</string>
<string name="su_db_corrupt">SU 数据库已损坏,将重新创建数据库</string>
<string name="cannot_check_sn_title">无法检查 SafetyNet</string>
<string name="cannot_check_sn_notice">由于一些 Google Play 服务的改变,隐藏后的 Magisk Manager 无法进行 SafetyNet 检查。</string>
<string name="setup_done">安装完成</string>
<string name="setup_fail">安装失败</string>
<string name="env_fix_title">需要额外安装</string>
<string name="env_fix_msg">您的设备需要额外的安装才能使 Magisk 正常工作。 将下载 Magisk 安装包,是否继续?</string>
<string name="setup_title">额外安装</string>
<string name="setup_msg">运行环境安装中…</string>
<!--Settings Activity -->
<string name="settings_general_category">常规</string>
<string name="settings_dark_theme_title">暗色主题</string>
<string name="settings_dark_theme_summary">使用暗色主题</string>
<string name="settings_clear_cache_title">清除仓库缓存</string>
<string name="settings_clear_cache_summary">清除已缓存的在线仓库信息,强制刷新在线数据</string>
<string name="settings_hide_manager_title">隐藏 Magisk Manager</string>
<string name="settings_hide_manager_summary">用随机包名重新安装 Magisk Manager</string>
<string name="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_update">更新设定</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">请输入自定义网址</string>
<string name="settings_boot_format_title">已修补的 Boot 镜像输出格式</string>
<string name="settings_boot_format_summary">选择已修补的 Boot 镜像文件输出格式\n若要通过 fastboot/download 模式刷入,请选择 .img 格式;若要通过 Odin 刷入,则选择 .img.tar\n</string>
<string name="settings_core_only_title">Magisk 核心功能模式</string>
<string name="settings_core_only_summary">仅启用核心功能,所有模块将不会被载入。MagiskSU、MagiskHide 和 systemless hosts 仍会持续运作</string>
<string name="settings_magiskhide_summary">隐藏 Magisk 使其不被多种方法检测到</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">为广告屏蔽应用提供 Systemless hosts 支持</string>
<string name="settings_su_app_adb">应用和 ADB</string>
<string name="settings_su_app">仅应用</string>
<string name="settings_su_adb">仅 ADB</string>
<string name="settings_su_disable">已禁用</string>
<string name="settings_su_request_10">10 秒</string>
<string name="settings_su_request_20">20 秒</string>
<string name="settings_su_request_30">30 秒</string>
<string name="settings_su_request_60">60 秒</string>
<string name="superuser_access">超级用户访问权限</string>
<string name="auto_response">自动响应</string>
<string name="request_timeout">请求超时</string>
<string name="superuser_notification">超级用户通知</string>
<string name="request_timeout_summary">%1$s 秒</string>
<string name="settings_su_reauth_title">更新后重新认证</string>
<string name="settings_su_reauth_summary">应用更新后重新认证超级用户权限</string>
<string name="settings_su_fingerprint_title">启用指纹验证</string>
<string name="settings_su_fingerprint_summary">使用指纹识别来允许超级用户请求</string>
<string name="multiuser_mode">多用户模式</string>
<string name="settings_owner_only">仅设备所有者</string>
<string name="settings_owner_manage">由设备所有者管理</string>
<string name="settings_user_independent">各用户独立</string>
<string name="owner_only_summary">仅设备所有者账户有超级用户权限</string>
<string name="owner_manage_summary">仅设备所有者账户能管理超级用户并接收权限请求提示</string>
<string name="user_indepenent_summary">每个用户有独立的权限规则</string>
<string name="multiuser_hint_owner_request">已发送权限请求到设备所有者账户中。请切换到所有者账户授予权限</string>
<string name="mount_namespace_mode">挂载命名空间 模式</string>
<string name="settings_ns_global">全局命名空间</string>
<string name="settings_ns_requester">继承命名空间</string>
<string name="settings_ns_isolate">独立命名空间</string>
<string name="global_summary">所有的 ROOT 会话使用全局挂载命名空间</string>
<string name="requester_summary">ROOT 会话继承原程序的命名空间</string>
<string name="isolate_summary">每一个 ROOT 会话使用自己独立的命名空间</string>
<string name="android_o_not_support">不支持 Android 8.0+</string>
<string name="disable_fingerprint">没有设置指纹或设备不支持</string>
<!--Superuser-->
<string name="su_request_title">超级用户请求</string>
<string name="deny_with_str">拒绝 %1$s</string>
<string name="deny">拒绝</string>
<string name="prompt">提示</string>
<string name="grant">允许</string>
<string name="su_warning">将授予对该设备的最高权限。\n如果不确定,请拒绝!</string>
<string name="forever">永久</string>
<string name="once">一次</string>
<string name="tenmin">10 分钟</string>
<string name="twentymin">20 分钟</string>
<string name="thirtymin">30 分钟</string>
<string name="sixtymin">60 分钟</string>
<string name="su_allow_toast">%1$s 已被授予超级用户权限</string>
<string name="su_deny_toast">%1$s 已被拒绝超级用户权限</string>
<string name="no_apps_found">未找到应用</string>
<string name="su_snack_grant">已授予 %1$s 超级用户权限</string>
<string name="su_snack_deny">已拒绝 %1$s 超级用户权限</string>
<string name="su_snack_notif_on">已启用 %1$s 的通知</string>
<string name="su_snack_notif_off">已禁用 %1$s 的通知</string>
<string name="su_snack_log_on">已启用对 %1$s 的日志记录</string>
<string name="su_snack_log_off">已禁用对 %1$s 的日志记录</string>
<string name="su_snack_revoke">已撤销 %1$s 的权限</string>
<string name="su_revoke_title">撤销</string>
<string name="su_revoke_msg">确认撤销 %1$s 的权限?</string>
<string name="toast">消息提示</string>
<string name="none"></string>
<string name="auth_fail">验证失败</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">目标 UID:\u0020</string>
<string name="command">命令:\u0020</string>
</resources>
<resources>
<!--Universal-->
<!--Welcome Activity-->
<string name="modules">模組</string>
<string name="downloads">下載</string>
<string name="superuser">超級用戶</string>
<string name="log">日誌</string>
<string name="settings">設置</string>
<string name="install">安裝</string>
<!--Status Fragment-->
<string name="magisk_version_error">未安裝 Magisk</string>
<string name="checking_for_updates">正在檢查更新…</string>
<string name="magisk_update_available">Magisk 可更新到 v%1$s!</string>
<string name="safetyNet_check_text">點擊啟動 SafetyNet 檢查</string>
<string name="checking_safetyNet_status">正在檢查 SafetyNet 狀態…</string>
<!--Install Fragment-->
<string name="advanced_settings_title">高級設置</string>
<string name="keep_force_encryption">保持強制加密</string>
<string name="keep_dm_verity">保留 AVB 2.0/dm-verity</string>
<string name="current_magisk_title">已安裝版本:%1$s</string>
<string name="install_magisk_title">最新的版本:%1$s</string>
<string name="uninstall">解除安裝</string>
<!--Module Fragment-->
<string name="no_info_provided">(未提供資訊)</string>
<string name="no_modules_found">未找到模組</string>
<string name="update_file_created">模組將在下次重啟後更新</string>
<string name="remove_file_created">模組將在下次重啟後移除</string>
<string name="remove_file_deleted">模組將不會在下次重啟後移除</string>
<string name="disable_file_created">模組將在下次重啟後禁用</string>
<string name="disable_file_removed">模組將在下次重啟後啟用</string>
<string name="author">作者:%1$s</string>
<!--Repo Fragment-->
<string name="update_available">可更新</string>
<string name="installed">已安裝</string>
<string name="not_installed">未安裝</string>
<!--Log Fragment-->
<string name="menuSaveLog">保存日誌</string>
<string name="menuReload">重載</string>
<string name="menuClearLog">清除日誌</string>
<string name="logs_cleared">日誌已成功清除</string>
<string name="log_is_empty">日誌為空</string>
<!--About Activity-->
<string name="about">關於</string>
<string name="app_changelog">應用更新日誌</string>
<string name="translators">topjohnwu</string>
<string name="app_version">應用版本</string>
<string name="app_source_code">原始碼</string>
<string name="donation">捐贈</string>
<string name="app_translators">翻譯者</string>
<string name="support_thread">討論串</string>
<!--Toasts, Dialogs-->
<string name="repo_install_title">安裝 %1$s</string>
<string name="repo_install_msg">你想要安裝 %1$s 嗎?</string>
<string name="reboot">重啟</string>
<string name="zip_process_msg">正在處理 zip 文件 …</string>
<string name="magisk_update_title">Magisk 可更新!</string>
<string name="settings_reboot_toast">重啟以完成設定</string>
<string name="release_notes">發布說明</string>
<string name="repo_cache_cleared">資源庫暫存已清除</string>
<!--Settings Activity -->
<string name="settings_general_category">常規</string>
<string name="settings_dark_theme_title">深色主題</string>
<string name="settings_dark_theme_summary">使用深色主題</string>
<string name="settings_clear_cache_title">清除資源庫快取</string>
<string name="settings_clear_cache_summary">清除已暫存的在線資源庫快取,強制刷新在線數據</string>
<string name="settings_core_only_title">Magisk 核心功能模式</string>
<string name="settings_magiskhide_summary">隱藏 Magisk 使其不被多種方法檢測到</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">為廣告屏蔽應用提供 Systemless hosts 支持</string>
<string name="settings_su_app_adb">應用和 ADB</string>
<string name="settings_su_app">僅應用</string>
<string name="settings_su_adb">僅 ADB</string>
<string name="settings_su_disable">已禁用</string>
<string name="settings_su_request_10">10 秒</string>
<string name="settings_su_request_20">20 秒</string>
<string name="settings_su_request_30">30 秒</string>
<string name="settings_su_request_60">60 秒</string>
<string name="superuser_access">超級用戶訪問權限</string>
<string name="auto_response">自動回應</string>
<string name="request_timeout">請求逾時</string>
<string name="superuser_notification">超級用戶通知</string>
<string name="request_timeout_summary">%1$s 秒</string>
<!--Superuser-->
<string name="su_request_title">超級用戶請求</string>
<string name="deny_with_str">拒絕 %1$s</string>
<string name="deny">拒絕</string>
<string name="prompt">提示</string>
<string name="grant">允許</string>
<string name="su_warning">將授予對你設備的最高權限。\n如果你不確定,請拒絕!</string>
<string name="forever">永久</string>
<string name="once">一次</string>
<string name="tenmin">10 分鐘</string>
<string name="twentymin">20 分鐘</string>
<string name="thirtymin">30 分鐘</string>
<string name="sixtymin">60 分鐘</string>
<string name="su_allow_toast">%1$s 已被授予超級用戶權限</string>
<string name="su_deny_toast">%1$s 已被拒絕超級用戶權限</string>
<string name="no_apps_found">未找到應用</string>
<string name="su_snack_grant">已授予 %1$s 超級用戶權限</string>
<string name="su_snack_deny">已拒絕 %1$s 超級用戶權限</string>
<string name="su_snack_notif_on">已啟用 %1$s 的通知</string>
<string name="su_snack_notif_off">已禁用 %1$s 的通知</string>
<string name="su_snack_log_on">已啟用對 %1$s 的日誌記錄</string>
<string name="su_snack_log_off">已禁用對 %1$s 的日誌記錄</string>
<string name="su_snack_revoke">已撤銷 %1$s 的權限</string>
<string name="su_revoke_title">撤銷</string>
<string name="su_revoke_msg">確認撤銷 %1$s 的權限?</string>
<string name="toast">消息提示</string>
<string name="none"></string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">目標 UID:\u0020</string>
<string name="command">"指令: "</string>
<string name="close">關閉</string>
<string name="internal_storage">Zip 已被儲存到:\n[內部儲存空間]%1$s</string>
<string name="process_error">處理失敗</string>
<string name="download">下載</string>
<string name="zip_process_title">處理中</string>
<string name="uninstall_magisk_title">解除安裝 Magisk</string>
<string name="uninstall_magisk_msg">所有模組將會被停用 / 刪除。root會被移除,並有可能在目前資料未加密的情況下被加密</string>
<string name="settings_core_only_summary">僅啟用核心功能,所有模組將不會被載入。MagiskSU、MagiskHide 和 systemless hosts 仍會持續運作</string>
<string name="safetyNet_check_success">SafetyNet 檢查成功</string>
<string name="safetyNet_network_loss">網路斷線</string>
<string name="safetyNet_res_invalid">回傳值無效</string>
<string name="safetyNet_service_disconnected">服務已被取消</string>
<string name="multiuser_hint_owner_request">已發送權限請求到擁有者帳戶中。請切換到擁有者帳戶進行准許</string>
<string name="multiuser_mode">多使用者設定</string>
<string name="owner_manage_summary">僅裝置擁有者帳戶能管理超級用戶權限並接收權限請求通知</string>
<string name="owner_only_summary">僅裝置擁有者帳戶有超級用戶權限</string>
<string name="user_indepenent_summary">每一位使用者有獨立的權限規則</string>
<string name="settings_user_independent">各使用者獨立</string>
<string name="settings_owner_only">僅裝置擁有者</string>
<string name="settings_owner_manage">由裝置擁有者管理</string>
<string name="manager_download_install">點擊以下載並安裝</string>
<string name="manager_update_title">有 Magisk Manager 更新!</string>
<string name="settings_su_reauth_summary">應用程式更新後,重新認證root權限</string>
<string name="settings_su_reauth_title">更新後重新認證</string>
<string name="global_summary">所有 root 工作使用全域 mount namespace</string>
<string name="isolate_summary">每一 root 工作有自己獨立的 namespace</string>
<string name="mount_namespace_mode">掛載命名空間(Namespace)模式</string>
<string name="requester_summary">Root 工作繼承原程式之 namespace</string>
<string name="settings_ns_global">全域 Namespace</string>
<string name="settings_ns_isolate">獨立 Namespace</string>
<string name="settings_ns_requester">繼承 Namespace</string>
<string name="update">更新 %1$s</string>
<string name="magisk_updates">Magisk 更新</string>
<string name="system_default">(系統預設)</string>
<string name="language">語言</string>
<string name="flashing">正在刷入</string>
<string name="hide_manager_toast">正在隱藏 Magisk Manager…</string>
<string name="hide_manager_fail_toast">隱藏 Magisk Manager 失敗</string>
<string name="settings_hide_manager_title">隱藏 Magisk Manager</string>
<string name="settings_update_channel_title">更新頻道</string>
<string name="settings_update_stable">穩定版</string>
<string name="settings_update_beta">測試版</string>
<string name="download_zip_only">僅下載 Zip</string>
<string name="patch_boot_file">補丁 Boot 映像文件檔</string>
<string name="direct_install">直接安裝 (推薦)</string>
<string name="select_method">選擇安裝方法</string>
<string name="no_boot_file_patch_support">目標安裝版本不支援補丁 Boot 映像文件</string>
<string name="settings_update">更新設定</string>
<string name="settings_boot_format_title">已補丁 Boot 映像輸出格式</string>
<string name="zip_download_title">正在下載</string>
<string name="zip_download_msg">正在下載 Zip 文件 (%1$d%%) …</string>
<string name="settings_boot_format_summary">選擇已補丁 Boot 映像文件輸出格式\n若要透過 fastboot/download 模式刷入,請選擇 .img 格式;若要透過 ODIN 刷入,則選擇 .img.tar\n</string>
<string name="complete_uninstall">完全解除安裝</string>
<string name="restore_done">還原完成!</string>
<string name="restore_fail">原廠 boot 映像備份不存在!</string>
<string name="boot_file_patch_msg">選擇原廠 boot 映像備份;支援 .img 以及 .img.tar 格式</string>
<string name="install_second_slot">安裝到第二分區 (安裝完OTA後)</string>
<string name="safetyNet_api_error">SafetyNet API 錯誤</string>
<string name="proprietary_title">下載非開源程式</string>
<string name="proprietary_notice">Magisk Manager 是一個 100% 開源的程式,因此不會包含 Google 私有所有權的 SafetyNet API 程式碼。\n\n你允許 Magisk Manager 下載一個擴充包 (包含 GoogleApiClient) 以執行 SafetyNet 檢查嗎?</string>
<string name="dtbo_patched_title">DTBO 已被打上補丁!</string>
<string name="dtbo_patched_reboot">Magisk Manager 已為 dtbo.img 打上補丁,請立即重新啟動</string>
<string name="hide_manager_toast2">這可能會花上一段時間…</string>
<string name="settings_hide_manager_summary">將 Magisk Manager 以隨機套件名稱重新打包,以達成隱藏效果</string>
<string name="invalid_update_channel">不合法的更新頻道</string>
<string name="settings_update_custom">自訂</string>
<string name="settings_update_custom_msg">請輸入自訂網址</string>
<string name="su_db_corrupt">SU 資料庫已毀損,將會重新建置</string>
<string name="reboot_recovery">重啟到 Recovery</string>
<string name="reboot_bootloader">重啟到 Bootloader</string>
<string name="reboot_download">重啟到 Download</string>
<string name="android_o_not_support">不支援 Android 8.0+</string>
<string name="restore_img">還原原廠映像檔</string>
<string name="updated_on">更新於:%1$s</string>
<string name="sorting_order">排序方式</string>
<string name="sort_by_name">按名稱排序</string>
<string name="sort_by_update">按更新時間排序</string>
<string name="settings_su_fingerprint_title">啟用指紋認證</string>
<string name="settings_su_fingerprint_summary">用指紋辨識來允許超級用戶權限</string>
<string name="auth_fail">認證失敗</string>
<string name="settings_restore_manager_title">還原 Magisk Manager</string>
<string name="settings_restore_manager_summary">以原安裝包還原 Magisk Manager</string>
<string name="settings_check_update_title">檢查更新</string>
<string name="settings_check_update_summary">在背景定期檢查更新</string>
<string name="disable_fingerprint">沒有指紋加入或是裝置不支援</string>
<string name="cannot_check_sn_title">無法檢查 SafetyNet</string>
<string name="cannot_check_sn_notice">由於一些 Google Play Service 的改變,重新包裝過的 Magisk Manager 無法進行 SafetyNet 檢查。</string>
<string name="setup_done">安裝完成</string>
<string name="setup_fail">安裝失敗</string>
<string name="env_fix_title">需要額外的安裝</string>
<string name="env_fix_msg">您的設備需要额外的安装才能正常使用 Magisk。將下載 Magisk 安装包,是否繼續?</string>
<string name="setup_title">額外安裝</string>
<string name="setup_msg">安裝環境進行中…</string>
<string name="restore_img_msg">還原中…</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="allow_timeout">
<item>@string/forever</item>
<item>@string/once</item>
<item>@string/tenmin</item>
<item>@string/twentymin</item>
<item>@string/thirtymin</item>
<item>@string/sixtymin</item>
</string-array>
<string-array name="su_access">
<item>@string/settings_su_disable</item>
<item>@string/settings_su_app</item>
<item>@string/settings_su_adb</item>
<item>@string/settings_su_app_adb</item>
</string-array>
<string-array name="value_array">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="request_timeout">
<item>@string/settings_su_request_10</item>
<item>@string/settings_su_request_20</item>
<item>@string/settings_su_request_30</item>
<item>@string/settings_su_request_60</item>
</string-array>
<string-array name="request_timeout_value">
<item>10</item>
<item>20</item>
<item>30</item>
<item>60</item>
</string-array>
<string-array name="auto_response">
<item>@string/prompt</item>
<item>@string/deny</item>
<item>@string/grant</item>
</string-array>
<string-array name="su_notification">
<item>@string/none</item>
<item>@string/toast</item>
</string-array>
<string-array name="multiuser_mode">
<item>@string/settings_owner_only</item>
<item>@string/settings_owner_manage</item>
<item>@string/settings_user_independent</item>
</string-array>
<string-array name="multiuser_summary">
<item>@string/owner_only_summary</item>
<item>@string/owner_manage_summary</item>
<item>@string/user_indepenent_summary</item>
</string-array>
<string-array name="namespace">
<item>@string/settings_ns_global</item>
<item>@string/settings_ns_requester</item>
<item>@string/settings_ns_isolate</item>
</string-array>
<string-array name="namespace_summary">
<item>@string/global_summary</item>
<item>@string/requester_summary</item>
<item>@string/isolate_summary</item>
</string-array>
<string-array name="update_channel">
<item>@string/settings_update_stable</item>
<item>@string/settings_update_beta</item>
<item>@string/settings_update_custom</item>
</string-array>
<string-array name="boot_formats">
<item>.img</item>
<item>.img.tar</item>
</string-array>
<string-array name="sorting_orders">
<item>@string/sort_by_name</item>
<item>@string/sort_by_update</item>
</string-array>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2017 topjohnwu
~ Copyright 2017 dvdandroid
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<declare-styleable name="AboutCardRow">
<attr name="icon" format="reference"/>
<attr name="text" format="string"/>
<attr name="cardStyle" format="reference"/>
<attr name="navStyle" format="reference"/>
<attr name="ColorOK" format="reference"/>
<attr name="ColorWarn" format="reference"/>
<attr name="ColorFail" format="reference"/>
<attr name="ColorNeutral" format="reference"/>
</declare-styleable>
<attr name="colorAccentFallback" format="reference" />
<attr name="imageColorTint" format="reference" />
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">false</bool>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="floating_height">650dp</dimen>
<dimen name="floating_width">500dp</dimen>
<dimen name="card_divider_space">5sp</dimen>
<dimen name="card_horizontal_margin">8dip</dimen>
<dimen name="card_vertical_margin">3dip</dimen>
<dimen name="card_corner_radius">2dp</dimen>
<dimen name="card_elevation">2dp</dimen>
<dimen name="card_layout_padding">10dp</dimen>
<dimen name="card_textview_width">300dip</dimen>
<dimen name="checkbox_padding">3dp</dimen>
<dimen name="fab_padding">16dp</dimen>
</resources>
\ No newline at end of file
<resources>
<!--Welcome Activity-->
<string name="modules">Modules</string>
<string name="downloads">Downloads</string>
<string name="superuser">Superuser</string>
<string name="log">Log</string>
<string name="settings">Settings</string>
<string name="install">Install</string>
<!--Status Fragment-->
<string name="magisk_version_error">Magisk is not installed</string>
<string name="checking_for_updates">Checking for updates…</string>
<string name="magisk_update_available">Magisk v%1$s is available!</string>
<string name="invalid_update_channel">Invalid Update Channel</string>
<string name="safetyNet_check_text">Tap to start SafetyNet check</string>
<string name="checking_safetyNet_status">Checking SafetyNet status…</string>
<string name="safetyNet_check_success">SafetyNet Check Success</string>
<string name="safetyNet_api_error">SafetyNet API Error</string>
<string name="safetyNet_network_loss">Network connection unavailable</string>
<string name="safetyNet_service_disconnected">Service has been killed</string>
<string name="safetyNet_res_invalid">The response is invalid</string>
<!--Install Fragment-->
<string name="advanced_settings_title">Advanced Settings</string>
<string name="keep_force_encryption">Preserve force encryption</string>
<string name="keep_dm_verity">Preserve AVB 2.0/dm-verity</string>
<string name="current_magisk_title">Installed Version: %1$s</string>
<string name="install_magisk_title">Latest Version: %1$s</string>
<string name="uninstall">Uninstall</string>
<string name="uninstall_magisk_title">Uninstall Magisk</string>
<string name="uninstall_magisk_msg">All modules will be disabled/removed. Root will be removed, and potentially encrypt your data if your data is not currently encrypted</string>
<string name="update">Update %1$s</string>
<!--Module Fragment-->
<string name="no_info_provided">(No info provided)</string>
<string name="no_modules_found">No modules found</string>
<string name="update_file_created">Module will be updated at next reboot</string>
<string name="remove_file_created">Module will be removed at next reboot</string>
<string name="remove_file_deleted">Module will not be removed at next reboot</string>
<string name="disable_file_created">Module will be disabled at next reboot</string>
<string name="disable_file_removed">Module will be enabled at next reboot</string>
<string name="author">Created by %1$s</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>
<!--Repo Fragment-->
<string name="update_available">Update Available</string>
<string name="installed">Installed</string>
<string name="not_installed">Not Installed</string>
<string name="updated_on">Updated on: %1$s</string>
<string name="sorting_order">Sorting Order</string>
<string name="sort_by_name">Sort by name</string>
<string name="sort_by_update">Sort by last update</string>
<!--Log Fragment-->
<string name="menuSaveLog">Save log</string>
<string name="menuReload">Reload</string>
<string name="menuClearLog">Clear log now</string>
<string name="logs_cleared">Log successfully cleared</string>
<string name="log_is_empty">Log is empty</string>
<!--About Activity-->
<string name="about">About</string>
<string name="app_changelog">Changelog</string>
<string name="translators" />
<string name="app_version">Version</string>
<string name="app_source_code">Source code</string>
<string name="donation">Donation</string>
<string name="app_translators">Translators</string>
<string name="support_thread">Support thread</string>
<!--Toasts, Dialogs-->
<string name="close">Close</string>
<string name="repo_install_title">Install %1$s</string>
<string name="repo_install_msg">Do you want to install %1$s now?</string>
<string name="download">Download</string>
<string name="reboot">Reboot</string>
<string name="magisk_update_title">New Magisk Update Available!</string>
<string name="settings_reboot_toast">Reboot to apply settings</string>
<string name="release_notes">Release notes</string>
<string name="repo_cache_cleared">Repo cache cleared</string>
<string name="process_error">Process error</string>
<string name="internal_storage">The zip is stored in:\n[Internal Storage]%1$s</string>
<string name="zip_download_title">Downloading</string>
<string name="zip_download_msg">Downloading zip file (%1$d%%) …</string>
<string name="zip_process_title">Processing</string>
<string name="zip_process_msg">Processing zip file …</string>
<string name="manager_update_title">New Magisk Manager Update Available!</string>
<string name="manager_download_install">Press to download and install</string>
<string name="dtbo_patched_title">DTBO was patched!</string>
<string name="dtbo_patched_reboot">Magisk Manager has patched dtbo.img, please reboot</string>
<string name="magisk_updates">Magisk Updates</string>
<string name="flashing">Flashing</string>
<string name="hide_manager_toast">Hiding Magisk Manager…</string>
<string name="hide_manager_toast2">This might take a while…</string>
<string name="hide_manager_fail_toast">Hide Magisk Manager failed…</string>
<string name="download_zip_only">Download Zip Only</string>
<string name="patch_boot_file">Patch Boot Image File</string>
<string name="direct_install">Direct Install (Recommended)</string>
<string name="install_second_slot">Install to Second Slot (After OTA)</string>
<string name="select_method">Select Method</string>
<string name="no_boot_file_patch_support">Target Magisk version doesn\'t support boot image file patching</string>
<string name="boot_file_patch_msg">Select stock boot image dump in .img or .img.tar format</string>
<string name="complete_uninstall">Complete Uninstall</string>
<string name="restore_img">Restore Images</string>
<string name="restore_img_msg">Restoring…</string>
<string name="restore_done">Restoration done!</string>
<string name="restore_fail">Stock backup does not exist!</string>
<string name="proprietary_title">Download Proprietary Code</string>
<string name="proprietary_notice">Magisk Manager is FOSS, which doesn\'t contain Google\'s proprietary SafetyNet API code.\n\nDo you allow Magisk Manager to download an extension (contains GoogleApiClient) for SafetyNet checks?</string>
<string name="su_db_corrupt">SU database is corrupted, will recreate new db</string>
<string name="cannot_check_sn_title">Cannot check SafetyNet</string>
<string name="cannot_check_sn_notice">Due to some changes in Google Play Services, it is not possible to check SafetyNet on repackaged Magisk Manager</string>
<string name="setup_done">Setup done</string>
<string name="setup_fail">Setup failed</string>
<string name="env_fix_title">Requires Additional Setup</string>
<string name="env_fix_msg">Your device needs additional setup for Magisk to work properly. It will download the Magisk setup zip, do you want to proceed now?</string>
<string name="setup_title">Additional Setup</string>
<string name="setup_msg">Running environment setup…</string>
<!--Settings Activity -->
<string name="settings_general_category">General</string>
<string name="settings_dark_theme_title">Dark Theme</string>
<string name="settings_dark_theme_summary">Enable dark theme</string>
<string name="settings_clear_cache_title">Clear Repo Cache</string>
<string name="settings_clear_cache_summary">Clear the cached information for online repos, forces the app to refresh online</string>
<string name="settings_hide_manager_title">Hide Magisk Manager</string>
<string name="settings_hide_manager_summary">Repackage Magisk Manager with random package name</string>
<string name="settings_restore_manager_title">Restore Magisk Manager</string>
<string name="settings_restore_manager_summary">Restore Magisk Manager with original package</string>
<string name="language">Language</string>
<string name="system_default">(System Default)</string>
<string name="settings_update">Update Settings</string>
<string name="settings_check_update_title">Check Updates</string>
<string name="settings_check_update_summary">Check updates in the background periodically</string>
<string name="settings_update_channel_title">Update Channel</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Insert a custom URL</string>
<string name="settings_boot_format_title">Patched Boot Output Format</string>
<string name="settings_boot_format_summary">Select the format of the output patched boot image.\nChoose .img to flash through fastboot/download mode; choose .img.tar to flash with ODIN.</string>
<string name="settings_core_only_title">Magisk Core Only Mode</string>
<string name="settings_core_only_summary">Enable only core features. MagiskSU, MagiskHide and systemless hosts will still be enabled, but no modules will be loaded.</string>
<string name="settings_magiskhide_summary">Hide Magisk from various detections</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Systemless hosts support for Adblock apps</string>
<string name="settings_su_app_adb">Apps and ADB</string>
<string name="settings_su_app">Apps only</string>
<string name="settings_su_adb">ADB only</string>
<string name="settings_su_disable">Disabled</string>
<string name="settings_su_request_10">10 seconds</string>
<string name="settings_su_request_20">20 seconds</string>
<string name="settings_su_request_30">30 seconds</string>
<string name="settings_su_request_60">60 seconds</string>
<string name="superuser_access">Superuser Access</string>
<string name="auto_response">Automatic Response</string>
<string name="request_timeout">Request Timeout</string>
<string name="superuser_notification">Superuser Notification</string>
<string name="request_timeout_summary">%1$s seconds</string>
<string name="settings_su_reauth_title">Re-authenticate after upgrade</string>
<string name="settings_su_reauth_summary">Re-authenticate superuser permissions after an application upgrades</string>
<string name="settings_su_fingerprint_title">Enable Fingerprint Authentication</string>
<string name="settings_su_fingerprint_summary">Use fingerprint scanner to allow superuser requests</string>
<string name="multiuser_mode">Multiuser Mode</string>
<string name="settings_owner_only">Device Owner Only</string>
<string name="settings_owner_manage">Device Owner Managed</string>
<string name="settings_user_independent">User Independent</string>
<string name="owner_only_summary">Only owner has root access</string>
<string name="owner_manage_summary">Only owner can manage root access and receive request prompts</string>
<string name="user_indepenent_summary">Each user has its own separate root rules</string>
<string name="multiuser_hint_owner_request">A request has been sent to the device owner. Please switch to the owner and grant the permissions required</string>
<string name="mount_namespace_mode">Mount Namespace Mode</string>
<string name="settings_ns_global">Global Namespace</string>
<string name="settings_ns_requester">Inherit Namespace</string>
<string name="settings_ns_isolate">Isolated Namespace</string>
<string name="global_summary">All root sessions use the global mount namespace</string>
<string name="requester_summary">Root sessions will inherit its requester\'s namespace</string>
<string name="isolate_summary">Each root session will have its own isolated namespace</string>
<string name="android_o_not_support">Does not support Android 8.0+</string>
<string name="disable_fingerprint">No fingerprints were set or no device support</string>
<!--Superuser-->
<string name="su_request_title">Superuser Request</string>
<string name="deny_with_str">Deny%1$s</string>
<string name="deny">Deny</string>
<string name="prompt">Prompt</string>
<string name="grant">Grant</string>
<string name="su_warning">Grants full access to your device.\nDeny if you\'re not sure!</string>
<string name="forever">Forever</string>
<string name="once">Once</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 was granted Superuser rights</string>
<string name="su_deny_toast">%1$s was denied Superuser rights</string>
<string name="no_apps_found">No apps found</string>
<string name="su_snack_grant">Superuser rights of %1$s are granted</string>
<string name="su_snack_deny">Superuser rights of %1$s are denied</string>
<string name="su_snack_notif_on">Notifications of %1$s are enabled</string>
<string name="su_snack_notif_off">Notifications of %1$s are disabled</string>
<string name="su_snack_log_on">Logging of %1$s is enabled</string>
<string name="su_snack_log_off">Logging of %1$s is disabled</string>
<string name="su_snack_revoke">%1$s rights are revoked</string>
<string name="su_revoke_title">Revoke?</string>
<string name="su_revoke_msg">Confirm to revoke %1$s rights?</string>
<string name="toast">Toast</string>
<string name="none">None</string>
<string name="auth_fail">Authentication Failed</string>
<!--Superuser logs-->
<string name="pid">PID:\u0020</string>
<string name="target_uid">Target UID:\u0020</string>
<string name="command">Command:\u0020</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="colorAccentFallback">@color/accentFallback</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="cardStyle">@style/CardViewStyle.Light</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="imageColorTint">@android:color/secondary_text_light</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat.NoActionBar">
<item name="colorAccent">@color/accent</item>
<item name="colorAccentFallback">@color/accentFallback</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="cardStyle">@style/CardViewStyle.Dark</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:textColorSecondary">@color/dark_secondary_text</item>
<item name="imageColorTint">@color/dark_secondary_text</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="AppTheme.Translucent" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
</style>
<style name="CardViewStyle.Dark" parent="CardView">
<item name="cardBackgroundColor">@android:color/background_dark</item>
</style>
<style name="CardViewStyle.Light" parent="CardView">
<item name="cardBackgroundColor">@android:color/background_light</item>
</style>
<style name="AppTheme.StatusBar" parent="AppTheme">
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
</style>
<style name="AppTheme.StatusBar.Dark" parent="AppTheme.Dark">
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
</style>
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/ic_splash_activity</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="SuRequest" parent="Theme.AppCompat.Light.Dialog">
<item name="android:windowCloseOnTouchOutside">false</item>
<item name="colorBackgroundFloating">@color/su_request_background</item>
</style>
<style name="SuRequest.Dark" parent="Theme.AppCompat.Dialog">
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
</resources>
<PreferenceScreen
android:layout_marginTop="?attr/actionBarSize"
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="general"
android:title="@string/settings_general_category">
<SwitchPreference
android:key="dark_theme"
android:title="@string/settings_dark_theme_title"
android:summary="@string/settings_dark_theme_summary" />
<ListPreference
android:key="locale"
android:title="@string/language"/>
<Preference
android:key="clear"
android:title="@string/settings_clear_cache_title"
android:summary="@string/settings_clear_cache_summary" />
<Preference
android:key="hide"
android:title="@string/settings_hide_manager_title"
android:summary="@string/settings_hide_manager_summary" />
<Preference
android:key="restore"
android:summary="@string/settings_restore_manager_summary"
android:title="@string/settings_restore_manager_title" />
</PreferenceCategory>
<PreferenceCategory
android:key="update"
android:title="@string/settings_update">
<SwitchPreference
android:key="check_update"
android:defaultValue="true"
android:title="@string/settings_check_update_title"
android:summary="@string/settings_check_update_summary" />
<ListPreference
android:key="update_channel"
android:title="@string/settings_update_channel_title"
android:entries="@array/update_channel"
android:entryValues="@array/value_array" />
<ListPreference
android:key="boot_format"
android:title="@string/settings_boot_format_title"
android:entries="@array/boot_formats"
android:entryValues="@array/boot_formats"
android:summary="@string/settings_boot_format_summary"/>
</PreferenceCategory>
<PreferenceCategory
android:key="magisk"
android:title="@string/magisk">
<CheckBoxPreference
android:key="disable"
android:title="@string/settings_core_only_title"
android:summary="@string/settings_core_only_summary" />
<SwitchPreference
android:key="magiskhide"
android:title="@string/magiskhide"
android:summary="@string/settings_magiskhide_summary" />
<SwitchPreference
android:key="hosts"
android:title="@string/settings_hosts_title"
android:summary="@string/settings_hosts_summary" />
</PreferenceCategory>
<PreferenceCategory
android:key="superuser"
android:title="@string/superuser">
<ListPreference
android:key="root_access"
android:title="@string/superuser_access"
android:entries="@array/su_access"
android:entryValues="@array/value_array" />
<ListPreference
android:key="multiuser_mode"
android:title="@string/multiuser_mode"
android:entries="@array/multiuser_mode"
android:entryValues="@array/value_array" />
<ListPreference
android:key="mnt_ns"
android:title="@string/mount_namespace_mode"
android:entries="@array/namespace"
android:entryValues="@array/value_array" />
<ListPreference
android:key="su_auto_response"
android:title="@string/auto_response"
android:entries="@array/auto_response"
android:entryValues="@array/value_array" />
<ListPreference
android:key="su_request_timeout"
android:title="@string/request_timeout"
android:entries="@array/request_timeout"
android:entryValues="@array/request_timeout_value" />
<ListPreference
android:key="su_notification"
android:title="@string/superuser_notification"
android:entries="@array/su_notification"
android:entryValues="@array/value_array" />
<SwitchPreference
android:key="su_fingerprint"
android:title="@string/settings_su_fingerprint_title"
android:summary="@string/settings_su_fingerprint_summary"/>
<SwitchPreference
android:key="su_reauth"
android:title="@string/settings_su_reauth_title"
android:summary="@string/settings_su_reauth_summary"/>
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.topjohnwu.magisk">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:name=".MagiskManager"
android:allowBackup="false"
android:directBootAware="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
tools:ignore="UnusedAttribute">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.topjohnwu.magisk.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
\ No newline at end of file
package com.topjohnwu.magisk.components;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;
import com.topjohnwu.magisk.NoUIActivity;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Const;
public abstract class Activity extends FlavorActivity {
protected static Runnable permissionGrantCallback;
private ActivityResultListener activityResultListener;
public Activity() {
super();
Configuration configuration = new Configuration();
configuration.setLocale(Application.locale);
applyOverrideConfiguration(configuration);
}
public static void runWithPermission(Context context, String[] permissions, Runnable callback) {
boolean granted = true;
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(context, perm) != PackageManager.PERMISSION_GRANTED)
granted = false;
}
if (granted) {
callback.run();
} else {
// Passed in context should be an activity if not granted, need to show dialog!
permissionGrantCallback = callback;
if (!(context instanceof Activity)) {
// Start activity to show dialog
Intent intent = new Intent(context, NoUIActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Const.Key.INTENT_PERM, permissions);
context.startActivity(intent);
} else {
ActivityCompat.requestPermissions((Activity) context, permissions, 0);
}
}
}
public void runWithPermission(String[] permissions, Runnable callback) {
runWithPermission(this, permissions, callback);
}
@Override
public Application getApplicationContext() {
return (Application) super.getApplicationContext();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean grant = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED)
grant = false;
}
if (grant) {
if (permissionGrantCallback != null) {
permissionGrantCallback.run();
}
} else {
Application.toast(R.string.no_rw_storage, Toast.LENGTH_LONG);
}
permissionGrantCallback = null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (activityResultListener != null)
activityResultListener.onActivityResult(requestCode, resultCode, data);
activityResultListener = null;
}
public void startActivityForResult(Intent intent, int requestCode, ActivityResultListener listener) {
activityResultListener = listener;
super.startActivityForResult(intent, requestCode);
}
public interface ActivityResultListener {
void onActivityResult(int requestCode, int resultCode, Intent data);
}
}
package com.topjohnwu.magisk.components;
import android.os.Handler;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.Locale;
public abstract class Application extends android.app.Application {
public static WeakReference<Application> weakSelf;
public static Locale locale;
public static Locale defaultLocale;
private static Handler mHandler = new Handler();
public Application() {
weakSelf = new WeakReference<>(this);
}
@Override
public void onCreate() {
super.onCreate();
locale = defaultLocale = Locale.getDefault();
}
public static void toast(CharSequence msg, int duration) {
mHandler.post(() -> Toast.makeText(weakSelf.get(), msg, duration).show());
}
public static void toast(int resId, int duration) {
mHandler.post(() -> Toast.makeText(weakSelf.get(), resId, duration).show());
}
}
package com.topjohnwu.magisk.receivers;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils;
import java.io.File;
public abstract class DownloadReceiver extends BroadcastReceiver {
protected File mFile;
private long downloadID;
@Override
public void onReceive(Context context, Intent intent) {
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadID);
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = c.getInt(columnIndex);
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
Uri uri = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
onDownloadDone(context, uri);
break;
default:
MagiskManager.toast(R.string.download_file_error, Toast.LENGTH_LONG);
break;
}
context.unregisterReceiver(this);
}
c.close();
}
Utils.isDownloading = false;
}
public DownloadReceiver setDownloadID(long id) {
downloadID = id;
return this;
}
public DownloadReceiver setFile(File file) {
mFile = file;
return this;
}
public abstract void onDownloadDone(Context context, Uri uri);
}
package com.topjohnwu.magisk.receivers;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import java.io.File;
public class ManagerInstall extends DownloadReceiver {
@Override
public void onDownloadDone(Context context, Uri uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri content = FileProvider.getUriForFile(context,
context.getPackageName() + ".provider", new File(uri.getPath()));
install.setData(content);
context.startActivity(install);
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(uri, "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
}
}
}
package com.topjohnwu.magisk.utils;
import android.os.Environment;
import android.os.Process;
import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.MagiskManager;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class Const {
public static final String DEBUG_TAG = "MagiskManager";
public static final String ORIG_PKG_NAME = BuildConfig.APPLICATION_ID;
public static final String MAGISKHIDE_PROP = "persist.magisk.hide";
// APK content
public static final String ANDROID_MANIFEST = "AndroidManifest.xml";
public static final String SU_KEYSTORE_KEY = "su_key";
// Paths
public static File MAGISK_PATH;
public static File MAGISK_DISABLE_FILE;
public static File MAGISK_HOST_FILE;
static {
/* Prevent crashing on unrooted devices */
MAGISK_PATH = MAGISK_DISABLE_FILE = MAGISK_HOST_FILE = new File("xxx");
}
public static final String BUSYBOX_PATH = "/sbin/.core/busybox";
public static final String TMP_FOLDER_PATH = "/dev/tmp";
public static final String MAGISK_LOG = "/cache/magisk.log";
public static final File EXTERNAL_PATH = new File(Environment.getExternalStorageDirectory(), "MagiskManager");
public static final String MANAGER_CONFIGS = ".tmp.magisk.config";
// Versions
public static final int UPDATE_SERVICE_VER = 1;
public static final int SNET_VER = 8;
public static int MIN_MODULE_VER() {
return MagiskManager.get().magiskVersionCode >= MAGISK_VER.REMOVE_LEGACY_LINK ? 1500 : 1400;
}
/* A list of apps that should not be shown as hide-able */
public static final List<String> HIDE_BLACKLIST = Arrays.asList(
"android",
MagiskManager.get().getPackageName(),
"com.google.android.gms"
);
public static final int USER_ID = Process.myUid() / 100000;
public static final class MAGISK_VER {
public static final int UNIFIED = 1300;
public static final int FBE_AWARE = 1410;
public static final int RESETPROP_PERSIST = 1436;
public static final int MANAGER_HIDE = 1440;
public static final int DTBO_SUPPORT = 1446;
public static final int HIDDEN_PATH = 1460;
public static final int REMOVE_LEGACY_LINK = 1630;
public static final int SEPOL_REFACTOR = 1640;
public static final int FIX_ENV = 1650;
}
public static class ID {
public static final int UPDATE_SERVICE_ID = 1;
public static final int FETCH_ZIP = 2;
public static final int SELECT_BOOT = 3;
// notifications
public static final int MAGISK_UPDATE_NOTIFICATION_ID = 4;
public static final int APK_UPDATE_NOTIFICATION_ID = 5;
public static final int ONBOOT_NOTIFICATION_ID = 6;
public static final int DTBO_NOTIFICATION_ID = 7;
public static final String NOTIFICATION_CHANNEL = "magisk_notification";
}
public static class Url {
public static final String STABLE_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/stable.json";
public static final String BETA_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/beta.json";
public static final String SNET_URL = "https://github.com/topjohnwu/MagiskManager/raw/788f01f499714471949613820d43bc364786e85d/snet.apk";
public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d";
public static final String FILE_URL = "https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s";
public static final String ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip";
public static final String DONATION_URL = "https://www.paypal.me/topjohnwu";
public static final String XDA_THREAD = "http://forum.xda-developers.com/showthread.php?t=3432382";
public static final String SOURCE_CODE_URL = "https://github.com/topjohnwu/MagiskManager";
}
public static class Key {
// su
public static final String ROOT_ACCESS = "root_access";
public static final String SU_MULTIUSER_MODE = "multiuser_mode";
public static final String SU_MNT_NS = "mnt_ns";
public static final String SU_MANAGER = "requester";
public static final String SU_REQUEST_TIMEOUT = "su_request_timeout";
public static final String SU_AUTO_RESPONSE = "su_auto_response";
public static final String SU_NOTIFICATION = "su_notification";
public static final String SU_REAUTH = "su_reauth";
public static final String SU_FINGERPRINT = "su_fingerprint";
// intents
public static final String OPEN_SECTION = "section";
public static final String INTENT_SET_FILENAME = "filename";
public static final String INTENT_SET_LINK = "link";
public static final String INTENT_PERM = "perm_dialog";
public static final String FLASH_ACTION = "action";
public static final String FLASH_SET_BOOT = "boot";
// others
public static final String CHECK_UPDATES = "check_update";
public static final String UPDATE_CHANNEL = "update_channel";
public static final String CUSTOM_CHANNEL = "custom_channel";
public static final String BOOT_FORMAT = "boot_format";
public static final String UPDATE_SERVICE_VER = "update_service_version";
public static final String APP_VER = "app_version";
public static final String MAGISKHIDE = "magiskhide";
public static final String HOSTS = "hosts";
public static final String COREONLY = "disable";
public static final String LOCALE = "locale";
public static final String DARK_THEME = "dark_theme";
public static final String ETAG_KEY = "ETag";
public static final String LINK_KEY = "Link";
public static final String IF_NONE_MATCH = "If-None-Match";
public static final String REPO_ORDER = "repo_order";
}
public static class Value {
public static final int STABLE_CHANNEL = 0;
public static final int BETA_CHANNEL = 1;
public static final int CUSTOM_CHANNEL = 2;
public static final int ROOT_ACCESS_DISABLED = 0;
public static final int ROOT_ACCESS_APPS_ONLY = 1;
public static final int ROOT_ACCESS_ADB_ONLY = 2;
public static final int ROOT_ACCESS_APPS_AND_ADB = 3;
public static final int MULTIUSER_MODE_OWNER_ONLY = 0;
public static final int MULTIUSER_MODE_OWNER_MANAGED = 1;
public static final int MULTIUSER_MODE_USER = 2;
public static final int NAMESPACE_MODE_GLOBAL = 0;
public static final int NAMESPACE_MODE_REQUESTER = 1;
public static final int NAMESPACE_MODE_ISOLATE = 2;
public static final int NO_NOTIFICATION = 0;
public static final int NOTIFICATION_TOAST = 1;
public static final int NOTIFY_NORMAL_LOG = 0;
public static final int NOTIFY_USER_TOASTS = 1;
public static final int NOTIFY_USER_TO_OWNER = 2;
public static final int SU_PROMPT = 0;
public static final int SU_AUTO_DENY = 1;
public static final int SU_AUTO_ALLOW = 2;
public static final String FLASH_ZIP = "flash";
public static final String PATCH_BOOT = "patch";
public static final String FLASH_MAGISK = "magisk";
public static final String FLASH_SECOND_SLOT = "slot";
public static final String UNINSTALL = "uninstall";
public static final int[] timeoutList = {0, -1, 10, 20, 30, 60};
public static final int ORDER_NAME = 0;
public static final int ORDER_DATE = 1;
}
}
package com.topjohnwu.magisk.utils;
import android.Manifest;
import android.app.DownloadManager;
import android.content.Context;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.support.annotation.StringRes;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
public class Utils {
public static boolean isDownloading = false;
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
if (isDownloading)
return;
Activity.runWithPermission(context,
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
File file = new File(Const.EXTERNAL_PATH, getLegalFilename(filename));
if ((!file.getParentFile().exists() && !file.getParentFile().mkdirs())
|| (file.exists() && !file.delete())) {
return;
}
MagiskManager.toast(context.getString(R.string.downloading_toast, filename), Toast.LENGTH_LONG);
isDownloading = true;
DownloadManager.Request request = new DownloadManager
.Request(Uri.parse(link))
.setDestinationUri(Uri.fromFile(file));
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
receiver.setDownloadID(dm.enqueue(request)).setFile(file);
context.getApplicationContext().registerReceiver(receiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
});
}
public static String getLegalFilename(CharSequence filename) {
return filename.toString().replace(" ", "_").replace("'", "").replace("\"", "")
.replace("$", "").replace("`", "").replace("*", "").replace("/", "_")
.replace("#", "").replace("@", "").replace("\\", "_");
}
public static int getPrefsInt(SharedPreferences prefs, String key, int def) {
return Integer.parseInt(prefs.getString(key, String.valueOf(def)));
}
public static int getPrefsInt(SharedPreferences prefs, String key) {
return getPrefsInt(prefs, key, 0);
}
public static MagiskManager getMagiskManager(Context context) {
return (MagiskManager) context.getApplicationContext();
}
public static String getNameFromUri(Context context, Uri uri) {
String name = null;
try (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) {
if (c != null) {
int nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (nameIndex != -1) {
c.moveToFirst();
name = c.getString(nameIndex);
}
}
}
if (name == null) {
int idx = uri.getPath().lastIndexOf('/');
name = uri.getPath().substring(idx + 1);
}
return name;
}
public static boolean checkNetworkStatus() {
ConnectivityManager manager = (ConnectivityManager)
MagiskManager.get().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
public static String getLocaleString(Locale locale, @StringRes int id) {
Context context = MagiskManager.get();
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
Context localizedContext = context.createConfigurationContext(config);
return localizedContext.getString(id);
}
public static List<Locale> getAvailableLocale() {
List<Locale> locales = new ArrayList<>();
HashSet<String> set = new HashSet<>();
Locale locale;
@StringRes int compareId = R.string.download_file_error;
// Add default locale
locales.add(Locale.ENGLISH);
set.add(getLocaleString(Locale.ENGLISH, compareId));
// Add some special locales
locales.add(Locale.TAIWAN);
set.add(getLocaleString(Locale.TAIWAN, compareId));
locale = new Locale("pt", "BR");
locales.add(locale);
set.add(getLocaleString(locale, compareId));
// Other locales
for (String s : MagiskManager.get().getAssets().getLocales()) {
locale = Locale.forLanguageTag(s);
if (set.add(getLocaleString(locale, compareId))) {
locales.add(locale);
}
}
Collections.sort(locales, (l1, l2) -> l1.getDisplayName(l1).compareTo(l2.getDisplayName(l2)));
return locales;
}
public static int dpInPx(int dp) {
Context context = MagiskManager.get();
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5);
}
public static String fmt(String fmt, Object... args) {
return String.format(Locale.US, fmt, args);
}
public static String dos2unix(String s) {
String newString = s.replace("\r\n", "\n");
if(!newString.endsWith("\n")) {
return newString + "\n";
} else {
return newString;
}
}
}
\ No newline at end of file
package com.topjohnwu.magisk.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class WebService {
public static String getString(String url) {
return getString(url, null);
}
public static String getString(String url, Map<String, String> header) {
try {
HttpURLConnection conn = request(url, header);
return getString(conn);
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
public static String getString(HttpURLConnection conn) {
try {
StringBuilder builder = new StringBuilder();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
int len;
char buf[] = new char[4096];
while ((len = br.read(buf)) != -1) {
builder.append(buf, 0, len);
}
}
}
conn.disconnect();
return builder.toString();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
public static HttpURLConnection request(String address, Map<String, String> header) throws IOException {
URL url = new URL(address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
if (header != null) {
for (Map.Entry<String, String> entry : header.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
conn.connect();
if (header != null) {
header.clear();
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
List<String> l = entry.getValue();
header.put(entry.getKey(), l.get(l.size() - 1));
}
}
return conn;
}
}
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_magisk_padded" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/ic_launcher_background"/>
</shape>
</item>
<item android:drawable="@drawable/ic_magisk" />
</layer-list>
\ No newline at end of file
<vector android:height="48dp" android:viewportHeight="720"
android:viewportWidth="720" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#303030" android:pathData="M332.48,421.18c0,0 3.77,22.45 -0.82,71.95c-5.76,62.06 23.64,160.64 23.64,160.64c0,0 40.1,-98.78 33.1,-162.59c-5.75,-52.45 2.6,-70.79 0.82,-68.33c-30.81,42.57 -56.75,-1.67 -56.75,-1.67z"/>
<path android:fillColor="#ffffff" android:pathData="M407.6,474.45c5.01,38.77 -0.57,60.01 -7.81,101.51c-3.66,20.99 74.78,-63.1 104.86,-113.23c5.02,-8.36 -28.77,32.6 -62.19,3.35c-23.18,-20.28 -27.16,-26.44 -45.18,-44.06c-6.08,-5.94 6.74,24.72 10.32,52.43z"/>
<path android:fillColor="#ffffff" android:pathData="M321.99,425.09c-18.02,17.62 -22,23.78 -45.18,44.06c-33.42,29.25 -67.21,-11.71 -62.19,-3.35c30.08,50.13 108.52,134.22 104.86,113.23c-7.24,-41.5 -12.82,-62.74 -7.81,-101.51c3.58,-27.71 16.4,-58.37 10.32,-52.43z"/>
<path android:fillColor="#303030" android:pathData="M399.15,355.87c36.67,10.57 50.89,61.5 87.91,67.8c7.65,1.3 16.27,3.6 26.31,3.12c18.77,-0.9 42.51,-11.51 74.22,-56.5c9.38,-13.3 -23.27,85.66 -105.13,86.86c-59.96,0.88 -66.97,-58.7 -106.93,-60.51c-14.43,-0.65 -15.34,-28.17 -15.34,-28.17c0,0 17.22,-18.86 38.96,-12.6z"/>
<path android:fillColor="#303030" android:pathData="M321.51,355.59c-36.67,10.57 -50.89,61.5 -87.91,67.8c-7.65,1.3 -16.27,3.6 -26.31,3.12c-18.77,-0.9 -42.51,-11.51 -74.22,-56.5c-9.38,-13.3 23.27,85.66 105.13,86.86c59.96,0.88 66.97,-58.7 106.93,-60.51c14.43,-0.65 15.34,-28.17 15.34,-28.17c0,0 -17.22,-18.86 -38.96,-12.6z"/>
<path android:fillColor="#fbbcc9" android:pathData="M458.64,355.09c36.87,27.94 25.88,58.7 46.57,49.92c69.7,-29.55 57.51,-181.21 51.87,-162.87c-31.77,103.41 -100.99,109.2 -167.61,61.63c-13.01,-9.29 48.38,35.57 69.16,51.31z"/>
<path android:fillColor="#fbbcc9" android:pathData="M330.91,303.77c-66.62,47.56 -135.84,41.78 -167.61,-61.63c-5.63,-18.34 -17.82,133.31 51.87,162.87c20.7,8.78 9.7,-21.98 46.57,-49.92c20.78,-15.75 82.17,-60.6 69.16,-51.31z"/>
<path android:fillColor="#3747a9" android:pathData="M465.61,318c80.43,-3.32 95.29,-135.17 88.96,-119.08c-28.39,72.22 -135.86,45.05 -146.13,90.64c-2.02,8.94 18.2,30.06 57.17,28.45z"/>
<path android:fillColor="#3747a9" android:pathData="M311.95,289.55c-10.27,-45.59 -117.75,-18.41 -146.13,-90.64c-6.32,-16.09 8.53,115.76 88.96,119.08c38.97,1.61 59.19,-19.5 57.17,-28.45z"/>
<path android:fillColor="#ff6e40" android:pathData="M403.42,269.47c0,0 43.73,-23.5 81.16,-33.74c34.99,-9.58 61.22,-33.13 64.14,-58.01c2.18,-18.53 -27.05,-53.55 -27.05,-53.55c0,0 -20.51,56.9 -47.41,85.34c-29.28,30.96 -18.15,26.78 -70.84,59.96z"/>
<path android:fillColor="#ff6e40" android:pathData="M246.13,209.51c-26.9,-28.44 -47.41,-85.34 -47.41,-85.34c0,0 -29.23,35.01 -27.05,53.55c2.93,24.88 29.16,48.43 64.14,58.01c37.43,10.25 81.16,33.74 81.16,33.74c-52.69,-33.18 -41.55,-29 -70.84,-59.96z"/>
<path android:fillColor="#ffffff" android:pathData="M398.12,265.85c47.36,-38.85 72.53,-89.54 113.51,-145.02c7.73,-10.46 -34.58,-35.7 -51.31,-37.37c-16.73,-1.67 -30.77,59.79 -32.35,95.94c-1.44,33.01 -36.21,91.68 -29.84,86.45z"/>
<path android:fillColor="#ffffff" android:pathData="M292.42,179.39c-1.58,-36.15 -15.62,-97.61 -32.35,-95.94c-16.73,1.67 -59.04,26.91 -51.31,37.37c40.98,55.48 66.14,106.17 113.51,145.02c6.37,5.22 -28.4,-53.45 -29.84,-86.45z"/>
<path android:fillColor="#ffb327" android:pathData="M402.86,140.35c3.34,-26.76 15.37,-46.32 39.32,-62.75c-21.17,-7.08 -38.77,-12.83 -47.97,-5.3c-9.2,7.53 -34.2,32.7 -30.85,73.68c3.34,40.98 0.18,194.09 7.43,191.25c3.9,-104.87 37.09,-135 32.07,-196.89z"/>
<path android:fillColor="#ffb327" android:pathData="M349.59,337.24c7.24,2.83 4.08,-150.27 7.43,-191.25c3.34,-40.98 -21.65,-66.16 -30.85,-73.68c-9.2,-7.53 -26.8,-1.78 -47.97,5.3c23.95,16.43 35.98,35.98 39.32,62.75c-5.02,61.89 28.17,92.02 32.07,196.89z"/>
</vector>
<vector android:height="108dp" android:viewportHeight="1080"
android:viewportWidth="1080" android:width="108dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#303030" android:pathData="M512.48,601.18c0,0 3.77,22.45 -0.82,71.95c-5.76,62.06 23.64,160.64 23.64,160.64c0,0 40.1,-98.78 33.1,-162.59c-5.75,-52.45 2.6,-70.79 0.82,-68.33c-30.81,42.57 -56.75,-1.67 -56.75,-1.67z"/>
<path android:fillColor="#ffffff" android:pathData="M587.6,654.45c5.01,38.77 -0.57,60.01 -7.81,101.51c-3.66,20.99 74.78,-63.1 104.86,-113.23c5.02,-8.36 -28.77,32.6 -62.19,3.35c-23.18,-20.28 -27.16,-26.44 -45.18,-44.06c-6.08,-5.94 6.74,24.72 10.32,52.43z"/>
<path android:fillColor="#ffffff" android:pathData="M501.99,605.09c-18.02,17.62 -22,23.78 -45.18,44.06c-33.42,29.25 -67.21,-11.71 -62.19,-3.35c30.08,50.13 108.52,134.22 104.86,113.23c-7.24,-41.5 -12.82,-62.74 -7.81,-101.51c3.58,-27.71 16.4,-58.37 10.32,-52.43z"/>
<path android:fillColor="#303030" android:pathData="M579.15,535.87c36.67,10.57 50.89,61.5 87.91,67.8c7.65,1.3 16.27,3.6 26.31,3.12c18.77,-0.9 42.51,-11.51 74.22,-56.5c9.38,-13.3 -23.27,85.66 -105.13,86.86c-59.96,0.88 -66.97,-58.7 -106.93,-60.51c-14.43,-0.65 -15.34,-28.17 -15.34,-28.17c0,0 17.22,-18.86 38.96,-12.6z"/>
<path android:fillColor="#303030" android:pathData="M501.51,535.59c-36.67,10.57 -50.89,61.5 -87.91,67.8c-7.65,1.3 -16.27,3.6 -26.31,3.12c-18.77,-0.9 -42.51,-11.51 -74.22,-56.5c-9.38,-13.3 23.27,85.66 105.13,86.86c59.96,0.88 66.97,-58.7 106.93,-60.51c14.43,-0.65 15.34,-28.17 15.34,-28.17c0,0 -17.22,-18.86 -38.96,-12.6z"/>
<path android:fillColor="#fbbcc9" android:pathData="M638.64,535.09c36.87,27.94 25.88,58.7 46.57,49.92c69.7,-29.55 57.51,-181.21 51.87,-162.87c-31.77,103.41 -100.99,109.2 -167.61,61.63c-13.01,-9.29 48.38,35.57 69.16,51.31z"/>
<path android:fillColor="#fbbcc9" android:pathData="M510.91,483.77c-66.62,47.56 -135.84,41.78 -167.61,-61.63c-5.63,-18.34 -17.82,133.31 51.87,162.87c20.7,8.78 9.7,-21.98 46.57,-49.92c20.78,-15.75 82.17,-60.6 69.16,-51.31z"/>
<path android:fillColor="#3747a9" android:pathData="M645.61,498c80.43,-3.32 95.29,-135.17 88.96,-119.08c-28.39,72.22 -135.86,45.05 -146.13,90.64c-2.02,8.94 18.2,30.06 57.17,28.45z"/>
<path android:fillColor="#3747a9" android:pathData="M491.95,469.55c-10.27,-45.59 -117.75,-18.41 -146.13,-90.64c-6.32,-16.09 8.53,115.76 88.96,119.08c38.97,1.61 59.19,-19.5 57.17,-28.45z"/>
<path android:fillColor="#ff6e40" android:pathData="M583.42,449.47c0,0 43.73,-23.5 81.16,-33.74c34.99,-9.58 61.22,-33.13 64.14,-58.01c2.18,-18.53 -27.05,-53.55 -27.05,-53.55c0,0 -20.51,56.9 -47.41,85.34c-29.28,30.96 -18.15,26.78 -70.84,59.96z"/>
<path android:fillColor="#ff6e40" android:pathData="M426.13,389.51c-26.9,-28.44 -47.41,-85.34 -47.41,-85.34c0,0 -29.23,35.01 -27.05,53.55c2.93,24.88 29.16,48.43 64.14,58.01c37.43,10.25 81.16,33.74 81.16,33.74c-52.69,-33.18 -41.55,-29 -70.84,-59.96z"/>
<path android:fillColor="#ffffff" android:pathData="M578.12,445.85c47.36,-38.85 72.53,-89.54 113.51,-145.02c7.73,-10.46 -34.58,-35.7 -51.31,-37.37c-16.73,-1.67 -30.77,59.79 -32.35,95.94c-1.44,33.01 -36.21,91.68 -29.84,86.45z"/>
<path android:fillColor="#ffffff" android:pathData="M472.42,359.39c-1.58,-36.15 -15.62,-97.61 -32.35,-95.94c-16.73,1.67 -59.04,26.91 -51.31,37.37c40.98,55.48 66.14,106.17 113.51,145.02c6.37,5.22 -28.4,-53.45 -29.84,-86.45z"/>
<path android:fillColor="#ffb327" android:pathData="M582.86,320.35c3.34,-26.76 15.37,-46.32 39.32,-62.75c-21.17,-7.08 -38.77,-12.83 -47.97,-5.3c-9.2,7.53 -34.2,32.7 -30.85,73.68c3.34,40.98 0.18,194.09 7.43,191.25c3.9,-104.87 37.09,-135 32.07,-196.89z"/>
<path android:fillColor="#ffb327" android:pathData="M529.59,517.24c7.24,2.83 4.08,-150.27 7.43,-191.25c3.34,-40.98 -21.65,-66.16 -30.85,-73.68c-9.2,-7.53 -26.8,-1.78 -47.97,5.3c23.95,16.43 35.98,35.98 39.32,62.75c-5.02,61.89 28.17,92.02 32.07,196.89z"/>
</vector>
<resources>
<string name="downloading_toast">جاري التنزيل %1$s</string>
<string name="download_file_error">خطأ تنزيل الملف</string>
<string name="no_rw_storage">أن هذه الميزة لا تعمل دون الحصول على إذن الكتابة على التخزين الخارجي.</string>
<string name="no_thanks">لا شكراً</string>
<string name="yes">نعم</string>
<string name="ok">موافق</string>
</resources>
<resources>
<string name="downloading_toast">Изтегляне на %1$s</string>
<string name="download_file_error">Грешка при изтеглянето на файла</string>
<string name="no_rw_storage">Тази функция няма да работи без разрешение за запис във външната памет.</string>
<string name="no_thanks">Не, благодаря</string>
<string name="yes">Да</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Chyba při Stahování souboru</string>
<string name="downloading_toast">Stahování %1$s</string>
<string name="no_rw_storage">Tato funkce nebude fungovat bez povolení k zápisu na externí úložiště.</string>
<string name="no_thanks">Ne, díky</string>
<string name="yes">Ano</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Fehler beim Herunterladen der Datei</string>
<string name="downloading_toast">Herunterladen von %1$s</string>
<string name="no_rw_storage">Diese Funktion benötigt Rechte zum Schreiben auf den externen Speicher.</string>
<string name="no_thanks">Nein danke</string>
<string name="yes">Ja</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Σφάλμα στη λήψη του αρχείου</string>
<string name="downloading_toast">Κατέβασμα %1$s</string>
<string name="no_rw_storage">Η λειτουργία αυτή δεν θα δουλέψει χωρίς την άδεια εγγραφής στον εξωτερικό χώρο αποθηκεύσης.</string>
<string name="no_thanks">Όχι ευχαριστώ</string>
<string name="yes">Ναι</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Error descargando archivo</string>
<string name="downloading_toast">Descargando %1$s</string>
<string name="no_rw_storage">Esta opción no funcionará sin permiso de escritura en la memoria externa.</string>
<string name="no_thanks">No gracias</string>
<string name="yes"></string>
<string name="ok">Aceptar</string>
</resources>
<resources>
<string name="download_file_error">Faili allalaadimisel esines viga</string>
<string name="downloading_toast">Laadin %1$s alla</string>
<string name="no_rw_storage">See funktsioon ei tööta ilma välismälule kirjutamise õiguseta.</string>
<string name="no_thanks">Tänan ei</string>
<string name="yes">Jah</string>
<string name="ok">OK</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Used in both stub and full app-->
<string name="download_file_error">Erreur de téléchargement du fichier</string>
<string name="downloading_toast">Téléchargement à %1$s</string>
<string name="no_rw_storage">Cette fonctionnalité ne marchera pas sans la permission d\'écriture sur le stockage externe.</string>
<string name="no_thanks">Non merci</string>
<string name="yes">Oui</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Pogreška prilikom preuzimanja datoteke</string>
<string name="downloading_toast">Preuzimanje %1$s</string>
<string name="no_rw_storage">Ova značajka neće raditi bez dopuštenja za korištenje vanjske pohrane.</string>
<string name="no_thanks">Ne hvala</string>
<string name="yes">Da</string>
<string name="ok">OK</string>
</resources>
\ No newline at end of file
<resources>
<string name="download_file_error">Kesalahan mengunduh file</string>
<string name="downloading_toast">Mengunduh %1$s</string>
<string name="no_rw_storage">Fitur ini tidak akan bekerja tanpa izin untuk menulis ke penyimpanan eksternal.</string>
<string name="no_thanks">Tidak, terima kasih</string>
<string name="yes">Ya</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Errore nel download del file</string>
<string name="downloading_toast">Download di %1$s</string>
<string name="no_rw_storage">Questa funzione non sarà attiva senza l\'autorizzazione di scrittura nella memoria di archiviazione esterna</string>
<string name="no_thanks">No, grazie</string>
<string name="yes"></string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">ダウンロード中にエラーが発生しました</string>
<string name="downloading_toast">%1$s をダウンロード中</string>
<string name="no_rw_storage">この機能は外部ストレージへの書き込み権限がないと動作しません</string>
<string name="no_thanks">いいえ</string>
<string name="yes">はい</string>
<string name="ok">OK</string>
</resources>
\ No newline at end of file
<resources>
<string name="download_file_error">파일 다운로드 오류</string>
<string name="downloading_toast">%1$s 다운로드 중</string>
<string name="no_rw_storage">이 기능은 외부 저장소 쓰기 권한 없이는 작동하지 않습니다.</string>
<string name="no_thanks">아니오, 괜찮습니다</string>
<string name="yes"></string>
<string name="ok">확인</string>
</resources>
<resources>
<string name="download_file_error">Atsisiunčiant failą įvyko klaida</string>
<string name="downloading_toast">Atsisiunčiamas %1$s</string>
<string name="no_rw_storage">Ši funkija neveiks be prieigos prie saugyklos</string>
<string name="no_thanks">Ačiū, nereikia</string>
<string name="yes">Taip</string>
<string name="ok">Gerai</string>
</resources>
<resources>
<string name="download_file_error">Fout tijdens downloaden</string>
<string name="downloading_toast">%1$s downloaden</string>
<string name="no_rw_storage">Deze functie werkt niet zonder schrijfpermissie voor externe opslag.</string>
<string name="no_thanks">Nee bedankt</string>
<string name="yes">Ja</string>
<string name="ok">Oké</string>
</resources>
<resources>
<string name="download_file_error">Błąd pobierania pliku</string>
<string name="downloading_toast">Pobieranie %1$s</string>
<string name="no_rw_storage">Ta funkcja nie będzie działać bez uprawnień do zapisu na pamięci zewnętrznej.</string>
<string name="no_thanks">Nie dziękuję</string>
<string name="yes">Tak</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Erro ao baixar arquivo</string>
<string name="downloading_toast">Baixando %1$s</string>
<string name="no_rw_storage">Este recurso não funcionará sem permissão para gravar no armazenamento externo.</string>
<string name="no_thanks">Não</string>
<string name="yes">Sim</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Erro ao transferir ficheiro</string>
<string name="downloading_toast">A transferir %1$s</string>
<string name="no_rw_storage">Esta funcionalidade não funcionará sem permissão de escrita do armazenamento externo.</string>
<string name="no_thanks">Não, Obrigado</string>
<string name="yes">Sim</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Eroare la descărcarea fișierului</string>
<string name="downloading_toast">Descărcare %1$s</string>
<string name="no_rw_storage">Această caracteristică nu va funcționa fără permisiunea de a scrie pe memoria externă.</string>
<string name="no_thanks">Nu, mulţumesc</string>
<string name="yes">Da</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Ошибка загрузки файла</string>
<string name="downloading_toast">Загрузка %1$s</string>
<string name="no_rw_storage">Требуется разрешение на запись во внешнее хранилище.</string>
<string name="no_thanks">Нет</string>
<string name="yes">Да</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Грешка при преузимању фајла</string>
<string name="downloading_toast">Преузимање %1$s</string>
<string name="no_rw_storage">Ово својство неће радити без дозволе приступу екстерном складишту.</string>
<string name="no_thanks">Не хвала</string>
<string name="yes">Да</string>
<string name="ok">ОК</string>
</resources>
<resources>
<string name="download_file_error">Fel vid nerladdning av fil</string>
<string name="downloading_toast">Laddar ner %1$s</string>
<string name="no_rw_storage">Denna funktionen måste ha behörighet att skriva till externt lagringsutrymme.</string>
<string name="no_thanks">Nej tack</string>
<string name="yes">Ja</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Dosya indirme hatası</string>
<string name="downloading_toast">%1$s indiriliyor</string>
<string name="no_rw_storage">Bu özellik harici depolamaya yazma izni olmadan çalışmaz.</string>
<string name="no_thanks">Hayır teşekkürler</string>
<string name="yes">Evet</string>
<string name="ok">Tamam</string>
</resources>
<resources>
<string name="download_file_error">Помилка завантаження файлу</string>
<string name="downloading_toast">Завантаження %1$s</string>
<string name="no_rw_storage">Ця функція не працюватиме без дозволу на запис у Внутрішнє сховище</string>
<string name="no_thanks">Ні, дякую</string>
<string name="yes">Так</string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">Lỗi tải tập tin</string>
<string name="downloading_toast">Đang tải xuống %1$s</string>
<string name="no_rw_storage">Tính năng này không hoạt động nếu thiếu quyền ghi vào bộ nhớ ngoài.</string>
<string name="no_thanks">Không, cảm ơn</string>
<string name="yes"></string>
<string name="ok">OK</string>
</resources>
<resources>
<string name="download_file_error">下载文件时出错</string>
<string name="downloading_toast">正在下载 %1$s</string>
<string name="no_rw_storage">未授予写入内置存储权限,此功能无法正常工作。</string>
<string name="no_thanks">不,谢谢</string>
<string name="yes"></string>
<string name="ok"></string>
</resources>
<resources>
<string name="download_file_error">下載文件時出錯</string>
<string name="downloading_toast">正在下載 %1$s</string>
<string name="no_rw_storage">未授予寫入外部存儲權限,此功能無法正常工作。</string>
<string name="no_thanks">不,謝謝</string>
<string name="yes"></string>
<string name="ok"></string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#009688</color>
<color name="primary_dark">#00796B</color>
<color name="accent">#FFC107</color>
<color name="accentFallback">#FBC02D</color>
<color name="icon_grey">#757575</color>
<color name="red500">#F44336</color>
<color name="green500">#4CAF50</color>
<color name="grey500">#9E9E9E</color>
<color name="blue500">#2196f3</color>
<color name="yellow500">#FFC107</color>
<color name="dark_secondary_text">#dedede</color>
<color name="su_request_background">#e0e0e0</color>
<!-- Flashing colors -->
<color name="flashing_background_color">@android:color/black</color>
<color name="ic_launcher_background">#00AF9C</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="ic_launcher">@drawable/ic_logo</drawable>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Not translatable-->
<string name="app_name" translatable="false">Magisk Manager</string>
<string name="magisk" translatable="false">Magisk</string>
<string name="magiskhide" translatable="false">Magisk Hide</string>
<!--Used in both stub and full app-->
<string name="download_file_error">Error downloading file</string>
<string name="downloading_toast">Downloading %1$s</string>
<string name="no_rw_storage">This feature will not work without permission to write external storage.</string>
<string name="no_thanks">No thanks</string>
<string name="yes">Yes</string>
<string name="ok">OK</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.topjohnwu.magisk">
<application>
<activity
android:name=".NoUIActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".receivers.BootLauncher">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
package com.topjohnwu.magisk;
import com.topjohnwu.magisk.components.Application;
public class MagiskManager extends Application {
public int magiskVersionCode = -1;
public static MagiskManager get() {
return (MagiskManager) weakSelf.get();
}
public void dumpPrefs() {/* NOP */}
}
package com.topjohnwu.magisk;
import android.Manifest;
import android.app.AlertDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.receivers.ManagerInstall;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import org.json.JSONException;
import org.json.JSONObject;
public class NoUIActivity extends Activity {
private String apkLink;
private String version;
private int versionCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Utils.checkNetworkStatus()) {
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
String str = WebService.getString(Const.Url.STABLE_URL);
try {
JSONObject json = new JSONObject(str);
JSONObject manager = json.getJSONObject("app");
version = manager.getString("version");
versionCode = manager.getInt("versionCode");
apkLink = manager.getString("link");
} catch (JSONException e) {
e.printStackTrace();
finish();
return;
}
runOnUiThread(() -> {
String filename = Utils.fmt("MagiskManager-v%s(%d).apk", version, versionCode);
new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setCancelable(false)
.setTitle(R.string.app_name)
.setMessage(R.string.upgrade_msg)
.setPositiveButton(R.string.yes, (d, w) -> runWithPermission(new String[]
{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
Utils.dlAndReceive(this, new ManagerInstall(), apkLink, filename);
finish();
}))
.setNegativeButton(R.string.no_thanks, (d, w) -> finish())
.show();
});
});
} else {
new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setCancelable(false)
.setTitle(R.string.app_name)
.setMessage(R.string.no_internet_msg)
.setNegativeButton(R.string.ok, (d, w) -> finish())
.show();
}
}
}
package com.topjohnwu.magisk.components;
import android.app.Activity;
public abstract class FlavorActivity extends Activity {}
package com.topjohnwu.magisk.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.topjohnwu.magisk.NoUIActivity;
public class BootLauncher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, NoUIActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Надградете до пълната версия на Magisk Manager, за да довършите първоначалната настройка. Изтегляне и инсталиране сега?</string>
<string name="no_internet_msg">Моля да се свържете към работеща интернет мрежа, защото надграждането до пълната версия на Magisk Manager е задължително.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Upgrade zu vollständigem Magisk Manager, um das Setup zu beenden. Herunterladen und installieren?</string>
<string name="no_internet_msg">Bitte mit dem Internet verbinden! Upgrade zu volsltändigem Magisk Manager ist erforderlich.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Actualizar a la Ver. Completa de Magisk Manager para finalizar la instalación. Descargar e instalar?</string>
<string name="no_internet_msg">¡Por favor conectarse a Internet! Se requiere actualizar a la Ver. Completa de Magisk Manager </string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Mettre à jour vers Magisk Manager version complête pour finir l\'installation. Télécharger et installer?</string>
<string name="no_internet_msg">Veuillez vous connecter à Internet! Mise à niveau de Magisk Manager requis.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Tingkatkan ke Magisk Manager versi penuh untuk menyelesaikan penyiapan. Unduh dan pasang?</string>
<string name="no_internet_msg">Harap menyambungkan ke Internet! Peningkatan ke Magisk Manager versi penuh diperlukan.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Aggiorna al Magisk Manager completo per completare l\'installazione. Vuoi procedere al download e all\'installazione?</string>
<string name="no_internet_msg">Controlla la connessione a Internet! È necessaria per l\'aggiornamento al Magisk Manager completo.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Atsinaujinkite į pilną Magisk Manager versiją, kad baigtumėte pasiruošimą. Atsisiųsti ir instaliuoti?</string>
<string name="no_internet_msg">Prašome prisijungti prie interneto! Atsinaujinimas į pilną Magisk Manager versiją yra privalomas.</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Przejdź na pełną wersję programu Magisk Manager, aby ukończyć konfigurację. Ściągnąć i zainstalować?</string>
<string name="no_internet_msg">Połącz się z Internetem! Wymagana jest aktualizacja do pełnego programu Magisk Manager.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Treceți la versiunea completă a Magic Manager pentru a finaliza configurarea. Descărcaţi şi instalaţi?</string>
<string name="no_internet_msg">Conectați-vă la internet! Este necesară actualizarea la Magisk Manager complet.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Обновите Magisk Manager для завершения установки. Загрузить и установить?</string>
<string name="no_internet_msg">Пожалуйста, подключитесь к интернету! Требуется обновление Magisk Manager.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Kurulumu tamamlamak için tam Magisk Manager\'a yükseltin. İndirip yüklensin mi?</string>
<string name="no_internet_msg">Lütfen internete bağlanın! Tam Magisk Manager\'a yükseltmek gerekiyor.</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">需要升级到完整的 Magisk Manager 来完成安装。 现在下载?</string>
<string name="no_internet_msg">请连接到互联网! 这是升级到完整 Magisk Manager 所必需的。</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">需要升級到完整版 Magisk Manager。是否下載並安裝?</string>
<string name="no_internet_msg">請連上網路!升級到完整版 Magisk Manager 是必須的。</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Upgrade to full Magisk Manager to finish the setup. Download and install?</string>
<string name="no_internet_msg">Please connect to the Internet! Upgrading to full Magisk Manager is required.</string>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment