Commit 23adcb54 authored by topjohnwu's avatar topjohnwu

MagiskHide Fragment complete refactor

parent e6b24d2e
...@@ -2,14 +2,14 @@ apply plugin: 'com.android.application' ...@@ -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 { ...@@ -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()
......
...@@ -25,19 +25,19 @@ import java.io.InputStream; ...@@ -25,19 +25,19 @@ import java.io.InputStream;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
public class AboutActivity extends AppCompatActivity { public class AboutActivity extends AppCompatActivity {
private static final String SOURCE_CODE_URL = "https://github.com/topjohnwu/MagiskManager"; private static final String SOURCE_CODE_URL = "https://github.com/topjohnwu/MagiskManager";
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
......
...@@ -29,7 +29,7 @@ import android.widget.TextView; ...@@ -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 { ...@@ -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();
} }
......
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);
}
}
}
\ No newline at end of file
...@@ -4,7 +4,6 @@ import android.app.Fragment; ...@@ -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 { ...@@ -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 { ...@@ -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)) {
......
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;
@Override @BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @BindView(R.id.recyclerView) RecyclerView recyclerView;
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
View view = inflater.inflate(R.layout.auto_root_fragment, container, false);
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); private PackageManager packageManager;
hideVersion = WhichHide(getActivity()); private View mView;
return view; private ApplicationAdapter appAdapter;
}
@Nullable
@Override @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); mView = inflater.inflate(R.layout.magisk_hide_fragment, container, false);
ButterKnife.bind(this, mView);
packageManager = getActivity().getPackageManager();
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() { private class LoadApps extends Async.RootTask<Void, Void, Void> {
listView = getListView();
packageManager = getActivity().getPackageManager();
new LoadApplications().execute();
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Logger.dev("Click");
super.onListItemClick(l, v, position, id);
ApplicationInfo app = applist.get(position);
ToggleApp(app.packageName, position, v);
}
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 @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... voids) {
applist = checkForLaunchIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA)); List<ApplicationInfo> listApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
listadaptor = new ApplicationAdapter(getActivity(), Collections.sort(listApps, (a, b) -> a.loadLabel(packageManager).toString().toLowerCase()
R.layout.list_item_app, applist); .compareTo(b.loadLabel(packageManager).toString().toLowerCase()));
List<String> hideList = Shell.su(Async.MAGISK_HIDE_PATH + "list");
appAdapter = new ApplicationAdapter(listApps, hideList);
return null; return null;
} }
@Override @Override
protected void onCancelled() { protected void onPostExecute(Void aVoid) {
super.onCancelled(); super.onPostExecute(aVoid);
} updateUI();
@Override
protected void onPostExecute(Void result) {
setListAdapter(listadaptor);
progress.dismiss();
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(getActivity(), null,
"Loading application info...");
super.onPreExecute();
} }
}
@Override private void updateUI() {
protected void onProgressUpdate(Void... values) { recyclerView.setAdapter(appAdapter);
super.onProgressUpdate(values); recyclerView.setVisibility(View.VISIBLE);
} mSwipeRefreshLayout.setRefreshing(false);
} }
} }
\ No newline at end of file
...@@ -4,7 +4,6 @@ import android.app.Fragment; ...@@ -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 { ...@@ -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 { ...@@ -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();
} }
} }
......
...@@ -6,7 +6,6 @@ import android.animation.ValueAnimator; ...@@ -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> ...@@ -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(),
......
...@@ -2,7 +2,6 @@ package com.topjohnwu.magisk; ...@@ -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 { ...@@ -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)) {
......
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);
}
}
}
\ No newline at end of file
...@@ -2,10 +2,8 @@ package com.topjohnwu.magisk; ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
......
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;
}
}
\ No newline at end of file
...@@ -31,9 +31,24 @@ import java.util.List; ...@@ -31,9 +31,24 @@ import java.util.List;
public class Async { public class Async {
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 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 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 AsyncTask<Void, Void, Void> { public static class constructEnv extends NormalTask<Void, Void, Void> {
ApplicationInfo mInfo; ApplicationInfo mInfo;
...@@ -59,12 +74,23 @@ public class Async { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
}
}
} }
...@@ -21,7 +21,6 @@ import java.io.UnsupportedEncodingException; ...@@ -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;
......
<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>
...@@ -57,35 +57,35 @@ ...@@ -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 @@ ...@@ -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"
......
<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>
\ No newline at end of file
...@@ -45,14 +45,13 @@ ...@@ -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 @@ ...@@ -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>
......
<?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>
\ No newline at end of file
...@@ -17,7 +17,7 @@ ...@@ -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"/>
......
...@@ -43,7 +43,6 @@ ...@@ -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 @@ ...@@ -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>
......
<?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"/>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment