Establish bi-di connection after ACK

This commit is contained in:
topjohnwu 2021-12-08 03:35:30 -08:00
parent e4fbdcb7d6
commit 77e761b88b
2 changed files with 45 additions and 14 deletions

View File

@ -69,6 +69,9 @@ public class RootServiceManager implements IBinder.DeathRecipient, Handler.Callb
static final String BUNDLE_BINDER_KEY = "binder";
static final String LOGGING_ENV = "LIBSU_VERBOSE_LOGGING";
static final int MSG_ACK = 1;
static final int MSG_STOP = 2;
private static final String MAIN_CLASSNAME = "com.topjohnwu.superuser.internal.RootServerMain";
private static final String INTENT_EXTRA_KEY = "binder_bundle";
private static final String ACTION_ENV = "LIBSU_BROADCAST_ACTION";
@ -120,6 +123,7 @@ public class RootServiceManager implements IBinder.DeathRecipient, Handler.Callb
}
private IRootServiceManager manager;
private IBinder mRemote;
private List<BindRequest> pendingTasks;
private final Map<ComponentName, RemoteService> services;
@ -190,20 +194,18 @@ public class RootServiceManager implements IBinder.DeathRecipient, Handler.Callb
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
Bundle bundle = intent.getBundleExtra(INTENT_EXTRA_KEY);
if (bundle == null)
return;
IBinder binder = bundle.getBinder(BUNDLE_BINDER_KEY);
if (binder == null)
return;
IRootServiceManager m = IRootServiceManager.Stub.asInterface(binder);
try {
m.connect(connectArgs);
binder.linkToDeath(RootServiceManager.this, 0);
m.connect(connectArgs);
mRemote = binder;
} catch (RemoteException e) {
Utils.err(TAG, e);
return;
}
manager = m;
List<BindRequest> requests = pendingTasks;
pendingTasks = null;
for (BindRequest r : requests) {
bind(r.intent, r.executor, r.conn);
}
}
};
@ -331,8 +333,9 @@ public class RootServiceManager implements IBinder.DeathRecipient, Handler.Callb
@Override
public void binderDied() {
UiThreadHandler.run(() -> {
if (manager != null) {
manager.asBinder().unlinkToDeath(this, 0);
if (mRemote != null) {
mRemote.unlinkToDeath(this, 0);
mRemote = null;
manager = null;
}
@ -349,8 +352,20 @@ public class RootServiceManager implements IBinder.DeathRecipient, Handler.Callb
@Override
public boolean handleMessage(@NonNull Message msg) {
ComponentName name = (ComponentName) msg.obj;
stopInternal(name);
switch (msg.what) {
case MSG_ACK:
manager = IRootServiceManager.Stub.asInterface(mRemote);
List<BindRequest> requests = pendingTasks;
pendingTasks = null;
for (BindRequest r : requests) {
bind(r.intent, r.executor, r.conn);
}
break;
case MSG_STOP:
ComponentName name = (ComponentName) msg.obj;
stopInternal(name);
break;
}
return false;
}

View File

@ -21,6 +21,8 @@ import static com.topjohnwu.superuser.internal.RootServerMain.getServiceName;
import static com.topjohnwu.superuser.internal.RootServiceManager.BUNDLE_BINDER_KEY;
import static com.topjohnwu.superuser.internal.RootServiceManager.BUNDLE_DEBUG_KEY;
import static com.topjohnwu.superuser.internal.RootServiceManager.LOGGING_ENV;
import static com.topjohnwu.superuser.internal.RootServiceManager.MSG_ACK;
import static com.topjohnwu.superuser.internal.RootServiceManager.MSG_STOP;
import static com.topjohnwu.superuser.internal.RootServiceManager.TAG;
import static com.topjohnwu.superuser.internal.Utils.context;
@ -107,20 +109,33 @@ public class RootServiceServer extends IRootServiceManager.Stub implements IBind
IBinder binder = bundle.getBinder(BUNDLE_BINDER_KEY);
if (binder == null)
return;
final Messenger c;
try {
binder.linkToDeath(this, 0);
client = new Messenger(binder);
} catch (RemoteException ignored) {}
c = new Messenger(binder);
} catch (RemoteException e) {
Utils.err(TAG, e);
return;
}
if (bundle.getBoolean(BUNDLE_DEBUG_KEY, false)) {
// ActivityThread.attach(true, 0) will set this to system_process
HiddenAPIs.setAppName(context.getPackageName() + ":root");
Utils.log(TAG, "Waiting for debugger to be attached...");
// For some reason Debug.waitForDebugger() won't work, manual spin lock...
while (!Debug.isDebuggerConnected()) {
try { Thread.sleep(200); }
catch (InterruptedException ignored) {}
}
Utils.log(TAG, "Debugger attached!");
}
Message m = Message.obtain();
m.what = MSG_ACK;
try {
c.send(m);
client = c;
} catch (RemoteException ignored) {}
}
@Override
@ -166,6 +181,7 @@ public class RootServiceServer extends IRootServiceManager.Stub implements IBind
Messenger c = client;
if (c != null) {
Message m = Message.obtain();
m.what = MSG_STOP;
m.obj = name;
try {
c.send(m);