Quicksettings Tile, more AutoRoot fun
It's so purdy...
This commit is contained in:
parent
8a8aa1337b
commit
2cdb6b811f
@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.topjohnwu.magisk"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.topjohnwu.magisk">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
tools:ignore="ProtectedPermissions"/>
|
||||
|
||||
<application
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
||||
<service
|
||||
android:label="@string/accessibility_service_name"
|
||||
android:name=".MonitorService"
|
||||
android:label="@string/accessibility_service_name"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService"/>
|
||||
@ -30,10 +30,20 @@
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/accessibilityservice"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".QuickSettingTileService"
|
||||
android:icon="@drawable/ic_autoroot"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".WelcomeActivity"
|
||||
android:exported="true"
|
||||
android:configChanges="orientation|screenSize">
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
@ -42,28 +52,29 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.ipaulpro.afilechooser.FileChooserActivity"
|
||||
android:icon="@drawable/ic_chooser"
|
||||
android:enabled="@bool/use_activity"
|
||||
android:exported="true"
|
||||
android:label="@string/choose_file" >
|
||||
android:icon="@drawable/ic_chooser"
|
||||
android:label="@string/choose_file">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<action android:name="android.intent.action.GET_CONTENT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.OPENABLE"/>
|
||||
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:mimeType="*/*"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="com.ianhanniballake.localstorage.LocalStorageProvider"
|
||||
android:authorities="com.topjohnwu.magisk.documents"
|
||||
android:enabled="@bool/use_provider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS" >
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER"/>
|
||||
</intent-filter>
|
||||
</provider>
|
||||
<activity
|
||||
@ -73,15 +84,15 @@
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="com.topjohnwu.magisk.provider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
android:resource="@xml/file_paths"/>
|
||||
</provider>
|
||||
<receiver android:name=".AutoStart">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
@ -11,7 +11,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
@ -19,16 +18,11 @@ import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
public class MonitorService extends AccessibilityService {
|
||||
private static final String TAG = "Magisk";
|
||||
private final Handler handler = new Handler();
|
||||
private Boolean disableroot;
|
||||
private Boolean disablerootprev;
|
||||
private int counter = 0;
|
||||
private String mPackageName = "";
|
||||
|
||||
@Override
|
||||
protected void onServiceConnected() {
|
||||
@ -39,7 +33,6 @@ public class MonitorService extends AccessibilityService {
|
||||
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;
|
||||
@ -51,7 +44,7 @@ public class MonitorService extends AccessibilityService {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d("Magisk","MonitorService: Service created");
|
||||
Log.d("Magisk", "MonitorService: Service created");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,14 +58,13 @@ public class MonitorService extends AccessibilityService {
|
||||
ActivityInfo activityInfo = tryGetActivity(componentName);
|
||||
boolean isActivity = activityInfo != null;
|
||||
if (isActivity) {
|
||||
Log.i("Magisk","CurrentActivity: " + componentName.getPackageName());
|
||||
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);
|
||||
@ -82,21 +74,21 @@ public class MonitorService extends AccessibilityService {
|
||||
ForceEnableRoot();
|
||||
}
|
||||
String appFriendly = getAppName(mPackage);
|
||||
ShowNotification(disableroot,appFriendly);
|
||||
ShowNotification(disableroot, appFriendly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getAppName (String packageName) {
|
||||
private String getAppName(String packageName) {
|
||||
PackageManager pkManager = getPackageManager();
|
||||
ApplicationInfo appInfo;
|
||||
String appname = "";
|
||||
String appName;
|
||||
try {
|
||||
appInfo = pkManager.getApplicationInfo(packageName, 0);
|
||||
appname = (String) ((appInfo != null) ? pkManager.getApplicationLabel(appInfo) : "???");
|
||||
return appname;
|
||||
appName = (String) ((appInfo != null) ? pkManager.getApplicationLabel(appInfo) : "???");
|
||||
return appName;
|
||||
} catch (final PackageManager.NameNotFoundException e) {
|
||||
return "";
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
import android.util.Log;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class QuickSettingTileService extends TileService {
|
||||
private int STATE_CURRENT;
|
||||
|
||||
public QuickSettingTileService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTileAdded() {
|
||||
super.onTileAdded();
|
||||
setupState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
switchState();
|
||||
|
||||
}
|
||||
|
||||
private void setupState() {
|
||||
Icon iconRoot = Icon.createWithResource(getApplicationContext(), R.drawable.root);
|
||||
Icon iconAuto = Icon.createWithResource(getApplicationContext(), R.drawable.ic_autoroot);
|
||||
Tile tile = this.getQsTile();
|
||||
boolean autoRootStatus = Utils.autoRootEnabled(getApplicationContext());
|
||||
boolean rootStatus = Utils.rootStatus();
|
||||
Log.d("Magisk", "QST: Auto and root are " + autoRootStatus + " and " + rootStatus);
|
||||
if (autoRootStatus) {
|
||||
tile.setLabel("Auto-root");
|
||||
tile.setIcon(iconAuto);
|
||||
tile.setState(Tile.STATE_ACTIVE);
|
||||
STATE_CURRENT = 0;
|
||||
} else {
|
||||
if (rootStatus) {
|
||||
tile.setLabel("Root enabled");
|
||||
tile.setIcon(iconRoot);
|
||||
tile.setState(Tile.STATE_ACTIVE);
|
||||
STATE_CURRENT = 1;
|
||||
|
||||
} else {
|
||||
tile.setLabel("Root disabled");
|
||||
tile.setIcon(iconRoot);
|
||||
tile.setState(Tile.STATE_INACTIVE);
|
||||
STATE_CURRENT = 2;
|
||||
|
||||
}
|
||||
}
|
||||
tile.updateTile();
|
||||
}
|
||||
|
||||
private void switchState() {
|
||||
Log.d("Magisk", "QST: Switching state to " + STATE_CURRENT);
|
||||
switch (STATE_CURRENT) {
|
||||
case 0:
|
||||
Utils.toggleRoot(false);
|
||||
Utils.toggleAutoRoot(false, getApplicationContext());
|
||||
break;
|
||||
case 1:
|
||||
Utils.toggleAutoRoot(true, getApplicationContext());
|
||||
break;
|
||||
case 2:
|
||||
Utils.toggleRoot(true);
|
||||
break;
|
||||
}
|
||||
setupState();
|
||||
|
||||
}
|
||||
}
|
@ -94,9 +94,8 @@ public class RootFragment extends Fragment {
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
|
||||
|
||||
if (prefs.contains("autoRootEnable")) {
|
||||
autoRootStatus = prefs.getBoolean("autoRootEnable",false);
|
||||
autoRootStatus = prefs.getBoolean("autoRootEnable", false);
|
||||
rootToggle.setEnabled(false);
|
||||
} else {
|
||||
autoRootStatus = false;
|
||||
@ -124,21 +123,18 @@ public class RootFragment extends Fragment {
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
// Check which request we're responding to
|
||||
Log.d("Magisk", "Got result: " + requestCode + " and " + resultCode);
|
||||
if (requestCode == 100) {
|
||||
// Make sure the request was successful
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Log.d("Magisk","Got result code OK for permissions");
|
||||
|
||||
Log.d("Magisk", "Got result code OK for permissions");
|
||||
|
||||
} else {
|
||||
autoRootToggle.setEnabled(false);
|
||||
Toast.makeText(getActivity(),"Auto-root disabled, permissions required.",Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getActivity(), "Auto-root disabled, permissions required.", Toast.LENGTH_LONG).show();
|
||||
|
||||
}
|
||||
|
||||
@ -151,7 +147,7 @@ public class RootFragment extends Fragment {
|
||||
editor.putBoolean("autoRootEnable", (toggleState));
|
||||
editor.apply();
|
||||
if (toggleState) {
|
||||
if (!Utils.hasStatsPermission(getActivity(),"com.topjohnwu.magisk/WindowChangeDetectingService")) {
|
||||
if (!Utils.hasServicePermission(getActivity())) {
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
startActivityForResult(intent, 100);
|
||||
}
|
||||
|
@ -62,6 +62,10 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Intent serviceIntent = new Intent(this, QuickSettingTileService.class);
|
||||
startService(serviceIntent);
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
import android.Manifest;
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.DownloadManager;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
@ -17,18 +15,20 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.Settings;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.ModulesFragment;
|
||||
import com.topjohnwu.magisk.MonitorService;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.ReposFragment;
|
||||
import com.topjohnwu.magisk.module.Module;
|
||||
@ -90,6 +90,11 @@ public class Utils {
|
||||
return Boolean.parseBoolean(ret.get(0));
|
||||
}
|
||||
|
||||
public static boolean autoRootEnabled(Context context) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("autoRootEnable", false);
|
||||
|
||||
}
|
||||
|
||||
public static boolean createFile(String path) {
|
||||
String command = "touch " + path + " 2>/dev/null; if [ -f " + path + " ]; then echo true; else echo false; fi";
|
||||
if (!Shell.rootAccess()) {
|
||||
@ -116,6 +121,17 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void toggleAutoRoot(Boolean b, Context context) {
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("autoRootEnable", b).apply();
|
||||
Intent myServiceIntent = new Intent(context, MonitorService.class);
|
||||
if (b) {
|
||||
context.startService(myServiceIntent);
|
||||
} else {
|
||||
context.stopService(myServiceIntent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<String> getModList(String path) {
|
||||
List<String> ret;
|
||||
ret = Shell.sh("find " + path + " -type d -maxdepth 1 ! -name \"*.core\" ! -name \"*lost+found\" ! -name \"*magisk\"");
|
||||
@ -174,25 +190,41 @@ public class Utils {
|
||||
return value;
|
||||
}
|
||||
|
||||
// To check if service is enabled
|
||||
public static boolean hasServicePermission(Context mContext) {
|
||||
int accessibilityEnabled = 0;
|
||||
final String service = mContext.getPackageName() + "/" + MonitorService.class.getCanonicalName();
|
||||
try {
|
||||
accessibilityEnabled = Settings.Secure.getInt(
|
||||
mContext.getApplicationContext().getContentResolver(),
|
||||
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
} catch (Settings.SettingNotFoundException e) {
|
||||
Log.e(TAG, "Error finding setting, default accessibility to not found: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
|
||||
|
||||
if (accessibilityEnabled == 1) {
|
||||
String settingValue = Settings.Secure.getString(
|
||||
mContext.getApplicationContext().getContentResolver(),
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
if (settingValue != null) {
|
||||
mStringColonSplitter.setString(settingValue);
|
||||
while (mStringColonSplitter.hasNext()) {
|
||||
String accessibilityService = mStringColonSplitter.next();
|
||||
|
||||
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())) {
|
||||
if (accessibilityService.equalsIgnoreCase(service)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.v(TAG, "***ACCESSIBILITY IS DISABLED***");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public abstract static class DownloadReceiver extends BroadcastReceiver {
|
||||
public Context mContext;
|
||||
long downloadID;
|
||||
|
Loading…
Reference in New Issue
Block a user