Merge "Condition Refactor." into tm-qpr-dev
This commit is contained in:
@@ -34,9 +34,26 @@ public abstract class Condition implements CallbackController<Condition.Callback
|
|||||||
private final String mTag = getClass().getSimpleName();
|
private final String mTag = getClass().getSimpleName();
|
||||||
|
|
||||||
private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
|
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 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.
|
* Starts monitoring the condition.
|
||||||
@@ -48,14 +65,6 @@ public abstract class Condition implements CallbackController<Condition.Callback
|
|||||||
*/
|
*/
|
||||||
protected abstract void stop();
|
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
|
* 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.
|
* @param isConditionMet True if the condition has been fulfilled. False otherwise.
|
||||||
*/
|
*/
|
||||||
protected void updateCondition(boolean isConditionMet) {
|
protected void updateCondition(boolean isConditionMet) {
|
||||||
if (mIsConditionMet == isConditionMet) {
|
if (mIsConditionMet != null && mIsConditionMet == isConditionMet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldLog()) Log.d(mTag, "updating condition to " + isConditionMet);
|
if (shouldLog()) Log.d(mTag, "updating condition to " + isConditionMet);
|
||||||
mIsConditionMet = 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();
|
final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final Callback cb = iterator.next().get();
|
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() {
|
public boolean isConditionMet() {
|
||||||
return mIsConditionMet;
|
return Boolean.TRUE.equals(mIsConditionMet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldLog() {
|
private boolean shouldLog() {
|
||||||
|
|||||||
@@ -57,12 +57,16 @@ public class Monitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
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
|
// 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());
|
.filter(Condition::isOverridingCondition).collect(Collectors.toSet());
|
||||||
|
|
||||||
final Collection<Condition> targetCollection = overridingConditions.isEmpty()
|
final Collection<Condition> targetCollection = overridingConditions.isEmpty()
|
||||||
? mSubscription.mConditions : overridingConditions;
|
? setConditions : overridingConditions;
|
||||||
|
|
||||||
final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection
|
final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection
|
||||||
.stream()
|
.stream()
|
||||||
|
|||||||
@@ -73,10 +73,16 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
|||||||
.addConditions(mConditions);
|
.addConditions(mConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Condition createMockCondition() {
|
||||||
|
final Condition condition = Mockito.mock(Condition.class);
|
||||||
|
when(condition.isConditionSet()).thenReturn(true);
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOverridingCondition() {
|
public void testOverridingCondition() {
|
||||||
final Condition overridingCondition = Mockito.mock(Condition.class);
|
final Condition overridingCondition = createMockCondition();
|
||||||
final Condition regularCondition = Mockito.mock(Condition.class);
|
final Condition regularCondition = createMockCondition();
|
||||||
final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
|
final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
|
||||||
|
|
||||||
final Monitor.Callback referenceCallback = Mockito.mock(Monitor.Callback.class);
|
final Monitor.Callback referenceCallback = Mockito.mock(Monitor.Callback.class);
|
||||||
@@ -127,9 +133,9 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleOverridingConditions() {
|
public void testMultipleOverridingConditions() {
|
||||||
final Condition overridingCondition = Mockito.mock(Condition.class);
|
final Condition overridingCondition = createMockCondition();
|
||||||
final Condition overridingCondition2 = Mockito.mock(Condition.class);
|
final Condition overridingCondition2 = createMockCondition();
|
||||||
final Condition regularCondition = Mockito.mock(Condition.class);
|
final Condition regularCondition = createMockCondition();
|
||||||
final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
|
final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
|
||||||
|
|
||||||
final Monitor monitor = new Monitor(mExecutor);
|
final Monitor monitor = new Monitor(mExecutor);
|
||||||
@@ -340,4 +346,114 @@ public class ConditionMonitorTest extends SysuiTestCase {
|
|||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
verify(callback).onConditionsChanged(true);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,4 +133,12 @@ public class ConditionTest extends SysuiTestCase {
|
|||||||
mCondition.fakeUpdateCondition(false);
|
mCondition.fakeUpdateCondition(false);
|
||||||
verify(callback, never()).onConditionChanged(eq(mCondition));
|
verify(callback, never()).onConditionChanged(eq(mCondition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearCondition_reportsNotSet() {
|
||||||
|
mCondition.fakeUpdateCondition(false);
|
||||||
|
assertThat(mCondition.isConditionSet()).isTrue();
|
||||||
|
mCondition.clearCondition();
|
||||||
|
assertThat(mCondition.isConditionSet()).isFalse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ package com.android.systemui.util.condition;
|
|||||||
* condition fulfillment.
|
* condition fulfillment.
|
||||||
*/
|
*/
|
||||||
public class FakeCondition extends Condition {
|
public class FakeCondition extends Condition {
|
||||||
|
FakeCondition() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeCondition(Boolean initialValue, Boolean overriding) {
|
||||||
|
super(initialValue, overriding);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {}
|
public void start() {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user