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

Commit 68037bf1 authored by brycelee's avatar brycelee
Browse files

Do not remove dream complications from layout post destroy.

This change foregoes removing complications from the dream overlay
after destroy as transitions might still reference the view's parent.

Fixes: 415897902
Test: atest ComplicationLayoutEngineTest#testNoViewGroupRemovalPostDestroy
Flag: EXEMPT bugfix
Change-Id: I68da135f4b12909df9c212e9a53cad1b478ceb1b
parent 9133df32
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -1042,6 +1042,31 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase {
        verify(mLayout, never()).removeView(firstViewInfo.view);
    }

    /**
     * Ensures removal after detach doesn't cause the view to be removed from its parent
     */
    @Test
    public void testNoViewGroupRemovalPostDestroy() {
        final ComplicationLayoutEngine engine = createComplicationLayoutEngine();
        final ViewInfo firstViewInfo = new ViewInfo(
                new ComplicationLayoutParams(
                        100,
                        100,
                        ComplicationLayoutParams.POSITION_TOP
                                | ComplicationLayoutParams.POSITION_END,
                        ComplicationLayoutParams.DIRECTION_DOWN,
                        0),
                Complication.CATEGORY_STANDARD,
                mLayout);

        engine.addComplication(firstViewInfo.id, firstViewInfo.view, firstViewInfo.lp,
                firstViewInfo.category);
        Mockito.clearInvocations(mLayout, firstViewInfo.view);
        engine.onDestroyed();
        engine.removeComplication(firstViewInfo.id);
        verify(mLayout, never()).removeView(firstViewInfo.view);
    }

    @Test
    public void testGetViews() {
        final ComplicationLayoutEngine engine = createComplicationLayoutEngine();
+9 −7
Original line number Diff line number Diff line
@@ -134,6 +134,11 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
        mLayoutEngine.updateLayoutEngine(bounds, latestComplicationLayoutParams);
    }

    private void removeComplication(ComplicationId id) {
        mLayoutEngine.removeComplication(id);
        mComplications.remove(id);
    }

    private void updateComplications(Collection<ComplicationViewModel> complications) {
        if (DEBUG) {
            Log.d(TAG, "updateComplications called. Callers = " + Debug.getCallers(25));
@@ -150,10 +155,7 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
                        .collect(Collectors.toSet());

        // Trim removed complications
        removedComplicationIds.forEach(complicationId -> {
            mLayoutEngine.removeComplication(complicationId);
            mComplications.remove(complicationId);
        });
        removedComplicationIds.forEach(complicationId -> removeComplication(complicationId));

        // Add new complications
        final Collection<ComplicationViewModel> newComplications = complications
@@ -206,9 +208,9 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay

    @Override
    public void destroy() {
        mComplications.forEach((id, viewHolder) ->
                mLayoutEngine.removeComplication(id));
        mComplications.clear();
        mLayoutEngine.onDestroyed();
        mComplications.keySet().stream().collect(Collectors.toSet())
                .forEach(id -> removeComplication(id));
        super.destroy();
    }

+17 −3
Original line number Diff line number Diff line
@@ -286,10 +286,15 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
         * Informs the {@link ViewEntry}'s parent entity to remove the {@link ViewEntry} from
         * being shown further.
         */
        public void remove() {
        public void remove(boolean destroyed) {
            mParent.removeEntry(this);

            // In the case we're destroyed and going away, we maintain the view inside its parent
            // for exit transition purposes.
            if (!destroyed) {
                ((ViewGroup) mView.getParent()).removeView(mView);
            }

            mTouchInsetSession.removeViewFromTracking(mView);
        }

@@ -622,6 +627,8 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            new HashMap<>();
    private final Provider<Margins> mComplicationMarginsProvider;
    private Rect mScreenBounds = new Rect();
    private boolean mDestroyed;

    /** */
    @Inject
    public ComplicationLayoutEngine(@Named(SCOPED_COMPLICATIONS_LAYOUT) ConstraintLayout layout,
@@ -718,6 +725,13 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
        }
    }

    protected void onDestroyed() {
        // Some behaviors change upon destroy. For example, removing a complication will not result
        // in its removal from the layout as there might be exit animations in progress. We note
        // this state with the following variable to reference in those cases.
        mDestroyed = true;
    }

    /**
     * Adds a complication to this {@link ComplicationLayoutEngine}.
     * @param id A {@link ComplicationId} unique to this complication. If this matches a
@@ -764,7 +778,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            return false;
        }

        entry.remove();
        entry.remove(mDestroyed);
        return true;
    }