Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec665861 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Ensure resultTo callback is always invoked.

Even if the broadcast is not enqueued for any
reason, we should ensure that resultTo callback
is invoked so that callers don't end up waiting
forever for the callback.

Bug: 284788269
Bug: 281722957
Test: manual
Change-Id: I89f14aec8b194da3ec35b0c9a6d465445ae9badb
parent b96e6395
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -14449,6 +14449,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
                Slog.w(TAG, "Skipping broadcast of " + intent
                        + ": user " + userId + " and its parent (if any) are stopped");
                scheduleCanceledResultTo(resultToApp, resultTo, intent, userId,
                        brOptions, callingUid, callerPackage);
                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
            }
        }
@@ -14520,6 +14522,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
        } catch (RemoteException e) {
            Slog.w(TAG, "Remote exception", e);
            scheduleCanceledResultTo(resultToApp, resultTo, intent,
                    userId, brOptions, callingUid, callerPackage);
            return ActivityManager.BROADCAST_SUCCESS;
        }
@@ -14753,6 +14757,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                        if (aInfo == null) {
                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
                                    + " ssp=" + ssp + " data=" + data);
                            scheduleCanceledResultTo(resultToApp, resultTo, intent,
                                    userId, brOptions, callingUid, callerPackage);
                            return ActivityManager.BROADCAST_SUCCESS;
                        }
                        updateAssociationForApp(aInfo);
@@ -14838,6 +14844,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    // Apps should now be using ShortcutManager.pinRequestShortcut().
                    Log.w(TAG, "Broadcast " + action
                            + " no longer supported. It will not be delivered.");
                    scheduleCanceledResultTo(resultToApp, resultTo, intent,
                            userId, brOptions, callingUid, callerPackage);
                    return ActivityManager.BROADCAST_SUCCESS;
                case Intent.ACTION_PRE_BOOT_COMPLETED:
                    timeoutExempt = true;
@@ -14845,6 +14853,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                case Intent.ACTION_CLOSE_SYSTEM_DIALOGS:
                    if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid,
                            callerPackage)) {
                        scheduleCanceledResultTo(resultToApp, resultTo, intent,
                                userId, brOptions, callingUid, callerPackage);
                        // Returning success seems to be the pattern here
                        return ActivityManager.BROADCAST_SUCCESS;
                    }
@@ -14879,6 +14889,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (requiredPermissions != null && requiredPermissions.length > 0) {
                Slog.w(TAG, "Can't broadcast sticky intent " + intent
                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
                scheduleCanceledResultTo(resultToApp, resultTo, intent,
                        userId, brOptions, callingUid, callerPackage);
                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
            }
            if (intent.getComponent() != null) {
@@ -15129,6 +15141,33 @@ public class ActivityManagerService extends IActivityManager.Stub
        return ActivityManager.BROADCAST_SUCCESS;
    }
    @GuardedBy("this")
    private void scheduleCanceledResultTo(ProcessRecord resultToApp, IIntentReceiver resultTo,
            Intent intent, int userId, BroadcastOptions options, int callingUid,
            String callingPackage) {
        if (resultTo == null) {
            return;
        }
        final ProcessRecord app = resultToApp;
        final IApplicationThread thread  = (app != null) ? app.getOnewayThread() : null;
        if (thread != null) {
            try {
                final boolean shareIdentity = (options != null && options.isShareIdentityEnabled());
                thread.scheduleRegisteredReceiver(
                        resultTo, intent, Activity.RESULT_CANCELED, null, null,
                        false, false, true, userId, app.mState.getReportedProcState(),
                        shareIdentity ? callingUid : Process.INVALID_UID,
                        shareIdentity ? callingPackage : null);
            } catch (RemoteException e) {
                final String msg = "Failed to schedule result of " + intent + " via "
                        + app + ": " + e;
                app.killLocked("Can't schedule resultTo", ApplicationExitInfo.REASON_OTHER,
                        ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
                Slog.d(TAG, msg);
            }
        }
    }
    @GuardedBy("this")
    private int getRealProcessStateLocked(ProcessRecord app, int pid) {
        if (app == null) {
+2 −2
Original line number Diff line number Diff line
@@ -928,8 +928,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
        final int result = mInterface.broadcastIntentWithFeature(null, null, intent, null,
                receiver, 0, null, null, requiredPermissions, null, null,
                android.app.AppOpsManager.OP_NONE, bundle, true, false, mUserId);
        Slogf.i(TAG, "Broadcasted %s: " + result, intent);
        if (!mAsync) {
        Slogf.i(TAG, "Enqueued broadcast %s: " + result, intent);
        if (result == ActivityManager.BROADCAST_SUCCESS && !mAsync) {
            receiver.waitForFinish();
        }
        return 0;