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

Commit 1e8b9618 authored by Bryce Lee's avatar Bryce Lee Committed by brycelee
Browse files

Prune unavailable complications.

This changelist checks the availability of a complication based on its required available complication types and trims ineligible complications from participating at the LiveData level. By default, the DreamOverlayStateController now only returns available complications.

Bug: 214039870
Test: atest DreamOverlayStateControllerTest ComplicationCollectionLiveDataTest

Change-Id: If1fa63b46e409dce944b6e0ae54d80c2c44f7024
parent 32c231ec
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import java.util.HashSet;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import javax.inject.Inject;

@@ -69,11 +70,20 @@ public class DreamOverlayStateController implements
         */
        default void onStateChanged() {
        }

        /**
         * Called when the available complication types changes.
         */
        default void onAvailableComplicationTypesChanged() {
        }
    }

    private final Executor mExecutor;
    private final ArrayList<Callback> mCallbacks = new ArrayList<>();

    @Complication.ComplicationType
    private int mAvailableComplicationTypes = Complication.COMPLICATION_TYPE_NONE;

    private final Collection<Complication> mComplications = new HashSet();

    @VisibleForTesting
@@ -108,7 +118,25 @@ public class DreamOverlayStateController implements
     * Returns collection of present {@link Complication}.
     */
    public Collection<Complication> getComplications() {
        return Collections.unmodifiableCollection(mComplications);
        return getComplications(true);
    }

    /**
     * Returns collection of present {@link Complication}.
     */
    public Collection<Complication> getComplications(boolean filterByAvailability) {
        return Collections.unmodifiableCollection(filterByAvailability
                ? mComplications
                .stream()
                .filter(complication -> {
                    @Complication.ComplicationType
                    final int requiredTypes = complication.getRequiredTypeAvailability();

                    return requiredTypes == Complication.COMPLICATION_TYPE_NONE
                            || (requiredTypes & getAvailableComplicationTypes()) == requiredTypes;
                })
                .collect(Collectors.toCollection(HashSet::new))
                : mComplications);
    }

    private void notifyCallbacks(Consumer<Callback> callbackConsumer) {
@@ -180,4 +208,22 @@ public class DreamOverlayStateController implements
    public void setOverlayActive(boolean active) {
        modifyState(active ? OP_SET_STATE : OP_CLEAR_STATE, STATE_DREAM_OVERLAY_ACTIVE);
    }

    /**
     * Returns the available complication types.
     */
    @Complication.ComplicationType
    public int getAvailableComplicationTypes() {
        return mAvailableComplicationTypes;
    }

    /**
     * Sets the available complication types for the dream overlay.
     */
    public void setAvailableComplicationTypes(@Complication.ComplicationType int types) {
        mExecutor.execute(() -> {
            mAvailableComplicationTypes = types;
            mCallbacks.forEach(callback -> callback.onAvailableComplicationTypesChanged());
        });
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -228,4 +228,15 @@ public interface Complication {
     * @return a {@link ViewHolder} for this {@link Complication} instance.
     */
    ViewHolder createView(ComplicationViewModel model);

    /**
     * Returns the types that must be present in order for this complication to participate on
     * the dream overlay. By default, this method returns
     * {@code Complication.COMPLICATION_TYPE_NONE} to indicate no types are required.
     * @return
     */
    @Complication.ComplicationType
    default int getRequiredTypeAvailability() {
        return Complication.COMPLICATION_TYPE_NONE;
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -42,6 +42,10 @@ public class ComplicationCollectionLiveData extends LiveData<Collection<Complica
                setValue(mDreamOverlayStateController.getComplications());
            }

            @Override
            public void onAvailableComplicationTypesChanged() {
                setValue(mDreamOverlayStateController.getComplications());
            }
        };
    }

+40 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.testing.AndroidTestingRunner;

@@ -120,4 +121,43 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
        mExecutor.runAllReady();
        verify(mCallback, times(1)).onComplicationsChanged();
    }

    @Test
    public void testComplicationFiltering() {
        final DreamOverlayStateController stateController =
                new DreamOverlayStateController(mExecutor);

        final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
        final Complication weatherComplication = Mockito.mock(Complication.class);
        when(alwaysAvailableComplication.getRequiredTypeAvailability())
                .thenReturn(Complication.COMPLICATION_TYPE_NONE);
        when(weatherComplication.getRequiredTypeAvailability())
                .thenReturn(Complication.COMPLICATION_TYPE_WEATHER);

        stateController.addComplication(alwaysAvailableComplication);
        stateController.addComplication(weatherComplication);

        final DreamOverlayStateController.Callback callback =
                Mockito.mock(DreamOverlayStateController.Callback.class);

        stateController.addCallback(callback);
        mExecutor.runAllReady();

        {
            final Collection<Complication> complications = stateController.getComplications();
            assertThat(complications.contains(alwaysAvailableComplication)).isTrue();
            assertThat(complications.contains(weatherComplication)).isFalse();
        }

        stateController.setAvailableComplicationTypes(Complication.COMPLICATION_TYPE_WEATHER);
        mExecutor.runAllReady();
        verify(callback).onAvailableComplicationTypesChanged();

        {
            final Collection<Complication> complications = stateController.getComplications();
            assertThat(complications.contains(alwaysAvailableComplication)).isTrue();
            assertThat(complications.contains(weatherComplication)).isTrue();
        }

    }
}
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ public class ComplicationCollectionLiveDataTest extends SysuiTestCase {
            callbackCaptor.getValue().onComplicationsChanged();

            verifyUpdate(observer, complications);

            callbackCaptor.getValue().onAvailableComplicationTypesChanged();

            verifyUpdate(observer, complications);
        });
    }