diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java index b5cf1a063..1893358e4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java @@ -108,11 +108,10 @@ public class MagiskManager extends Application { } magiskHide = prefs.getBoolean("magiskhide", false); updateNotification = prefs.getBoolean("notification", true); + initSU(); // Always start a new root shell manually, just for safety Shell.init(); updateMagiskInfo(); - initSuAccess(); - initSuConfigs(); // Initialize busybox File busybox = new File(getApplicationInfo().dataDir + "/busybox/busybox"); if (!busybox.exists() || !TextUtils.equals(prefs.getString("busybox_version", ""), BUSYBOX_VERSION)) { @@ -141,13 +140,14 @@ public class MagiskManager extends Application { Shell.su("PATH=$PATH:" + busybox.getParent()); } - public void initSuConfigs() { + public void initSU() { + // Create the app data directory, so su binary can work properly + new File(getApplicationInfo().dataDir).mkdirs(); + suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10); suResponseType = Utils.getPrefsInt(prefs, "su_auto_response", 0); suNotificationType = Utils.getPrefsInt(prefs, "su_notification", 1); - } - public void initSuAccess() { List ret = Shell.sh("su -v"); if (Utils.isValidShellResponse(ret)) { suVersion = ret.get(0); diff --git a/app/src/main/java/com/topjohnwu/magisk/services/BootupIntentService.java b/app/src/main/java/com/topjohnwu/magisk/services/BootupIntentService.java index 06aa1c1a3..b15ec7bc4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/services/BootupIntentService.java +++ b/app/src/main/java/com/topjohnwu/magisk/services/BootupIntentService.java @@ -3,6 +3,8 @@ package com.topjohnwu.magisk.services; import android.app.IntentService; import android.content.Intent; +import com.topjohnwu.magisk.MagiskManager; + public class BootupIntentService extends IntentService { public BootupIntentService() { @@ -11,10 +13,6 @@ public class BootupIntentService extends IntentService { @Override protected void onHandleIntent(Intent intent) { - /* Currently no bootup task to do - MagiskManager magiskManager = Utils.getMagiskManager(this); - magiskManager.initSuAccess(); - magiskManager.updateMagiskInfo(); - */ + ((MagiskManager) getApplication()).initSU(); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java b/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java index 54b1080f4..34f9266ec 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java @@ -11,7 +11,7 @@ public class Policy { public static final int DENY = 1; public static final int ALLOW = 2; - public int uid, policy; + public int uid, policy = INTERACTIVE; public long until; public boolean logging = true, notification = true; public String packageName, appName; diff --git a/app/src/main/java/com/topjohnwu/magisk/superuser/RequestActivity.java b/app/src/main/java/com/topjohnwu/magisk/superuser/RequestActivity.java index 9a52b8941..0267e573f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/RequestActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/RequestActivity.java @@ -17,7 +17,7 @@ public class RequestActivity extends Activity { return; } - getApplicationContext().initSuConfigs(); + getApplicationContext().initSU(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).setClass(this, SuRequestActivity.class); startActivity(intent); finish(); diff --git a/app/src/main/java/com/topjohnwu/magisk/superuser/SuReceiver.java b/app/src/main/java/com/topjohnwu/magisk/superuser/SuReceiver.java index 0374f74aa..fbd72f03d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/SuReceiver.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/SuReceiver.java @@ -56,7 +56,7 @@ public class SuReceiver extends BroadcastReceiver { } } - magiskManager.initSuConfigs(); + magiskManager.initSU(); SuLogEntry log = new SuLogEntry(policy); diff --git a/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java b/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java index 702e7ce07..d0946fa1b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java @@ -23,20 +23,18 @@ import com.topjohnwu.magisk.asyncs.ParallelTask; import com.topjohnwu.magisk.components.Activity; import com.topjohnwu.magisk.database.SuDatabaseHelper; import com.topjohnwu.magisk.utils.CallbackEvent; +import com.topjohnwu.magisk.utils.Logger; import java.io.DataInputStream; import java.io.IOException; +import java.io.OutputStream; import butterknife.BindView; import butterknife.ButterKnife; -public class SuRequestActivity extends Activity implements CallbackEvent.Listener { +public class SuRequestActivity extends Activity { private static final int[] timeoutList = {0, -1, 10, 20, 30, 60}; - private static final int SU_PROTOCOL_PARAM_MAX = 20; - private static final int SU_PROTOCOL_NAME_MAX = 20; - private static final int SU_PROTOCOL_VALUE_MAX = 256; - private static final int PROMPT = 0; private static final int AUTO_DENY = 1; private static final int AUTO_ALLOW = 2; @@ -53,13 +51,11 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene private LocalSocket socket; private PackageManager pm; private MagiskManager magiskManager; + private SuDatabaseHelper suDB; - private int uid; private boolean hasTimeout; private Policy policy; private CountDownTimer timer; - private CallbackEvent.Listener self; - private CallbackEvent event = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -68,19 +64,16 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene pm = getPackageManager(); magiskManager = getApplicationContext(); + suDB = new SuDatabaseHelper(this); Intent intent = getIntent(); socketPath = intent.getStringExtra("socket"); hasTimeout = intent.getBooleanExtra("timeout", true); - self = this; new FileObserver(socketPath) { @Override public void onEvent(int fileEvent, String path) { if (fileEvent == FileObserver.DELETE_SELF) { - if (event != null) { - event.trigger(); - } finish(); } } @@ -97,6 +90,8 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene private void showRequest() { + Logger.debug("Show request"); + switch (magiskManager.suResponseType) { case AUTO_DENY: handleAction(Policy.DENY, 0); @@ -108,6 +103,12 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene default: } + // If not interactive, response directly + if (policy.policy != Policy.INTERACTIVE) { + handleAction(); + return; + } + setContentView(R.layout.activity_request); ButterKnife.bind(this); @@ -128,13 +129,19 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene @Override public void onFinish() { deny_btn.setText(getString(R.string.deny_with_str, "(0)")); - event.trigger(); + handleAction(Policy.DENY); } }; - grant_btn.setOnClickListener(v -> handleAction(Policy.ALLOW)); - deny_btn.setOnClickListener(v -> handleAction(Policy.DENY)); - suPopup.setOnClickListener((v) -> cancelTimeout()); + grant_btn.setOnClickListener(v -> { + handleAction(Policy.ALLOW); + timer.cancel(); + }); + deny_btn.setOnClickListener(v -> { + handleAction(Policy.DENY); + timer.cancel(); + }); + suPopup.setOnClickListener(v -> cancelTimeout()); timeout.setOnTouchListener((v, event) -> cancelTimeout()); if (hasTimeout) { @@ -146,19 +153,25 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene @Override public void onBackPressed() { - event.trigger(); + if (policy != null) { + handleAction(Policy.DENY); + } + finish(); } - @Override - public void onTrigger(CallbackEvent event) { - Policy policy = event.getResult(); - String response = "socket:DENY"; - if (policy != null &&policy.policy == Policy.ALLOW ) { + void handleAction() { + String response; + if (policy.policy == Policy.ALLOW) { response = "socket:ALLOW"; + } else { + response = "socket:DENY"; } try { socket.getOutputStream().write((response).getBytes()); - } catch (Exception ignored) {} + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } finish(); } @@ -168,16 +181,16 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene void handleAction(int action, int time) { policy.policy = action; - event.trigger(policy); if (time >= 0) { - policy.until = time == 0 ? 0 : (System.currentTimeMillis() / 1000 + time * 60); + policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60); new SuDatabaseHelper(this).addPolicy(policy); } + handleAction(); } private class SocketManager extends ParallelTask { - public SocketManager(Activity context) { + SocketManager(Activity context) { super(context); } @@ -188,40 +201,33 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene socket.connect(new LocalSocketAddress(socketPath, LocalSocketAddress.Namespace.FILESYSTEM)); DataInputStream is = new DataInputStream(socket.getInputStream()); - ContentValues payload = new ContentValues(); - for (int i = 0; i < SU_PROTOCOL_PARAM_MAX; i++) { - + while (true) { int nameLen = is.readInt(); - if (nameLen > SU_PROTOCOL_NAME_MAX) - throw new IllegalArgumentException("name length too long: " + nameLen); - byte[] nameBytes = new byte[nameLen]; is.readFully(nameBytes); - String name = new String(nameBytes); - if (TextUtils.equals(name, "eof")) break; int dataLen = is.readInt(); - if (dataLen > SU_PROTOCOL_VALUE_MAX) - throw new IllegalArgumentException(name + " data length too long: " + dataLen); - byte[] dataBytes = new byte[dataLen]; is.readFully(dataBytes); - String data = new String(dataBytes); - payload.put(name, data); } - if (payload.getAsInteger("uid") == null) + if (payload.getAsInteger("uid") == null) { return false; - uid = payload.getAsInteger("uid"); + } - } catch (IOException e) { + int uid = payload.getAsInteger("uid"); + policy = suDB.getPolicy(uid); + if (policy == null) { + policy = new Policy(uid, pm); + } + } catch (Exception e) { e.printStackTrace(); return false; } @@ -230,35 +236,10 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene @Override protected void onPostExecute(Boolean result) { - if (!result) { + if (result) { + showRequest(); + } else { finish(); - return; - } - boolean showRequest = false; - event = magiskManager.uidSuRequest.get(uid); - if (event == null) { - showRequest = true; - event = new CallbackEvent() { - @Override - public void trigger(Policy result) { - super.trigger(result); - unRegister(); - magiskManager.uidSuRequest.remove(uid); - } - }; - magiskManager.uidSuRequest.put(uid, event); - } - event.register(self); - try { - if (showRequest) { - policy = new Policy(uid, pm); - showRequest(); - } else { - finish(); - } - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - event.trigger(); } } }