mirror of
https://github.com/topjohnwu/libsu.git
synced 2024-11-27 05:50:26 +00:00
Add new public API isAppGrantedRoot
This commit is contained in:
parent
270aa6d426
commit
19126657f7
@ -15,7 +15,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.1.2")
|
||||
classpath("com.android.tools.build:gradle:7.1.3")
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -35,6 +35,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -205,6 +206,21 @@ public abstract class Shell implements Closeable {
|
||||
return MainShell.getCached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the application has access to root.
|
||||
* <p>
|
||||
* This method returns {@code null} when it is currently unable to determine whether
|
||||
* root access has been granted to the application. A non-null value meant that the root
|
||||
* permission grant state has been accurately determined and finalized. The application
|
||||
* must have at least 1 root shell created to have this method return {@code true}.
|
||||
* This method will not block the calling thread; results will be returned immediately.
|
||||
* @return whether the application has access to root, or {@code null} when undetermined.
|
||||
*/
|
||||
@Nullable
|
||||
public static Boolean isAppGrantedRoot() {
|
||||
return Utils.isAppGrantedRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the application has access to root.
|
||||
* <p>
|
||||
@ -214,9 +230,11 @@ public abstract class Shell implements Closeable {
|
||||
* did not grant root access to your application. However, after any root shell is constructed,
|
||||
* this method will accurately return {@code true}.
|
||||
* @return whether the application has access to root.
|
||||
* @deprecated please switch to {@link #isAppGrantedRoot()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean rootAccess() {
|
||||
return Utils.isAppGrantedRoot();
|
||||
return Objects.equals(isAppGrantedRoot(), Boolean.TRUE);
|
||||
}
|
||||
|
||||
/* ************
|
||||
|
@ -97,9 +97,7 @@ public final class BuilderImpl extends Shell.Builder {
|
||||
// Try normal non-root shell
|
||||
if (shell == null) {
|
||||
if (!hasFlags(FLAG_NON_ROOT_SHELL)) {
|
||||
synchronized (Utils.class) {
|
||||
Utils.confirmedRootState = false;
|
||||
}
|
||||
Utils.setConfirmedRootState(false);
|
||||
}
|
||||
shell = build("sh");
|
||||
}
|
||||
|
@ -150,9 +150,7 @@ class ShellImpl extends Shell {
|
||||
s = br.readLine();
|
||||
if (!TextUtils.isEmpty(s) && s.contains("uid=0")) {
|
||||
status = ROOT_SHELL;
|
||||
synchronized (Utils.class) {
|
||||
Utils.confirmedRootState = true;
|
||||
}
|
||||
Utils.setConfirmedRootState(true);
|
||||
// noinspection ConstantConditions
|
||||
String cwd = ShellUtils.escapedString(System.getProperty("user.dir"));
|
||||
STDIN.write(("cd " + cwd + "\n").getBytes(UTF_8));
|
||||
|
@ -43,9 +43,14 @@ public final class Utils {
|
||||
private static Class<?> synchronizedCollectionClass;
|
||||
private static final String TAG = "LIBSU";
|
||||
|
||||
// -1: uninitialized
|
||||
// 0: checked, no root
|
||||
// 1: checked, undetermined
|
||||
// 2: checked, root access
|
||||
private static int currentRootState = -1;
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
static Context context;
|
||||
static Boolean confirmedRootState;
|
||||
|
||||
public static void log(Object log) {
|
||||
log(TAG, log);
|
||||
@ -128,28 +133,34 @@ public final class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static boolean isAppGrantedRoot() {
|
||||
if (confirmedRootState != null) {
|
||||
// This confirmed root state will also be set in BuilderImpl
|
||||
// and ShellImpl when new shells are getting constructed.
|
||||
return confirmedRootState;
|
||||
}
|
||||
if (Process.myUid() == 0) {
|
||||
// The current process is a root service
|
||||
confirmedRootState = true;
|
||||
return true;
|
||||
}
|
||||
// noinspection ConstantConditions
|
||||
for (String path : System.getenv("PATH").split(":")) {
|
||||
File su = new File(path + "/su");
|
||||
if (su.canExecute()) {
|
||||
// We don't actually know whether the app has been granted root access.
|
||||
// As a heuristic, let's return true here,
|
||||
// but do NOT set the value as a confirmed state.
|
||||
public synchronized static Boolean isAppGrantedRoot() {
|
||||
if (currentRootState < 0) {
|
||||
if (Process.myUid() == 0) {
|
||||
// The current process is a root service
|
||||
currentRootState = 2;
|
||||
return true;
|
||||
}
|
||||
// noinspection ConstantConditions
|
||||
for (String path : System.getenv("PATH").split(":")) {
|
||||
File su = new File(path, "su");
|
||||
if (su.canExecute()) {
|
||||
// We don't actually know whether the app has been granted root access.
|
||||
// Do NOT set the value as a confirmed state.
|
||||
currentRootState = 1;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
currentRootState = 0;
|
||||
return false;
|
||||
}
|
||||
confirmedRootState = false;
|
||||
return false;
|
||||
switch (currentRootState) {
|
||||
case 0 : return false;
|
||||
case 2 : return true;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized static void setConfirmedRootState(boolean value) {
|
||||
currentRootState = value ? 2 : 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user