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:
parent
1bb7a340ba
commit
0b27b23952
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue