diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro index 789780d..31e2667 100644 --- a/core/proguard-rules.pro +++ b/core/proguard-rules.pro @@ -21,8 +21,9 @@ #-renamesourcefileattribute SourceFile # Strip out verbose logging --assumenosideeffects class com.topjohnwu.superuser.internal.InternalUtils { - public static *** log(...); +-assumenosideeffects class com.topjohnwu.superuser.internal.Utils { + public static void log(...); + public static void ex(...); } # Make sure R8/Proguard never remove Shell.Initializer classes diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/Impl.java b/core/src/main/java/com/topjohnwu/superuser/internal/Impl.java index 25071b5..b3e6313 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/Impl.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/Impl.java @@ -33,7 +33,7 @@ import static com.topjohnwu.superuser.Shell.FLAG_MOUNT_MASTER; import static com.topjohnwu.superuser.Shell.FLAG_NON_ROOT_SHELL; import static com.topjohnwu.superuser.Shell.GetShellCallback; import static com.topjohnwu.superuser.Shell.ROOT_SHELL; -import static com.topjohnwu.superuser.internal.InternalUtils.hasFlag; +import static com.topjohnwu.superuser.internal.Utils.hasFlags; @RestrictTo(RestrictTo.Scope.LIBRARY) public final class Impl { @@ -71,7 +71,7 @@ public final class Impl { isInitGlobal = false; } } catch (NoShellException e) { - InternalUtils.stackTrace(e); + Utils.ex(e); return; } if (executor == null) @@ -92,7 +92,7 @@ public final class Impl { ShellImpl shell = null; // Root mount master - if (!hasFlag(FLAG_NON_ROOT_SHELL) && hasFlag(FLAG_MOUNT_MASTER)) { + if (!hasFlags(FLAG_NON_ROOT_SHELL) && hasFlags(FLAG_MOUNT_MASTER)) { try { shell = newShell("su", "--mount-master"); if (shell.getStatus() != Shell.ROOT_MOUNT_MASTER) @@ -101,7 +101,7 @@ public final class Impl { } // Normal root shell - if (shell == null && !hasFlag(FLAG_NON_ROOT_SHELL)) { + if (shell == null && !hasFlags(FLAG_NON_ROOT_SHELL)) { try { shell = newShell("su"); if (shell.getStatus() != ROOT_SHELL) @@ -120,7 +120,7 @@ public final class Impl { try { ShellImpl shell = new ShellImpl(timeout, commands); try { - Context ctx = InternalUtils.getContext(); + Context ctx = Utils.getApplication(); setCachedShell(shell); if (initClasses != null) { for (Class cls : initClasses) { @@ -136,11 +136,11 @@ public final class Impl { } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException) e; - InternalUtils.stackTrace(e); + Utils.err(e); } return shell; } catch (IOException e) { - InternalUtils.stackTrace(e); + Utils.ex(e); throw new NoShellException("Unable to create a shell!", e); } } diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/InputHandler.java b/core/src/main/java/com/topjohnwu/superuser/internal/InputHandler.java index aa95efd..172d5fa 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/InputHandler.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/InputHandler.java @@ -31,15 +31,15 @@ interface InputHandler { for (String command : cmd) { in.write(command.getBytes("UTF-8")); in.write('\n'); - InternalUtils.log(TAG, command); + Utils.log(TAG, command); } }; } static InputHandler newInstance(InputStream is) { return in -> { - InternalUtils.log(TAG, ""); - InternalUtils.pump(is, in); + Utils.log(TAG, ""); + Utils.pump(is, in); is.close(); // Make sure it ends properly in.write('\n'); diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/JobImpl.java b/core/src/main/java/com/topjohnwu/superuser/internal/JobImpl.java index 084f82d..32e25eb 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/JobImpl.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/JobImpl.java @@ -54,7 +54,7 @@ class JobImpl extends Shell.Job { if (e instanceof ShellTerminatedException) { return ResultImpl.SHELL_ERR; } else { - InternalUtils.stackTrace(e); + Utils.err(e); return ResultImpl.INSTANCE; } } @@ -78,7 +78,7 @@ class JobImpl extends Shell.Job { @Override public Shell.Job to(List output) { out = output; - redirect = InternalUtils.hasFlag(Shell.FLAG_REDIRECT_STDERR); + redirect = Utils.hasFlags(Shell.FLAG_REDIRECT_STDERR); return this; } diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/ShellImpl.java b/core/src/main/java/com/topjohnwu/superuser/internal/ShellImpl.java index 630cdcf..a7d101c 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/ShellImpl.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/ShellImpl.java @@ -95,14 +95,14 @@ class ShellImpl extends Shell { ShellImpl(long timeout, String... cmd) throws IOException { status = UNKNOWN; - InternalUtils.log(TAG, "exec " + TextUtils.join(" ", cmd)); + Utils.log(TAG, "exec " + TextUtils.join(" ", cmd)); process = Runtime.getRuntime().exec(cmd); STDIN = new NoCloseOutputStream(process.getOutputStream()); STDOUT = new NoCloseInputStream(process.getInputStream()); STDERR = new NoCloseInputStream(process.getErrorStream()); String uuid = UUID.randomUUID().toString(); - InternalUtils.log(TAG, "UUID: " + uuid); + Utils.log(TAG, "UUID: " + uuid); outGobbler = new StreamGobbler.OUT(uuid); errGobbler = new StreamGobbler.ERR(uuid); endCmd = String.format("__RET=$?;echo %s;echo %s >&2;echo $__RET;unset __RET\n", uuid, uuid).getBytes("UTF-8"); diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/StreamGobbler.java b/core/src/main/java/com/topjohnwu/superuser/internal/StreamGobbler.java index b6ec9c1..b7102d7 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/StreamGobbler.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/StreamGobbler.java @@ -58,7 +58,7 @@ abstract class StreamGobbler implements Callable { } if (list != null && line != null) { list.add(line); - InternalUtils.log(TAG, line); + Utils.log(TAG, line); } return eof; } diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/InternalUtils.java b/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java similarity index 55% rename from core/src/main/java/com/topjohnwu/superuser/internal/InternalUtils.java rename to core/src/main/java/com/topjohnwu/superuser/internal/Utils.java index f7696e8..4ae1ac3 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/InternalUtils.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java @@ -26,53 +26,54 @@ import com.topjohnwu.superuser.Shell; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.lang.ref.WeakReference; import java.lang.reflect.Method; @RestrictTo(RestrictTo.Scope.LIBRARY) -public final class InternalUtils { +public final class Utils { - private static Method currentApplication; - private static WeakReference weakContext; + private static Context application; + private static final String TAG = "LIBSU"; - static { - try { - currentApplication = Class.forName("android.app.ActivityThread") - .getMethod("currentApplication"); - } catch (Exception e) { - /* Impossible */ - } + public static void log(Object log) { + log(TAG, log); } public static void log(String tag, Object log) { - if (hasFlag(Shell.FLAG_VERBOSE_LOGGING)) + if (vLog()) Log.d(tag, log.toString()); } - public static void stackTrace(Throwable t) { - if (hasFlag(Shell.FLAG_VERBOSE_LOGGING)) - Log.d("LIBSU", "Internal Error", t); + public static void ex(Throwable t) { + if (vLog()) + Log.d(TAG, "", t); } - public static boolean hasFlag(int flags) { - return hasFlag(Impl.flags, flags); + // Unexpected errors, log regardless of + public static void err(Throwable t) { + Log.d(TAG, "", t); } - public static boolean hasFlag(int base, int flags) { - return (base & flags) == flags; + public static boolean vLog() { + return hasFlags(Shell.FLAG_VERBOSE_LOGGING); } - public static Context getContext() { - if (weakContext == null || weakContext.get() == null) { - UiThreadHandler.runAndWait(() -> { - try { - weakContext = new WeakReference<>((Context) currentApplication.invoke(null)); - } catch (Exception e) { - weakContext = new WeakReference<>(null); - } - }); + public static boolean hasFlags(int flags) { + return (Impl.flags & flags) == flags; + } + + public static synchronized Context getApplication() { + try { + if (application == null) { + Method currentApplication = Class.forName("android.app.ActivityThread") + .getMethod("currentApplication"); + application = (Context) currentApplication.invoke(null); + } + return application; + } catch (Exception e) { + // Shall never happen + Utils.err(e); + return null; } - return weakContext.get(); } public static long pump(InputStream in, OutputStream out) throws IOException { diff --git a/io/src/main/java/com/topjohnwu/superuser/internal/ShellIO.java b/io/src/main/java/com/topjohnwu/superuser/internal/ShellIO.java index f342ddc..d49feed 100644 --- a/io/src/main/java/com/topjohnwu/superuser/internal/ShellIO.java +++ b/io/src/main/java/com/topjohnwu/superuser/internal/ShellIO.java @@ -105,7 +105,7 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp "dd of='%s' ibs=%d count=1 obs=%d seek=1 %s 2>/dev/null; echo", file.getAbsolutePath(), len, fileOff, WRITE_CONV); } - InternalUtils.log(TAG, cmd); + Utils.log(TAG, cmd); in.write(cmd.getBytes("UTF-8")); in.write('\n'); in.flush(); @@ -124,7 +124,7 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp Shell.getShell().execTask((in, out, err) -> { String cmd = String.format(Locale.ROOT, "dd bs=%d count=1 >> '%s' 2>/dev/null; echo", len, file.getAbsolutePath()); - InternalUtils.log(TAG, cmd); + Utils.log(TAG, cmd); in.write(cmd.getBytes("UTF-8")); in.write('\n'); in.flush(); @@ -195,7 +195,7 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp String cmd = String.format(Locale.ROOT, "dd if='%s' ibs=%d skip=%d count=%d obs=%d 2>/dev/null; echo >&2", file.getAbsolutePath(), bs, fileOff / bs, len / bs, len); - InternalUtils.log(TAG, cmd); + Utils.log(TAG, cmd); in.write(cmd.getBytes("UTF-8")); in.write('\n'); in.flush(); @@ -231,7 +231,7 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp String cmd = String.format(Locale.ROOT, "dd of='%s' bs=%d seek=1 count=0 2>/dev/null; echo", file.getAbsolutePath(), newLength); - InternalUtils.log(TAG, cmd); + Utils.log(TAG, cmd); in.write(cmd.getBytes("UTF-8")); in.write('\n'); in.flush(); diff --git a/service/src/main/java/com/topjohnwu/superuser/ipc/IPCClient.java b/service/src/main/java/com/topjohnwu/superuser/ipc/IPCClient.java index c2ada2a..d249259 100644 --- a/service/src/main/java/com/topjohnwu/superuser/ipc/IPCClient.java +++ b/service/src/main/java/com/topjohnwu/superuser/ipc/IPCClient.java @@ -30,7 +30,7 @@ import android.os.RemoteException; import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.internal.IRootIPC; -import com.topjohnwu.superuser.internal.InternalUtils; +import com.topjohnwu.superuser.internal.Utils; import java.io.File; import java.io.FileOutputStream; @@ -55,7 +55,7 @@ class IPCClient implements IBinder.DeathRecipient { IPCClient(Intent intent) throws InterruptedException, RemoteException, IOException { name = intent.getComponent(); - startRootServer(InternalUtils.getContext(), intent); + startRootServer(Utils.getApplication(), intent); } private void startRootServer(Context context, Intent intent) @@ -66,7 +66,7 @@ class IPCClient implements IBinder.DeathRecipient { try (InputStream in = context.getResources().openRawResource(R.raw.main); OutputStream out = new FileOutputStream(mainJar)) { - InternalUtils.pump(in, out); + Utils.pump(in, out); } // Register BinderReceiver to receive binder from root process diff --git a/service/src/main/java/com/topjohnwu/superuser/ipc/IPCServer.java b/service/src/main/java/com/topjohnwu/superuser/ipc/IPCServer.java index ffa2b07..50da6e4 100644 --- a/service/src/main/java/com/topjohnwu/superuser/ipc/IPCServer.java +++ b/service/src/main/java/com/topjohnwu/superuser/ipc/IPCServer.java @@ -23,7 +23,7 @@ import android.os.Looper; import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.internal.IRootIPC; -import com.topjohnwu.superuser.internal.InternalUtils; +import com.topjohnwu.superuser.internal.Utils; import java.lang.reflect.Constructor; @@ -64,7 +64,7 @@ class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient { client.linkToDeath(this, 0); return service.onBind(intent); } catch (Exception e) { - InternalUtils.stackTrace(e); + Utils.err(e); return null; } } diff --git a/service/src/main/java/com/topjohnwu/superuser/ipc/RootService.java b/service/src/main/java/com/topjohnwu/superuser/ipc/RootService.java index e260b74..63243d2 100644 --- a/service/src/main/java/com/topjohnwu/superuser/ipc/RootService.java +++ b/service/src/main/java/com/topjohnwu/superuser/ipc/RootService.java @@ -26,9 +26,9 @@ import android.os.IBinder; import androidx.annotation.NonNull; import com.topjohnwu.superuser.Shell; -import com.topjohnwu.superuser.internal.InternalUtils; import com.topjohnwu.superuser.internal.SerialExecutorService; import com.topjohnwu.superuser.internal.UiThreadHandler; +import com.topjohnwu.superuser.internal.Utils; import java.util.ArrayList; import java.util.Iterator; @@ -36,9 +36,6 @@ import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; -import static com.topjohnwu.superuser.Shell.FLAG_VERBOSE_LOGGING; -import static com.topjohnwu.superuser.internal.InternalUtils.hasFlag; - /** * A remote root service using native Android Binder IPC. *

@@ -78,7 +75,7 @@ public abstract class RootService extends ContextWrapper { return; Intent intentCopy = new Intent(intent); - intentCopy.putExtra(INTENT_VERBOSE_KEY, hasFlag(FLAG_VERBOSE_LOGGING)); + intentCopy.putExtra(INTENT_VERBOSE_KEY, Utils.vLog()); for (IPCClient client : active) { if (client.isSameService(intentCopy)) { @@ -92,7 +89,7 @@ public abstract class RootService extends ContextWrapper { client.newConnection(conn, executor); active.add(client); } catch (Exception e) { - InternalUtils.stackTrace(e); + Utils.err(e); } }); }