diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 31cbe28334f91..a4c9f8c88eda8 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1020,6 +1020,12 @@ public final class ActivityThread extends ClientTransactionHandler int flags; } + // A list of receivers and an index into the receiver to be processed next. + static final class ReceiverList { + List receivers; + int index; + } + private class ApplicationThread extends IApplicationThread.Stub { private static final String DB_CONNECTION_INFO_HEADER = " %8s %8s %14s %5s %5s %5s %s"; private static final String DB_CONNECTION_INFO_FORMAT = " %8s %8s %14s %5d %5d %5d %s"; @@ -1036,6 +1042,21 @@ public final class ActivityThread extends ClientTransactionHandler sendMessage(H.RECEIVER, r); } + public final void scheduleReceiverList(List info) throws RemoteException { + for (int i = 0; i < info.size(); i++) { + ReceiverInfo r = info.get(i); + if (r.registered) { + scheduleRegisteredReceiver(r.receiver, r.intent, + r.resultCode, r.data, r.extras, r.ordered, r.sticky, + r.sendingUser, r.processState); + } else { + scheduleReceiver(r.intent, r.activityInfo, r.compatInfo, + r.resultCode, r.data, r.extras, r.sync, + r.sendingUser, r.processState); + } + } + } + public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode, int userId, @BackupDestination int backupDestination) { CreateBackupAgentData d = new CreateBackupAgentData(); diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl index 595c7f7ab0085..3984fee192037 100644 --- a/core/java/android/app/IApplicationThread.aidl +++ b/core/java/android/app/IApplicationThread.aidl @@ -20,6 +20,7 @@ import android.app.ContentProviderHolder; import android.app.IInstrumentationWatcher; import android.app.IUiAutomationConnection; import android.app.ProfilerInfo; +import android.app.ReceiverInfo; import android.app.ResultInfo; import android.app.servertransaction.ClientTransaction; import android.content.AutofillOptions; @@ -66,6 +67,9 @@ oneway interface IApplicationThread { in CompatibilityInfo compatInfo, int resultCode, in String data, in Bundle extras, boolean sync, int sendingUser, int processState); + + void scheduleReceiverList(in List info); + @UnsupportedAppUsage void scheduleCreateService(IBinder token, in ServiceInfo info, in CompatibilityInfo compatInfo, int processState); diff --git a/core/java/android/app/ReceiverInfo.aidl b/core/java/android/app/ReceiverInfo.aidl new file mode 100644 index 0000000000000..d90eee704a7e5 --- /dev/null +++ b/core/java/android/app/ReceiverInfo.aidl @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2022, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.content.IIntentReceiver; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.CompatibilityInfo; +import android.os.Bundle; + +/** + * Collect the information needed for manifest and registered receivers into a single structure + * that can be the element of a list. All fields are already parcelable. + * @hide + */ +parcelable ReceiverInfo { + /** + * Fields common to registered and manifest receivers. + */ + Intent intent; + String data; + Bundle extras; + int sendingUser; + int processState; + int resultCode; + + /** + * True if this instance represents a registered receiver and false if this instance + * represents a manifest receiver. + */ + boolean registered; + + /** + * Fields used only for registered receivers. + */ + IIntentReceiver receiver; + boolean ordered; + boolean sticky; + + /** + * Fields used only for manifest receivers. + */ + ActivityInfo activityInfo; + CompatibilityInfo compatInfo; + boolean sync; +} diff --git a/services/core/java/com/android/server/am/SameProcessApplicationThread.java b/services/core/java/com/android/server/am/SameProcessApplicationThread.java index a3c011188539d..62fd6e9d551b8 100644 --- a/services/core/java/com/android/server/am/SameProcessApplicationThread.java +++ b/services/core/java/com/android/server/am/SameProcessApplicationThread.java @@ -18,6 +18,7 @@ package com.android.server.am; import android.annotation.NonNull; import android.app.IApplicationThread; +import android.app.ReceiverInfo; import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -26,6 +27,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; +import java.util.List; import java.util.Objects; /** @@ -70,4 +72,20 @@ public class SameProcessApplicationThread extends IApplicationThread.Default { } }); } + + @Override + public void scheduleReceiverList(List info) { + for (int i = 0; i < info.size(); i++) { + ReceiverInfo r = info.get(i); + if (r.registered) { + scheduleRegisteredReceiver(r.receiver, r.intent, + r.resultCode, r.data, r.extras, r.ordered, r.sticky, + r.sendingUser, r.processState); + } else { + scheduleReceiver(r.intent, r.activityInfo, r.compatInfo, + r.resultCode, r.data, r.extras, r.sync, + r.sendingUser, r.processState); + } + } + } }