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

Commit a4ba2978 authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Condition Refactor." into tm-qpr-dev

parents f4ceebba 50a91d40
Loading
Loading
Loading
Loading
+52 −12
Original line number Diff line number Diff line
@@ -34,9 +34,26 @@ public abstract class Condition implements CallbackController<Condition.Callback
    private final String mTag = getClass().getSimpleName();

    private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
    private boolean mIsConditionMet = false;
    private final boolean mOverriding;
    private Boolean mIsConditionMet;
    private boolean mStarted = false;
    private boolean mOverriding = false;

    /**
     * By default, conditions have an initial value of false and are not overriding.
     */
    public Condition() {
        this(false, false);
    }

    /**
     * Constructor for specifying initial state and overriding condition attribute.
     * @param initialConditionMet Initial state of the condition.
     * @param overriding Whether this condition overrides others.
     */
    protected Condition(Boolean initialConditionMet, boolean overriding) {
        mIsConditionMet = initialConditionMet;
        mOverriding = overriding;
    }

    /**
     * Starts monitoring the condition.
@@ -48,14 +65,6 @@ public abstract class Condition implements CallbackController<Condition.Callback
     */
    protected abstract void stop();

    /**
     * Sets whether this condition's value overrides others in determining the overall state.
     */
    public void setOverriding(boolean overriding) {
        mOverriding = overriding;
        updateCondition(mIsConditionMet);
    }

    /**
     * Returns whether the current condition overrides
     */
@@ -110,13 +119,31 @@ public abstract class Condition implements CallbackController<Condition.Callback
     * @param isConditionMet True if the condition has been fulfilled. False otherwise.
     */
    protected void updateCondition(boolean isConditionMet) {
        if (mIsConditionMet == isConditionMet) {
        if (mIsConditionMet != null && mIsConditionMet == isConditionMet) {
            return;
        }

        if (shouldLog()) Log.d(mTag, "updating condition to " + isConditionMet);
        mIsConditionMet = isConditionMet;
        sendUpdate();
    }

    /**
     * Clears the set condition value. This is purposefully separate from
     * {@link #updateCondition(boolean)} to avoid confusion around {@code null} values.
     */
    protected void clearCondition() {
        if (mIsConditionMet == null) {
            return;
        }

        if (shouldLog()) Log.d(mTag, "clearing condition");

        mIsConditionMet = null;
        sendUpdate();
    }

    private void sendUpdate() {
        final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
        while (iterator.hasNext()) {
            final Callback cb = iterator.next().get();
@@ -128,8 +155,21 @@ public abstract class Condition implements CallbackController<Condition.Callback
        }
    }

    /**
     * Returns whether the condition is set. This method should be consulted to understand the
     * value of {@link #isConditionMet()}.
     * @return {@code true} if value is present, {@code false} otherwise.
     */
    public boolean isConditionSet() {
        return mIsConditionMet != null;
    }

    /**
     * Returns whether the condition has been met. Note that this method will return {@code false}
     * if the condition is not set as well.
     */
    public boolean isConditionMet() {
        return mIsConditionMet;
        return Boolean.TRUE.equals(mIsConditionMet);
    }

    private boolean shouldLog() {
+6 −2
Original line number Diff line number Diff line
@@ -57,12 +57,16 @@ public class Monitor {
        }

        public void update() {
            // Only consider set conditions.
            final Collection<Condition> setConditions = mSubscription.mConditions.stream()
                    .filter(Condition::isConditionSet).collect(Collectors.toSet());

            // Overriding conditions do not override each other
            final Collection<Condition> overridingConditions = mSubscription.mConditions.stream()
            final Collection<Condition> overridingConditions = setConditions.stream()
                    .filter(Condition::isOverridingCondition).collect(Collectors.toSet());

            final Collection<Condition> targetCollection = overridingConditions.isEmpty()
                    ? mSubscription.mConditions : overridingConditions;
                    ? setConditions : overridingConditions;

            final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection
                    .stream()
+121 −5
Original line number Diff line number Diff line
@@ -73,10 +73,16 @@ public class ConditionMonitorTest extends SysuiTestCase {
                .addConditions(mConditions);
    }

    private Condition createMockCondition() {
        final Condition condition = Mockito.mock(Condition.class);
        when(condition.isConditionSet()).thenReturn(true);
        return condition;
    }

    @Test
    public void testOverridingCondition() {
        final Condition overridingCondition = Mockito.mock(Condition.class);
        final Condition regularCondition = Mockito.mock(Condition.class);
        final Condition overridingCondition = createMockCondition();
        final Condition regularCondition = createMockCondition();
        final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);

        final Monitor.Callback referenceCallback = Mockito.mock(Monitor.Callback.class);
@@ -127,9 +133,9 @@ public class ConditionMonitorTest extends SysuiTestCase {
     */
    @Test
    public void testMultipleOverridingConditions() {
        final Condition overridingCondition = Mockito.mock(Condition.class);
        final Condition overridingCondition2 = Mockito.mock(Condition.class);
        final Condition regularCondition = Mockito.mock(Condition.class);
        final Condition overridingCondition = createMockCondition();
        final Condition overridingCondition2 = createMockCondition();
        final Condition regularCondition = createMockCondition();
        final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);

        final Monitor monitor = new Monitor(mExecutor);
@@ -340,4 +346,114 @@ public class ConditionMonitorTest extends SysuiTestCase {
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
    }

    @Test
    public void clearCondition_shouldUpdateValue() {
        mCondition1.fakeUpdateCondition(false);
        mCondition2.fakeUpdateCondition(true);
        mCondition3.fakeUpdateCondition(true);

        final Monitor.Callback callback =
                mock(Monitor.Callback.class);
        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(false);

        mCondition1.clearCondition();
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
    }

    @Test
    public void unsetCondition_shouldNotAffectValue() {
        final FakeCondition settableCondition = new FakeCondition(null, false);
        mCondition1.fakeUpdateCondition(true);
        mCondition2.fakeUpdateCondition(true);
        mCondition3.fakeUpdateCondition(true);

        final Monitor.Callback callback =
                mock(Monitor.Callback.class);

        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
                .addCondition(settableCondition)
                .build());

        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
    }

    @Test
    public void setUnsetCondition_shouldAffectValue() {
        final FakeCondition settableCondition = new FakeCondition(null, false);
        mCondition1.fakeUpdateCondition(true);
        mCondition2.fakeUpdateCondition(true);
        mCondition3.fakeUpdateCondition(true);

        final Monitor.Callback callback =
                mock(Monitor.Callback.class);

        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
                .addCondition(settableCondition)
                .build());

        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
        clearInvocations(callback);

        settableCondition.fakeUpdateCondition(false);
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(false);
        clearInvocations(callback);


        settableCondition.clearCondition();
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
    }

    @Test
    public void clearingOverridingCondition_shouldBeExcluded() {
        final FakeCondition overridingCondition = new FakeCondition(true, true);
        mCondition1.fakeUpdateCondition(false);
        mCondition2.fakeUpdateCondition(false);
        mCondition3.fakeUpdateCondition(false);

        final Monitor.Callback callback =
                mock(Monitor.Callback.class);

        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
                .addCondition(overridingCondition)
                .build());

        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
        clearInvocations(callback);

        overridingCondition.clearCondition();
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(false);
    }

    @Test
    public void settingUnsetOverridingCondition_shouldBeIncluded() {
        final FakeCondition overridingCondition = new FakeCondition(null, true);
        mCondition1.fakeUpdateCondition(false);
        mCondition2.fakeUpdateCondition(false);
        mCondition3.fakeUpdateCondition(false);

        final Monitor.Callback callback =
                mock(Monitor.Callback.class);

        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
                .addCondition(overridingCondition)
                .build());

        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(false);
        clearInvocations(callback);

        overridingCondition.fakeUpdateCondition(true);
        mExecutor.runAllReady();
        verify(callback).onConditionsChanged(true);
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -133,4 +133,12 @@ public class ConditionTest extends SysuiTestCase {
        mCondition.fakeUpdateCondition(false);
        verify(callback, never()).onConditionChanged(eq(mCondition));
    }

    @Test
    public void clearCondition_reportsNotSet() {
        mCondition.fakeUpdateCondition(false);
        assertThat(mCondition.isConditionSet()).isTrue();
        mCondition.clearCondition();
        assertThat(mCondition.isConditionSet()).isFalse();
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,14 @@ package com.android.systemui.util.condition;
 * condition fulfillment.
 */
public class FakeCondition extends Condition {
    FakeCondition() {
        super();
    }

    FakeCondition(Boolean initialValue, Boolean overriding) {
        super(initialValue, overriding);
    }

    @Override
    public void start() {}