Loading packages/SystemUI/src/com/android/systemui/util/condition/Condition.java +52 −12 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 */ Loading Loading @@ -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(); Loading @@ -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() { Loading packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +6 −2 Original line number Diff line number Diff line Loading @@ -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() Loading packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java +121 −5 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); } } packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -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(); } } packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java +8 −0 Original line number Diff line number Diff line Loading @@ -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() {} Loading Loading
packages/SystemUI/src/com/android/systemui/util/condition/Condition.java +52 −12 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 */ Loading Loading @@ -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(); Loading @@ -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() { Loading
packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +6 −2 Original line number Diff line number Diff line Loading @@ -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() Loading
packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java +121 −5 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); } }
packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -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(); } }
packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java +8 −0 Original line number Diff line number Diff line Loading @@ -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() {} Loading