MagiskHide Fragment complete refactor

This commit is contained in:
topjohnwu 2016-11-07 21:06:18 +08:00
parent e6b24d2e3c
commit 23adcb544b
22 changed files with 274 additions and 502 deletions

View File

@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
android { android {
compileSdkVersion 25 compileSdkVersion 25
buildToolsVersion "25.0.0" buildToolsVersion "24.0.2"
defaultConfig { defaultConfig {
applicationId "com.topjohnwu.magisk" applicationId "com.topjohnwu.magisk"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 25 targetSdkVersion 25
versionCode 6 versionCode 7
versionName "2.1" versionName "2.5"
jackOptions { jackOptions {
enabled true enabled true
} }
@ -24,6 +24,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
dexOptions {
preDexLibraries = false
}
} }
repositories { repositories {
jcenter() jcenter()

View File

@ -31,13 +31,13 @@ public class AboutActivity extends AppCompatActivity {
private static final String XDA_THREAD = "http://forum.xda-developers.com/showthread.php?t=3432382"; private static final String XDA_THREAD = "http://forum.xda-developers.com/showthread.php?t=3432382";
private static final String DONATION_URL = "http://topjohnwu.github.io/donate"; private static final String DONATION_URL = "http://topjohnwu.github.io/donate";
@BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.app_version_info) RowItem appVersionInfo; @BindView(R.id.app_version_info) AboutCardRow appVersionInfo;
@BindView(R.id.app_changelog) RowItem appChangelog; @BindView(R.id.app_changelog) AboutCardRow appChangelog;
@BindView(R.id.app_developers) RowItem appDevelopers; @BindView(R.id.app_developers) AboutCardRow appDevelopers;
@BindView(R.id.app_translators) RowItem appTranslators; @BindView(R.id.app_translators) AboutCardRow appTranslators;
@BindView(R.id.app_source_code) RowItem appSourceCode; @BindView(R.id.app_source_code) AboutCardRow appSourceCode;
@BindView(R.id.support_thread) RowItem supportThread; @BindView(R.id.support_thread) AboutCardRow supportThread;
@BindView(R.id.donation) RowItem donation; @BindView(R.id.donation) AboutCardRow donation;
private AlertDialog.Builder builder; private AlertDialog.Builder builder;
@Override @Override

View File

@ -29,7 +29,7 @@ import android.widget.TextView;
/** /**
* @author dvdandroid * @author dvdandroid
*/ */
public class RowItem extends LinearLayout { public class AboutCardRow extends LinearLayout {
private final String title; private final String title;
private final Drawable icon; private final Drawable icon;
@ -40,22 +40,22 @@ public class RowItem extends LinearLayout {
private final View mView; private final View mView;
public RowItem(Context context) { public AboutCardRow(Context context) {
this(context, null); this(context, null);
} }
public RowItem(Context context, AttributeSet attrs) { public AboutCardRow(Context context, AttributeSet attrs) {
this(context, attrs, 0); this(context, attrs, 0);
} }
public RowItem(Context context, AttributeSet attrs, int defStyleAttr) { public AboutCardRow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.info_item_row, this); LayoutInflater.from(context).inflate(R.layout.info_item_row, this);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RowItem, 0, 0); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AboutCardRow, 0, 0);
try { try {
title = a.getString(R.styleable.RowItem_text); title = a.getString(R.styleable.AboutCardRow_text);
icon = a.getDrawable(R.styleable.RowItem_icon); icon = a.getDrawable(R.styleable.AboutCardRow_icon);
} finally { } finally {
a.recycle(); a.recycle();
} }

View File

@ -0,0 +1,99 @@
package com.topjohnwu.magisk;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.utils.Async;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
private List<ApplicationInfo> mList;
private List<String> mHideList;
private Context context;
private PackageManager packageManager;
// Don't show in list...
private static final String[] blackList = {
"com.topjohnwu.magisk",
"com.google.android.gms"
};
public ApplicationAdapter(List<ApplicationInfo> list, List<String> hideList) {
mList = list;
mHideList = hideList;
List<String> bl = Arrays.asList(blackList);
for (int i = 0; i < mList.size(); ++i)
if (bl.contains(mList.get(i).packageName))
mList.remove(i);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
context = parent.getContext();
packageManager = context.getPackageManager();
ButterKnife.bind(this, mView);
return new ViewHolder(mView);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
ApplicationInfo info = mList.get(position);
holder.appIcon.setImageDrawable(info.loadIcon(packageManager));
holder.appName.setText(info.loadLabel(packageManager));
holder.appPackage.setText(info.packageName);
holder.checkBox.setChecked(false);
for (String hidePackage : mHideList) {
if (info.packageName.contains(hidePackage)) {
holder.checkBox.setChecked(true);
break;
}
}
holder.checkBox.setOnCheckedChangeListener((compoundButton, b) -> {
Async.MagiskHide mh = new Async.MagiskHide();
if (b) {
mh.add(info.packageName);
} else {
mh.rm(info.packageName);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.app_package) TextView appPackage;
@BindView(R.id.checkbox) CheckBox checkBox;
public ViewHolder(View itemView) {
super(itemView);
WindowManager windowmanager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
ButterKnife.bind(this, itemView);
DisplayMetrics dimension = new DisplayMetrics();
windowmanager.getDefaultDisplay().getMetrics(dimension);
}
}
}

View File

@ -4,7 +4,6 @@ import android.app.Fragment;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -88,7 +87,7 @@ public class MagiskFragment extends Fragment {
Shell.su("setprop magisk.version " + String.valueOf(remoteMagiskVersion)); Shell.su("setprop magisk.version " + String.valueOf(remoteMagiskVersion));
super.done(); super.done();
} }
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); }.exec();
} }
}, },
magiskLink, magiskLink,
@ -141,7 +140,7 @@ public class MagiskFragment extends Fragment {
appCheckUpdatesProgress.setVisibility(View.VISIBLE); appCheckUpdatesProgress.setVisibility(View.VISIBLE);
magiskCheckUpdatesProgress.setVisibility(View.VISIBLE); magiskCheckUpdatesProgress.setVisibility(View.VISIBLE);
new Async.CheckUpdates(prefs).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new Async.CheckUpdates(prefs).exec();
}); });
if (prefs.getBoolean("update_check_done", false)) { if (prefs.getBoolean("update_check_done", false)) {

View File

@ -1,208 +1,80 @@
package com.topjohnwu.magisk; package com.topjohnwu.magisk;
import android.app.ListFragment; import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.TypedValue; import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ListView;
import com.topjohnwu.magisk.utils.ApplicationAdapter; import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import static com.topjohnwu.magisk.utils.Utils.WhichHide; import butterknife.BindView;
import butterknife.ButterKnife;
public class MagiskHideFragment extends ListFragment { public class MagiskHideFragment extends Fragment {
private PackageManager packageManager = null;
private List<ApplicationInfo> applist = null;
private ApplicationAdapter listadaptor = null;
public ListView listView;
public SharedPreferences prefs;
private int hideVersion;
List<String> arrayBlackList;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
private PackageManager packageManager;
private View mView;
private ApplicationAdapter appAdapter;
@Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); mView = inflater.inflate(R.layout.magisk_hide_fragment, container, false);
View view = inflater.inflate(R.layout.auto_root_fragment, container, false); ButterKnife.bind(this, mView);
int horizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
int verticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
TypedValue tv = new TypedValue();
int actionBarHeight = 130;
if (getActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}
view.setPadding(horizontalMargin, actionBarHeight, horizontalMargin, verticalMargin); packageManager = getActivity().getPackageManager();
hideVersion = WhichHide(getActivity());
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mSwipeRefreshLayout.setRefreshing(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE);
new LoadApps().exec();
});
new LoadApps().exec();
return mView;
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
initializeElements(); mView = this.getView();
super.onResume();
getActivity().setTitle(R.string.magiskhide);
hideVersion = WhichHide(getActivity());
}
private void initializeElements() {
listView = getListView();
packageManager = getActivity().getPackageManager();
new LoadApplications().execute();
} }
private class LoadApps extends Async.RootTask<Void, Void, Void> {
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { protected Void doInBackground(Void... voids) {
Logger.dev("Click"); List<ApplicationInfo> listApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
super.onListItemClick(l, v, position, id); Collections.sort(listApps, (a, b) -> a.loadLabel(packageManager).toString().toLowerCase()
ApplicationInfo app = applist.get(position); .compareTo(b.loadLabel(packageManager).toString().toLowerCase()));
ToggleApp(app.packageName, position, v); List<String> hideList = Shell.su(Async.MAGISK_HIDE_PATH + "list");
appAdapter = new ApplicationAdapter(listApps, hideList);
}
private void ToggleApp(String appToCheck, int position, View v) {
Logger.dev("Magisk", "MagiskHideFragment: ToggleApp called for " + appToCheck);
Set<String> blackListSet = prefs.getStringSet("auto_blacklist", null);
assert blackListSet != null;
arrayBlackList = new ArrayList<>(blackListSet);
String UID = Utils.getAppUID(appToCheck);
if (!arrayBlackList.contains(appToCheck)) {
arrayBlackList.add(appToCheck);
switch (hideVersion) {
case 1 :
Shell.su("/magisk/.core/magiskhide/add " + appToCheck);
break;
case 2 :
Shell.su("/su/suhide/add " + UID);
break;
case 3 :
Shell.su("/su/suhide/add " + UID + "&& /magisk/.core/magiskhide/add " + appToCheck);
break;
default :
break;
}
} else {
for (int i = 0; i < arrayBlackList.size(); i++) {
if (appToCheck.equals(arrayBlackList.get(i))) {
arrayBlackList.remove(i);
}
}
switch (hideVersion) {
case 1 :
Shell.su("/magisk/.core/magiskhide/rm " + appToCheck);
break;
case 2 :
Shell.su("/su/suhide/rm " + UID);
break;
case 3 :
Shell.su("/su/suhide/rm " + UID + "&& /magisk/.core/magiskhide/rm " + appToCheck);
break;
default :
break;
}
}
Logger.dev("Committing set, value is: " + arrayBlackList.toString());
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet("auto_blacklist", new HashSet<>(arrayBlackList));
editor.apply();
listadaptor.UpdateRootStatusView(position, v);
}
private List<ApplicationInfo> checkForLaunchIntent(List<ApplicationInfo> list) {
ArrayList<ApplicationInfo> applist = new ArrayList<>();
for (ApplicationInfo info : list) {
try {
if (null != packageManager.getLaunchIntentForPackage(info.packageName)) {
if (!info.packageName.contains("magisk")) {
applist.add(info);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Collections.sort(applist, new CustomComparator());
return applist;
}
public class CustomComparator implements Comparator<ApplicationInfo> {
@Override
public int compare(ApplicationInfo o1, ApplicationInfo o2) {
return o1.loadLabel(packageManager).toString().compareToIgnoreCase(o2.loadLabel(packageManager).toString());
}
}
private class LoadApplications extends AsyncTask<Void, Void, Void> {
private ProgressDialog progress = null;
@Override
protected Void doInBackground(Void... params) {
applist = checkForLaunchIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA));
listadaptor = new ApplicationAdapter(getActivity(),
R.layout.list_item_app, applist);
return null; return null;
} }
@Override @Override
protected void onCancelled() { protected void onPostExecute(Void aVoid) {
super.onCancelled(); super.onPostExecute(aVoid);
updateUI();
}
} }
@Override private void updateUI() {
protected void onPostExecute(Void result) { recyclerView.setAdapter(appAdapter);
setListAdapter(listadaptor); recyclerView.setVisibility(View.VISIBLE);
progress.dismiss(); mSwipeRefreshLayout.setRefreshing(false);
super.onPostExecute(result);
} }
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(getActivity(), null,
"Loading application info...");
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
} }

View File

@ -4,7 +4,6 @@ import android.app.Fragment;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -59,7 +58,7 @@ public class ModulesFragment extends Fragment {
mSwipeRefreshLayout.setOnRefreshListener(() -> { mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
prefs.edit().putBoolean("module_done", false).apply(); prefs.edit().putBoolean("module_done", false).apply();
new Async.LoadModules(prefs).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); new Async.LoadModules(prefs).exec();
}); });
if (prefs.getBoolean("module_done", false)) { if (prefs.getBoolean("module_done", false)) {
@ -84,7 +83,7 @@ public class ModulesFragment extends Fragment {
// Get the URI of the selected file // Get the URI of the selected file
final Uri uri = data.getData(); final Uri uri = data.getData();
// Get the file path from the URI // Get the file path from the URI
new Async.FlashZIP(getActivity(), uri).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); new Async.FlashZIP(getActivity(), uri).exec();
} }
} }

View File

@ -6,7 +6,6 @@ import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -126,7 +125,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
"rm -rf ../install" "rm -rf ../install"
); );
} }
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); }.exec();
} }
}, },
repo.getZipUrl(), repo.getZipUrl(),

View File

@ -2,7 +2,6 @@ package com.topjohnwu.magisk;
import android.app.Fragment; import android.app.Fragment;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -67,7 +66,7 @@ public class ReposFragment extends Fragment {
mSwipeRefreshLayout.setOnRefreshListener(() -> { mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
prefs.edit().putBoolean("repo_done", false).apply(); prefs.edit().putBoolean("repo_done", false).apply();
new Async.LoadRepos(getActivity()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new Async.LoadRepos(getActivity()).exec();
}); });
if (prefs.getBoolean("repo_done", false)) { if (prefs.getBoolean("repo_done", false)) {

View File

@ -1,118 +0,0 @@
package com.topjohnwu.magisk;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import butterknife.ButterKnife;
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private ListPreference themePreference;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_settings);
PreferenceManager.setDefaultValues(getActivity(), R.xml.app_settings, false);
}
@Override
public void onResume() {
super.onResume();
getActivity().setTitle(R.string.settings);
PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
themePreference = (ListPreference) findPreference("theme");
CheckBoxPreference busyboxPreference = (CheckBoxPreference) findPreference("busybox");
CheckBoxPreference quickTilePreference = (CheckBoxPreference) findPreference("enable_quicktile");
busyboxPreference.setChecked(Utils.commandExists("unzip"));
PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
CheckBoxPreference keepRootOffPreference = (CheckBoxPreference) findPreference("keep_root_off");
CheckBoxPreference hideRootNotificationPreference = (CheckBoxPreference) findPreference("hide_root_notification");
themePreference.setSummary(themePreference.getValue());
if (MagiskFragment.magiskVersion == -1) {
quickTilePreference.setEnabled(false);
keepRootOffPreference.setEnabled(false);
hideRootNotificationPreference.setEnabled(false);
busyboxPreference.setEnabled(false);
} else {
quickTilePreference.setEnabled(true);
keepRootOffPreference.setEnabled(true);
hideRootNotificationPreference.setEnabled(true);
busyboxPreference.setEnabled(true);
}
// calculate margins
int horizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
int verticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
TypedValue tv = new TypedValue();
int actionBarHeight = 130;
if (getActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}
view.setPadding(horizontalMargin, actionBarHeight, horizontalMargin, verticalMargin);
return view;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Logger.dev("Settings: NewValue is " + key);
if (key.equals("theme")) {
String pref = sharedPreferences.getString(key, "");
themePreference.setSummary(pref);
if (pref.equals("Dark")) {
getActivity().getApplication().setTheme(R.style.AppTheme_dh);
} else {
getActivity().getApplication().setTheme(R.style.AppTheme);
}
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("Relaunch", "Settings");
startActivity(intent);
Logger.dev("SettingsFragment: theme is " + pref);
} else if (key.equals("busybox")) {
boolean checked = sharedPreferences.getBoolean("busybox", false);
new Async.LinkBusyBox(checked).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
} else if (key.equals("developer_logging")) {
Logger.devLog = sharedPreferences.getBoolean("developer_logging", false);
} else if (key.equals("shell_logging")) {
Logger.logShell = sharedPreferences.getBoolean("shell_logging", false);
}
}
}

View File

@ -2,10 +2,8 @@ package com.topjohnwu.magisk;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import com.topjohnwu.magisk.utils.Async; import com.topjohnwu.magisk.utils.Async;
@ -13,9 +11,7 @@ import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -45,20 +41,20 @@ public class SplashActivity extends AppCompatActivity {
.putBoolean("update_check_done", false) .putBoolean("update_check_done", false)
.apply(); .apply();
new Async.CheckUpdates(prefs).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new Async.CheckUpdates(prefs).exec();
new Async.constructEnv(getApplicationInfo()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); new Async.constructEnv(getApplicationInfo()).exec();
new Async.LoadModules(prefs) { new Async.LoadModules(prefs) {
@Override @Override
protected void onPostExecute(Void v) { protected void onPostExecute(Void v) {
super.onPostExecute(v); super.onPostExecute(v);
new Async.LoadRepos(getApplicationContext()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new Async.LoadRepos(getApplicationContext()).exec();
// Start main activity // Start main activity
Intent intent = new Intent(getApplicationContext(), MainActivity.class); Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent); startActivity(intent);
finish(); finish();
} }
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); }.exec();
} }
@ -67,7 +63,7 @@ public class SplashActivity extends AppCompatActivity {
Set<String> set = new HashSet<>(); Set<String> set = new HashSet<>();
Set<String> setOriginal = null; Set<String> setOriginal = null;
List<String> hideList = null; List<String> hideList = null;
List<String> addList = null; // List<String> addList = null;
String listCmd, addCmd, addCmd2, rmCmd, rmCmd2; String listCmd, addCmd, addCmd2, rmCmd, rmCmd2;
// Build list of apps currently listed, add to preferences // Build list of apps currently listed, add to preferences
@ -108,13 +104,13 @@ public class SplashActivity extends AppCompatActivity {
} }
setOriginal = prefs.getStringSet("auto_blacklist", set); setOriginal = prefs.getStringSet("auto_blacklist", set);
if (hideList != null) { // if (hideList != null) {
for (String item : hideList) { // for (String item : hideList) {
if (!(setOriginal.contains(item))) { // if (!(setOriginal.contains(item))) {
addList.add(item); // addList.add(item);
} // }
} // }
} // }
SharedPreferences.Editor editor = prefs.edit(); SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet("auto_blacklist", set); editor.putStringSet("auto_blacklist", set);

View File

@ -1,116 +0,0 @@
package com.topjohnwu.magisk.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import java.util.List;
import java.util.Set;
public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
private List<ApplicationInfo> appsList = null;
private Context context;
private PackageManager packageManager;
public SharedPreferences prefs;
public ApplicationAdapter(Context context, int textViewResourceId,
List<ApplicationInfo> appsList) {
super(context, textViewResourceId, appsList);
this.context = context;
this.appsList = appsList;
packageManager = context.getPackageManager();
}
@Override
public int getCount() {
return ((null != appsList) ? appsList.size() : 0);
}
@Override
public ApplicationInfo getItem(int position) {
return ((null != appsList) ? appsList.get(position) : null);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
if (null == view) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item_app, null);
}
ApplicationInfo applicationInfo = appsList.get(position);
if (null != applicationInfo) {
TextView appName = (TextView) view.findViewById(R.id.app_name);
TextView packageName = (TextView) view.findViewById(R.id.app_paackage);
ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
CheckBox statusview = (CheckBox) view.findViewById(R.id.checkbox);
appName.setText(applicationInfo.loadLabel(packageManager));
packageName.setText(applicationInfo.packageName);
iconview.setImageDrawable(applicationInfo.loadIcon(packageManager));
if (CheckApp(applicationInfo.packageName)) {
statusview.setChecked(true);
} else {
statusview.setChecked(false);
}
}
return view;
}
public void UpdateRootStatusView(int position, View convertView) {
View view = convertView;
if (null == view) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item_app, null);
}
ApplicationInfo applicationInfo = appsList.get(position);
if (null != applicationInfo) {
CheckBox statusview = (CheckBox) view.findViewById(R.id.checkbox);
if (CheckApp(applicationInfo.packageName)) {
statusview.setChecked(true);
} else {
statusview.setChecked(false);
}
}
}
private boolean CheckApp(String appToCheck) {
boolean starter = false;
Set<String> set = prefs.getStringSet("auto_blacklist", null);
if (set != null) {
for (String string : set) {
if (string.contains(appToCheck)) {
starter = true;
}
}
}
return starter;
}
}

View File

@ -31,9 +31,24 @@ import java.util.List;
public class Async { public class Async {
public static final String UPDATE_JSON = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/updates/magisk_update.json"; public abstract static class RootTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
@SafeVarargs
public final void exec(Params... params) {
executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
}
}
public static class constructEnv extends AsyncTask<Void, Void, Void> { public abstract static class NormalTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
@SafeVarargs
public final void exec(Params... params) {
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
}
}
public static final String UPDATE_JSON = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/updates/magisk_update.json";
public static final String MAGISK_HIDE_PATH = "/magisk/.core/magiskhide/";
public static class constructEnv extends NormalTask<Void, Void, Void> {
ApplicationInfo mInfo; ApplicationInfo mInfo;
@ -59,12 +74,23 @@ public class Async {
"ln -s " + zip + " zip" "ln -s " + zip + " zip"
); );
} }
Shell.su("PATH=" + toolPath + ":$PATH");
return null; return null;
} }
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
new RootTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
Shell.su("PATH=" + mInfo.dataDir + "/tools:$PATH");
return null;
}
}.exec();
}
} }
public static class CheckUpdates extends AsyncTask<Void, Void, Void> { public static class CheckUpdates extends NormalTask<Void, Void, Void> {
private SharedPreferences mPrefs; private SharedPreferences mPrefs;
@ -102,7 +128,7 @@ public class Async {
} }
} }
public static class LoadModules extends AsyncTask<Void, Void, Void> { public static class LoadModules extends RootTask<Void, Void, Void> {
private SharedPreferences mPrefs; private SharedPreferences mPrefs;
@ -122,7 +148,7 @@ public class Async {
} }
} }
public static class LoadRepos extends AsyncTask<Void, Void, Void> { public static class LoadRepos extends NormalTask<Void, Void, Void> {
private Context mContext; private Context mContext;
@ -143,7 +169,7 @@ public class Async {
} }
} }
public static class FlashZIP extends AsyncTask<Void, Void, Integer> { public static class FlashZIP extends RootTask<Void, Void, Integer> {
protected Uri mUri; protected Uri mUri;
protected File mFile, sdFile; protected File mFile, sdFile;
@ -306,7 +332,7 @@ public class Async {
protected void done() { protected void done() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
prefs.edit().putBoolean("module_done", false).putBoolean("update_check_done", true).apply(); prefs.edit().putBoolean("module_done", false).putBoolean("update_check_done", true).apply();
new LoadModules(prefs).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); new LoadModules(prefs).exec();
AlertDialog.Builder builder; AlertDialog.Builder builder;
String theme = prefs.getString("theme", ""); String theme = prefs.getString("theme", "");
@ -345,4 +371,23 @@ public class Async {
return null; return null;
} }
} }
public static class MagiskHide extends RootTask<Object, Void, Void> {
@Override
protected Void doInBackground(Object... params) {
boolean add = (boolean) params[0];
String packageName = (String) params[1];
Shell.su(MAGISK_HIDE_PATH + (add ? "add " : "rm ") + packageName);
return null;
}
public void add(CharSequence packageName) {
exec(true, packageName);
}
public void rm(CharSequence packageName) {
exec(false, packageName);
}
}
} }

View File

@ -21,7 +21,6 @@ import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;

View File

@ -1,4 +0,0 @@
<vector android:height="24dp" android:viewportHeight="400.0"
android:viewportWidth="400.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1.00" android:fillColor="#fff" android:pathData="M200.6,24.2C231.8,24.2 263,33 289.6,49.5C304.7,58.8 318.2,70.7 329.8,84.1C351.5,109.6 365.2,141.7 368.8,175C373.6,217.4 361.5,261.5 335.5,295.5C334.2,297.1 332.8,298.7 331.9,300.7C341.7,310.1 351,320 360.9,329.3C322.7,339.3 284.5,349.6 246.3,359.9C256.4,323.5 266,287 275.7,250.5C262.4,250.5 249.1,250.5 235.8,250.5C228.5,269.8 221.2,289.1 214.1,308.4C205.9,308.6 197.8,308.5 189.6,308.5C188.4,306.7 187.1,304.9 185.9,303C192.4,285.5 199.1,268 205.6,250.5C189.5,250.6 173.4,250.3 157.4,250.6C150.4,270 142.9,289.2 135.8,308.5C129.8,308.5 123.9,308.4 117.9,308.6C130.4,317.8 144,325.6 158.9,330.3C171.9,334.6 185.6,336.6 199.4,336.7C199.4,349.4 199.3,362.1 199.4,374.8C165.8,374.9 132.2,364.5 104.4,345.6C91.7,337 80.3,326.5 70.2,314.9C48.5,289.4 34.8,257.3 31.2,224C26.3,180.4 39.2,134.9 66.8,100.7C67.2,99.9 67.7,99.2 68.1,98.4C58.3,88.9 49,79 39.1,69.7C77.3,59.7 115.6,49.4 153.7,39.1C143.6,75.7 133.8,112.5 124.1,149.3C137.9,149.3 151.7,149.2 165.5,149.3C172.9,130 180.2,110.6 187.3,91.2C195.5,90.8 203.7,91 211.8,91C213,92.8 214.3,94.6 215.5,96.3C209.1,114 202.3,131.6 195.8,149.2C211.8,149.3 227.8,149.2 243.9,149.3C251.2,129.9 258.3,110.3 265.8,90.9C271.5,90.8 277.3,91.6 282.9,90.4C280.2,89.5 278.1,87.7 275.9,86.1C254,70.7 227.4,62.2 200.6,62.3C200.6,49.6 200.7,36.9 200.6,24.2M292.5,100C286.4,116.4 280.2,132.8 274,149.3C280.9,149.2 287.8,149.3 294.7,149.2C296,150.8 297.3,152.4 298.6,153.9C297.1,162.1 295.7,170.3 294.3,178.5C283.9,178.5 273.4,178.5 262.9,178.5C257.5,192.7 252.1,206.9 246.9,221.2C258.7,221.3 270.5,221.1 282.3,221.3C283.5,222.9 284.8,224.4 286.1,225.9C284.9,233.7 283.4,241.4 282.1,249.1C281.6,251 283.6,252.1 284.6,253.3C291.5,259.8 297.7,266.9 304.8,273.1C312.9,262.1 319.6,250.1 324.2,237.3C334.3,208.7 334.2,176.7 323.7,148.3C317,130.1 306.4,113.4 292.5,100M95.2,125.9C86.2,138 79,151.4 74.5,165.8C65.3,194.4 66.4,226.3 77.6,254.2C84.6,271.5 95.1,287.4 108.7,300.1C114.9,283.6 121.3,267.1 127.2,250.5C121.5,250.5 115.8,250.5 110,250.5C108.6,250.4 106.7,251 105.8,249.5C104.5,247.9 102.3,246.3 102.9,244.1C104.2,236.5 105.5,228.9 106.8,221.2C117.4,221.2 128.1,221.4 138.7,221.1C143.9,206.9 149.3,192.7 154.6,178.5C142.9,178.4 131.1,178.6 119.3,178.4C117.6,177.3 116.4,175.3 115,173.8C116.3,165.8 117.9,157.9 119,150C118.3,148.2 116.6,147.1 115.3,145.7C108.6,139.2 102.3,132.1 95.2,125.9M168.8,221.2C184.8,221.2 200.8,221.3 216.8,221.2C222.2,207 227.5,192.8 232.8,178.5C216.8,178.5 200.7,178.5 184.6,178.5C179.4,192.8 174,207 168.8,221.2Z"/>
</vector>

View File

@ -57,35 +57,35 @@
android:textAppearance="@style/TextAppearance.AppCompat.Headline"/> android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>
</LinearLayout> </LinearLayout>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/app_version_info" android:id="@+id/app_version_info"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_info_outline" app:icon="@drawable/ic_info_outline"
app:text="@string/app_version"/> app:text="@string/app_version"/>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/app_changelog" android:id="@+id/app_changelog"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_history" app:icon="@drawable/ic_history"
app:text="@string/app_changelog"/> app:text="@string/app_changelog"/>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/app_developers" android:id="@+id/app_developers"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_person" app:icon="@drawable/ic_person"
app:text="@string/app_developers"/> app:text="@string/app_developers"/>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/app_translators" android:id="@+id/app_translators"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_language" app:icon="@drawable/ic_language"
app:text="@string/app_translators"/> app:text="@string/app_translators"/>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/app_source_code" android:id="@+id/app_source_code"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -110,14 +110,14 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:orientation="vertical"> android:orientation="vertical">
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/support_thread" android:id="@+id/support_thread"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_xda" app:icon="@drawable/ic_xda"
app:text="@string/support_thread"/> app:text="@string/support_thread"/>
<com.topjohnwu.magisk.RowItem <com.topjohnwu.magisk.AboutCardRow
android:id="@+id/donation" android:id="@+id/donation"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -1,14 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/Top">
<ListView android:id="@android:id/list"
android:divider="@android:color/transparent"
android:dividerHeight="@dimen/card_divider_space"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="6dp"/>
</LinearLayout>

View File

@ -45,14 +45,13 @@
android:id="@+id/app_name" android:id="@+id/app_name"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="false"
android:layout_weight="1" android:layout_weight="1"
android:paddingEnd="3dp" android:paddingEnd="3dp"
android:paddingStart="3dp" android:paddingStart="3dp"
android:textStyle="bold"/> android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/app_paackage" android:id="@+id/app_package"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="25dp" android:layout_height="25dp"
android:ellipsize="marquee" android:ellipsize="marquee"
@ -74,10 +73,10 @@
android:id="@+id/checkbox" android:id="@+id/checkbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false" android:focusable="false"
android:gravity="center" android:gravity="center"
android:src="@drawable/ic_menu_overflow_material"/> android:src="@drawable/ic_menu_overflow_material"
android:checked="false" />
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:dividerHeight="@dimen/card_divider_space"
android:paddingBottom="60dip"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@ -17,7 +17,7 @@
<resources> <resources>
<declare-styleable name="RowItem"> <declare-styleable name="AboutCardRow">
<attr name="icon" format="reference"/> <attr name="icon" format="reference"/>
<attr name="text" format="string"/> <attr name="text" format="string"/>
<attr name="cardStyle" format="reference"/> <attr name="cardStyle" format="reference"/>

View File

@ -43,7 +43,6 @@
<string name="menuSaveToSd">Save to SD</string> <string name="menuSaveToSd">Save to SD</string>
<string name="menuSend">Send</string> <string name="menuSend">Send</string>
<string name="menuReload">Reload</string> <string name="menuReload">Reload</string>
<string name="sdcard_not_writable">SD card not found or not writable</string>
<string name="menuClearLog">Clear log now</string> <string name="menuClearLog">Clear log now</string>
<string name="logs_cleared">Log successfully cleared</string> <string name="logs_cleared">Log successfully cleared</string>
<string name="logs_clear_failed">Could not clear the log:</string> <string name="logs_clear_failed">Could not clear the log:</string>
@ -66,7 +65,6 @@
<string name="permissionNotGranted">This feature will not work without permission to write external storage.</string> <string name="permissionNotGranted">This feature will not work without permission to write external storage.</string>
<string name="no_root_access">No root access, functionality limited</string> <string name="no_root_access">No root access, functionality limited</string>
<string name="no_thanks">No thanks</string> <string name="no_thanks">No thanks</string>
<string name="accessibility_service_description">Accessibility service required for Magisk auto-unroot feature</string>
<string name="update_title">%1$s Update!</string> <string name="update_title">%1$s Update!</string>
<string name="update_msg">New version v%2$s of %1$s is available!\nChangelog:\n%3$s</string> <string name="update_msg">New version v%2$s of %1$s is available!\nChangelog:\n%3$s</string>
<string name="repo_install_title">Install %1$s</string> <string name="repo_install_title">Install %1$s</string>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- These options MUST be specified here in order for the events to be received on first
start in Android 4.1.1 -->
<accessibility-service
xmlns:tools="http://schemas.android.com/tools"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagIncludeNotImportantViews"
android:description="@string/accessibility_service_description"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="UnusedAttribute"/>