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

Commit bd8a3539 authored by wilsonshih's avatar wilsonshih
Browse files

Implement a reference count for the REFERENCE_WRITE_TO_PARCEL flag.

During the broadcast of a snapshot object to remote processes, a
writeToParcel operation is also performed. If this broadcast occurs
before the snapshot object is intended to be returned to a remote
process, the WRITE_TO_PARCEL reference flag becomes ambiguous.
To prevent the hardware buffer from being released too early, record
how many WRITE_TO_PARCEL operations are required for the snapshot
object. The flag is only removed when this count drops to zero.

Flag: EXEMPT bugfix
Bug: 412389050
Test: launch multiple apps and move they in the background. Repeatly
resume then close apps by swipe up gesture multiple times, verify the
broadcast occur after write_to_parcel(takeTaskSnapshot) flag removed.

Change-Id: I8a57993cb58d42350baf013443486a98c916f518
parent b3eb540d
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ public class TaskSnapshot implements Parcelable {
    // Must be one of the named color spaces, otherwise, always use SRGB color space.
    private final ColorSpace mColorSpace;
    private int mInternalReferences;
    private int mWriteToParcelCount;
    private Consumer<HardwareBuffer> mSafeSnapshotReleaser;

    /** Keep in cache, doesn't need reference. */
@@ -320,10 +321,13 @@ public class TaskSnapshot implements Parcelable {
        dest.writeInt(mUiMode);
        synchronized (this) {
            if ((mInternalReferences & REFERENCE_WRITE_TO_PARCEL) != 0) {
                mWriteToParcelCount--;
                if (mWriteToParcelCount == 0) {
                    removeReference(REFERENCE_WRITE_TO_PARCEL);
                }
            }
        }
    }

    @Override
    public String toString() {
@@ -354,6 +358,7 @@ public class TaskSnapshot implements Parcelable {
                + " mIsTranslucent=" + mIsTranslucent
                + " mHasImeSurface=" + mHasImeSurface
                + " mInternalReferences=" + mInternalReferences
                + " mWriteToParcelCount=" + mWriteToParcelCount
                + " mUiMode=" + Integer.toHexString(mUiMode);
    }

@@ -362,6 +367,9 @@ public class TaskSnapshot implements Parcelable {
     * Only used in core.
     */
    public synchronized void addReference(@ReferenceFlags int usage) {
        if (usage == REFERENCE_WRITE_TO_PARCEL) {
            mWriteToParcelCount++;
        }
        mInternalReferences |= usage;
    }

+8 −2
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ class TaskChangeNotificationController {
    private static final int NOTIFY_TASK_SNAPSHOT_INVALIDATED_LISTENERS_MSG = 29;
    private static final int NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG = 30;


    // Delay in notifying task stack change listeners (in millis)
    private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;

@@ -152,6 +151,13 @@ class TaskChangeNotificationController {
    private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
        l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
    };

    private final TaskStackConsumer mNotifyTaskSnapshotChangedRemote = (l, m) -> {
        final TaskSnapshot taskSnapshot = (TaskSnapshot) m.obj;
        taskSnapshot.addReference(TaskSnapshot.REFERENCE_WRITE_TO_PARCEL);
        l.onTaskSnapshotChanged(m.arg1, taskSnapshot);
    };

    private final TaskStackConsumer mNotifyTaskSnapshotInvalidated = (l, m) -> {
        l.onTaskSnapshotInvalidated(m.arg1);
    };
@@ -251,7 +257,7 @@ class TaskChangeNotificationController {
                    forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
                    break;
                case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
                    forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
                    forAllRemoteListeners(mNotifyTaskSnapshotChangedRemote, msg);
                    ((TaskSnapshot) msg.obj).removeReference(TaskSnapshot.REFERENCE_BROADCAST);
                    break;
                case NOTIFY_BACK_PRESSED_ON_TASK_ROOT: