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

View File

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

View File

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

View File

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

View File

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