From bfec381933798cc3e36f0a3985fd47a84cc0178f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 30 Jan 2017 19:27:00 +0800 Subject: [PATCH] Improve su requests --- .../java/com/topjohnwu/magisk/Global.java | 6 +- .../topjohnwu/magisk/MagiskHideFragment.java | 3 - .../topjohnwu/magisk/MagiskLogFragment.java | 2 - .../topjohnwu/magisk/SettingsActivity.java | 1 - .../topjohnwu/magisk/module/ModuleHelper.java | 4 +- .../topjohnwu/magisk/superuser/Policy.java | 13 +- .../magisk/superuser/SuRequestActivity.java | 130 +++++++++--------- .../com/topjohnwu/magisk/utils/Async.java | 1 - 8 files changed, 79 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/Global.java b/app/src/main/java/com/topjohnwu/magisk/Global.java index a68d20386..615e5237f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/Global.java +++ b/app/src/main/java/com/topjohnwu/magisk/Global.java @@ -3,6 +3,7 @@ package com.topjohnwu.magisk; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.util.SparseArray; import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Repo; @@ -30,8 +31,8 @@ public class Global { public static String suVersion = null; } public static class Data { - public static ValueSortedMap repoMap = new ValueSortedMap<>(); - public static ValueSortedMap moduleMap = new ValueSortedMap<>(); + public static ValueSortedMap repoMap; + public static ValueSortedMap moduleMap; public static List blockList; } public static class Events { @@ -42,6 +43,7 @@ public class Global { public static final CallbackHandler.Event repoLoadDone = new CallbackHandler.Event(); public static final CallbackHandler.Event updateCheckDone = new CallbackHandler.Event(); public static final CallbackHandler.Event safetyNetDone = new CallbackHandler.Event(); + public static SparseArray uidMap = new SparseArray<>(); } public static class Configs { public static boolean isDarkTheme; diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskHideFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskHideFragment.java index 299e82a8c..8380ae2dd 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskHideFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskHideFragment.java @@ -20,9 +20,6 @@ import com.topjohnwu.magisk.utils.Async; import com.topjohnwu.magisk.utils.CallbackHandler; import com.topjohnwu.magisk.utils.Logger; -import java.util.Arrays; -import java.util.List; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java index 683500a07..de2f9ad71 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java @@ -2,9 +2,7 @@ package com.topjohnwu.magisk; import android.Manifest; import android.annotation.SuppressLint; -import android.content.Intent; import android.content.pm.PackageManager; -import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; diff --git a/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java b/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java index 967843d72..9fcce6e85 100644 --- a/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java @@ -4,7 +4,6 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; -import android.preference.Preference; import android.preference.PreferenceCategory; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; diff --git a/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java b/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java index 4cc495a56..e1b4faafa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java @@ -38,7 +38,7 @@ public class ModuleHelper { public static void createModuleMap() { Logger.dev("ModuleHelper: Loading modules"); - Global.Data.moduleMap.clear(); + Global.Data.moduleMap = new ValueSortedMap<>(); for (String path : Utils.getModList(MAGISK_PATH)) { Logger.dev("ModuleHelper: Adding modules from " + path); @@ -57,7 +57,7 @@ public class ModuleHelper { SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE); - Global.Data.repoMap.clear(); + Global.Data.repoMap = new ValueSortedMap<>(); Gson gson = new Gson(); String jsonString; 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 a8a6f0766..9604aaf3e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/Policy.java @@ -14,20 +14,17 @@ public class Policy { public int uid, policy; public long until; - public boolean logging, notification; + public boolean logging = true, notification = true; public String packageName, appName; + public PackageInfo info; - public Policy() {} - - public Policy(int uid, PackageManager pm) throws Throwable { + public Policy(int uid, PackageManager pm) throws PackageManager.NameNotFoundException { String[] pkgs = pm.getPackagesForUid(uid); if (pkgs != null && pkgs.length > 0) { - PackageInfo info = pm.getPackageInfo(pkgs[0], 0); + info = pm.getPackageInfo(pkgs[0], 0); packageName = pkgs[0]; appName = info.applicationInfo.loadLabel(pm).toString(); - logging = true; - notification = true; - } else throw new Throwable(); + } else throw new PackageManager.NameNotFoundException(); } public Policy(Cursor c) { 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 9f80574ed..4e39c5c4d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java @@ -2,15 +2,14 @@ package com.topjohnwu.magisk.superuser; import android.content.ContentValues; import android.content.Intent; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.LocalSocket; import android.net.LocalSocketAddress; -import android.os.AsyncTask; import android.os.Bundle; import android.os.CountDownTimer; +import android.os.FileObserver; import android.support.v7.app.AppCompatActivity; -import android.util.SparseArray; +import android.text.TextUtils; import android.view.Window; import android.widget.ArrayAdapter; import android.widget.Button; @@ -41,8 +40,6 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand private static final int AUTO_DENY = 1; private static final int AUTO_ALLOW = 2; - private static SparseArray uidMap = new SparseArray<>(); - @BindView(R.id.su_popup) LinearLayout suPopup; @BindView(R.id.timeout) Spinner timeout; @BindView(R.id.app_icon) ImageView appIcon; @@ -54,13 +51,12 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand private String socketPath; private LocalSocket socket; private PackageManager pm; - private PackageInfo info; private int uid; - private String appName, packageName; + private Policy policy; private CountDownTimer timer; private CallbackHandler.EventListener self; - private CallbackHandler.Event event; + private CallbackHandler.Event event = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -73,20 +69,29 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand socketPath = intent.getStringExtra("socket"); self = this; + new FileObserver(socketPath) { + @Override + public void onEvent(int fileEvent, String path) { + if (fileEvent == FileObserver.DELETE_SELF) { + if (event != null) + event.trigger(); + finish(); + } + } + }.startWatching(); + new SocketManager().exec(); } void showRequest() { - packageName = info.packageName; - appName = info.applicationInfo.loadLabel(pm).toString(); - switch (Global.Configs.suResponseType) { case AUTO_DENY: - handleAction(false, 0); + event.trigger(); return; case AUTO_ALLOW: - handleAction(true, 0); + policy.policy = Policy.ALLOW; + event.trigger(policy); return; case PROMPT: default: @@ -95,9 +100,9 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand setContentView(R.layout.activity_request); ButterKnife.bind(this); - appIcon.setImageDrawable(info.applicationInfo.loadIcon(pm)); - appNameView.setText(appName); - packageNameView.setText(packageName); + appIcon.setImageDrawable(policy.info.applicationInfo.loadIcon(pm)); + appNameView.setText(policy.appName); + packageNameView.setText(policy.packageName); ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.allow_timeout, android.R.layout.simple_spinner_item); @@ -112,12 +117,12 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand @Override public void onFinish() { deny_btn.setText(getString(R.string.deny_with_str, "(0)")); - handleAction(false, -1); + event.trigger(); } }; - grant_btn.setOnClickListener(v -> handleAction(true, timeoutList[timeout.getSelectedItemPosition()])); - deny_btn.setOnClickListener(v -> handleAction(false, timeoutList[timeout.getSelectedItemPosition()])); + grant_btn.setOnClickListener(v -> handleAction(Policy.ALLOW)); + deny_btn.setOnClickListener(v -> handleAction(Policy.DENY)); suPopup.setOnClickListener((v) -> { timer.cancel(); deny_btn.setText(getString(R.string.deny)); @@ -133,41 +138,32 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand @Override public void onBackPressed() { - Policy temp = new Policy(); - temp.policy = Policy.DENY; - event.trigger(temp); - CallbackHandler.unRegister(event); - uidMap.remove(uid); - finish(); + event.trigger(); } @Override public void onTrigger(CallbackHandler.Event event) { Policy policy = (Policy) event.getResult(); + String response = "socket:DENY"; + if (policy != null) { + Global.Events.uidMap.remove(policy.uid); + if (policy.policy == Policy.ALLOW) + response = "socket:ALLOW"; + } try { - socket.getOutputStream().write( - (policy.policy == Policy.ALLOW ? "socket:ALLOW" : "socket:DENY").getBytes()); + socket.getOutputStream().write((response).getBytes()); } catch (Exception ignored) {} + finish(); } - void handleAction(boolean action, int timeout) { - - Policy policy = new Policy(); - policy.uid = uid; - policy.packageName = packageName; - policy.appName = appName; - policy.until = (timeout == 0) ? 0 : (System.currentTimeMillis() / 1000 + timeout * 60); - policy.policy = action ? Policy.ALLOW : Policy.DENY; - policy.logging = true; - policy.notification = true; - - if (timeout >= 0) new SuDatabaseHelper(this).addPolicy(policy); - + void handleAction(int action) { + policy.policy = action; event.trigger(policy); - CallbackHandler.unRegister(event); - uidMap.remove(uid); - - finish(); + int time = timeoutList[timeout.getSelectedItemPosition()]; + if (time >= 0) { + policy.until = time == 0 ? 0 : (System.currentTimeMillis() / 1000 + time * 60); + new SuDatabaseHelper(this).addPolicy(policy); + } } private class SocketManager extends Async.NormalTask { @@ -193,6 +189,9 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand 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); @@ -203,14 +202,13 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand String data = new String(dataBytes); payload.put(name, data); - - if ("eof".equals(name)) - break; } + if (payload.getAsInteger("uid") == null) + return false; uid = payload.getAsInteger("uid"); - }catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); return false; } @@ -219,26 +217,34 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand @Override protected void onPostExecute(Boolean result) { + if (!result) { + finish(); + return; + } + boolean showRequest = false; + event = Global.Events.uidMap.get(uid); + if (event == null) { + showRequest = true; + event = new CallbackHandler.Event() { + @Override + public void trigger(Object result) { + super.trigger(result); + CallbackHandler.unRegister(this); + } + }; + Global.Events.uidMap.put(uid, event); + } + CallbackHandler.register(event, self); try { - if (!result) throw new Throwable(); - boolean showRequest = false; - event = uidMap.get(uid); - if (event == null) { - showRequest = true; - event = new CallbackHandler.Event(); - uidMap.put(uid, event); - } - CallbackHandler.register(event, self); if (showRequest) { - String[] pkgs = pm.getPackagesForUid(uid); - if (pkgs == null || pkgs.length == 0) throw new Throwable(); - info = pm.getPackageInfo(pkgs[0], 0); + policy = new Policy(uid, pm); showRequest(); } else { finish(); } - } catch (Throwable e) { - handleAction(false, -1); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + event.trigger(); } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Async.java b/app/src/main/java/com/topjohnwu/magisk/utils/Async.java index 867b0d63f..3816fe11b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Async.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Async.java @@ -11,7 +11,6 @@ import android.provider.OpenableColumns; import android.widget.Toast; import com.topjohnwu.magisk.Global; -import com.topjohnwu.magisk.MagiskHideFragment; import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.adapters.ApplicationAdapter; import com.topjohnwu.magisk.module.ModuleHelper;