More root stuff
Because we can can can...
This commit is contained in:
parent
3fe5647a15
commit
8a8aa1337b
@ -12,12 +12,24 @@
|
|||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
||||||
|
<service
|
||||||
|
android:label="@string/accessibility_service_name"
|
||||||
|
android:name=".MonitorService"
|
||||||
|
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.accessibilityservice.AccessibilityService"/>
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.accessibilityservice"
|
||||||
|
android:resource="@xml/accessibilityservice"/>
|
||||||
|
</service>
|
||||||
<activity
|
<activity
|
||||||
android:name=".WelcomeActivity"
|
android:name=".WelcomeActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@ -73,9 +85,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".MonitorService"
|
|
||||||
android:exported="false" />
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -9,7 +9,6 @@ import android.os.Bundle;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.ListFragment;
|
import android.support.v4.app.ListFragment;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -30,7 +29,7 @@ public class AutoRootFragment extends ListFragment {
|
|||||||
private ApplicationAdapter listadaptor = null;
|
private ApplicationAdapter listadaptor = null;
|
||||||
public ListView listView;
|
public ListView listView;
|
||||||
public SharedPreferences prefs;
|
public SharedPreferences prefs;
|
||||||
List<String> arrayBlackList, arrayWhiteList;
|
List<String> arrayBlackList;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
@ -49,9 +48,6 @@ public class AutoRootFragment extends ListFragment {
|
|||||||
set.add("com.google.android.apps.walletnfcrel");
|
set.add("com.google.android.apps.walletnfcrel");
|
||||||
set.add("com.google.android.gms");
|
set.add("com.google.android.gms");
|
||||||
editor.putStringSet("auto_blacklist", set);
|
editor.putStringSet("auto_blacklist", set);
|
||||||
set.clear();
|
|
||||||
set.add("com.kermidas.TitaniumBackupPro");
|
|
||||||
editor.putStringSet("auto_whitelist", set);
|
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
new LoadApplications().execute();
|
new LoadApplications().execute();
|
||||||
@ -75,29 +71,15 @@ public class AutoRootFragment extends ListFragment {
|
|||||||
private void ToggleApp(String appToCheck, int position, View v) {
|
private void ToggleApp(String appToCheck, int position, View v) {
|
||||||
|
|
||||||
Set<String> blackListSet = prefs.getStringSet("auto_blacklist", null);
|
Set<String> blackListSet = prefs.getStringSet("auto_blacklist", null);
|
||||||
Set<String> whiteListSet = prefs.getStringSet("auto_whitelist", null);
|
|
||||||
|
|
||||||
assert blackListSet != null;
|
assert blackListSet != null;
|
||||||
arrayBlackList = new ArrayList<>(blackListSet);
|
arrayBlackList = new ArrayList<>(blackListSet);
|
||||||
assert whiteListSet != null;
|
|
||||||
arrayWhiteList = new ArrayList<>(whiteListSet);
|
|
||||||
Log.d("Magisk", "Trying to toggle for " + appToCheck + " stringset is " + arrayBlackList.toString());
|
|
||||||
|
|
||||||
if ((!arrayBlackList.contains(appToCheck)) && (!arrayWhiteList.contains(appToCheck))) {
|
if (!arrayBlackList.contains(appToCheck)) {
|
||||||
Log.d("Magisk", "App is not in any array, adding to whitelist");
|
|
||||||
arrayWhiteList.add(appToCheck);
|
|
||||||
|
|
||||||
} else if (arrayWhiteList.contains(appToCheck)) {
|
|
||||||
Log.d("Magisk", "App is in whitelist, moving to blacklist");
|
|
||||||
for (int i = 0; i < arrayWhiteList.size(); i++) {
|
|
||||||
if (appToCheck.equals(arrayWhiteList.get(i))) {
|
|
||||||
arrayWhiteList.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arrayBlackList.add(appToCheck);
|
arrayBlackList.add(appToCheck);
|
||||||
|
|
||||||
} else if (arrayBlackList.contains(appToCheck)) {
|
} else {
|
||||||
Log.d("Magisk", "App is in Blacklist, removing");
|
|
||||||
for (int i = 0; i < arrayBlackList.size(); i++) {
|
for (int i = 0; i < arrayBlackList.size(); i++) {
|
||||||
if (appToCheck.equals(arrayBlackList.get(i))) {
|
if (appToCheck.equals(arrayBlackList.get(i))) {
|
||||||
arrayBlackList.remove(i);
|
arrayBlackList.remove(i);
|
||||||
@ -105,12 +87,7 @@ public class AutoRootFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Set<String> set2 = new HashSet<>(arrayBlackList);
|
prefs.edit().putStringSet("auto_blacklist", new HashSet<>(arrayBlackList)).apply();
|
||||||
Log.d("Magisk", "Committing set, value is: " + set2);
|
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
|
||||||
editor.putStringSet("auto_blacklist", new HashSet<>(arrayBlackList));
|
|
||||||
editor.putStringSet("auto_whitelist", new HashSet<>(arrayWhiteList));
|
|
||||||
editor.apply();
|
|
||||||
listadaptor.UpdateRootStatusView(position, v);
|
listadaptor.UpdateRootStatusView(position, v);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,28 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
|
import android.accessibilityservice.AccessibilityService;
|
||||||
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.content.ComponentName;
|
||||||
import android.app.usage.UsageStats;
|
|
||||||
import android.app.usage.UsageStatsManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
public class MonitorService extends Service
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
|
public class MonitorService extends AccessibilityService {
|
||||||
private static final String TAG = "Magisk";
|
private static final String TAG = "Magisk";
|
||||||
private final Handler handler = new Handler();
|
private final Handler handler = new Handler();
|
||||||
private Boolean disableroot;
|
private Boolean disableroot;
|
||||||
@ -38,65 +30,85 @@ public class MonitorService extends Service
|
|||||||
private int counter = 0;
|
private int counter = 0;
|
||||||
private String mPackageName = "";
|
private String mPackageName = "";
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
protected void onServiceConnected() {
|
||||||
return null;
|
super.onServiceConnected();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
//Configure these here for compatibility with API 13 and below.
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
AccessibilityServiceInfo config = new AccessibilityServiceInfo();
|
||||||
return START_STICKY;
|
config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
|
||||||
|
config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
|
||||||
|
disableroot = false;
|
||||||
|
disablerootprev = disableroot;
|
||||||
|
if (Build.VERSION.SDK_INT >= 16)
|
||||||
|
//Just in case this helps
|
||||||
|
config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
|
||||||
|
|
||||||
|
setServiceInfo(config);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
checkProcesses.run();
|
|
||||||
Log.d("Magisk","MonitorService: Service created");
|
Log.d("Magisk","MonitorService: Service created");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||||
super.onDestroy();
|
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
|
||||||
Log.d("Magisk","MonitorService: Service destroyed");
|
ComponentName componentName = new ComponentName(
|
||||||
|
event.getPackageName().toString(),
|
||||||
|
event.getClassName().toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
ActivityInfo activityInfo = tryGetActivity(componentName);
|
||||||
|
boolean isActivity = activityInfo != null;
|
||||||
|
if (isActivity) {
|
||||||
|
Log.i("Magisk","CurrentActivity: " + componentName.getPackageName());
|
||||||
|
String mPackage = componentName.getPackageName();
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||||
|
if (prefs.getBoolean("autoRootEnable", false)) {
|
||||||
|
|
||||||
|
Set<String> setBlackList = prefs.getStringSet("auto_blacklist", null);
|
||||||
|
Set<String> setWhiteList = prefs.getStringSet("auto_whitelist", null);
|
||||||
|
|
||||||
|
if (setBlackList != null) {
|
||||||
|
disableroot = setBlackList.contains(mPackage);
|
||||||
|
if (disableroot) {
|
||||||
|
ForceDisableRoot();
|
||||||
|
} else {
|
||||||
|
ForceEnableRoot();
|
||||||
|
}
|
||||||
|
String appFriendly = getAppName(mPackage);
|
||||||
|
ShowNotification(disableroot,appFriendly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable checkProcesses = new Runnable() {
|
private String getAppName (String packageName) {
|
||||||
@Override
|
PackageManager pkManager = getPackageManager();
|
||||||
public void run() {
|
ApplicationInfo appInfo;
|
||||||
|
String appname = "";
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
try {
|
||||||
if (prefs.getBoolean("autoRootEnable", false)) {
|
appInfo = pkManager.getApplicationInfo(packageName, 0);
|
||||||
|
appname = (String) ((appInfo != null) ? pkManager.getApplicationLabel(appInfo) : "???");
|
||||||
Set<String> setBlackList = prefs.getStringSet("auto_blacklist", null);
|
return appname;
|
||||||
Set<String> setWhiteList = prefs.getStringSet("auto_whitelist", null);
|
} catch (final PackageManager.NameNotFoundException e) {
|
||||||
|
return "";
|
||||||
if (setBlackList != null) {
|
|
||||||
disableroot = getStats(setBlackList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disableroot != disablerootprev) {
|
|
||||||
|
|
||||||
String rootstatus = (disableroot ? "disabled" : "enabled");
|
|
||||||
if (disableroot) {
|
|
||||||
ForceDisableRoot();
|
|
||||||
} else {
|
|
||||||
ForceEnableRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowNotification(disableroot);
|
|
||||||
|
|
||||||
}
|
|
||||||
disablerootprev = disableroot;
|
|
||||||
//Log.d(TAG,"Root check completed, set to " + (disableroot ? "disabled" : "enabled"));
|
|
||||||
|
|
||||||
}
|
|
||||||
handler.postDelayed(checkProcesses, 500);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
private ActivityInfo tryGetActivity(ComponentName componentName) {
|
||||||
|
try {
|
||||||
|
return getPackageManager().getActivityInfo(componentName, 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ForceDisableRoot() {
|
private void ForceDisableRoot() {
|
||||||
Log.d("Magisk", "MonitorService: Forcedisable called.");
|
Log.d("Magisk", "MonitorService: Forcedisable called.");
|
||||||
@ -113,10 +125,10 @@ public class MonitorService extends Service
|
|||||||
Utils.toggleRoot(true);
|
Utils.toggleRoot(true);
|
||||||
if (!Utils.rootEnabled()) {
|
if (!Utils.rootEnabled()) {
|
||||||
Utils.toggleRoot(true);
|
Utils.toggleRoot(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowNotification(boolean rootAction) {
|
private void ShowNotification(boolean rootAction, String packageName) {
|
||||||
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
NotificationCompat.Builder mBuilder;
|
NotificationCompat.Builder mBuilder;
|
||||||
|
|
||||||
@ -130,10 +142,10 @@ public class MonitorService extends Service
|
|||||||
0,
|
0,
|
||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
if (mPackageName.equals("")) {
|
if (packageName.equals("")) {
|
||||||
rootMessage = "Root has been disabled";
|
rootMessage = "Root has been disabled";
|
||||||
} else {
|
} else {
|
||||||
rootMessage = "Root has been disabled for " + mPackageName;
|
rootMessage = "Root has been disabled for " + packageName;
|
||||||
}
|
}
|
||||||
mBuilder =
|
mBuilder =
|
||||||
new NotificationCompat.Builder(getApplicationContext())
|
new NotificationCompat.Builder(getApplicationContext())
|
||||||
@ -149,64 +161,7 @@ public class MonitorService extends Service
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getStats(Set<String> seti) {
|
@Override
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
public void onInterrupt() {
|
||||||
boolean inStats = false;
|
|
||||||
if (seti != null) {
|
|
||||||
ArrayList<String> statList = new ArrayList<>(seti);
|
|
||||||
for (int i = 0; i < statList.size(); i++) {
|
|
||||||
if (isAppForeground(statList.get(i))) {
|
|
||||||
inStats = (isAppForeground(statList.get(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inStats;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "SDK check failed.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private String getAppName (String packageName) {
|
|
||||||
PackageManager pkManager = getPackageManager();
|
|
||||||
ApplicationInfo appInfo;
|
|
||||||
String appname = "";
|
|
||||||
try {
|
|
||||||
appInfo = pkManager.getApplicationInfo(packageName, 0);
|
|
||||||
appname = (String) ((appInfo != null) ? pkManager.getApplicationLabel(appInfo) : "???");
|
|
||||||
return appname;
|
|
||||||
} catch (final PackageManager.NameNotFoundException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected boolean isAppForeground(String packageName) {
|
|
||||||
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time);
|
|
||||||
String topPackageName = "";
|
|
||||||
if (stats != null) {
|
|
||||||
|
|
||||||
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
|
|
||||||
for (UsageStats usageStats : stats) {
|
|
||||||
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!mySortedMap.isEmpty()) {
|
|
||||||
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
|
|
||||||
if (topPackageName.equals("com.topjohnwu.magisk")) {
|
|
||||||
mySortedMap.remove(mySortedMap.lastKey());
|
|
||||||
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
|
|
||||||
Log.d("Magisk","MonitorService: Package is " + topPackageName);
|
|
||||||
mPackageName = getAppName(topPackageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return topPackageName.equals(packageName);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,6 @@ import android.os.AsyncTask;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -126,13 +125,7 @@ public class RootFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void CheckAccessPermissions() {
|
|
||||||
if (!Utils.hasStatsPermission(getActivity())) {
|
|
||||||
Toast.makeText(getActivity(),"Please allow Usage Access for auto root to work.",Toast.LENGTH_LONG).show();
|
|
||||||
startActivityForResult(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS), 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
@ -141,24 +134,27 @@ public class RootFragment extends Fragment {
|
|||||||
// Make sure the request was successful
|
// Make sure the request was successful
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
Log.d("Magisk","Got result code OK for permissions");
|
Log.d("Magisk","Got result code OK for permissions");
|
||||||
Toast.makeText(getActivity(),"Auto-root disabled, permissions required.",Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
autoRootToggle.setEnabled(false);
|
autoRootToggle.setEnabled(false);
|
||||||
|
Toast.makeText(getActivity(),"Auto-root disabled, permissions required.",Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleAutoRoot(boolean toggleState) {
|
private void ToggleAutoRoot(boolean toggleState) {
|
||||||
CheckAccessPermissions();
|
|
||||||
if (Utils.hasStatsPermission(getActivity())) {
|
|
||||||
autoRootStatus = toggleState;
|
autoRootStatus = toggleState;
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
editor.putBoolean("autoRootEnable", (toggleState));
|
editor.putBoolean("autoRootEnable", (toggleState));
|
||||||
editor.apply();
|
editor.apply();
|
||||||
if (toggleState) {
|
if (toggleState) {
|
||||||
|
if (!Utils.hasStatsPermission(getActivity(),"com.topjohnwu.magisk/WindowChangeDetectingService")) {
|
||||||
|
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||||
|
startActivityForResult(intent, 100);
|
||||||
|
}
|
||||||
Intent myIntent = new Intent(getActivity(), MonitorService.class);
|
Intent myIntent = new Intent(getActivity(), MonitorService.class);
|
||||||
getActivity().startService(myIntent);
|
getActivity().startService(myIntent);
|
||||||
rootToggle.setEnabled(false);
|
rootToggle.setEnabled(false);
|
||||||
@ -172,7 +168,7 @@ public class RootFragment extends Fragment {
|
|||||||
getActivity().stopService(myIntent);
|
getActivity().stopService(myIntent);
|
||||||
rootToggle.setEnabled(true);
|
rootToggle.setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,7 +9,6 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.support.annotation.IdRes;
|
import android.support.annotation.IdRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.design.widget.NavigationView;
|
import android.support.design.widget.NavigationView;
|
||||||
@ -86,7 +85,7 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
|
|||||||
@Override
|
@Override
|
||||||
public void onDrawerOpened(View drawerView) {
|
public void onDrawerOpened(View drawerView) {
|
||||||
super.onDrawerOpened(drawerView);
|
super.onDrawerOpened(drawerView);
|
||||||
super.onDrawerSlide(drawerView, 0); // this disables the arrow @ completed state
|
super.onDrawerSlide(drawerView, 0); // this disables the arrow @ completed tate
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,6 +9,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -24,8 +25,6 @@ public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
|
|||||||
private PackageManager packageManager;
|
private PackageManager packageManager;
|
||||||
public ArrayList arrayList;
|
public ArrayList arrayList;
|
||||||
public SharedPreferences prefs;
|
public SharedPreferences prefs;
|
||||||
private int BLACKLIST_LIST = 1;
|
|
||||||
private int WHITELIST_LIST = 2;
|
|
||||||
|
|
||||||
public ApplicationAdapter(Context context, int textViewResourceId,
|
public ApplicationAdapter(Context context, int textViewResourceId,
|
||||||
List<ApplicationInfo> appsList) {
|
List<ApplicationInfo> appsList) {
|
||||||
@ -66,14 +65,14 @@ public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
|
|||||||
TextView appName = (TextView) view.findViewById(R.id.app_name);
|
TextView appName = (TextView) view.findViewById(R.id.app_name);
|
||||||
TextView packageName = (TextView) view.findViewById(R.id.app_paackage);
|
TextView packageName = (TextView) view.findViewById(R.id.app_paackage);
|
||||||
ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
|
ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
|
||||||
ImageView statusview = (ImageView) view.findViewById(R.id.app_status);
|
CheckBox statusview = (CheckBox) view.findViewById(R.id.checkbox);
|
||||||
appName.setText(applicationInfo.loadLabel(packageManager));
|
appName.setText(applicationInfo.loadLabel(packageManager));
|
||||||
packageName.setText(applicationInfo.packageName);
|
packageName.setText(applicationInfo.packageName);
|
||||||
iconview.setImageDrawable(applicationInfo.loadIcon(packageManager));
|
iconview.setImageDrawable(applicationInfo.loadIcon(packageManager));
|
||||||
if (CheckApp(applicationInfo.packageName, BLACKLIST_LIST)) {
|
if (CheckApp(applicationInfo.packageName)) {
|
||||||
statusview.setImageDrawable(this.context.getDrawable(R.drawable.root));
|
statusview.setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
statusview.setImageDrawable(null);
|
statusview.setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
@ -88,21 +87,18 @@ public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
|
|||||||
}
|
}
|
||||||
ApplicationInfo applicationInfo = appsList.get(position);
|
ApplicationInfo applicationInfo = appsList.get(position);
|
||||||
if (null != applicationInfo) {
|
if (null != applicationInfo) {
|
||||||
ImageView statusview = (ImageView) view.findViewById(R.id.app_status);
|
CheckBox statusview = (CheckBox) view.findViewById(R.id.checkbox);
|
||||||
if (CheckApp(applicationInfo.packageName, BLACKLIST_LIST)) {
|
if (CheckApp(applicationInfo.packageName)) {
|
||||||
statusview.setImageDrawable(this.context.getDrawable(R.drawable.root));
|
statusview.setChecked(true);
|
||||||
} else if (CheckApp(applicationInfo.packageName, WHITELIST_LIST)) {
|
|
||||||
statusview.setImageDrawable(this.context.getDrawable(R.drawable.ic_stat_notification_autoroot_off));
|
|
||||||
} else {
|
} else {
|
||||||
statusview.setImageDrawable(null);
|
statusview.setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean CheckApp(String appToCheck, int list) {
|
private boolean CheckApp(String appToCheck) {
|
||||||
boolean starter = false;
|
boolean starter = false;
|
||||||
if (list == BLACKLIST_LIST) {
|
|
||||||
Set<String> set = prefs.getStringSet("auto_blacklist", null);
|
Set<String> set = prefs.getStringSet("auto_blacklist", null);
|
||||||
if (set != null) {
|
if (set != null) {
|
||||||
arrayList = new ArrayList<>(set);
|
arrayList = new ArrayList<>(set);
|
||||||
@ -113,18 +109,6 @@ public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
Set<String> set = prefs.getStringSet("auto_whitelist", null);
|
|
||||||
if (set != null) {
|
|
||||||
arrayList = new ArrayList<>(set);
|
|
||||||
for (String string : set) {
|
|
||||||
if (string.equals(appToCheck)) {
|
|
||||||
starter = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return starter;
|
return starter;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.topjohnwu.magisk.utils;
|
package com.topjohnwu.magisk.utils;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
@ -23,6 +24,8 @@ import android.support.v7.app.AlertDialog;
|
|||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
import android.view.accessibility.AccessibilityManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.ModulesFragment;
|
import com.topjohnwu.magisk.ModulesFragment;
|
||||||
@ -171,14 +174,24 @@ public class Utils {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasStatsPermission(Context context) {
|
|
||||||
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
|
||||||
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
|
|
||||||
android.os.Process.myUid(), context.getPackageName());
|
|
||||||
return mode == AppOpsManager.MODE_ALLOWED;
|
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean hasStatsPermission(Context context, String id) {
|
||||||
|
|
||||||
|
AccessibilityManager am = (AccessibilityManager) context
|
||||||
|
.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||||
|
|
||||||
|
List<AccessibilityServiceInfo> runningServices = am
|
||||||
|
.getEnabledAccessibilityServiceList(AccessibilityEvent.TYPES_ALL_MASK);
|
||||||
|
for (AccessibilityServiceInfo service : runningServices) {
|
||||||
|
if (id.equals(service.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract static class DownloadReceiver extends BroadcastReceiver {
|
public abstract static class DownloadReceiver extends BroadcastReceiver {
|
||||||
public Context mContext;
|
public Context mContext;
|
||||||
|
@ -1,59 +1,73 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dp">
|
|
||||||
|
|
||||||
<ImageView
|
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/app_icon"
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="50dp"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="50dp"
|
android:layout_height="wrap_content"
|
||||||
android:padding="3dp"
|
android:layout_gravity="center"
|
||||||
android:scaleType="centerCrop"/>
|
android:layout_marginBottom="3dip"
|
||||||
|
android:layout_marginLeft="8dip"
|
||||||
|
android:layout_marginRight="8dip"
|
||||||
|
android:layout_marginTop="3dip"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
|
||||||
|
card_view:cardCornerRadius="2dp"
|
||||||
|
card_view:cardElevation="2dp"
|
||||||
|
style="@style/Base.CardView">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:layout_gravity="center_vertical"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
<LinearLayout
|
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/lynn"
|
android:id="@+id/app_icon"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/app_name"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="5dp"
|
|
||||||
android:paddingRight="50dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/app_name"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/app_paackage"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_vertical"/>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"></RelativeLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/app_status"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="30dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_toEndOf="@+id/app_icon"
|
||||||
android:padding="3dp"
|
android:gravity="center_vertical"
|
||||||
android:scaleType="centerCrop"/>
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/app_paackage"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_below="@+id/app_name"
|
||||||
|
android:layout_toEndOf="@+id/app_icon"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingStart="3dp" />
|
||||||
|
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/checkbox"
|
||||||
|
android:layout_width="68dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@drawable/ic_menu_overflow_material"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
</android.support.v7.widget.CardView>
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
<ListView android:id="@android:id/list"
|
<ListView android:id="@android:id/list"
|
||||||
android:paddingTop="5dip"
|
android:paddingTop="5dip"
|
||||||
android:paddingBottom="5dip"
|
android:paddingBottom="5dip"
|
||||||
android:layout_width="fill_parent"
|
android:divider="@android:color/transparent"
|
||||||
android:layout_height="fill_parent"/>
|
android:dividerHeight="10.0sp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="15dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -5,10 +5,7 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginBottom="3dip"
|
android:layout_margin="8dp"
|
||||||
android:layout_marginLeft="8dip"
|
|
||||||
android:layout_marginRight="8dip"
|
|
||||||
android:layout_marginTop="3dip"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
card_view:cardCornerRadius="2dp"
|
card_view:cardCornerRadius="2dp"
|
||||||
|
@ -82,6 +82,8 @@
|
|||||||
<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="accessibility_service_name">Magisk Manager</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="download_install">Download and install</string>
|
<string name="download_install">Download and install</string>
|
||||||
|
11
app/src/main/res/xml/accessibilityservice.xml
Normal file
11
app/src/main/res/xml/accessibilityservice.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?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"/>
|
Loading…
Reference in New Issue
Block a user