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

Commit 316c6f26 authored by Steve Elliott's avatar Steve Elliott
Browse files

Fix occasional bad placement of Conversation header

This CL refactors the header placement logic to be "simpler", in that
we're abstracting a lot of the state manipulation behind a new inner
class, and are consolidating manipulation of that state to fewer
places in the overall algorithm.

Additional tests and comments have been added to hopefully further
improve robustness and clarity, respectively.

Fixes: 158475746
Test: atest, manual
Change-Id: I92a62cd5e46bfd1aff897b4189e53bc6768623d3
parent 06174db5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ public class LogModule {
    public static LogBuffer provideNotificationSectionLogBuffer(
            LogcatEchoTracker bufferFilter,
            DumpManager dumpManager) {
        LogBuffer buffer = new LogBuffer("NotifSectionLog", 500, 10, bufferFilter);
        LogBuffer buffer = new LogBuffer("NotifSectionLog", 1000, 10, bufferFilter);
        buffer.attach(dumpManager);
        return buffer;
    }
+160 −204

File changed.

Preview size limit exceeded, changes collapsed.

+11 −1
Original line number Diff line number Diff line
@@ -23,3 +23,13 @@ val ViewGroup.children
    get() = sequence {
        for (i in 0 until childCount) yield(getChildAt(i))
    }

/** Inclusive version of [Iterable.takeWhile] */
fun <T> Sequence<T>.takeUntil(pred: (T) -> Boolean): Sequence<T> = sequence {
    for (x in this@takeUntil) {
        yield(x)
        if (pred(x)) {
            break
        }
    }
}
 No newline at end of file
+16 −0
Original line number Diff line number Diff line
@@ -18,6 +18,22 @@ package com.android.systemui.util

import android.util.SparseArray

/**
 * Transforms a sequence of Key/Value pairs into a SparseArray.
 *
 * See [kotlin.collections.toMap].
 */
fun <T> Sequence<Pair<Int, T>>.toSparseArray(size: Int = -1): SparseArray<T> {
    val sparseArray = when {
        size < 0 -> SparseArray<T>()
        else -> SparseArray<T>(size)
    }
    for ((i, v) in this) {
        sparseArray.put(i, v)
    }
    return sparseArray
}

/**
 * Transforms an [Array] into a [SparseArray], by applying each element to [keySelector] in order to
 * generate the index at which it will be placed. If two elements produce the same index, the latter
+76 −6
Original line number Diff line number Diff line
@@ -403,11 +403,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
        enablePeopleFiltering();

        setupMockStack(
                PERSON.headsUp(),   // personHeaderTarget = 0
                INCOMING_HEADER,    // currentIncomingHeaderIdx = 1
                ALERTING.headsUp(), // alertingHeaderTarget = 1
                PEOPLE_HEADER,      // currentPeopleHeaderIdx = 3
                PERSON              //
                PERSON.headsUp(),
                INCOMING_HEADER,
                ALERTING.headsUp(),
                PEOPLE_HEADER,
                PERSON
        );
        mSectionsManager.updateSectionBoundaries();

@@ -520,6 +520,70 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
                ChildType.GENTLE);
    }

    @Test
    public void testRemoveIncomingHeader() {
        enablePeopleFiltering();
        enableMediaControls();

        setupMockStack(
                MEDIA_CONTROLS,
                INCOMING_HEADER,
                PERSON,
                ALERTING,
                PEOPLE_HEADER,
                ALERTING_HEADER,
                ALERTING,
                ALERTING,
                GENTLE_HEADER,
                GENTLE,
                GENTLE
        );

        mSectionsManager.updateSectionBoundaries();

        verifyMockStack(
                ChildType.MEDIA_CONTROLS,
                ChildType.PEOPLE_HEADER,
                ChildType.PERSON,
                ChildType.ALERTING_HEADER,
                ChildType.ALERTING,
                ChildType.ALERTING,
                ChildType.ALERTING,
                ChildType.GENTLE_HEADER,
                ChildType.GENTLE,
                ChildType.GENTLE
        );
    }

    @Test
    public void testExpandIncomingSection() {
        enablePeopleFiltering();

        setupMockStack(
                INCOMING_HEADER,
                PERSON,
                ALERTING,
                PEOPLE_HEADER,
                ALERTING,
                PERSON,
                ALERTING_HEADER,
                ALERTING
        );

        mSectionsManager.updateSectionBoundaries();

        verifyMockStack(
                ChildType.INCOMING_HEADER,
                ChildType.HEADS_UP,
                ChildType.HEADS_UP,
                ChildType.HEADS_UP,
                ChildType.PEOPLE_HEADER,
                ChildType.PERSON,
                ChildType.ALERTING_HEADER,
                ChildType.ALERTING
        );
    }

    private void enablePeopleFiltering() {
        when(mSectionsFeatureManager.isFilteringEnabled()).thenReturn(true);
    }
@@ -657,7 +721,13 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
        final List<View> children = new ArrayList<>();
        when(mNssl.getChildCount()).thenAnswer(invocation -> children.size());
        when(mNssl.getChildAt(anyInt()))
                .thenAnswer(invocation -> children.get(invocation.getArgument(0)));
                .thenAnswer(invocation -> {
                    Integer index = invocation.getArgument(0);
                    if (index == null || index < 0 || index >= children.size()) {
                        return null;
                    }
                    return children.get(index);
                });
        when(mNssl.indexOfChild(any()))
                .thenAnswer(invocation -> children.indexOf(invocation.getArgument(0)));
        doAnswer(invocation -> {