mirror of
https://github.com/topjohnwu/libsu.git
synced 2025-02-17 02:29:09 +00:00
Minor IPC changes
This commit is contained in:
parent
ee21b566c1
commit
6f888049d8
@ -50,9 +50,12 @@ public final class Utils {
|
||||
Log.d(TAG, "", t);
|
||||
}
|
||||
|
||||
// Unexpected errors, log regardless of
|
||||
public static void err(Throwable t) {
|
||||
Log.d(TAG, "", t);
|
||||
err(TAG, t);
|
||||
}
|
||||
|
||||
public static void err(String tag, Throwable t) {
|
||||
Log.d(tag, "", t);
|
||||
}
|
||||
|
||||
public static boolean vLog() {
|
||||
|
@ -5,7 +5,7 @@ package com.topjohnwu.superuser.internal;
|
||||
|
||||
interface IRootIPC {
|
||||
void broadcast();
|
||||
IBinder bind(in Intent intent, IBinder client);
|
||||
IBinder bind(in Intent intent);
|
||||
void unbind();
|
||||
void stop();
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import com.topjohnwu.superuser.internal.Utils;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.topjohnwu.superuser.ipc.RootService.TAG;
|
||||
|
||||
/**
|
||||
* All hidden Android framework APIs used here are very stable.
|
||||
* <p>
|
||||
@ -71,7 +73,7 @@ class HiddenAPIs {
|
||||
try {
|
||||
return (IBinder) IPCMain.getService.invoke(null, name);
|
||||
} catch (Exception e) {
|
||||
Utils.err(e);
|
||||
Utils.err(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -80,7 +82,7 @@ class HiddenAPIs {
|
||||
try {
|
||||
IPCMain.addService.invoke(null, name, service);
|
||||
} catch (Exception e) {
|
||||
Utils.err(e);
|
||||
Utils.err(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,12 +49,13 @@ import static com.topjohnwu.superuser.internal.IPCMain.CMDLINE_STOP_SERVER;
|
||||
import static com.topjohnwu.superuser.ipc.RootService.serialExecutor;
|
||||
|
||||
class IPCClient implements IBinder.DeathRecipient, Closeable {
|
||||
static final String INTENT_LOGGING_KEY = "logging";
|
||||
static final String INTENT_DEBUG_KEY = "debug";
|
||||
static final String INTENT_EXTRA_KEY = "binder_bundle";
|
||||
static final String BUNDLE_BINDER_KEY = "binder";
|
||||
static final String LOGGING_ENV = "LIBSU_VERBOSE_LOGGING";
|
||||
|
||||
private static final String BROADCAST_ACTION = "com.topjohnwu.superuser.BROADCAST_IPC";
|
||||
private static final String INTENT_EXTRA_KEY = "binder_bundle";
|
||||
private static final String BUNDLE_BINDER_KEY = "binder";
|
||||
private static final String IPCSERVER_CLASSNAME = "com.topjohnwu.superuser.internal.IPCMain";
|
||||
|
||||
private final ComponentName name;
|
||||
private final Map<ServiceConnection, Executor> connections = new HashMap<>();
|
||||
@ -84,8 +85,7 @@ class IPCClient implements IBinder.DeathRecipient, Closeable {
|
||||
// Execute main.jar through root shell
|
||||
String cmd = String.format(Locale.US,
|
||||
"(CLASSPATH=%s /proc/%d/exe /system/bin %s %s %s)&",
|
||||
mainJar, Process.myPid(),
|
||||
"com.topjohnwu.superuser.internal.IPCMain", /* main class */
|
||||
mainJar, Process.myPid(), IPCSERVER_CLASSNAME,
|
||||
name.flattenToString(), CMDLINE_STOP_SERVER /* command args */);
|
||||
// Make sure cmd is properly formatted in shell
|
||||
cmd = cmd.replace("$", "\\$");
|
||||
@ -102,11 +102,8 @@ class IPCClient implements IBinder.DeathRecipient, Closeable {
|
||||
IntentFilter filter = new IntentFilter(getBroadcastAction(name));
|
||||
context.registerReceiver(new BinderReceiver(), filter);
|
||||
|
||||
// Copy intent and add client info into intent extra
|
||||
intent = new Intent(intent);
|
||||
if (Utils.vLog()) {
|
||||
intent.putExtra(INTENT_LOGGING_KEY, true);
|
||||
}
|
||||
// Strip extra and add our own data
|
||||
intent = intent.cloneFilter();
|
||||
String debugParams = "";
|
||||
if (Debug.isDebuggerConnected()) {
|
||||
// Also debug the remote root server
|
||||
@ -121,25 +118,31 @@ class IPCClient implements IBinder.DeathRecipient, Closeable {
|
||||
debugParams = "-XjdwpProvider:adbconnection";
|
||||
}
|
||||
}
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBinder(BUNDLE_BINDER_KEY, new Binder());
|
||||
intent.putExtra(INTENT_EXTRA_KEY, bundle);
|
||||
|
||||
// Dump main.jar as trampoline
|
||||
File mainJar = dumpMainJar(context);
|
||||
|
||||
// Execute main.jar through root shell
|
||||
String cmd = String.format(Locale.US,
|
||||
"(CLASSPATH=%s /proc/%d/exe %s /system/bin --nice-name=%s:root %s %s %s)&",
|
||||
"CLASSPATH=%s /proc/%d/exe %s /system/bin --nice-name=%s:root %s %s %s",
|
||||
mainJar, Process.myPid(), debugParams, context.getPackageName(),
|
||||
"com.topjohnwu.superuser.internal.IPCMain", /* main class */
|
||||
IPCSERVER_CLASSNAME, /* main class */
|
||||
name.flattenToString(), IPCServer.class.getName() /* command args */);
|
||||
// Make sure cmd is properly formatted in shell
|
||||
cmd = cmd.replace("$", "\\$");
|
||||
if (Utils.vLog())
|
||||
cmd = LOGGING_ENV + "=1 " + cmd;
|
||||
|
||||
synchronized (this) {
|
||||
Shell.su(cmd).exec();
|
||||
Shell.su("(" + cmd + ")&").exec();
|
||||
// Wait for broadcast receiver
|
||||
wait();
|
||||
}
|
||||
server.asBinder().linkToDeath(this, 0);
|
||||
binder = server.bind(intent, new Binder());
|
||||
binder = server.bind(intent);
|
||||
}
|
||||
|
||||
boolean isSameService(Intent intent) {
|
||||
|
@ -19,6 +19,7 @@ package com.topjohnwu.superuser.ipc;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.FileObserver;
|
||||
import android.os.IBinder;
|
||||
@ -43,8 +44,10 @@ import static android.os.FileObserver.MODIFY;
|
||||
import static android.os.FileObserver.MOVED_FROM;
|
||||
import static android.os.FileObserver.MOVED_TO;
|
||||
import static com.topjohnwu.superuser.internal.IPCMain.getServiceName;
|
||||
import static com.topjohnwu.superuser.ipc.IPCClient.BUNDLE_BINDER_KEY;
|
||||
import static com.topjohnwu.superuser.ipc.IPCClient.INTENT_DEBUG_KEY;
|
||||
import static com.topjohnwu.superuser.ipc.IPCClient.INTENT_LOGGING_KEY;
|
||||
import static com.topjohnwu.superuser.ipc.IPCClient.INTENT_EXTRA_KEY;
|
||||
import static com.topjohnwu.superuser.ipc.IPCClient.LOGGING_ENV;
|
||||
import static com.topjohnwu.superuser.ipc.RootService.TAG;
|
||||
|
||||
class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient {
|
||||
@ -75,6 +78,8 @@ class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient {
|
||||
}
|
||||
}
|
||||
|
||||
Shell.Config.verboseLogging(System.getenv(LOGGING_ENV) != null);
|
||||
|
||||
mName = name;
|
||||
Class<RootService> clz = (Class<RootService>) Class.forName(name.getClassName());
|
||||
Constructor<RootService> constructor = clz.getDeclaredConstructor();
|
||||
@ -137,15 +142,11 @@ class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized IBinder bind(Intent intent, IBinder client) {
|
||||
public synchronized IBinder bind(Intent intent) {
|
||||
// ComponentName doesn't match, abort
|
||||
if (!mName.equals(intent.getComponent()))
|
||||
System.exit(1);
|
||||
|
||||
Shell.Config.verboseLogging(intent.getBooleanExtra(INTENT_LOGGING_KEY, false));
|
||||
|
||||
Utils.log(TAG, mName + " bind");
|
||||
|
||||
if (intent.getBooleanExtra(INTENT_DEBUG_KEY, false)) {
|
||||
// ActivityThread.attach(true, 0) will set this to system_process
|
||||
HiddenAPIs.setAppName(service.getPackageName() + ":root");
|
||||
@ -157,21 +158,25 @@ class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
try {
|
||||
mClient = client;
|
||||
client.linkToDeath(this, 0);
|
||||
Bundle bundle = intent.getBundleExtra(INTENT_EXTRA_KEY);
|
||||
mClient = bundle.getBinder(BUNDLE_BINDER_KEY);
|
||||
mClient.linkToDeath(this, 0);
|
||||
|
||||
class Container { IBinder obj; }
|
||||
Container binderContainer = new Container();
|
||||
Container c = new Container();
|
||||
UiThreadHandler.runAndWait(() -> {
|
||||
if (mIntent != null)
|
||||
if (mIntent != null) {
|
||||
Utils.log(TAG, mName + " rebind");
|
||||
service.onRebind(intent);
|
||||
else
|
||||
} else {
|
||||
Utils.log(TAG, mName + " bind");
|
||||
mIntent = intent.cloneFilter();
|
||||
binderContainer.obj = service.onBind(intent);
|
||||
}
|
||||
c.obj = service.onBind(intent);
|
||||
});
|
||||
return binderContainer.obj;
|
||||
return c.obj;
|
||||
} catch (Exception e) {
|
||||
Utils.err(e);
|
||||
Utils.err(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -207,7 +212,7 @@ class IPCServer extends IRootIPC.Stub implements IBinder.DeathRecipient {
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
Utils.log(TAG, mName + " binderDied");
|
||||
Utils.log(TAG, "client binderDied");
|
||||
unbind();
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ public abstract class RootService extends ContextWrapper {
|
||||
client.newConnection(conn, executor);
|
||||
bound.add(client);
|
||||
} catch (Exception e) {
|
||||
Utils.err(e);
|
||||
Utils.err(TAG, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -168,7 +168,7 @@ public abstract class RootService extends ContextWrapper {
|
||||
try {
|
||||
IPCClient.stopRootServer(intent.getComponent());
|
||||
} catch (IOException e) {
|
||||
Utils.err(e);
|
||||
Utils.err(TAG, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user