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

Commit 591bf61f authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Don't lock WM when calling ActivityStackSupervisor.resolveIntent()

In startActivities, now WM lock is only acquired on the execution of
activity starter. This fixes the deadlock from startActivitiesAsPackage
that locks WM then AM (in PackageManagerService.resolveIntentInternal).

Fixes: 123934974
Test: Manual - Long press an app icon to add a shortcut and launch it.
      (That invokes ILauncherApps.startShortcut -> startActivities)

Change-Id: Ief8d6eeeba40d33d2853df69b9a090abbf06b32f
parent 3e0c7248
Loading
Loading
Loading
Loading
+59 −55
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.RemoteAnimationAdapter;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.PendingIntentRecord;
import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
@@ -368,42 +369,38 @@ public class ActivityStartController {
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mService.mGlobalLock) {
                ActivityRecord[] outActivity = new ActivityRecord[1];
            intents = ArrayUtils.filterNotNull(intents, Intent[]::new);
            final ActivityStarter[] starters = new ActivityStarter[intents.length];
            // Do not hold WM global lock on this loop because when resolving intent, it may
            // potentially acquire activity manager lock that leads to deadlock.
            for (int i = 0; i < intents.length; i++) {
                Intent intent = intents[i];
                    if (intent == null) {
                        continue;
                    }

                    // Refuse possible leaked file descriptors
                    if (intent != null && intent.hasFileDescriptors()) {
                // Refuse possible leaked file descriptors.
                if (intent.hasFileDescriptors()) {
                    throw new IllegalArgumentException("File descriptors passed in Intent");
                }

                    boolean componentSpecified = intent.getComponent() != null;

                // Don't modify the client's object!
                intent = new Intent(intent);

                // Collect information about the target of the Intent.
                    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
                            null, userId, ActivityStarter.computeResolveFilterUid(
                ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i],
                        0 /* startFlags */, null /* profilerInfo */, userId,
                        ActivityStarter.computeResolveFilterUid(
                                callingUid, realCallingUid, UserHandle.USER_NULL));
                aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);

                    if (aInfo != null &&
                            (aInfo.applicationInfo.privateFlags
                if (aInfo != null && (aInfo.applicationInfo.privateFlags
                        & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                        throw new IllegalArgumentException(
                                "FLAG_CANT_SAVE_STATE not supported here");
                    throw new IllegalArgumentException("FLAG_CANT_SAVE_STATE not supported here");
                }

                final boolean top = i == intents.length - 1;
                final SafeActivityOptions checkedOptions = top
                        ? options
                        : null;
                    final int res = obtainStarter(intent, reason)
                starters[i] = obtainStarter(intent, reason)
                        .setCaller(caller)
                        .setResolvedType(resolvedTypes[i])
                        .setActivityInfo(aInfo)
@@ -415,20 +412,27 @@ public class ActivityStartController {
                        .setRealCallingPid(realCallingPid)
                        .setRealCallingUid(realCallingUid)
                        .setActivityOptions(checkedOptions)
                            .setComponentSpecified(componentSpecified)
                            .setOutActivity(outActivity)
                        .setComponentSpecified(intent.getComponent() != null)

                        // Top activity decides on animation being run, so we allow only for the
                        // top one as otherwise an activity below might consume it.
                        .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
                        .setOriginatingPendingIntent(originatingPendingIntent)
                            .setAllowBackgroundActivityStart(allowBackgroundActivityStart)
                            .execute();

                    if (res < 0) {
                        return res;
                        .setAllowBackgroundActivityStart(allowBackgroundActivityStart);
            }

            final ActivityRecord[] outActivity = new ActivityRecord[1];
            // Lock the loop to ensure the activities launched in a sequence.
            synchronized (mService.mGlobalLock) {
                for (int i = 0; i < starters.length; i++) {
                    final int startResult = starters[i].setOutActivity(outActivity).execute();
                    if (startResult < START_SUCCESS) {
                        // Abort by error result and recycle unused starters.
                        for (int j = i + 1; j < starters.length; j++) {
                            mFactory.recycle(starters[j]);
                        }
                        return startResult;
                    }
                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
                }
            }
+6 −8
Original line number Diff line number Diff line
@@ -5923,7 +5923,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                Binder.restoreCallingIdentity(ident);
            }

            synchronized (mGlobalLock) {
            return getActivityStartController().startActivitiesInPackage(
                    packageUid, packageName,
                    intents, resolvedTypes, null /* resultTo */,
@@ -5931,7 +5930,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    false /* validateIncomingUser */, null /* originatingPendingIntent */,
                    false /* allowBackgroundActivityStart */);
        }
        }

        @Override
        public int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,