Improve su requests
This commit is contained in:
parent
2dddb8df69
commit
bfec381933
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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,14 +202,13 @@ 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) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -219,26 +217,34 @@ public class SuRequestActivity extends AppCompatActivity implements CallbackHand
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Boolean result) {
|
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 {
|
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) {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user