mirror of
				https://github.com/topjohnwu/Magisk
				synced 2025-11-03 15:52:30 +01:00 
			
		
		
		
	Compare commits
	
		
			46 Commits
		
	
	
		
			manager-v5
			...
			manager-v5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0c782edf21 | ||
| 
						 | 
					e3948d295e | ||
| 
						 | 
					5f2c742a5c | ||
| 
						 | 
					b30c77aab9 | ||
| 
						 | 
					a5916b9c49 | ||
| 
						 | 
					453180e30b | ||
| 
						 | 
					8bd432d391 | ||
| 
						 | 
					c9d3e20aef | ||
| 
						 | 
					d5408d1f09 | ||
| 
						 | 
					f334532aba | ||
| 
						 | 
					be77c09f3d | ||
| 
						 | 
					7de6a92753 | ||
| 
						 | 
					36f76f5a14 | ||
| 
						 | 
					b84523d557 | ||
| 
						 | 
					2c78c415e9 | ||
| 
						 | 
					79ccb30dd2 | ||
| 
						 | 
					3c566becf6 | ||
| 
						 | 
					151ca593af | ||
| 
						 | 
					4132eacba0 | ||
| 
						 | 
					06e6151816 | ||
| 
						 | 
					70277d4edd | ||
| 
						 | 
					d21d2f1a9c | ||
| 
						 | 
					74a7be996f | ||
| 
						 | 
					3f38579529 | ||
| 
						 | 
					4d5a9f6e15 | ||
| 
						 | 
					41f47acd76 | ||
| 
						 | 
					821dcaa7c7 | ||
| 
						 | 
					7135d26419 | ||
| 
						 | 
					f7fd354dce | ||
| 
						 | 
					0c69a65bc4 | ||
| 
						 | 
					2f2ca5eab4 | ||
| 
						 | 
					df9c40c035 | ||
| 
						 | 
					25b67017e4 | ||
| 
						 | 
					bc9c3346f3 | ||
| 
						 | 
					1db7e19fe8 | ||
| 
						 | 
					102c03ce2b | ||
| 
						 | 
					ec19eb4455 | ||
| 
						 | 
					6d9924d50e | ||
| 
						 | 
					16c4d74274 | ||
| 
						 | 
					e4af5fd36a | ||
| 
						 | 
					702775493a | ||
| 
						 | 
					b2ae826066 | ||
| 
						 | 
					cc3e9990fa | ||
| 
						 | 
					271cbddd5e | ||
| 
						 | 
					c1423ca9ad | ||
| 
						 | 
					74379150a1 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
app/release
 | 
			
		||||
*.hprof
 | 
			
		||||
.externalNativeBuild/
 | 
			
		||||
*.sh
 | 
			
		||||
src/main/assets
 | 
			
		||||
public.certificate.x509.pem
 | 
			
		||||
private.key.pk8
 | 
			
		||||
*.apk
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								build.gradle
									
									
									
									
									
								
							@@ -2,14 +2,13 @@ apply plugin: 'com.android.application'
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    compileSdkVersion 27
 | 
			
		||||
    buildToolsVersion "27.0.3"
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        applicationId "com.topjohnwu.magisk"
 | 
			
		||||
        minSdkVersion 21
 | 
			
		||||
        targetSdkVersion 27
 | 
			
		||||
        versionCode 100
 | 
			
		||||
        versionName "5.6.0"
 | 
			
		||||
        versionCode 110
 | 
			
		||||
        versionName "5.6.3"
 | 
			
		||||
        javaCompileOptions {
 | 
			
		||||
            annotationProcessorOptions {
 | 
			
		||||
                argument('butterknife.debuggable', 'false')
 | 
			
		||||
@@ -46,14 +45,13 @@ repositories {
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation fileTree(include: ['*.jar'], dir: 'libs')
 | 
			
		||||
    implementation project(':utils')
 | 
			
		||||
    implementation 'com.github.topjohnwu:libsu:1.1.0'
 | 
			
		||||
    implementation 'com.android.support:recyclerview-v7:27.0.2'
 | 
			
		||||
    implementation 'com.android.support:cardview-v7:27.0.2'
 | 
			
		||||
    implementation 'com.android.support:design:27.0.2'
 | 
			
		||||
    implementation 'com.android.support:support-v4:27.0.2'
 | 
			
		||||
    implementation 'com.github.topjohnwu:libsu:1.1.1'
 | 
			
		||||
    implementation 'com.android.support:recyclerview-v7:27.1.0'
 | 
			
		||||
    implementation 'com.android.support:cardview-v7:27.1.0'
 | 
			
		||||
    implementation 'com.android.support:design:27.1.0'
 | 
			
		||||
    implementation 'com.android.support:support-v4:27.1.0'
 | 
			
		||||
    implementation 'com.jakewharton:butterknife:8.8.1'
 | 
			
		||||
    implementation 'com.atlassian.commonmark:commonmark:0.10.0'
 | 
			
		||||
    implementation 'org.kamranzafar:jtar:2.3'
 | 
			
		||||
    implementation 'com.google.code.gson:gson:2.8.2'
 | 
			
		||||
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
### v5.6.0
 | 
			
		||||
- Remove JNI requirement, Magisk Manager is now pure Java
 | 
			
		||||
- Update the method of handling su database, may fix the issue that root requests won't save
 | 
			
		||||
- Add the option to restore Magisk Manager after repackaging with random package name
 | 
			
		||||
- Massive under-the-hood optimizations
 | 
			
		||||
@@ -14,8 +14,6 @@ import com.topjohnwu.magisk.components.AboutCardRow;
 | 
			
		||||
import com.topjohnwu.magisk.components.Activity;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Const;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
import butterknife.BindView;
 | 
			
		||||
@@ -56,12 +54,8 @@ public class AboutActivity extends Activity {
 | 
			
		||||
 | 
			
		||||
        appChangelog.removeSummary();
 | 
			
		||||
        appChangelog.setOnClickListener(v -> {
 | 
			
		||||
            try {
 | 
			
		||||
                InputStream is = getAssets().open("changelog.md");
 | 
			
		||||
                new MarkDownWindow(this, getString(R.string.app_changelog), is).exec();
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            new MarkDownWindow(this, getString(R.string.app_changelog),
 | 
			
		||||
                    getResources().openRawResource(R.raw.changelog)).exec();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        String translators = getString(R.string.translators);
 | 
			
		||||
 
 | 
			
		||||
@@ -159,8 +159,8 @@ public class MagiskFragment extends Fragment
 | 
			
		||||
 | 
			
		||||
        safetyNetStatusText.setText(R.string.safetyNet_check_text);
 | 
			
		||||
 | 
			
		||||
        mm.safetyNetDone.hasPublished = false;
 | 
			
		||||
        mm.updateCheckDone.hasPublished = false;
 | 
			
		||||
        mm.safetyNetDone.reset();
 | 
			
		||||
        mm.updateCheckDone.reset();
 | 
			
		||||
        mm.remoteMagiskVersionString = null;
 | 
			
		||||
        mm.remoteMagiskVersionCode = -1;
 | 
			
		||||
        collapse();
 | 
			
		||||
@@ -176,11 +176,11 @@ public class MagiskFragment extends Fragment
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    public void onTopicPublished(Topic topic) {
 | 
			
		||||
        if (topic == mm.updateCheckDone) {
 | 
			
		||||
            updateCheckUI();
 | 
			
		||||
        } else if (topic == mm.safetyNetDone) {
 | 
			
		||||
            updateSafetyNetUI((int) result);
 | 
			
		||||
            updateSafetyNetUI((int) topic.getResults()[0]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,7 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    public void onTopicPublished(Topic topic) {
 | 
			
		||||
        mSwipeRefreshLayout.setRefreshing(false);
 | 
			
		||||
        appAdapter.filter(lastFilter);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,8 @@
 | 
			
		||||
package com.topjohnwu.magisk;
 | 
			
		||||
 | 
			
		||||
import android.app.job.JobInfo;
 | 
			
		||||
import android.app.job.JobScheduler;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
import android.content.pm.PackageManager;
 | 
			
		||||
@@ -14,6 +17,7 @@ import android.widget.Toast;
 | 
			
		||||
import com.topjohnwu.magisk.container.Module;
 | 
			
		||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
 | 
			
		||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
 | 
			
		||||
import com.topjohnwu.magisk.services.UpdateCheckService;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Const;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Topic;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Utils;
 | 
			
		||||
@@ -101,8 +105,10 @@ public class MagiskManager extends Shell.ContainerApp {
 | 
			
		||||
        Shell.setInitializer(new Shell.Initializer() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRootShellInit(@NonNull Shell shell) {
 | 
			
		||||
                try (InputStream in = MagiskManager.get().getAssets().open(Const.UTIL_FUNCTIONS)) {
 | 
			
		||||
                    shell.loadInputStream(null, null, in);
 | 
			
		||||
                try (InputStream utils = getAssets().open(Const.UTIL_FUNCTIONS);
 | 
			
		||||
                     InputStream sudb = getResources().openRawResource(R.raw.sudb)) {
 | 
			
		||||
                    shell.loadInputStream(null, null, utils);
 | 
			
		||||
                    shell.loadInputStream(null, null, sudb);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
@@ -205,7 +211,8 @@ public class MagiskManager extends Shell.ContainerApp {
 | 
			
		||||
        try {
 | 
			
		||||
            magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
 | 
			
		||||
            magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
 | 
			
		||||
            String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
 | 
			
		||||
            String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ")
 | 
			
		||||
                    + Const.MAGISKHIDE_PROP);
 | 
			
		||||
            magiskHide = s == null || Integer.parseInt(s) != 0;
 | 
			
		||||
        } catch (Exception ignored) {}
 | 
			
		||||
 | 
			
		||||
@@ -223,4 +230,23 @@ public class MagiskManager extends Shell.ContainerApp {
 | 
			
		||||
    public void setPermissionGrantCallback(Runnable callback) {
 | 
			
		||||
        permissionGrantCallback = callback;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,9 +23,6 @@ import com.topjohnwu.magisk.utils.Topic;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Utils;
 | 
			
		||||
import com.topjohnwu.superuser.Shell;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import butterknife.BindView;
 | 
			
		||||
import butterknife.ButterKnife;
 | 
			
		||||
 | 
			
		||||
@@ -99,12 +96,8 @@ public class MainActivity extends Activity
 | 
			
		||||
 | 
			
		||||
        if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) {
 | 
			
		||||
            prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
 | 
			
		||||
            try {
 | 
			
		||||
                InputStream is = getAssets().open("changelog.md");
 | 
			
		||||
                new MarkDownWindow(this, getString(R.string.app_changelog), is).exec();
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            new MarkDownWindow(this, getString(R.string.app_changelog),
 | 
			
		||||
                    getResources().openRawResource(R.raw.changelog)).exec();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +127,7 @@ public class MainActivity extends Activity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    public void onTopicPublished(Topic topic) {
 | 
			
		||||
        recreate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -197,22 +190,22 @@ public class MainActivity extends Activity
 | 
			
		||||
        navigationView.setCheckedItem(itemId);
 | 
			
		||||
        switch (itemId) {
 | 
			
		||||
            case R.id.magisk:
 | 
			
		||||
                displayFragment(new MagiskFragment(), "magisk", true);
 | 
			
		||||
                displayFragment(new MagiskFragment(), true);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.superuser:
 | 
			
		||||
                displayFragment(new SuperuserFragment(), "superuser", true);
 | 
			
		||||
                displayFragment(new SuperuserFragment(), true);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.modules:
 | 
			
		||||
                displayFragment(new ModulesFragment(), "modules", true);
 | 
			
		||||
                displayFragment(new ModulesFragment(), true);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.downloads:
 | 
			
		||||
                displayFragment(new ReposFragment(), "downloads", true);
 | 
			
		||||
                displayFragment(new ReposFragment(), true);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.magiskhide:
 | 
			
		||||
                displayFragment(new MagiskHideFragment(), Const.Key.MAGISKHIDE, true);
 | 
			
		||||
                displayFragment(new MagiskHideFragment(), true);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.log:
 | 
			
		||||
                displayFragment(new LogFragment(), "log", false);
 | 
			
		||||
                displayFragment(new LogFragment(), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.settings:
 | 
			
		||||
                startActivity(new Intent(this, SettingsActivity.class));
 | 
			
		||||
@@ -225,12 +218,13 @@ public class MainActivity extends Activity
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void displayFragment(@NonNull Fragment navFragment, String tag, boolean setElevation) {
 | 
			
		||||
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 | 
			
		||||
    private void displayFragment(@NonNull Fragment navFragment, boolean setElevation) {
 | 
			
		||||
        supportInvalidateOptionsMenu();
 | 
			
		||||
        transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
 | 
			
		||||
        transaction.replace(R.id.content_frame, navFragment, tag).commitNow();
 | 
			
		||||
        if (setElevation) toolbar.setElevation(toolbarElevation);
 | 
			
		||||
        else toolbar.setElevation(0);
 | 
			
		||||
        getSupportFragmentManager()
 | 
			
		||||
                .beginTransaction()
 | 
			
		||||
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
 | 
			
		||||
                .replace(R.id.content_frame, navFragment)
 | 
			
		||||
                .commitNow();
 | 
			
		||||
        toolbar.setElevation(setElevation ? toolbarElevation : 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    public void onTopicPublished(Topic topic) {
 | 
			
		||||
        updateUI();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ 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;
 | 
			
		||||
@@ -44,8 +45,9 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
    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(true);
 | 
			
		||||
        mSwipeRefreshLayout.setRefreshing(mm.repoLoadDone.isPending());
 | 
			
		||||
 | 
			
		||||
        mSwipeRefreshLayout.setOnRefreshListener(() -> {
 | 
			
		||||
            recyclerView.setVisibility(View.VISIBLE);
 | 
			
		||||
@@ -60,7 +62,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        adapter = new ReposAdapter(getApplication().repoDB, getApplication().moduleMap);
 | 
			
		||||
        adapter = new ReposAdapter(mm.repoDB, mm.moduleMap);
 | 
			
		||||
        recyclerView.setAdapter(adapter);
 | 
			
		||||
        super.onResume();
 | 
			
		||||
    }
 | 
			
		||||
@@ -72,7 +74,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    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);
 | 
			
		||||
@@ -80,7 +82,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Topic[] getSubscription() {
 | 
			
		||||
        return new Topic[] { getApplication().repoLoadDone };
 | 
			
		||||
        return new Topic[] { mm.repoLoadDone };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -103,7 +105,6 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onOptionsItemSelected(MenuItem item) {
 | 
			
		||||
        MagiskManager mm = getApplication();
 | 
			
		||||
        if (item.getItemId() == R.id.repo_sort) {
 | 
			
		||||
            new AlertDialog.Builder(getActivity())
 | 
			
		||||
                .setTitle(R.string.sorting_order)
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
    public void onTopicPublished(Topic topic) {
 | 
			
		||||
        recreate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -150,17 +150,16 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
 | 
			
		||||
                reauth.setSummary(R.string.android_o_not_support);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Remove fingerprint option if not possible
 | 
			
		||||
            // Disable fingerprint option if not possible
 | 
			
		||||
            if (!FingerprintHelper.canUseFingerprint()) {
 | 
			
		||||
                suCategory.removePreference(fingerprint);
 | 
			
		||||
                fingerprint.setEnabled(false);
 | 
			
		||||
                fingerprint.setSummary(R.string.disable_fingerprint);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mm.magiskVersionCode >= 1440) {
 | 
			
		||||
                if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
 | 
			
		||||
                    hideManager.setOnPreferenceClickListener((pref) -> {
 | 
			
		||||
                        Utils.runWithPermission(getActivity(),
 | 
			
		||||
                                Manifest.permission.WRITE_EXTERNAL_STORAGE,
 | 
			
		||||
                                () -> new HideManager(getActivity()).exec());
 | 
			
		||||
                        new HideManager(getActivity()).exec();
 | 
			
		||||
                        return true;
 | 
			
		||||
                    });
 | 
			
		||||
                    generalCatagory.removePreference(restoreManager);
 | 
			
		||||
@@ -187,18 +186,6 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
 | 
			
		||||
                generalCatagory.removePreference(hideManager);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mm.getPackageName().equals(Const.ORIG_PKG_NAME) && mm.magiskVersionCode >= 1440) {
 | 
			
		||||
                hideManager.setOnPreferenceClickListener((pref) -> {
 | 
			
		||||
                    Utils.runWithPermission(getActivity(),
 | 
			
		||||
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
 | 
			
		||||
                            () -> new HideManager(getActivity()).exec());
 | 
			
		||||
                    return true;
 | 
			
		||||
                });
 | 
			
		||||
                generalCatagory.removePreference(restoreManager);
 | 
			
		||||
            } else {
 | 
			
		||||
                generalCatagory.removePreference(hideManager);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!Shell.rootAccess() || (Const.USER_ID > 0 &&
 | 
			
		||||
                    mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
 | 
			
		||||
                prefScreen.removePreference(suCategory);
 | 
			
		||||
@@ -298,6 +285,9 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
 | 
			
		||||
                case Const.Key.UPDATE_CHANNEL:
 | 
			
		||||
                    new CheckUpdates().exec();
 | 
			
		||||
                    break;
 | 
			
		||||
                case Const.Key.CHECK_UPDATES:
 | 
			
		||||
                    mm.setupUpdateCheck();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            mm.loadConfig();
 | 
			
		||||
            setSummary();
 | 
			
		||||
@@ -321,7 +311,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onTopicPublished(Topic topic, Object result) {
 | 
			
		||||
        public void onTopicPublished(Topic topic) {
 | 
			
		||||
            setLocalePreference((ListPreference) findPreference(Const.Key.LOCALE));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,6 @@ package com.topjohnwu.magisk;
 | 
			
		||||
 | 
			
		||||
import android.app.NotificationChannel;
 | 
			
		||||
import android.app.NotificationManager;
 | 
			
		||||
import android.app.job.JobInfo;
 | 
			
		||||
import android.app.job.JobScheduler;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
@@ -15,7 +11,6 @@ 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.services.UpdateCheckService;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Const;
 | 
			
		||||
import com.topjohnwu.magisk.utils.Utils;
 | 
			
		||||
import com.topjohnwu.superuser.Shell;
 | 
			
		||||
@@ -50,31 +45,18 @@ public class SplashActivity extends Activity {
 | 
			
		||||
        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) {
 | 
			
		||||
 | 
			
		||||
            // Add update checking service
 | 
			
		||||
            if (Const.UPDATE_SERVICE_VER > mm.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();
 | 
			
		||||
                ((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(info);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Update check service
 | 
			
		||||
            mm.setupUpdateCheck();
 | 
			
		||||
            // Fire asynctasks
 | 
			
		||||
            loadModuleTask.exec();
 | 
			
		||||
 | 
			
		||||
            // Check dtbo status
 | 
			
		||||
            Utils.patchDTBO();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPostExecute(Void v) {
 | 
			
		||||
        MagiskManager mm = MagiskManager.get();
 | 
			
		||||
        if (showNotification && mm.prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true)) {
 | 
			
		||||
        if (showNotification) {
 | 
			
		||||
            if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
 | 
			
		||||
                ShowUI.managerUpdateNotification();
 | 
			
		||||
            } else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,10 @@ import com.topjohnwu.magisk.utils.Utils;
 | 
			
		||||
import com.topjohnwu.magisk.utils.ZipUtils;
 | 
			
		||||
import com.topjohnwu.superuser.Shell;
 | 
			
		||||
import com.topjohnwu.superuser.ShellUtils;
 | 
			
		||||
import com.topjohnwu.superuser.io.SuFile;
 | 
			
		||||
import com.topjohnwu.superuser.io.SuFileOutputStream;
 | 
			
		||||
import com.topjohnwu.utils.JarMap;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.security.SecureRandom;
 | 
			
		||||
import java.util.jar.JarEntry;
 | 
			
		||||
@@ -104,8 +105,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
        MagiskManager mm = MagiskManager.get();
 | 
			
		||||
 | 
			
		||||
        // Generate a new unhide app with random package name
 | 
			
		||||
        File repack = new File(Const.EXTERNAL_PATH, "repack.apk");
 | 
			
		||||
        repack.getParentFile().mkdirs();
 | 
			
		||||
        SuFile repack = new SuFile("/data/local/tmp/repack.apk", true);
 | 
			
		||||
        String pkg = genPackageName("com.", Const.ORIG_PKG_NAME.length());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
@@ -123,7 +123,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
            apk.getOutputStream(je).write(xml);
 | 
			
		||||
 | 
			
		||||
            // Sign the APK
 | 
			
		||||
            ZipUtils.signZip(apk, repack);
 | 
			
		||||
            ZipUtils.signZip(apk, new SuFileOutputStream(repack));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -136,7 +136,6 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
        repack.delete();
 | 
			
		||||
 | 
			
		||||
        mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
 | 
			
		||||
        mm.suDB.flush();
 | 
			
		||||
        Utils.dumpPrefs();
 | 
			
		||||
        Utils.uninstallPkg(Const.ORIG_PKG_NAME);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
    private List<String> console, logs;
 | 
			
		||||
    private String mBootLocation;
 | 
			
		||||
    private int mode;
 | 
			
		||||
    private File install;
 | 
			
		||||
 | 
			
		||||
    private InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip) {
 | 
			
		||||
        super(context);
 | 
			
		||||
@@ -66,10 +67,10 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
    protected Boolean doInBackground(Void... voids) {
 | 
			
		||||
        MagiskManager mm = MagiskManager.get();
 | 
			
		||||
 | 
			
		||||
        File install = new File(
 | 
			
		||||
        install = new File(
 | 
			
		||||
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
 | 
			
		||||
                        mm.createDeviceProtectedStorageContext() :
 | 
			
		||||
                        mm).getFilesDir().getParent()
 | 
			
		||||
                        mm.createDeviceProtectedStorageContext() : mm)
 | 
			
		||||
                        .getFilesDir().getParent()
 | 
			
		||||
                , "install");
 | 
			
		||||
        Shell.Sync.sh("rm -rf " + install);
 | 
			
		||||
 | 
			
		||||
@@ -249,6 +250,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
 | 
			
		||||
    protected void onPostExecute(Boolean result) {
 | 
			
		||||
        FlashActivity activity = (FlashActivity) getActivity();
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            Shell.Async.sh("rm -rf " + install);
 | 
			
		||||
            console.add("! Installation failed");
 | 
			
		||||
            activity.reboot.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -54,11 +54,13 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
 | 
			
		||||
        }
 | 
			
		||||
        String css;
 | 
			
		||||
        try (
 | 
			
		||||
            InputStream in = mm.getAssets().open(mm.isDarkTheme ? "dark.css" : "light.css");
 | 
			
		||||
            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 "";
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
 | 
			
		||||
        MagiskManager mm = MagiskManager.get();
 | 
			
		||||
        prefs = mm.prefs;
 | 
			
		||||
        repoDB = mm.repoDB;
 | 
			
		||||
        mm.repoLoadDone.hasPublished = false;
 | 
			
		||||
        mm.repoLoadDone.reset();
 | 
			
		||||
        // Legacy data cleanup
 | 
			
		||||
        File old = new File(mm.getApplicationInfo().dataDir + "/shared_prefs", "RepoMap.xml");
 | 
			
		||||
        if (old.exists() || prefs.getString("repomap", null) != null) {
 | 
			
		||||
@@ -160,6 +160,11 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
 | 
			
		||||
            ReposFragment.adapter.notifyDBChanged();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPreExecute() {
 | 
			
		||||
        MagiskManager.get().repoLoadDone.setPending();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Void doInBackground(Void... voids) {
 | 
			
		||||
        etags = new ArrayList<>(Arrays.asList(prefs.getString(Const.Key.ETAG_KEY, "").split(",")));
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ 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;
 | 
			
		||||
 | 
			
		||||
@@ -17,6 +18,7 @@ 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;
 | 
			
		||||
@@ -37,30 +39,21 @@ public class SuDatabaseHelper {
 | 
			
		||||
    private SQLiteDatabase mDb;
 | 
			
		||||
    private File DB_FILE;
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    public static SuDatabaseHelper getInstance(MagiskManager mm) {
 | 
			
		||||
        try {
 | 
			
		||||
            return new SuDatabaseHelper(mm);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            // Let's cleanup everything and try again
 | 
			
		||||
            cleanup("*");
 | 
			
		||||
            Shell.Sync.su("sudb_clean '*'");
 | 
			
		||||
            return new SuDatabaseHelper(mm);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void cleanup() {
 | 
			
		||||
        cleanup(String.valueOf(Const.USER_ID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void cleanup(String s) {
 | 
			
		||||
        Shell.Sync.su(
 | 
			
		||||
                "umount -l /data/user*/*/*/databases/su.db",
 | 
			
		||||
                "umount -l /sbin/.core/db-" + s + "/magisk.db",
 | 
			
		||||
                "rm -rf /sbin/.core/db-" + s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SuDatabaseHelper(MagiskManager mm) {
 | 
			
		||||
        pm = mm.getPackageManager();
 | 
			
		||||
        mDb = openDatabase(mm);
 | 
			
		||||
        mDb.disableWriteAheadLogging();
 | 
			
		||||
        int version = mDb.getVersion();
 | 
			
		||||
        if (version < DATABASE_VER) {
 | 
			
		||||
            onUpgrade(mDb, version);
 | 
			
		||||
@@ -72,11 +65,11 @@ public class SuDatabaseHelper {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SQLiteDatabase openDatabase(MagiskManager mm) {
 | 
			
		||||
        String GLOBAL_DB = "/data/adb/magisk.db";
 | 
			
		||||
        final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db", true);
 | 
			
		||||
        DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
 | 
			
		||||
        Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
 | 
			
		||||
                ? mm.createDeviceProtectedStorageContext() : mm;
 | 
			
		||||
        if (!DB_FILE.exists()) {
 | 
			
		||||
        if (!DB_FILE.canWrite()) {
 | 
			
		||||
            if (!Shell.rootAccess()) {
 | 
			
		||||
                // We don't want the app to crash, create a db and return
 | 
			
		||||
                DB_FILE = mm.getDatabasePath("su.db");
 | 
			
		||||
@@ -84,7 +77,7 @@ public class SuDatabaseHelper {
 | 
			
		||||
            }
 | 
			
		||||
            mm.loadMagiskInfo();
 | 
			
		||||
            // Cleanup
 | 
			
		||||
            cleanup();
 | 
			
		||||
            Shell.Sync.su("sudb_clean " + Const.USER_ID);
 | 
			
		||||
            if (mm.magiskVersionCode < 1410) {
 | 
			
		||||
                // Super old legacy mode
 | 
			
		||||
                DB_FILE = mm.getDatabasePath("su.db");
 | 
			
		||||
@@ -100,22 +93,23 @@ public class SuDatabaseHelper {
 | 
			
		||||
                mm.deleteDatabase("su.db");
 | 
			
		||||
                de.deleteDatabase("su.db");
 | 
			
		||||
                if (mm.magiskVersionCode < 1460) {
 | 
			
		||||
                    // v14.5 global DB location
 | 
			
		||||
                    GLOBAL_DB = new File(de.getFilesDir().getParentFile().getParentFile(),
 | 
			
		||||
                            "magisk.db").getPath();
 | 
			
		||||
                    // We need some additional policies on old versions
 | 
			
		||||
                    Shell.Sync.su("magiskpolicy --live 'create su_file' 'allow * su_file file *'");
 | 
			
		||||
                    // Link to new path
 | 
			
		||||
                    File oldDB = new File(de.getFilesDir().getParentFile().getParentFile(),
 | 
			
		||||
                            "magisk.db");
 | 
			
		||||
                    Shell.Sync.su(Utils.fmt("mv -f %s %s; ln -s %s %s",
 | 
			
		||||
                            oldDB, GLOBAL_DB, GLOBAL_DB, oldDB));
 | 
			
		||||
                }
 | 
			
		||||
                // Touch global DB and setup db in tmpfs
 | 
			
		||||
                Shell.Sync.su(Utils.fmt("touch %s; mkdir -p %s; touch %s; touch %s-journal;" +
 | 
			
		||||
                                "mount -o bind %s %s;" +
 | 
			
		||||
                                "chcon u:object_r:su_file:s0 %s/*; chown %d.%d %s;" +
 | 
			
		||||
                                "chmod 666 %s/*; chmod 700 %s;",
 | 
			
		||||
                        GLOBAL_DB, DB_FILE.getParent(), DB_FILE, DB_FILE,
 | 
			
		||||
                        GLOBAL_DB, DB_FILE,
 | 
			
		||||
                        DB_FILE.getParent(), Process.myUid(), Process.myUid(), DB_FILE.getParent(),
 | 
			
		||||
                        DB_FILE.getParent(), DB_FILE.getParent()
 | 
			
		||||
                ));
 | 
			
		||||
                if (mm.magiskVersionCode < 1550) {
 | 
			
		||||
                    // We need some additional policies on old versions
 | 
			
		||||
                    Shell.Sync.su("magiskpolicy --live " +
 | 
			
		||||
                            "'create su_file' 'allow * su_file file *' 'allow * su_file dir *'");
 | 
			
		||||
                }
 | 
			
		||||
                if (!GLOBAL_DB.exists()) {
 | 
			
		||||
                    Shell.Sync.su("sudb_init");
 | 
			
		||||
                    SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close();
 | 
			
		||||
                    Shell.Sync.su("sudb_restore");
 | 
			
		||||
                }
 | 
			
		||||
                Shell.Sync.su("sudb_setup " + Process.myUid());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Not using legacy mode, open the mounted global DB
 | 
			
		||||
@@ -123,42 +117,37 @@ public class SuDatabaseHelper {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onUpgrade(SQLiteDatabase db, int oldVersion) {
 | 
			
		||||
        try {
 | 
			
		||||
            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));
 | 
			
		||||
        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);
 | 
			
		||||
            // 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));
 | 
			
		||||
            // 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;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            onDowngrade(db);
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -320,9 +309,4 @@ public class SuDatabaseHelper {
 | 
			
		||||
        }
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void flush() {
 | 
			
		||||
        mDb.close();
 | 
			
		||||
        mDb = SQLiteDatabase.openOrCreateDatabase(DB_FILE, null);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@ public class Const {
 | 
			
		||||
        public static final String FLASH_SET_BOOT = "boot";
 | 
			
		||||
 | 
			
		||||
        // others
 | 
			
		||||
        public static final String UPDATE_NOTIFICATION = "notification";
 | 
			
		||||
        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";
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,13 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Topic {
 | 
			
		||||
 | 
			
		||||
    public boolean hasPublished = false;
 | 
			
		||||
    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 void subscribe(Subscriber sub) {
 | 
			
		||||
        if (subscribers == null) {
 | 
			
		||||
@@ -30,29 +35,47 @@ public class Topic {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void reset() {
 | 
			
		||||
        state = NON_INIT;
 | 
			
		||||
        results = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isPublished() {
 | 
			
		||||
        return state == PUBLISHED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void publish() {
 | 
			
		||||
        publish(true, null);
 | 
			
		||||
        publish(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void publish(boolean record) {
 | 
			
		||||
        publish(record, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void publish(boolean record, Object result) {
 | 
			
		||||
        hasPublished = record;
 | 
			
		||||
    public void publish(boolean record, Object... results) {
 | 
			
		||||
        if (record)
 | 
			
		||||
            state = PUBLISHED;
 | 
			
		||||
        this.results = results;
 | 
			
		||||
        if (subscribers != null) {
 | 
			
		||||
            for (WeakReference<Subscriber> subscriber : subscribers) {
 | 
			
		||||
                if (subscriber.get() != null)
 | 
			
		||||
                    subscriber.get().onTopicPublished(this, result);
 | 
			
		||||
                    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.hasPublished) {
 | 
			
		||||
                if (topic.isPublished()) {
 | 
			
		||||
                    onTopicPublished(topic);
 | 
			
		||||
                }
 | 
			
		||||
                topic.subscribe(this);
 | 
			
		||||
@@ -63,13 +86,7 @@ public class Topic {
 | 
			
		||||
                event.unsubscribe(this);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        default void onTopicPublished() {
 | 
			
		||||
            onTopicPublished(null, null);
 | 
			
		||||
        }
 | 
			
		||||
        default void onTopicPublished(Topic topic) {
 | 
			
		||||
            onTopicPublished(topic, null);
 | 
			
		||||
        }
 | 
			
		||||
        void onTopicPublished(Topic topic, Object result);
 | 
			
		||||
        void onTopicPublished(Topic topic);
 | 
			
		||||
        Topic[] getSubscription();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,27 +19,29 @@ import android.support.annotation.StringRes;
 | 
			
		||||
import android.support.design.widget.Snackbar;
 | 
			
		||||
import android.support.v4.app.ActivityCompat;
 | 
			
		||||
import android.support.v4.content.ContextCompat;
 | 
			
		||||
import android.util.Xml;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.reflect.TypeToken;
 | 
			
		||||
import com.topjohnwu.magisk.MagiskManager;
 | 
			
		||||
import com.topjohnwu.magisk.R;
 | 
			
		||||
import com.topjohnwu.magisk.SplashActivity;
 | 
			
		||||
import com.topjohnwu.magisk.components.SnackbarMaker;
 | 
			
		||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
 | 
			
		||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
 | 
			
		||||
import com.topjohnwu.superuser.Shell;
 | 
			
		||||
import com.topjohnwu.superuser.ShellUtils;
 | 
			
		||||
import com.topjohnwu.superuser.io.SuFile;
 | 
			
		||||
import 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.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class Utils {
 | 
			
		||||
 | 
			
		||||
@@ -50,8 +52,7 @@ public class Utils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void uninstallPkg(String pkg) {
 | 
			
		||||
        SuDatabaseHelper.cleanup();
 | 
			
		||||
        Shell.Sync.su("pm uninstall " + pkg);
 | 
			
		||||
        Shell.Sync.su("sudb_clean " + Const.USER_ID, "pm uninstall " + pkg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
 | 
			
		||||
@@ -215,35 +216,71 @@ public class Utils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void dumpPrefs() {
 | 
			
		||||
        Gson gson = new Gson();
 | 
			
		||||
        Map<String, ?> prefs = MagiskManager.get().prefs.getAll();
 | 
			
		||||
        prefs.remove("App Restrictions");
 | 
			
		||||
        String json = gson.toJson(prefs, new TypeToken<Map<String, ?>>(){}.getType());
 | 
			
		||||
        Shell.Sync.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS));
 | 
			
		||||
        MagiskManager mm = MagiskManager.get();
 | 
			
		||||
        // Flush prefs to disk
 | 
			
		||||
        mm.prefs.edit().commit();
 | 
			
		||||
        File xml = new File(mm.getFilesDir().getParent() + "/shared_prefs",
 | 
			
		||||
                mm.getPackageName() + "_preferences.xml");
 | 
			
		||||
        Shell.Sync.su(fmt("for usr in /data/user/*; do cat %s > ${usr}/%s; done", xml, Const.MANAGER_CONFIGS));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void loadPrefs() {
 | 
			
		||||
        SuFile config = new SuFile(fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS), true);
 | 
			
		||||
        List<String> ret = Shell.Sync.su("cat " + config);
 | 
			
		||||
        if (ShellUtils.isValidOutput(ret)) {
 | 
			
		||||
            SharedPreferences.Editor editor = MagiskManager.get().prefs.edit();
 | 
			
		||||
            String json = ret.get(0);
 | 
			
		||||
            Gson gson = new Gson();
 | 
			
		||||
            Map<String, ?> prefMap = gson.fromJson(json, new TypeToken<Map<String, ?>>(){}.getType());
 | 
			
		||||
            editor.clear();
 | 
			
		||||
            for (Map.Entry<String, ?> entry : prefMap.entrySet()) {
 | 
			
		||||
                Object value = entry.getValue();
 | 
			
		||||
                if (value instanceof String) {
 | 
			
		||||
                    editor.putString(entry.getKey(), (String) value);
 | 
			
		||||
                } else if (value instanceof Boolean) {
 | 
			
		||||
                    editor.putBoolean(entry.getKey(), (boolean) value);
 | 
			
		||||
                } else if (value instanceof Number) {
 | 
			
		||||
                    editor.putInt(entry.getKey(), ((Number) value).intValue());
 | 
			
		||||
        if (config.exists()) {
 | 
			
		||||
            MagiskManager mm = MagiskManager.get();
 | 
			
		||||
            SharedPreferences.Editor editor = mm.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();
 | 
			
		||||
            MagiskManager.get().loadConfig();
 | 
			
		||||
            mm.loadConfig();
 | 
			
		||||
            config.delete();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -49,21 +49,10 @@ public class ZipUtils {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void signZip(InputStream is, File output) throws Exception {
 | 
			
		||||
        try (JarMap map = new JarMap(is, false)) {
 | 
			
		||||
            signZip(map, output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void signZip(File input, File output) throws Exception {
 | 
			
		||||
        try (JarMap map = new JarMap(input, false)) {
 | 
			
		||||
            signZip(map, output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void signZip(JarMap input, File output) throws Exception {
 | 
			
		||||
        try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output))) {
 | 
			
		||||
            signZip(input, out);
 | 
			
		||||
        try (JarMap map = new JarMap(input, false);
 | 
			
		||||
             BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output))) {
 | 
			
		||||
            signZip(map, out);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								src/main/res/raw/changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/main/res/raw/changelog.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
### v5.6.3
 | 
			
		||||
- Fix repo loading UI logic
 | 
			
		||||
							
								
								
									
										32
									
								
								src/main/res/raw/sudb.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/main/res/raw/sudb.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
sudb_clean() {
 | 
			
		||||
  local USERID=$1
 | 
			
		||||
  local DIR="/sbin/.core/db-${USERID}"
 | 
			
		||||
  umount -l /data/user*/*/*/databases/su.db $DIR $DIR/*
 | 
			
		||||
  rm -rf $DIR
 | 
			
		||||
  [ "$USERID" = "*" ] && rm -f /data/adb/magisk.db
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sudb_init() {
 | 
			
		||||
  ADB_CONTEXT=`/system/bin/ls -dZ /data/adb | awk '{print $1}'`
 | 
			
		||||
  chcon u:object_r:su_file:s0 /data/adb
 | 
			
		||||
  chmod 777 /data/adb
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sudb_restore() {
 | 
			
		||||
  chcon $ADB_CONTEXT /data/adb
 | 
			
		||||
  chmod 700 /data/adb
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sudb_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-journal
 | 
			
		||||
  chcon u:object_r:su_file:s0 $DIR $DIR/*
 | 
			
		||||
  chmod 700 $DIR
 | 
			
		||||
  chown $USER.$USER $DIR
 | 
			
		||||
  chmod 666 $DIR/*
 | 
			
		||||
}
 | 
			
		||||
@@ -135,9 +135,13 @@
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -186,6 +190,7 @@
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -195,7 +200,7 @@
 | 
			
		||||
    <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">Nur diesmal</string>
 | 
			
		||||
    <string name="once">Einmalig</string>
 | 
			
		||||
    <string name="tenmin">10 Min.</string>
 | 
			
		||||
    <string name="twentymin">20 Min.</string>
 | 
			
		||||
    <string name="thirtymin">30 Min.</string>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,14 +11,14 @@
 | 
			
		||||
 | 
			
		||||
    <!--Status Fragment-->
 | 
			
		||||
    <string name="magisk_version_error">Magisk no está instalado</string>
 | 
			
		||||
    <string name="checking_for_updates">Comprobando actualizaciones…</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">Toque para empezar la comprobación de SafetyNet</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 de SafetyNet fue exitosa</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">Conexión de red perdida</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>
 | 
			
		||||
 | 
			
		||||
@@ -29,13 +29,13 @@
 | 
			
		||||
    <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, encriptará los datos si los datos no están cifrados actualmente.</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 han encontrado módulos</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>
 | 
			
		||||
@@ -47,10 +47,10 @@
 | 
			
		||||
    <string name="reboot_download">Reiniciar en Modo Download</string>
 | 
			
		||||
 | 
			
		||||
    <!--Repo Fragment-->
 | 
			
		||||
    <string name="update_available">Actualización disponible</string>
 | 
			
		||||
    <string name="update_available">Actualización Disponible</string>
 | 
			
		||||
    <string name="installed">Instalado</string>
 | 
			
		||||
    <string name="not_installed">No Instalado</string>
 | 
			
		||||
    <string name="updated_on">Actualizando en: %1$s</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>
 | 
			
		||||
@@ -84,7 +84,7 @@
 | 
			
		||||
    <string name="download">Descargar</string>
 | 
			
		||||
    <string name="download_file_error">Error descargando archivo</string>
 | 
			
		||||
    <string name="reboot">Reiniciar</string>
 | 
			
		||||
    <string name="zip_process_msg">Procesando archivo zip …</string>
 | 
			
		||||
    <string name="zip_process_msg">Procesando archivo zip…</string>
 | 
			
		||||
    <string name="downloading_toast">Descargando %1$s</string>
 | 
			
		||||
    <string name="magisk_update_title">¡Nueva actualización de Magisk disponible!</string>
 | 
			
		||||
    <string name="settings_reboot_toast">Reinicia para aplicar los ajustes</string>
 | 
			
		||||
@@ -94,7 +94,7 @@
 | 
			
		||||
    <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_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>
 | 
			
		||||
@@ -102,8 +102,8 @@
 | 
			
		||||
    <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_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>
 | 
			
		||||
@@ -132,9 +132,13 @@
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -143,10 +147,10 @@
 | 
			
		||||
    <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 archivo hosts fuera de la partición de sistema seguirán habilitados</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">Habilitar archivo hosts fuera de la partición de sistema</string>
 | 
			
		||||
    <string name="settings_hosts_summary">Soporte para aplicaciones de bloqueo de publicidad fuera de la partición de sistema</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>
 | 
			
		||||
@@ -163,8 +167,8 @@
 | 
			
		||||
    <string name="request_timeout_summary">%1$s segundos</string>
 | 
			
		||||
    <string name="settings_su_reauth_title">Re-autenticación</string>
 | 
			
		||||
    <string name="settings_su_reauth_summary">Pedir permisos de superusuario nuevamente si una aplicación es actualizada o reinstalada</string>
 | 
			
		||||
    <string name="settings_su_fingerprint_title">Habilitar la autenticación de huellas digitales</string>
 | 
			
		||||
    <string name="settings_su_fingerprint_summary">Utilice el escáner de huellas digitales para permitir las solicitudes de superusuario</string>
 | 
			
		||||
    <string name="settings_su_fingerprint_title">Habilitar autenticación de Huella Dactilar</string>
 | 
			
		||||
    <string name="settings_su_fingerprint_summary">Utilice el sensor de Huella Dactilar para permitir las solicitudes de superusuario</string>
 | 
			
		||||
 
 | 
			
		||||
    
 | 
			
		||||
    <string name="multiuser_mode">Modo MultiUsuario</string> 
 | 
			
		||||
@@ -184,6 +188,7 @@
 | 
			
		||||
    <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>
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -132,6 +132,8 @@
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -183,6 +185,7 @@
 | 
			
		||||
    <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>
 | 
			
		||||
 
 | 
			
		||||
@@ -132,9 +132,13 @@
 | 
			
		||||
	<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>
 | 
			
		||||
@@ -183,6 +187,7 @@
 | 
			
		||||
	<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>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,10 @@
 | 
			
		||||
    <!--Universal-->
 | 
			
		||||
    
 | 
			
		||||
    <!--Welcome Activity-->
 | 
			
		||||
    <string name="modules">Moduliai</string>
 | 
			
		||||
    <string name="modules">Papildiniai</string>
 | 
			
		||||
    <string name="downloads">Atsisiuntimai</string>
 | 
			
		||||
    <string name="superuser">Super Naudotojas</string>
 | 
			
		||||
    <string name="log">Surašyti (Log)</string>
 | 
			
		||||
    <string name="superuser">Supervartotojas</string>
 | 
			
		||||
    <string name="log">Surašymai</string>
 | 
			
		||||
    <string name="settings">Nustatymai</string>
 | 
			
		||||
    <string name="install">Instaliuoti</string>
 | 
			
		||||
 | 
			
		||||
@@ -28,23 +28,23 @@
 | 
			
		||||
    <string name="keep_dm_verity">Palikti dm-verity</string>
 | 
			
		||||
    <string name="current_magisk_title">Instaliuota versija: %1$s</string>
 | 
			
		||||
    <string name="install_magisk_title">Naujausia versija: %1$s</string>
 | 
			
		||||
    <string name="uninstall">Ištrinti</string>
 | 
			
		||||
    <string name="uninstall_magisk_title">Ištrinti Magisk</string>
 | 
			
		||||
    <string name="uninstall_magisk_msg">Visi moduliai bus išjungti/panaikinti. Roo bus panaikintas ir duomenys bus potencialiai užšifruoti, jeigu jie nėra užšifruoti.</string>
 | 
			
		||||
    <string name="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. Jei duomenys nėra užšifruoti, yra galimybė, kad jie taps užšifruotais..</string>
 | 
			
		||||
    <string name="update">Atnaujinti %1$s</string>
 | 
			
		||||
 | 
			
		||||
    <!--Module Fragment-->
 | 
			
		||||
    <string name="no_info_provided">(Nėra informacijos)</string>
 | 
			
		||||
    <string name="no_modules_found">Modulių nesurasta</string>
 | 
			
		||||
    <string name="update_file_created">Perkrovus sistemą modulis bus atnaulintas</string>
 | 
			
		||||
    <string name="remove_file_created">Perkrovus sistemą modulis bus panaikintas</string>
 | 
			
		||||
    <string name="remove_file_deleted">Perkrovus sistemą modulis nebus panaikintas</string>
 | 
			
		||||
    <string name="disable_file_created">Perkrovus sistemą modulis bus išjungtas, bet ne panaikintas</string>
 | 
			
		||||
    <string name="disable_file_removed">Perkrovus sistemą modulis bus įjungtas</string>
 | 
			
		||||
    <string name="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, bet ne panaikintas</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">Perkraukite, į Download režimą</string>
 | 
			
		||||
    <string name="reboot_download">Perkrauti į Download režimą</string>
 | 
			
		||||
 | 
			
		||||
    <!--Repo Fragment-->
 | 
			
		||||
    <string name="update_available">Galimas atnaujinimas</string>
 | 
			
		||||
@@ -52,15 +52,15 @@
 | 
			
		||||
    <string name="not_installed">Ne instaliuota</string>
 | 
			
		||||
    <string name="updated_on">Atnaujinta: %1$s</string>
 | 
			
		||||
    <string name="sorting_order">Išdėliojimo tvarka</string>
 | 
			
		||||
    <string name="sort_by_name">Išdėlioti pagal pavadinimą</string>
 | 
			
		||||
    <string name="sort_by_update">Išdėlioti pagal paskutinį atnaujinimą</string>
 | 
			
		||||
    <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šsauguti surašymus (log)</string>
 | 
			
		||||
    <string name="menuSaveLog">Išsaugoti surašymus</string>
 | 
			
		||||
    <string name="menuReload">Iš naujo</string>
 | 
			
		||||
    <string name="menuClearLog">Išvalyti surašymus (log)</string>
 | 
			
		||||
    <string name="logs_cleared">Surašymas (log) sėkmingai užrašytas</string>
 | 
			
		||||
    <string name="log_is_empty">Surašymas yra tuščias</string>
 | 
			
		||||
    <string name="menuClearLog">Išvalyti surašymus</string>
 | 
			
		||||
    <string name="logs_cleared">Surašymai pašalinti</string>
 | 
			
		||||
    <string name="log_is_empty">Surašymų nėra</string>
 | 
			
		||||
    <string name="logs_save_failed">Nesugebėjome įrašyti surašymų į SD kortelę:</string>
 | 
			
		||||
 | 
			
		||||
    <!--About Activity-->
 | 
			
		||||
@@ -68,8 +68,9 @@
 | 
			
		||||
    <string name="app_changelog">Pakeitimų sąrašas</string>
 | 
			
		||||
    <string name="translators">Vv2233Bb</string>
 | 
			
		||||
    <string name="app_version">Versija</string>
 | 
			
		||||
 | 
			
		||||
    <string name="app_source_code">Prisidėkite</string>
 | 
			
		||||
    <string name="donation">Auka</string>
 | 
			
		||||
    <string name="donation">Paaukoti</string>
 | 
			
		||||
    <string name="app_translators">Vertėjai</string>
 | 
			
		||||
    <string name="support_thread">Mūsų XDA puslapis</string>
 | 
			
		||||
 | 
			
		||||
@@ -85,9 +86,9 @@
 | 
			
		||||
    <string name="download_file_error">Atsisiunčiant failą įvyko klaida</string>
 | 
			
		||||
    <string name="reboot">Perkrauti</string>
 | 
			
		||||
    <string name="downloading_toast">Atsisiunčiamas %1$s</string>
 | 
			
		||||
    <string name="magisk_update_title">Naujas Magisk atnaujinimas egzistuoja!</string>
 | 
			
		||||
    <string name="magisk_update_title">Atsirado nauja Magisk versija!</string>
 | 
			
		||||
    <string name="settings_reboot_toast">Nustatymų įgalinimui prašome perkrauti telefoną</string>
 | 
			
		||||
    <string name="release_notes">Šios versijos naujos įpatybės</string>
 | 
			
		||||
    <string name="release_notes">Pakeitimai</string>
 | 
			
		||||
    <string name="repo_cache_cleared">Repo failai išvalyti</string>
 | 
			
		||||
    <string name="safetyNet_hide_notice">Ši programėlė naudoja SafetyNet\nMagiskHide tai automatiškai sutvarko</string>
 | 
			
		||||
    <string name="process_error">Proceso klaida</string>
 | 
			
		||||
@@ -114,7 +115,7 @@
 | 
			
		||||
    <string name="boot_file_patch_msg">Pasirinkti boot failą .img ar .img.tar formate.</string>
 | 
			
		||||
    <string name="complete_uninstall">Pilnas pašalinimas</string>
 | 
			
		||||
    <string name="restore_img">Atstatyti boot failą.</string>
 | 
			
		||||
    <string name="uninstall_app">Ištrinti programėlę</string>
 | 
			
		||||
    <string name="uninstall_app">Pašalinti programėlę</string>
 | 
			
		||||
    <string name="restore_done">Atstatymas įvykdytas!</string>
 | 
			
		||||
    <string name="restore_fail">Gamyklinis atstatymo failas neegzistuoja!</string>
 | 
			
		||||
    <string name="uninstall_toast">Magisk Manager bus pašalintas po 5 sekundžių, pašalinus perkraukite telefoną.</string>
 | 
			
		||||
@@ -129,24 +130,28 @@
 | 
			
		||||
    <string name="settings_notification_title">Pranešimai atsiradus atnaujinimui</string>
 | 
			
		||||
    <string name="settings_notification_summary">Parodyti pranešmus atsiradus naujai versijai</string>
 | 
			
		||||
    <string name="settings_clear_cache_title">Išvalyti nereikalingus saugyklos failus</string>
 | 
			
		||||
    <string name="settings_clear_cache_summary">Išvalyti patalpintą informaciją talpykloms internete, priverčia perkrauti inerneto jungtį</string>
 | 
			
		||||
    <string name="settings_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">Pasirinkite boot failo formatą.\nPasirinkite .img įdiegimui per fastboot/download; Pasirinkite .img.tar įdiegimui per ODIN.</string>
 | 
			
		||||
    <string name="settings_core_only_title">Magisk Pagrindinis režimas</string>
 | 
			
		||||
    <string name="settings_core_only_summary">Įgalintos bus tik pagrindines funkcijos, visi moduliai bus išjungti. MagiskSU, Magisk Hide ir Sistemos pedejėjai liks įgalinti</string>
 | 
			
		||||
    <string name="settings_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 funkcijos, 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">Sistemų padejėjų įgalinimas Adblock programėlėms</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>
 | 
			
		||||
@@ -158,7 +163,7 @@
 | 
			
		||||
    <string name="settings_su_request_60">60 sekundžių</string>
 | 
			
		||||
    <string name="superuser_access">Supervartotojo prieiga</string>
 | 
			
		||||
    <string name="auto_response">Automatinis atsakymas</string>
 | 
			
		||||
    <string name="request_timeout">Prašymo laikas baigėsi</string>
 | 
			
		||||
    <string name="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>
 | 
			
		||||
@@ -183,7 +188,8 @@
 | 
			
		||||
    <string name="requester_summary">Root sesijos paveldi jos išprašytojo/s vardų sritį</string>
 | 
			
		||||
    <string name="isolate_summary">Kiekviena root sesija turi savo izoliuotą vardų sritį</string>
 | 
			
		||||
    <string name="android_o_not_support">Negalima įrenginiams naudojantiems Android 8.0+</string>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -200,15 +206,15 @@
 | 
			
		||||
    <string name="su_allow_toast">%1$s gavo Supervartotojo teises</string>
 | 
			
		||||
    <string name="su_deny_toast">%1$s negavo Supervartotojo teisių</string>
 | 
			
		||||
    <string name="no_apps_found">Nėra surastų programėlių</string>
 | 
			
		||||
    <string name="su_snack_grant">Supervartotojo teisių buvo %1$s suteikta</string>
 | 
			
		||||
    <string name="su_snack_deny">Supervartotojo teisių buvo %1$s atmesta</string>
 | 
			
		||||
    <string name="su_snack_notif_on">Buvo įjungta %1$s pranešimų</string>
 | 
			
		||||
    <string name="su_snack_notif_off">Buvo išjungta %1$s pranešimų</string>
 | 
			
		||||
    <string name="su_snack_log_on">%1$s surašymų buvo įjungta</string>
 | 
			
		||||
    <string name="su_snack_log_off">%1$s surašymų buvo išjungta</string>
 | 
			
		||||
    <string name="su_snack_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 veiksmų surašymas yra įgalintas</string>
 | 
			
		||||
    <string name="su_snack_log_off">%1$s veiksmų surašymas yra išjungtas</string>
 | 
			
		||||
    <string name="su_snack_revoke">%1$s teisių atšaukta</string>
 | 
			
		||||
    <string name="su_revoke_title">Atšaukti?</string>
 | 
			
		||||
    <string name="su_revoke_msg">Atšaukti %1$s teisių?</string>
 | 
			
		||||
    <string name="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>
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user