Always call finishReceiver after dispatched BOOT_COMPLETED (#2693)

For Android 14:
1. Receivers registered with `scheduleRegisteredReceiver` need to call `finishReceiver` when `assumeDelivered` is false to avoid blocking.
2. `LOCKED_BOOT_COMPLETED` is no longer `ordered` but `assumeDelivered` = false

Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
This commit is contained in:
Howard Wu 2023-08-18 10:07:11 +08:00 committed by GitHub
parent 1bb7a340ba
commit 0b27b23952
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 71 deletions

View File

@ -21,7 +21,6 @@ package org.lsposed.lspd.service;
import static org.lsposed.lspd.service.ServiceManager.TAG;
import android.annotation.SuppressLint;
import android.app.ContentProviderHolder;
import android.app.IActivityManager;
import android.app.IApplicationThread;
@ -45,7 +44,7 @@ import android.util.Log;
public class ActivityManagerService {
private static IActivityManager am = null;
private static IBinder binder = null;
private static IApplicationThread thread = null;
private static IApplicationThread appThread = null;
private static IBinder token = null;
private static final IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@ -55,7 +54,7 @@ public class ActivityManagerService {
binder.unlinkToDeath(this, 0);
binder = null;
am = null;
thread = null;
appThread = null;
token = null;
}
};
@ -81,21 +80,21 @@ public class ActivityManagerService {
String resultData, Bundle map, String[] requiredPermissions,
int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return -1;
if (am == null || appThread == null) return -1;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
return am.broadcastIntentWithFeature(thread, callingFeatureId, intent, resolvedType, resultTo,
return am.broadcastIntentWithFeature(appThread, callingFeatureId, intent, resolvedType, resultTo,
resultCode, resultData, null, requiredPermissions, null, null, appOp, null,
serialized, sticky, userId);
} catch (NoSuchMethodError ignored) {
return am.broadcastIntentWithFeature(thread, callingFeatureId, intent, resolvedType, resultTo,
return am.broadcastIntentWithFeature(appThread, callingFeatureId, intent, resolvedType, resultTo,
resultCode, resultData, null, requiredPermissions, null, appOp, null,
serialized, sticky, userId);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.broadcastIntentWithFeature(thread, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
return am.broadcastIntentWithFeature(appThread, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
} else {
return am.broadcastIntent(thread, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
return am.broadcastIntent(appThread, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
}
}
@ -111,27 +110,31 @@ public class ActivityManagerService {
return am.startUserInBackground(userId);
}
@SuppressLint("NewApi")
public static Intent registerReceiver(String callerPackage,
String callingFeatureId, IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return null;
if (am == null || appThread == null) return null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
return am.registerReceiverWithFeature(thread, callerPackage, callingFeatureId, "null", receiver, filter, requiredPermission, userId, flags);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.registerReceiverWithFeature(thread, callerPackage, callingFeatureId, receiver, filter, requiredPermission, userId, flags);
return am.registerReceiverWithFeature(appThread, callerPackage, callingFeatureId, "null", receiver, filter, requiredPermission, userId, flags);
else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
return am.registerReceiverWithFeature(appThread, callerPackage, callingFeatureId, receiver, filter, requiredPermission, userId, flags);
} else {
return am.registerReceiver(thread, callerPackage, receiver, filter, requiredPermission, userId, flags);
return am.registerReceiver(appThread, callerPackage, receiver, filter, requiredPermission, userId, flags);
}
}
public static void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
boolean abortBroadcast, int flags) throws RemoteException {
public static void finishReceiver(IBinder intentReceiver, IBinder applicationThread, int resultCode,
String resultData, Bundle resultExtras, boolean resultAbort,
int flags) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return;
am.finishReceiver(who, resultCode, resultData, map, abortBroadcast, flags);
if (am == null || appThread == null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
am.finishReceiver(applicationThread, resultCode, resultData, resultExtras, resultAbort, flags);
} else {
am.finishReceiver(intentReceiver, resultCode, resultData, resultExtras, resultAbort, flags);
}
}
public static int bindService(Intent service,
@ -139,8 +142,8 @@ public class ActivityManagerService {
String callingPackage, int userId) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return -1;
return am.bindService(thread, token, service, resolvedType, connection, flags, callingPackage, userId);
if (am == null || appThread == null) return -1;
return am.bindService(appThread, token, service, resolvedType, connection, flags, callingPackage, userId);
}
public static boolean unbindService(IServiceConnection connection) throws RemoteException {
@ -154,17 +157,17 @@ public class ActivityManagerService {
IBinder resultTo, String resultWho, int requestCode, int flags,
ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return -1;
if (am == null || appThread == null) return -1;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.startActivityAsUserWithFeature(thread, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, flags, profilerInfo, options, userId);
return am.startActivityAsUserWithFeature(appThread, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, flags, profilerInfo, options, userId);
} else {
return am.startActivityAsUser(thread, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, flags, profilerInfo, options, userId);
return am.startActivityAsUser(appThread, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, flags, profilerInfo, options, userId);
}
}
public static void onSystemServerContext(IApplicationThread thread, IBinder token) {
ActivityManagerService.thread = thread;
ActivityManagerService.appThread = thread;
ActivityManagerService.token = token;
}

View File

@ -94,7 +94,7 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
}
switch (code) {
case BridgeService.TRANSACTION_CODE:
case BridgeService.TRANSACTION_CODE -> {
int uid = data.readInt();
int pid = data.readInt();
String processName = data.readString();
@ -109,12 +109,14 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected");
return false;
}
case LSPApplicationService.OBFUSCATION_MAP_TRANSACTION_CODE:
case LSPApplicationService.DEX_TRANSACTION_CODE:
}
case LSPApplicationService.OBFUSCATION_MAP_TRANSACTION_CODE, LSPApplicationService.DEX_TRANSACTION_CODE -> {
// Proxy LSP dex transaction to Application Binder
return ServiceManager.getApplicationService().onTransact(code, data, reply, flags);
default:
}
default -> {
return super.onTransact(code, data, reply, flags);
}
}
}

View File

@ -49,6 +49,7 @@ import org.lsposed.daemon.BuildConfig;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.zip.ZipFile;
@ -62,6 +63,8 @@ public class LSPosedService extends ILSPosedService.Stub {
public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
private static final String EXTRA_USER_HANDLE = "android.intent.extra.user_handle";
private static final String EXTRA_REMOVED_FOR_ALL_USERS = "android.intent.extra.REMOVED_FOR_ALL_USERS";
private static boolean bootCompleted = false;
private IBinder appThread = null;
private static boolean isModernModules(ApplicationInfo info) {
String[] apks;
@ -217,6 +220,7 @@ public class LSPosedService extends ILSPosedService.Stub {
}
private void dispatchBootCompleted(Intent intent) {
bootCompleted = true;
try {
var am = ActivityManagerService.getActivityManager();
if (am != null) am.setActivityController(null, false);
@ -232,6 +236,7 @@ public class LSPosedService extends ILSPosedService.Stub {
}
private void dispatchConfigurationChanged(Intent intent) {
if (!bootCompleted) return;
ConfigFileManager.reloadConfiguration();
var configManager = ConfigManager.getInstance();
if (configManager.enableStatusNotification()) {
@ -315,9 +320,10 @@ public class LSPosedService extends ILSPosedService.Stub {
Log.e(TAG, "performReceive: ", t);
}
});
if (!ordered) return;
if (!ordered && !Objects.equals(intent.getAction(), Intent.ACTION_LOCKED_BOOT_COMPLETED))
return;
try {
ActivityManagerService.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
ActivityManagerService.finishReceiver(this, appThread, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
Log.e(TAG, "finish receiver", e);
}
@ -376,7 +382,7 @@ public class LSPosedService extends ILSPosedService.Stub {
private void registerBootCompleteReceiver() {
var intentFilter = new IntentFilter(Intent.ACTION_LOCKED_BOOT_COMPLETED);
intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(List.of(intentFilter), 0, this::dispatchBootCompleted);
Log.d(TAG, "registered boot receiver");
}
@ -441,14 +447,15 @@ public class LSPosedService extends ILSPosedService.Stub {
}
@Override
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken, String api) {
public void dispatchSystemServerContext(IBinder appThread, IBinder activityToken, String api) {
Log.d(TAG, "received system context");
this.appThread = appThread;
ConfigManager.getInstance().setApi(api);
ActivityManagerService.onSystemServerContext(IApplicationThread.Stub.asInterface(activityThread), activityToken);
ActivityManagerService.onSystemServerContext(IApplicationThread.Stub.asInterface(appThread), activityToken);
registerBootCompleteReceiver();
registerPackageReceiver();
registerConfigurationReceiver();
registerSecretCodeReceiver();
registerBootCompleteReceiver();
registerUserChangeReceiver();
registerOpenManagerReceiver();
registerModuleScopeReceiver();

View File

@ -7,47 +7,48 @@ import android.os.IBinder;
import android.os.PersistableBundle;
public final class ActivityThread {
public static ActivityThread currentActivityThread() {
throw new UnsupportedOperationException("STUB");
}
public static ActivityThread currentActivityThread() {
throw new UnsupportedOperationException("STUB");
}
public ApplicationThread getApplicationThread() {
throw new UnsupportedOperationException("STUB");
}
public ApplicationThread getApplicationThread() {
throw new UnsupportedOperationException("STUB");
}
public static Application currentApplication() {
throw new UnsupportedOperationException("STUB");
}
public static Application currentApplication() {
throw new UnsupportedOperationException("STUB");
}
public static String currentPackageName() {
throw new UnsupportedOperationException("STUB");
}
public static String currentPackageName() {
throw new UnsupportedOperationException("STUB");
}
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo) {
throw new UnsupportedOperationException("STUB");
}
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo) {
throw new UnsupportedOperationException("STUB");
}
public static String currentProcessName() {
throw new UnsupportedOperationException("STUB");
}
public static String currentProcessName() {
throw new UnsupportedOperationException("STUB");
}
public ContextImpl getSystemContext() {
throw new UnsupportedOperationException("STUB");
}
public ContextImpl getSystemContext() {
throw new UnsupportedOperationException("STUB");
}
public static ActivityThread systemMain() {
throw new UnsupportedOperationException("STUB");
}
public static ActivityThread systemMain() {
throw new UnsupportedOperationException("STUB");
}
private class ApplicationThread extends IApplicationThread.Stub{
@Override
public IBinder asBinder() {
return null;
}
}
public static final class ActivityClientRecord {
Bundle state;
PersistableBundle persistentState;
}
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public IBinder asBinder() {
return null;
}
}
public static final class ActivityClientRecord {
Bundle state;
PersistableBundle persistentState;
}
}

View File

@ -89,8 +89,8 @@ public interface IActivityManager extends IInterface {
IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags) throws RemoteException;
void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
boolean abortBroadcast, int flags) throws RemoteException;
void finishReceiver(IBinder caller, int resultCode, String resultData,
Bundle resultExtras, boolean resultAbort, int flags) throws RemoteException;
@RequiresApi(30)
Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,