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

Commit 991bcc3d authored by Christopher Tate's avatar Christopher Tate Committed by android-build-merger
Browse files

Merge "Prevent double teardown of service connections" into qt-dev

am: ae76af46

Change-Id: I47d3b9eb266f19a9f81ef6c1447fb8f112be89dd
parents af1a6cd5 ae76af46
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ public abstract class ActivityManagerInternal {
            String resolvedType, boolean fgRequired, String callingPackage, int userId,
            boolean allowBackgroundActivityStarts) throws TransactionTooLargeException;

    public abstract void disconnectActivityFromServices(Object connectionHolder);
    public abstract void disconnectActivityFromServices(Object connectionHolder, Object conns);
    public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
    public abstract ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId);
    public abstract void ensureBootCompleted();
+12 −5
Original line number Diff line number Diff line
@@ -18156,13 +18156,20 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        @Override
        public void disconnectActivityFromServices(Object connectionHolder) {
            synchronized(ActivityManagerService.this) {
                final ActivityServiceConnectionsHolder c =
        // The arguments here are untyped because the base ActivityManagerInternal class
        // doesn't have compile-time visiblity into ActivityServiceConnectionHolder or
        // ConnectionRecord.
        @Override
        public void disconnectActivityFromServices(Object connectionHolder, Object conns) {
            // 'connectionHolder' is an untyped ActivityServiceConnectionsHolder
            // 'conns' is an untyped HashSet<ConnectionRecord>
            final ActivityServiceConnectionsHolder holder =
                    (ActivityServiceConnectionsHolder) connectionHolder;
                c.forEachConnection(cr -> mServices.removeConnectionLocked(
                        (ConnectionRecord) cr, null, c));
            final HashSet<ConnectionRecord> toDisconnect = (HashSet<ConnectionRecord>) conns;
            synchronized(ActivityManagerService.this) {
                for (ConnectionRecord cr : toDisconnect) {
                    mServices.removeConnectionLocked(cr, null, holder);
                }
            }
        }
+7 −1
Original line number Diff line number Diff line
@@ -101,7 +101,13 @@ public class ActivityServiceConnectionsHolder<T> {
        if (mConnections == null || mConnections.isEmpty()) {
            return;
        }
        mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this));
        // Capture and null out mConnections, to guarantee that we process
        // disconnect of these specific connections exactly once even if
        // we're racing with rapid activity lifecycle churn and this
        // method is invoked more than once on this object.
        final Object disc = mConnections;
        mConnections = null;
        mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this, disc));
    }

    public void dump(PrintWriter pw, String prefix) {