Quicksettings Tile, more AutoRoot fun

It's so purdy...
This commit is contained in:
d8ahazard 2016-09-20 00:05:41 -05:00
parent 8a8aa1337b
commit 2cdb6b811f
6 changed files with 223 additions and 111 deletions

View File

@ -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>

View File

@ -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 "";
}

View File

@ -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();
}
}

View File

@ -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();
}
@ -146,28 +142,28 @@ public class RootFragment extends Fragment {
}
private void ToggleAutoRoot(boolean toggleState) {
autoRootStatus = toggleState;
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("autoRootEnable", (toggleState));
editor.apply();
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);
getActivity().startService(myIntent);
rootToggle.setEnabled(false);
boolean boo = Utils.isMyServiceRunning(MonitorService.class, getActivity());
if (boo) {
Intent myServiceIntent = new Intent(getActivity(), MonitorService.class);
getActivity().startService(myServiceIntent);
}
} else {
Intent myIntent = new Intent(getActivity(), MonitorService.class);
getActivity().stopService(myIntent);
rootToggle.setEnabled(true);
autoRootStatus = toggleState;
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("autoRootEnable", (toggleState));
editor.apply();
if (toggleState) {
if (!Utils.hasServicePermission(getActivity())) {
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, 100);
}
Intent myIntent = new Intent(getActivity(), MonitorService.class);
getActivity().startService(myIntent);
rootToggle.setEnabled(false);
boolean boo = Utils.isMyServiceRunning(MonitorService.class, getActivity());
if (boo) {
Intent myServiceIntent = new Intent(getActivity(), MonitorService.class);
getActivity().startService(myServiceIntent);
}
} else {
Intent myIntent = new Intent(getActivity(), MonitorService.class);
getActivity().stopService(myIntent);
rootToggle.setEnabled(true);
}
}
@ -254,39 +250,39 @@ public class RootFragment extends Fragment {
break;
case 1:
// Proper root
if (autoRootStatus) {
rootStatusContainer.setBackgroundColor(green500);
rootStatusIcon.setImageResource(statusAuto);
rootStatusIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
rootStatus.setTextColor(green500);
rootStatus.setText(R.string.root_auto_unmounted);
rootToggle.setEnabled(false);
safetyNetStatusIcon.setImageResource(statusOK);
safetyNetStatus.setText(R.string.root_auto_unmounted_info);
if (autoRootStatus) {
rootStatusContainer.setBackgroundColor(green500);
rootStatusIcon.setImageResource(statusAuto);
rootStatusIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
rootStatus.setTextColor(green500);
rootStatus.setText(R.string.root_auto_unmounted);
rootToggle.setEnabled(false);
safetyNetStatusIcon.setImageResource(statusOK);
safetyNetStatus.setText(R.string.root_auto_unmounted_info);
break;
} else {
rootToggle.setEnabled(true);
if (Utils.rootEnabled()) {
// Mounted
rootStatusContainer.setBackgroundColor(accent);
rootStatusIcon.setImageResource(statusError);
rootStatus.setTextColor(accent);
rootStatus.setText(R.string.root_enabled);
rootToggle.setChecked(true);
safetyNetStatusIcon.setImageResource(statusError);
safetyNetStatus.setText(R.string.root_enabled_info);
break;
} else {
rootToggle.setEnabled(true);
if (Utils.rootEnabled()) {
// Mounted
rootStatusContainer.setBackgroundColor(accent);
rootStatusIcon.setImageResource(statusError);
rootStatus.setTextColor(accent);
rootStatus.setText(R.string.root_enabled);
rootToggle.setChecked(true);
safetyNetStatusIcon.setImageResource(statusError);
safetyNetStatus.setText(R.string.root_enabled_info);
break;
} else {
// Disabled
rootStatusContainer.setBackgroundColor(green500);
rootStatusIcon.setImageResource(statusOK);
rootStatus.setTextColor(green500);
rootStatus.setText(R.string.root_disabled);
rootToggle.setChecked(false);
safetyNetStatusIcon.setImageResource(statusOK);
safetyNetStatus.setText(R.string.root_disabled_info);
break;
}
// Disabled
rootStatusContainer.setBackgroundColor(green500);
rootStatusIcon.setImageResource(statusOK);
rootStatus.setTextColor(green500);
rootStatus.setText(R.string.root_disabled);
rootToggle.setChecked(false);
safetyNetStatusIcon.setImageResource(statusOK);
safetyNetStatus.setText(R.string.root_disabled_info);
break;
}
}
case 2:
// Improper root

View File

@ -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);

View File

@ -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())) {
return true;
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;
@ -479,7 +511,7 @@ public class Utils {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
}
return false;
}