diff --git a/app-core/src/main/java/com/topjohnwu/magisk/Config.java b/app-core/src/main/java/com/topjohnwu/magisk/Config.java index dfc4d84de..fe9c5a9c1 100644 --- a/app-core/src/main/java/com/topjohnwu/magisk/Config.java +++ b/app-core/src/main/java/com/topjohnwu/magisk/Config.java @@ -66,6 +66,7 @@ public class Config { public static final String DARK_THEME = "dark_theme"; public static final String ETAG_KEY = "ETag"; public static final String REPO_ORDER = "repo_order"; + public static final String SHOW_SYSTEM_APP = "show_system"; } public static class Value { @@ -108,16 +109,17 @@ public class Config { // prefs bool defs.putBoolean(Key.CHECK_UPDATES, true); - // defs.putBoolean(Const.Key.DARK_THEME, false); - // defs.putBoolean(Const.Key.SU_REAUTH, false); - // defs.putBoolean(Const.Key.MAGISKHIDE, false); - // defs.putBoolean(Const.Key.COREONLY, false); + // defs.putBoolean(Key.DARK_THEME, false); + // defs.putBoolean(Key.SU_REAUTH, false); + // defs.putBoolean(Key.MAGISKHIDE, false); + // defs.putBoolean(Key.COREONLY, false); + // defs.putBoolean(Key.SHOW_SYSTEM_APP, false); // prefs string defs.putString(Key.CUSTOM_CHANNEL, ""); defs.putString(Key.BOOT_FORMAT, ".img"); defs.putString(Key.LOCALE, ""); - // defs.putString(Const.Key.ETAG_KEY, null); + // defs.putString(Key.ETAG_KEY, null); // db int defs.putInt(Key.ROOT_ACCESS, Value.ROOT_ACCESS_APPS_AND_ADB); @@ -125,10 +127,10 @@ public class Config { defs.putInt(Key.SU_MULTIUSER_MODE, Value.MULTIUSER_MODE_OWNER_ONLY); // db bool - // defs.putBoolean(Const.Key.SU_FINGERPRINT, false); + // defs.putBoolean(Key.SU_FINGERPRINT, false); // db strings - // defs.putString(Const.Key.SU_MANAGER, null); + // defs.putString(Key.SU_MANAGER, null); } public static void loadMagiskInfo() { @@ -245,6 +247,7 @@ public class Config { case Key.CHECK_UPDATES: case Key.MAGISKHIDE: case Key.COREONLY: + case Key.SHOW_SYSTEM_APP: return PREF_BOOL; case Key.CUSTOM_CHANNEL: diff --git a/app/src/full/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java b/app/src/full/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java index 68c7fb13c..e24b99299 100644 --- a/app/src/full/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java +++ b/app/src/full/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java @@ -2,14 +2,13 @@ package com.topjohnwu.magisk.adapters; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.AsyncTask; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; -import android.widget.Filter; import android.widget.ImageView; import android.widget.TextView; @@ -18,6 +17,7 @@ import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.superuser.Shell; +import com.topjohnwu.superuser.internal.UiThreadHandler; import java.util.ArrayList; import java.util.Collections; @@ -25,22 +25,30 @@ import java.util.Iterator; import java.util.List; import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; import androidx.recyclerview.widget.RecyclerView; import butterknife.BindView; public class ApplicationAdapter extends RecyclerView.Adapter { - private List fullList, showList; + private static PackageInfo PLATFORM; + + private List fullList, showList; private List hideList; private PackageManager pm; - private ApplicationFilter filter; + private boolean showSystem; public ApplicationAdapter(Context context) { fullList = showList = Collections.emptyList(); hideList = Collections.emptyList(); - filter = new ApplicationFilter(); pm = context.getPackageManager(); - AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps); + showSystem = false; + if (PLATFORM == null) { + try { + PLATFORM = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES); + } catch (PackageManager.NameNotFoundException ignored) {} + } + AsyncTask.SERIAL_EXECUTOR.execute(this::loadApps); } @NonNull @@ -50,12 +58,17 @@ public class ApplicationAdapter extends RecyclerView.Adapter i = fullList.iterator(); i.hasNext(); ) { - ApplicationInfo info = i.next(); - if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled || info.uid == 1000) { + for (Iterator i = fullList.iterator(); i.hasNext(); ) { + PackageInfo info = i.next(); + if (Const.HIDE_BLACKLIST.contains(info.packageName) || + /* Do not show disabled apps */ + !info.applicationInfo.enabled || + /* Never show platform apps */ + PLATFORM.signatures[0].equals(info.signatures[0])) { i.remove(); } } @@ -63,7 +76,8 @@ public class ApplicationAdapter extends RecyclerView.Adapter { + showList = new ArrayList<>(); + if (constraint == null || constraint.length() == 0) { + for (PackageInfo info : fullList) { + if (systemFilter(info)) + showList.add(info); + } + } else { + String filter = constraint.toLowerCase(); + for (PackageInfo info : fullList) { + if ((contains(Utils.getAppLabel(info.applicationInfo, pm), filter) || + contains(info.packageName, filter)) && systemFilter(info)) { + showList.add(info); + } + } + } + UiThreadHandler.run(this::notifyDataSetChanged); + }); } public void refresh() { @@ -119,33 +166,4 @@ public class ApplicationAdapter extends RecyclerView.Adapter(); - String filter = constraint.toString().toLowerCase(); - for (ApplicationInfo info : fullList) { - if (lowercaseContains(Utils.getAppLabel(info, pm), filter) - || lowercaseContains(info.packageName, filter)) { - showList.add(info); - } - } - } - return null; - } - - @Override - protected void publishResults(CharSequence constraint, FilterResults results) { - notifyDataSetChanged(); - } - } } diff --git a/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskHideFragment.java b/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskHideFragment.java index ac9599db4..836ca853f 100644 --- a/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskHideFragment.java +++ b/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskHideFragment.java @@ -4,10 +4,12 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.SearchView; +import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.adapters.ApplicationAdapter; import com.topjohnwu.magisk.components.BaseFragment; @@ -23,10 +25,9 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber @BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; @BindView(R.id.recyclerView) RecyclerView recyclerView; - SearchView search; - - private ApplicationAdapter appAdapter; + private SearchView search; + private ApplicationAdapter adapter; private SearchView.OnQueryTextListener searchListener; @Override @@ -41,22 +42,22 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false); unbinder = new MagiskHideFragment_ViewBinding(this, view); - appAdapter = new ApplicationAdapter(requireActivity()); - recyclerView.setAdapter(appAdapter); + adapter = new ApplicationAdapter(requireActivity()); + recyclerView.setAdapter(adapter); mSwipeRefreshLayout.setRefreshing(true); - mSwipeRefreshLayout.setOnRefreshListener(appAdapter::refresh); + mSwipeRefreshLayout.setOnRefreshListener(adapter::refresh); searchListener = new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { - appAdapter.filter(query); + adapter.filter(query); return false; } @Override public boolean onQueryTextChange(String newText) { - appAdapter.filter(newText); + adapter.filter(newText); return false; } }; @@ -71,6 +72,21 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber inflater.inflate(R.menu.menu_magiskhide, menu); search = (SearchView) menu.findItem(R.id.app_search).getActionView(); search.setOnQueryTextListener(searchListener); + boolean showSystem = Config.get(Config.Key.SHOW_SYSTEM_APP); + menu.findItem(R.id.show_system).setChecked(showSystem); + adapter.setShowSystem(showSystem); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.show_system) { + boolean showSystem = !item.isChecked(); + item.setChecked(showSystem); + Config.set(Config.Key.SHOW_SYSTEM_APP, showSystem); + adapter.setShowSystem(showSystem); + adapter.filter(search.getQuery().toString()); + } + return true; } @Override @@ -81,6 +97,6 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber @Override public void onPublish(int topic, Object[] result) { mSwipeRefreshLayout.setRefreshing(false); - appAdapter.filter(search.getQuery().toString()); + adapter.filter(search.getQuery().toString()); } } diff --git a/app/src/full/res/menu/menu_magiskhide.xml b/app/src/full/res/menu/menu_magiskhide.xml index 448057799..6a44ae6cf 100644 --- a/app/src/full/res/menu/menu_magiskhide.xml +++ b/app/src/full/res/menu/menu_magiskhide.xml @@ -7,4 +7,10 @@ android:title="" app:actionViewClass="android.widget.SearchView" app:showAsAction="always"/> + + + \ No newline at end of file diff --git a/app/src/full/res/values/strings.xml b/app/src/full/res/values/strings.xml index 83805b8e7..2ba68c233 100644 --- a/app/src/full/res/values/strings.xml +++ b/app/src/full/res/values/strings.xml @@ -232,4 +232,7 @@ Target UID: %1$d Command: %1$s + + Show system apps +