diff --git a/app/build.gradle b/app/build.gradle
index 442597aa7..eebc46c62 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,9 +32,9 @@ repositories {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:recyclerview-v7:24.2.0'
- compile 'com.android.support:cardview-v7:24.2.0'
- compile 'com.android.support:design:24.2.0'
+ compile 'com.android.support:recyclerview-v7:24.2.1'
+ compile 'com.android.support:cardview-v7:24.2.1'
+ compile 'com.android.support:design:24.2.1'
compile 'com.github.d8ahazard:BroadcastTileSupportUpdate:master'
compile 'com.jakewharton:butterknife:8.4.0'
compile 'com.github.michalis-vitos:aFileChooser:master'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f4da821eb..d8f5677ca 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -107,12 +107,9 @@
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/topjohnwu/magisk/AutoRootFragment.java b/app/src/main/java/com/topjohnwu/magisk/AutoRootFragment.java
index 4207f34d6..8ec9d8852 100644
--- a/app/src/main/java/com/topjohnwu/magisk/AutoRootFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/AutoRootFragment.java
@@ -1,5 +1,6 @@
package com.topjohnwu.magisk;
+import android.app.ListFragment;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
@@ -8,7 +9,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import android.support.v4.app.ListFragment;
+
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,7 +42,7 @@ public class AutoRootFragment extends ListFragment {
super.onActivityCreated(savedInstanceState);
listView = getListView();
packageManager = getActivity().getPackageManager();
- prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
+ prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (!prefs.contains("auto_blacklist")) {
SharedPreferences.Editor editor = prefs.edit();
Set set = new HashSet<>();
diff --git a/app/src/main/java/com/topjohnwu/magisk/LogFragment.java b/app/src/main/java/com/topjohnwu/magisk/LogFragment.java
index 80d0c75b9..0c35ca353 100644
--- a/app/src/main/java/com/topjohnwu/magisk/LogFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/LogFragment.java
@@ -6,13 +6,14 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
+import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -132,7 +133,9 @@ public class LogFragment extends Fragment {
@SuppressLint("DefaultLocale")
private File save() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
+ }
return null;
}
diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
index 623e25b0b..4197b1960 100644
--- a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
@@ -1,10 +1,11 @@
package com.topjohnwu.magisk;
+import android.app.Fragment;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
index 50e26bbb7..832f1214c 100644
--- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
@@ -1,12 +1,13 @@
package com.topjohnwu.magisk;
+import android.app.Fragment;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
-import android.support.v4.app.Fragment;
+
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java
index ef89500b7..ee9ede7d6 100644
--- a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java
@@ -5,7 +5,7 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import android.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
diff --git a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java
index 2f823f98e..6c4bde17a 100644
--- a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java
+++ b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java
@@ -12,7 +12,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import android.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.LayoutInflater;
@@ -97,7 +97,7 @@ public class RootFragment extends Fragment implements Receiver{
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.root_fragment, container, false);
ButterKnife.bind(this, view);
- prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
+ prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (prefs.contains("autoRootEnable")) {
autoRootStatus = prefs.getBoolean("autoRootEnable", false);
@@ -125,22 +125,22 @@ public class RootFragment extends Fragment implements Receiver{
new updateUI().execute();
});
- LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mYourBroadcastReceiver,
- new IntentFilter("com.magisk.UPDATEUI"));
+// LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mYourBroadcastReceiver,
+// new IntentFilter("com.magisk.UPDATEUI"));
return view;
}
- private final BroadcastReceiver mYourBroadcastReceiver = new RootFragmentReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
-
- Log.d("Magisk", "RootFragment: UpdateRF called and fired");
- new updateUI().execute();
- }
-
-
- };
+// private final BroadcastReceiver mYourBroadcastReceiver = new RootFragmentReceiver(Re) {
+// @Override
+// public void onReceive(Context context, Intent intent) {
+//
+// Log.d("Magisk", "RootFragment: UpdateRF called and fired");
+// new updateUI().execute();
+// }
+//
+//
+// };
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
diff --git a/app/src/main/java/com/topjohnwu/magisk/SettingsFragment.java b/app/src/main/java/com/topjohnwu/magisk/SettingsFragment.java
new file mode 100644
index 000000000..349a3df48
--- /dev/null
+++ b/app/src/main/java/com/topjohnwu/magisk/SettingsFragment.java
@@ -0,0 +1,95 @@
+package com.topjohnwu.magisk;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+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.Utils;
+
+import butterknife.ButterKnife;
+
+
+public class SettingsFragment extends PreferenceFragment {
+ private CheckBoxPreference quickTilePreference;
+ private CheckBoxPreference devLogPreference;
+ private CheckBoxPreference keepRootOffPreference;
+ private CheckBoxPreference hideRootNotificationPreference;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ // TODO Auto-generated method stub
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.uisettings);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ ButterKnife.bind(this, view);
+ quickTilePreference = (CheckBoxPreference) findPreference("enable_quicktile");
+ devLogPreference = (CheckBoxPreference) findPreference("developer_logging");
+ keepRootOffPreference = (CheckBoxPreference) findPreference("keep_root_off");
+ hideRootNotificationPreference = (CheckBoxPreference) findPreference("hide_root_notification");
+
+ if (Utils.magiskVersion == -1) {
+ quickTilePreference.setEnabled(false);
+ keepRootOffPreference.setEnabled(false);
+ hideRootNotificationPreference.setEnabled(false);
+ } else {
+ quickTilePreference.setEnabled(true);
+ keepRootOffPreference.setEnabled(true);
+ hideRootNotificationPreference.setEnabled(true);
+ }
+
+ Preference.OnPreferenceClickListener preferenceClickListener = preference -> {
+ if (preference == quickTilePreference) {
+ boolean isChecked = quickTilePreference.isChecked();
+ if (isChecked) {
+ Utils.installTile(getActivity());
+ } else {
+ Utils.uninstallTile(getActivity());
+ }
+
+ }
+ if (preference == devLogPreference) {
+ boolean isChecked = devLogPreference.isChecked();
+
+ }
+ if (preference == keepRootOffPreference) {
+ boolean isChecked = devLogPreference.isChecked();
+
+ }
+ if (preference == hideRootNotificationPreference) {
+ boolean isChecked = devLogPreference.isChecked();
+
+ }
+ return false;
+ };
+
+ quickTilePreference.setOnPreferenceClickListener(preferenceClickListener);
+ // 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;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
index 34792bbc0..67a2ae011 100644
--- a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
+++ b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
@@ -1,6 +1,7 @@
package com.topjohnwu.magisk;
import android.Manifest;
+import android.app.Fragment;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -12,9 +13,9 @@ import android.preference.PreferenceManager;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
+
import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
+import android.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@@ -175,14 +176,19 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
tag = "log";
navFragment = new LogFragment();
break;
+ case R.id.settings:
+ setTitle(R.string.settings);
+ tag = "settings";
+ navFragment = new SettingsFragment();
+ break;
case R.id.app_about:
startActivity(new Intent(this, AboutActivity.class));
return;
}
if (navFragment != null) {
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
+ FragmentTransaction transaction = getFragmentManager().beginTransaction();
+ transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
try {
toolbar.setElevation(navFragment instanceof ModulesFragment ? 0 : 10);
diff --git a/app/src/main/java/com/topjohnwu/magisk/receivers/AutoStartReceiver.java b/app/src/main/java/com/topjohnwu/magisk/receivers/AutoStartReceiver.java
index 3a88e2d92..543b3cd23 100644
--- a/app/src/main/java/com/topjohnwu/magisk/receivers/AutoStartReceiver.java
+++ b/app/src/main/java/com/topjohnwu/magisk/receivers/AutoStartReceiver.java
@@ -6,6 +6,7 @@ import android.content.Intent;
import android.util.Log;
import com.topjohnwu.magisk.services.MonitorService;
+import com.topjohnwu.magisk.utils.PrefHelper;
import com.topjohnwu.magisk.utils.Utils;
public class AutoStartReceiver extends BroadcastReceiver {
@@ -14,7 +15,13 @@ public class AutoStartReceiver extends BroadcastReceiver {
Log.d("Magisk", "Received Boot call, attempting to start service");
Intent myIntent = new Intent(context, MonitorService.class);
context.startService(myIntent);
- Utils.SetupQuickSettingsTile(context);
+ if (PrefHelper.CheckBool("keep_root_off")) {
+ Utils.toggleRoot(false);
+ }
+ if (PrefHelper.CheckBool("enable_quicktile")) {
+ Utils.SetupQuickSettingsTile(context);
+ }
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/topjohnwu/magisk/receivers/TileReceiver.java b/app/src/main/java/com/topjohnwu/magisk/receivers/TileReceiver.java
new file mode 100644
index 000000000..d9fd9a59c
--- /dev/null
+++ b/app/src/main/java/com/topjohnwu/magisk/receivers/TileReceiver.java
@@ -0,0 +1,25 @@
+package com.topjohnwu.magisk.receivers;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.topjohnwu.magisk.services.TileService;
+
+public class TileReceiver extends BroadcastReceiver {
+ private static final String TAG = "MainReceiver";
+ public TileReceiver() {
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG,"RECEIVED");
+ String action = intent.getAction();
+
+ if (action.equals(Intent.ACTION_BOOT_COMPLETED) || action.equals(Intent.ACTION_USER_PRESENT) || action.equals(Intent.ACTION_SCREEN_ON)) {
+ context.startService(new Intent(context,TileService.class));
+
+ }
+ }
+}
diff --git a/app/src/main/java/com/topjohnwu/magisk/services/MonitorService.java b/app/src/main/java/com/topjohnwu/magisk/services/MonitorService.java
index 64f6cee71..f746269d3 100644
--- a/app/src/main/java/com/topjohnwu/magisk/services/MonitorService.java
+++ b/app/src/main/java/com/topjohnwu/magisk/services/MonitorService.java
@@ -18,6 +18,7 @@ import android.view.accessibility.AccessibilityEvent;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.WelcomeActivity;
+import com.topjohnwu.magisk.utils.PrefHelper;
import com.topjohnwu.magisk.utils.Utils;
import java.util.Set;
@@ -125,32 +126,33 @@ public class MonitorService extends AccessibilityService {
private void ShowNotification(boolean rootAction, String packageName) {
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder;
+ if (!PrefHelper.CheckBool("hide_root_notification")) {
+ if (rootAction) {
- if (rootAction) {
-
- Intent intent = new Intent(getApplication(), WelcomeActivity.class);
- intent.putExtra("relaunch", "relaunch");
- String rootMessage;
- PendingIntent pendingIntent = PendingIntent.getActivity(
- getApplicationContext(),
- 0,
- intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- if (packageName.equals("")) {
- rootMessage = "Root has been disabled";
+ Intent intent = new Intent(getApplication(), WelcomeActivity.class);
+ intent.putExtra("relaunch", "relaunch");
+ String rootMessage;
+ PendingIntent pendingIntent = PendingIntent.getActivity(
+ getApplicationContext(),
+ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ if (packageName.equals("")) {
+ rootMessage = "Root has been disabled";
+ } else {
+ rootMessage = "Root has been disabled for " + packageName;
+ }
+ mBuilder =
+ new NotificationCompat.Builder(getApplicationContext())
+ .setSmallIcon(disableroot ? R.drawable.ic_stat_notification_autoroot_off : R.drawable.ic_stat_notification_autoroot_on)
+ .setContentIntent(pendingIntent)
+ .setContentTitle("Auto-root status changed")
+ .setContentText(rootMessage);
+ int mNotificationId = 1;
+ mNotifyMgr.notify(mNotificationId, mBuilder.build());
} else {
- rootMessage = "Root has been disabled for " + packageName;
+ mNotifyMgr.cancelAll();
}
- mBuilder =
- new NotificationCompat.Builder(getApplicationContext())
- .setSmallIcon(disableroot ? R.drawable.ic_stat_notification_autoroot_off : R.drawable.ic_stat_notification_autoroot_on)
- .setContentIntent(pendingIntent)
- .setContentTitle("Auto-root status changed")
- .setContentText(rootMessage);
- int mNotificationId = 1;
- mNotifyMgr.notify(mNotificationId, mBuilder.build());
- } else {
- mNotifyMgr.cancelAll();
}
}
diff --git a/app/src/main/java/com/topjohnwu/magisk/services/TileService.java b/app/src/main/java/com/topjohnwu/magisk/services/TileService.java
new file mode 100644
index 000000000..bb09602a6
--- /dev/null
+++ b/app/src/main/java/com/topjohnwu/magisk/services/TileService.java
@@ -0,0 +1,139 @@
+package com.topjohnwu.magisk.services;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.service.quicksettings.Tile;
+
+import com.kcoppock.broadcasttilesupport.BroadcastTileIntentBuilder;
+import com.topjohnwu.magisk.utils.Shell;
+import com.topjohnwu.magisk.R;
+import com.topjohnwu.magisk.utils.Utils;
+
+import java.util.List;
+
+public class TileService extends Service {
+ private static BroadcastReceiver clickTileReceiver;
+
+ private static boolean running = false;
+ private static boolean root, autoRoot;
+
+ public static final String TILE_ID = "com.shovelgrill.magiskmmtile.TILE";
+ public static final String ACTION_TILE_CLICK = "com.shovelgrill.magiskmmtile.ACTION_TILE_CLICK";
+ public static final String EXTRA_CLICK_TYPE = "com.shovelgrill.magiskmmtile.EXTRA_CLICK_TYPE";
+ public static final int CLICK_TYPE_UNKNOWN = -1;
+ public static final int CLICK_TYPE_SIMPLE = 0;
+ public static final int CLICK_TYPE_LONG = 1;
+
+ public TileService() {
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ running = true;
+ root = true;
+ registerClickTileReceiver();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ root = Utils.rootEnabled();
+ autoRoot = Utils.autoRootEnabled(getApplicationContext());
+ updateTile();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+
+
+ private void registerClickTileReceiver() {
+ clickTileReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int clickType = intent.getIntExtra(EXTRA_CLICK_TYPE, CLICK_TYPE_UNKNOWN);
+ switch (clickType) {
+ case CLICK_TYPE_SIMPLE:
+ onSimpleClick();
+ break;
+ case CLICK_TYPE_LONG:
+ onLongClick();
+ break;
+ }
+ }
+ };
+ registerReceiver(clickTileReceiver, new IntentFilter(ACTION_TILE_CLICK));
+ }
+
+
+ private void onSimpleClick() {
+ Utils.toggleRoot(!root);
+ }
+
+ private void onLongClick() {
+ Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+ sendBroadcast(it);
+ openApp(this,"com.topjohnwu.magisk");
+ }
+
+ public static boolean openApp(Context context, String packageName) {
+ PackageManager manager = context.getPackageManager();
+ Intent i = manager.getLaunchIntentForPackage(packageName);
+ if (i == null) {
+ return false;
+ //throw new PackageManager.NameNotFoundException();
+ }
+ i.addCategory(Intent.CATEGORY_LAUNCHER);
+ i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ context.startActivity(i);
+ return true;
+ }
+
+ private void updateTile() {
+ BroadcastTileIntentBuilder broadcastTileIntentBuilder = new BroadcastTileIntentBuilder(this, TILE_ID);
+ if (autoRoot) {
+ broadcastTileIntentBuilder.setLabel("Auto-root");
+ broadcastTileIntentBuilder.setIconResource(R.drawable.ic_autoroot_white);
+
+ } else {
+ if (root) {
+ broadcastTileIntentBuilder.setLabel("Root enabled");
+ broadcastTileIntentBuilder.setIconResource(R.drawable.root_white);
+
+ } else {
+ broadcastTileIntentBuilder.setLabel("Root disabled");
+ broadcastTileIntentBuilder.setIconResource(R.drawable.root_grey);
+
+ }
+ }
+
+ Intent simpleClick = new Intent(ACTION_TILE_CLICK);
+ simpleClick.putExtra(EXTRA_CLICK_TYPE, CLICK_TYPE_SIMPLE);
+ Intent longClick = new Intent(ACTION_TILE_CLICK);
+ longClick.putExtra(EXTRA_CLICK_TYPE, CLICK_TYPE_LONG);
+
+ broadcastTileIntentBuilder.setVisible(true);
+ broadcastTileIntentBuilder.setOnClickBroadcast(simpleClick);
+ broadcastTileIntentBuilder.setOnLongClickBroadcast(longClick);
+ this.sendBroadcast(broadcastTileIntentBuilder.build());
+
+ }
+
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(clickTileReceiver);
+ running = false;
+ }
+
+}
diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Logger.java b/app/src/main/java/com/topjohnwu/magisk/utils/Logger.java
new file mode 100644
index 000000000..9eb6b66a8
--- /dev/null
+++ b/app/src/main/java/com/topjohnwu/magisk/utils/Logger.java
@@ -0,0 +1,20 @@
+package com.topjohnwu.magisk.utils;
+
+import android.util.Log;
+
+
+
+public class Logger {
+
+ private static final String LOG_TAG = "Magisk";
+
+ public static void dh(String msg, Object... args) {
+ if (PrefHelper.CheckBool("developer_logging")) {
+ if (args.length == 1 && args[0] instanceof Throwable) {
+ Log.d(LOG_TAG, msg, (Throwable) args[0]);
+ } else {
+ Log.d(LOG_TAG, String.format(msg, args));
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/PrefHelper.java b/app/src/main/java/com/topjohnwu/magisk/utils/PrefHelper.java
new file mode 100644
index 000000000..8a9e93533
--- /dev/null
+++ b/app/src/main/java/com/topjohnwu/magisk/utils/PrefHelper.java
@@ -0,0 +1,28 @@
+package com.topjohnwu.magisk.utils;
+
+
+import android.app.Application;
+import android.content.Context;
+import android.preference.PreferenceManager;
+
+public class PrefHelper {
+ public PrefHelper() {
+
+ }
+
+ public static boolean CheckBool(String key) {
+ Context context = null;
+ try {
+ context = getApplicationUsingReflection();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(key, false);
+ }
+
+ private static Application getApplicationUsingReflection() throws Exception {
+ return (Application) Class.forName("android.app.AppGlobals")
+ .getMethod("getInitialApplication").invoke(null, (Object[]) null);
+ }
+
+}
diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
index 61890c5ad..8d2b59008 100644
--- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
+++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
@@ -31,13 +31,16 @@ import com.topjohnwu.magisk.module.BaseModule;
import com.topjohnwu.magisk.receivers.PrivateBroadcastReceiver;
import com.topjohnwu.magisk.services.MonitorService;
import com.topjohnwu.magisk.services.QuickSettingTileService;
+import com.topjohnwu.magisk.services.TileService;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
import java.util.Comparator;
+import java.util.LinkedList;
import java.util.List;
import javax.crypto.BadPaddingException;
@@ -68,6 +71,12 @@ public class Utils {
if (!Shell.rootAccess()) {
Snackbar.make(((Activity) context).findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show();
}
+ if (PrefHelper.CheckBool("keep_root_off")) {
+ Utils.toggleRoot(false);
+ }
+ if (PrefHelper.CheckBool("enable_quicktile")) {
+ Utils.SetupQuickSettingsTile(context);
+ }
}
public static boolean fileExist(String path) {
@@ -201,19 +210,19 @@ public class Utils {
}
public static void SetupQuickSettingsTile(Context mContext) {
- Log.d("Magisk", "Utils: SetupQuickSettings called");
+ Logger.dh("Utils: SetupQuickSettings called");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Intent serviceIntent = new Intent(mContext, QuickSettingTileService.class);
mContext.startService(serviceIntent);
}
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
- Log.d("Magisk", "Utils: Marshmallow build detected");
+ Logger.dh("Utils: Marshmallow build detected");
String mLabelString;
int mRootIcon = R.drawable.root_white;
int mAutoRootIcon = R.drawable.ic_autoroot_white;
int mRootDisabled = R.drawable.root_grey;
int mRootsState = CheckRootsState(mContext);
- Log.d("Magisk", "Utils: Root State returned as " + mRootsState);
+ Logger.dh("Utils: Root State returned as " + mRootsState);
final Intent enableBroadcast = new Intent(PrivateBroadcastReceiver.ACTION_ENABLEROOT);
final Intent disableBroadcast = new Intent(PrivateBroadcastReceiver.ACTION_DISABLEROOT);
final Intent autoBroadcast = new Intent(PrivateBroadcastReceiver.ACTION_AUTOROOT);
@@ -255,9 +264,67 @@ public class Utils {
}
}
+ public static void installTile(Context context) {
+
+ String qsTileId = "intent(" + TileService.TILE_ID + ")";
+ List lines = Shell.su("settings get secure sysui_qs_tiles");
+ if (lines != null && lines.size() == 1) {
+ List tiles = new LinkedList(Arrays.asList(lines.get(0).split(",")));
+ if (tiles.size() > 1) {
+ for (String tile : tiles) {
+ if (tile.equals(qsTileId)) {
+ Toast.makeText(context, "Tile already installed", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+ String newTiles = TextUtils.join(",", tiles);
+ Shell.su("settings put secure sysui_qs_tiles \"" + newTiles + "\"");
+ Toast.makeText(context, "Tile installed", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+ Toast.makeText(context, "Tile installation error", Toast.LENGTH_SHORT).show();
+ }
+
+
+ public static void uninstallTile(Context context) {
+
+ String qsTileId = "intent(" + TileService.TILE_ID + ")";
+ List lines = Shell.su("settings get secure sysui_qs_tiles");
+ if (lines != null && lines.size() == 1) {
+ List tiles = new LinkedList(Arrays.asList(lines.get(0).split(",")));
+ if (tiles.size() > 1) {
+ boolean isPresent = false;
+ for (int i = 0; i < tiles.size(); i++) {
+ if (tiles.get(i).equals(qsTileId)) {
+ isPresent = true;
+ tiles.remove(i);
+ break;
+ }
+ }
+ if (isPresent) {
+ String newTiles = TextUtils.join(",", tiles);
+ Shell.su("settings put secure sysui_qs_tiles \"" + newTiles + "\"");
+ Toast.makeText(context, "Tile uninstalled", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ Toast.makeText(context, "Tile already uninstalled", Toast.LENGTH_SHORT).show();
+
+
+ }
+ }
+ Toast.makeText(context, "Tile uninstallation error", Toast.LENGTH_SHORT).show();
+ }
+
+
+ private void refreshService(Context context) {
+ context.startService(new Intent(context, TileService.class));
+ }
+
+
public static void UpdateRootFragmentUI(Context context) {
- Log.d("Magisk", "Utils: UpdateRF called");
+ Logger.dh("Magisk", "Utils: UpdateRF called");
Intent intent = new Intent(context, RootFragment.class);
intent.setAction("com.magisk.UPDATEUI");
context.sendBroadcast(intent);
diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml
new file mode 100644
index 000000000..ace746c40
--- /dev/null
+++ b/app/src/main/res/drawable/ic_settings.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/settings_fragment.xml b/app/src/main/res/layout/settings_fragment.xml
new file mode 100644
index 000000000..a3191a2e8
--- /dev/null
+++ b/app/src/main/res/layout/settings_fragment.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/drawer.xml b/app/src/main/res/menu/drawer.xml
index 397a9c27c..d45fd3319 100644
--- a/app/src/main/res/menu/drawer.xml
+++ b/app/src/main/res/menu/drawer.xml
@@ -35,6 +35,11 @@
android:icon="@drawable/ic_bug_report"
android:title="@string/log"/>
+
+
About
Main developers
- topjohnwu in collaboration with dvdandroid]]>
+ Topjohnwu in collaboration with Digitalhigh and Dvdandroid.]]>
App\'s changelog
App\'s version
@@ -107,4 +107,18 @@
https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token=
https://raw.githubusercontent.com/Magisk-Modules-Repo/%1$s/master/%2$s
https://github.com/Magisk-Modules-Repo/%1$s/archive/master.zip
+
+
+ Settings
+ Quick Settings
+ Enable Quicksettings Tile
+ Click here to enable or disable the quick settings tile.
+ Disable root unless otherwise enabled by Auto-root or toggle.
+ Keep root turned off
+ Enable advanced debug logging
+ Check this to enable more verbose logging.
+ Root
+ Development
+ When checked, auto-root notifications will not be displayed.
+ Hide auto-root notifications
diff --git a/app/src/main/res/xml/uisettings.xml b/app/src/main/res/xml/uisettings.xml
new file mode 100644
index 000000000..b88cd28ec
--- /dev/null
+++ b/app/src/main/res/xml/uisettings.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file