Improve su requests

This commit is contained in:
topjohnwu 2017-01-30 19:27:00 +08:00
parent 2dddb8df69
commit bfec381933
8 changed files with 79 additions and 81 deletions

View File

@ -3,6 +3,7 @@ package com.topjohnwu.magisk;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.SparseArray;
import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.Repo; import com.topjohnwu.magisk.module.Repo;
@ -30,8 +31,8 @@ public class Global {
public static String suVersion = null; public static String suVersion = null;
} }
public static class Data { public static class Data {
public static ValueSortedMap<String, Repo> repoMap = new ValueSortedMap<>(); public static ValueSortedMap<String, Repo> repoMap;
public static ValueSortedMap<String, Module> moduleMap = new ValueSortedMap<>(); public static ValueSortedMap<String, Module> moduleMap;
public static List<String> blockList; public static List<String> blockList;
} }
public static class Events { 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 repoLoadDone = new CallbackHandler.Event();
public static final CallbackHandler.Event updateCheckDone = new CallbackHandler.Event(); public static final CallbackHandler.Event updateCheckDone = new CallbackHandler.Event();
public static final CallbackHandler.Event safetyNetDone = new CallbackHandler.Event(); public static final CallbackHandler.Event safetyNetDone = new CallbackHandler.Event();
public static SparseArray<CallbackHandler.Event> uidMap = new SparseArray<>();
} }
public static class Configs { public static class Configs {
public static boolean isDarkTheme; public static boolean isDarkTheme;

View File

@ -20,9 +20,6 @@ import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.CallbackHandler; import com.topjohnwu.magisk.utils.CallbackHandler;
import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Logger;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.Unbinder; import butterknife.Unbinder;

View File

@ -2,9 +2,7 @@ package com.topjohnwu.magisk;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;

View File

@ -4,7 +4,6 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;

View File

@ -38,7 +38,7 @@ public class ModuleHelper {
public static void createModuleMap() { public static void createModuleMap() {
Logger.dev("ModuleHelper: Loading modules"); Logger.dev("ModuleHelper: Loading modules");
Global.Data.moduleMap.clear(); Global.Data.moduleMap = new ValueSortedMap<>();
for (String path : Utils.getModList(MAGISK_PATH)) { for (String path : Utils.getModList(MAGISK_PATH)) {
Logger.dev("ModuleHelper: Adding modules from " + path); Logger.dev("ModuleHelper: Adding modules from " + path);
@ -57,7 +57,7 @@ public class ModuleHelper {
SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE); SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE);
Global.Data.repoMap.clear(); Global.Data.repoMap = new ValueSortedMap<>();
Gson gson = new Gson(); Gson gson = new Gson();
String jsonString; String jsonString;

View File

@ -14,20 +14,17 @@ public class Policy {
public int uid, policy; public int uid, policy;
public long until; public long until;
public boolean logging, notification; public boolean logging = true, notification = true;
public String packageName, appName; public String packageName, appName;
public PackageInfo info;
public Policy() {} public Policy(int uid, PackageManager pm) throws PackageManager.NameNotFoundException {
public Policy(int uid, PackageManager pm) throws Throwable {
String[] pkgs = pm.getPackagesForUid(uid); String[] pkgs = pm.getPackagesForUid(uid);
if (pkgs != null && pkgs.length > 0) { if (pkgs != null && pkgs.length > 0) {
PackageInfo info = pm.getPackageInfo(pkgs[0], 0); info = pm.getPackageInfo(pkgs[0], 0);
packageName = pkgs[0]; packageName = pkgs[0];
appName = info.applicationInfo.loadLabel(pm).toString(); appName = info.applicationInfo.loadLabel(pm).toString();
logging = true; } else throw new PackageManager.NameNotFoundException();
notification = true;
} else throw new Throwable();
} }
public Policy(Cursor c) { public Policy(Cursor c) {

View File

@ -2,15 +2,14 @@ package com.topjohnwu.magisk.superuser;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.LocalSocket; import android.net.LocalSocket;
import android.net.LocalSocketAddress; import android.net.LocalSocketAddress;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.FileObserver;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.util.SparseArray; import android.text.TextUtils;
import android.view.Window; import android.view.Window;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; 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_DENY = 1;
private static final int AUTO_ALLOW = 2; private static final int AUTO_ALLOW = 2;
private static SparseArray<CallbackHandler.Event> uidMap = new SparseArray<>();
@BindView(R.id.su_popup) LinearLayout suPopup; @BindView(R.id.su_popup) LinearLayout suPopup;
@BindView(R.id.timeout) Spinner timeout; @BindView(R.id.timeout) Spinner timeout;
@BindView(R.id.app_icon) ImageView appIcon; @BindView(R.id.app_icon) ImageView appIcon;
@ -54,13 +51,12 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
private String socketPath; private String socketPath;
private LocalSocket socket; private LocalSocket socket;
private PackageManager pm; private PackageManager pm;
private PackageInfo info;
private int uid; private int uid;
private String appName, packageName; private Policy policy;
private CountDownTimer timer; private CountDownTimer timer;
private CallbackHandler.EventListener self; private CallbackHandler.EventListener self;
private CallbackHandler.Event event; private CallbackHandler.Event event = null;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -73,20 +69,29 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
socketPath = intent.getStringExtra("socket"); socketPath = intent.getStringExtra("socket");
self = this; 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(); new SocketManager().exec();
} }
void showRequest() { void showRequest() {
packageName = info.packageName;
appName = info.applicationInfo.loadLabel(pm).toString();
switch (Global.Configs.suResponseType) { switch (Global.Configs.suResponseType) {
case AUTO_DENY: case AUTO_DENY:
handleAction(false, 0); event.trigger();
return; return;
case AUTO_ALLOW: case AUTO_ALLOW:
handleAction(true, 0); policy.policy = Policy.ALLOW;
event.trigger(policy);
return; return;
case PROMPT: case PROMPT:
default: default:
@ -95,9 +100,9 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
setContentView(R.layout.activity_request); setContentView(R.layout.activity_request);
ButterKnife.bind(this); ButterKnife.bind(this);
appIcon.setImageDrawable(info.applicationInfo.loadIcon(pm)); appIcon.setImageDrawable(policy.info.applicationInfo.loadIcon(pm));
appNameView.setText(appName); appNameView.setText(policy.appName);
packageNameView.setText(packageName); packageNameView.setText(policy.packageName);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.allow_timeout, android.R.layout.simple_spinner_item); R.array.allow_timeout, android.R.layout.simple_spinner_item);
@ -112,12 +117,12 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
@Override @Override
public void onFinish() { public void onFinish() {
deny_btn.setText(getString(R.string.deny_with_str, "(0)")); deny_btn.setText(getString(R.string.deny_with_str, "(0)"));
handleAction(false, -1); event.trigger();
} }
}; };
grant_btn.setOnClickListener(v -> handleAction(true, timeoutList[timeout.getSelectedItemPosition()])); grant_btn.setOnClickListener(v -> handleAction(Policy.ALLOW));
deny_btn.setOnClickListener(v -> handleAction(false, timeoutList[timeout.getSelectedItemPosition()])); deny_btn.setOnClickListener(v -> handleAction(Policy.DENY));
suPopup.setOnClickListener((v) -> { suPopup.setOnClickListener((v) -> {
timer.cancel(); timer.cancel();
deny_btn.setText(getString(R.string.deny)); deny_btn.setText(getString(R.string.deny));
@ -133,41 +138,32 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
@Override @Override
public void onBackPressed() { public void onBackPressed() {
Policy temp = new Policy(); event.trigger();
temp.policy = Policy.DENY;
event.trigger(temp);
CallbackHandler.unRegister(event);
uidMap.remove(uid);
finish();
} }
@Override @Override
public void onTrigger(CallbackHandler.Event event) { public void onTrigger(CallbackHandler.Event event) {
Policy policy = (Policy) event.getResult(); 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 { try {
socket.getOutputStream().write( socket.getOutputStream().write((response).getBytes());
(policy.policy == Policy.ALLOW ? "socket:ALLOW" : "socket:DENY").getBytes());
} catch (Exception ignored) {} } catch (Exception ignored) {}
finish();
} }
void handleAction(boolean action, int timeout) { void handleAction(int action) {
policy.policy = action;
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);
event.trigger(policy); event.trigger(policy);
CallbackHandler.unRegister(event); int time = timeoutList[timeout.getSelectedItemPosition()];
uidMap.remove(uid); if (time >= 0) {
policy.until = time == 0 ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
finish(); new SuDatabaseHelper(this).addPolicy(policy);
}
} }
private class SocketManager extends Async.NormalTask<Void, Void, Boolean> { private class SocketManager extends Async.NormalTask<Void, Void, Boolean> {
@ -193,6 +189,9 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
String name = new String(nameBytes); String name = new String(nameBytes);
if (TextUtils.equals(name, "eof"))
break;
int dataLen = is.readInt(); int dataLen = is.readInt();
if (dataLen > SU_PROTOCOL_VALUE_MAX) if (dataLen > SU_PROTOCOL_VALUE_MAX)
throw new IllegalArgumentException(name + " data length too long: " + dataLen); throw new IllegalArgumentException(name + " data length too long: " + dataLen);
@ -203,11 +202,10 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
String data = new String(dataBytes); String data = new String(dataBytes);
payload.put(name, data); payload.put(name, data);
if ("eof".equals(name))
break;
} }
if (payload.getAsInteger("uid") == null)
return false;
uid = payload.getAsInteger("uid"); uid = payload.getAsInteger("uid");
} catch (IOException e) { } catch (IOException e) {
@ -219,26 +217,34 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
@Override @Override
protected void onPostExecute(Boolean result) { protected void onPostExecute(Boolean result) {
try { if (!result) {
if (!result) throw new Throwable(); finish();
return;
}
boolean showRequest = false; boolean showRequest = false;
event = uidMap.get(uid); event = Global.Events.uidMap.get(uid);
if (event == null) { if (event == null) {
showRequest = true; showRequest = true;
event = new CallbackHandler.Event(); event = new CallbackHandler.Event() {
uidMap.put(uid, event); @Override
public void trigger(Object result) {
super.trigger(result);
CallbackHandler.unRegister(this);
}
};
Global.Events.uidMap.put(uid, event);
} }
CallbackHandler.register(event, self); CallbackHandler.register(event, self);
try {
if (showRequest) { if (showRequest) {
String[] pkgs = pm.getPackagesForUid(uid); policy = new Policy(uid, pm);
if (pkgs == null || pkgs.length == 0) throw new Throwable();
info = pm.getPackageInfo(pkgs[0], 0);
showRequest(); showRequest();
} else { } else {
finish(); finish();
} }
} catch (Throwable e) { } catch (PackageManager.NameNotFoundException e) {
handleAction(false, -1); e.printStackTrace();
event.trigger();
} }
} }
} }

View File

@ -11,7 +11,6 @@ import android.provider.OpenableColumns;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.Global; import com.topjohnwu.magisk.Global;
import com.topjohnwu.magisk.MagiskHideFragment;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.adapters.ApplicationAdapter; import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import com.topjohnwu.magisk.module.ModuleHelper; import com.topjohnwu.magisk.module.ModuleHelper;