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

Commit ae76af46 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 9c117455 36c998c6
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) {