Loading packages/SystemUI/src/com/android/systemui/flags/Flags.java +5 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,11 @@ public class Flags { public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, false); public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true); // 1000 - dock public static final BooleanFlag SIMULATE_DOCK_THROUGH_CHARGING = new BooleanFlag(1000, true); // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== // | | Loading packages/SystemUI/src/com/android/systemui/util/condition/Condition.java +23 −4 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ public abstract class Condition implements CallbackController<Condition.Callback private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>(); private boolean mIsConditionMet = false; private boolean mStarted = false; private boolean mOverriding = false; /** * Starts monitoring the condition. Loading @@ -47,6 +48,21 @@ 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 */ public boolean isOverridingCondition() { return mOverriding; } /** * Registers a callback to receive updates once started. This should be called before * {@link #start()}. Also triggers the callback immediately if already started. Loading @@ -57,7 +73,7 @@ public abstract class Condition implements CallbackController<Condition.Callback mCallbacks.add(new WeakReference<>(callback)); if (mStarted) { callback.onConditionChanged(this, mIsConditionMet); callback.onConditionChanged(this); return; } Loading Loading @@ -107,11 +123,15 @@ public abstract class Condition implements CallbackController<Condition.Callback if (cb == null) { iterator.remove(); } else { cb.onConditionChanged(this, mIsConditionMet); cb.onConditionChanged(this); } } } public boolean isConditionMet() { return mIsConditionMet; } private boolean shouldLog() { return Log.isLoggable(mTag, Log.DEBUG); } Loading @@ -124,8 +144,7 @@ public abstract class Condition implements CallbackController<Condition.Callback * Called when the fulfillment of the condition changes. * * @param condition The condition in question. * @param isConditionMet True if the condition has been fulfilled. False otherwise. */ void onConditionChanged(Condition condition, boolean isConditionMet); void onConditionChanged(Condition condition); } } packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +91 −46 Original line number Diff line number Diff line Loading @@ -18,15 +18,17 @@ package com.android.systemui.util.condition; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.policy.CallbackController; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.Executor; import java.util.stream.Collectors; import javax.inject.Inject; Loading @@ -41,9 +43,7 @@ public class Monitor implements CallbackController<Monitor.Callback> { // Set of all conditions that need to be monitored. private final Set<Condition> mConditions; // Map of values of each condition. private final HashMap<Condition, Boolean> mConditionsMap = new HashMap<>(); private final Executor mExecutor; // Whether all conditions have been met. private boolean mAllConditionsMet = false; Loading @@ -52,10 +52,43 @@ public class Monitor implements CallbackController<Monitor.Callback> { private boolean mHaveConditionsStarted = false; // Callback for when each condition has been updated. private final Condition.Callback mConditionCallback = (condition, isConditionMet) -> { mConditionsMap.put(condition, isConditionMet); private final Condition.Callback mConditionCallback = new Condition.Callback() { @Override public void onConditionChanged(Condition condition) { mExecutor.execute(() -> updateConditionMetState()); } }; @Inject public Monitor(Executor executor, Set<Condition> conditions, Set<Callback> callbacks) { mConditions = new HashSet<>(); mExecutor = executor; if (conditions != null) { mConditions.addAll(conditions); } if (callbacks == null) { return; } for (Callback callback : callbacks) { addCallbackLocked(callback); } } private void updateConditionMetState() { // Overriding conditions do not override each other final Collection<Condition> overridingConditions = mConditions.stream() .filter(Condition::isOverridingCondition).collect(Collectors.toSet()); final boolean newAllConditionsMet = !mConditionsMap.containsValue(false); final Collection<Condition> targetCollection = overridingConditions.isEmpty() ? mConditions : overridingConditions; final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection .stream() .map(Condition::isConditionMet) .allMatch(conditionMet -> conditionMet); if (newAllConditionsMet == mAllConditionsMet) { return; Loading @@ -74,32 +107,44 @@ public class Monitor implements CallbackController<Monitor.Callback> { callback.onConditionsChanged(mAllConditionsMet); } } }; } @Inject public Monitor(Set<Condition> conditions, Set<Callback> callbacks) { mConditions = conditions; private void addConditionLocked(@NotNull Condition condition) { mConditions.add(condition); // If there is no condition, give green pass. if (mConditions.isEmpty()) { mAllConditionsMet = true; if (!mHaveConditionsStarted) { return; } // Initializes the conditions map and registers a callback for each condition. mConditions.forEach((condition -> mConditionsMap.put(condition, false))); condition.addCallback(mConditionCallback); updateConditionMetState(); } if (callbacks == null) { return; /** * Adds a condition for the monitor to listen to and consider when determining whether the * overall condition state is met. */ public void addCondition(@NotNull Condition condition) { mExecutor.execute(() -> addConditionLocked(condition)); } for (Callback callback : callbacks) { addCallback(callback); /** * Removes a condition from further consideration. */ public void removeCondition(@NotNull Condition condition) { mExecutor.execute(() -> { mConditions.remove(condition); if (!mHaveConditionsStarted) { return; } condition.removeCallback(mConditionCallback); updateConditionMetState(); }); } @Override public void addCallback(@NotNull Callback callback) { private void addCallbackLocked(@NotNull Callback callback) { if (shouldLog()) Log.d(mTag, "adding callback"); mCallbacks.add(callback); Loading @@ -109,12 +154,19 @@ public class Monitor implements CallbackController<Monitor.Callback> { if (!mHaveConditionsStarted) { if (shouldLog()) Log.d(mTag, "starting all conditions"); mConditions.forEach(condition -> condition.addCallback(mConditionCallback)); updateConditionMetState(); mHaveConditionsStarted = true; } } @Override public void addCallback(@NotNull Callback callback) { mExecutor.execute(() -> addCallbackLocked(callback)); } @Override public void removeCallback(@NotNull Callback callback) { mExecutor.execute(() -> { if (shouldLog()) Log.d(mTag, "removing callback"); final Iterator<Callback> iterator = mCallbacks.iterator(); while (iterator.hasNext()) { Loading @@ -131,14 +183,7 @@ public class Monitor implements CallbackController<Monitor.Callback> { mAllConditionsMet = false; mHaveConditionsStarted = false; } } /** * Force updates each condition to the value provided. */ @VisibleForTesting public void overrideAllConditionsMet(boolean value) { mConditions.forEach(condition -> condition.updateCondition(value)); }); } private boolean shouldLog() { Loading packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.communal; import static org.mockito.ArgumentMatchers.anyBoolean; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; Loading Loading @@ -59,7 +60,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { final Condition.Callback callback = mock(Condition.Callback.class); mCondition.addCallback(callback); verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -68,7 +70,7 @@ public class CommunalSettingConditionTest extends SysuiTestCase { final Condition.Callback callback = mock(Condition.Callback.class); mCondition.addCallback(callback); verify(callback, never()).onConditionChanged(eq(mCondition), anyBoolean()); verify(callback, never()).onConditionChanged(eq(mCondition)); } @Test Loading @@ -80,7 +82,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(true); verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -92,7 +95,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(false); verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } @Test Loading @@ -104,7 +108,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(true); verify(callback, never()).onConditionChanged(mCondition, true); verify(callback, never()).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } private void updateCommunalSetting(boolean value) { Loading packages/SystemUI/tests/src/com/android/systemui/communal/CommunalTrustedNetworkConditionTest.java +11 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.communal; import static org.mockito.ArgumentMatchers.anyBoolean; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.clearInvocations; Loading Loading @@ -49,6 +50,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @SmallTest Loading Loading @@ -89,7 +91,8 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1)); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -110,7 +113,7 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi2)); // Verifies that the callback is not triggered. verify(callback, never()).onConditionChanged(eq(mCondition), anyBoolean()); verify(callback, never()).onConditionChanged(eq(mCondition)); } @Test Loading @@ -126,11 +129,13 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onAvailable(network); networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1)); Mockito.clearInvocations(callback); // Connected to non-trusted Wi-Fi network. networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities("random-wifi")); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } @Test Loading @@ -151,7 +156,8 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onLost(network); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } // Captures and returns the network callback, assuming it is registered with the connectivity Loading Loading
packages/SystemUI/src/com/android/systemui/flags/Flags.java +5 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,11 @@ public class Flags { public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, false); public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true); // 1000 - dock public static final BooleanFlag SIMULATE_DOCK_THROUGH_CHARGING = new BooleanFlag(1000, true); // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== // | | Loading
packages/SystemUI/src/com/android/systemui/util/condition/Condition.java +23 −4 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ public abstract class Condition implements CallbackController<Condition.Callback private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>(); private boolean mIsConditionMet = false; private boolean mStarted = false; private boolean mOverriding = false; /** * Starts monitoring the condition. Loading @@ -47,6 +48,21 @@ 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 */ public boolean isOverridingCondition() { return mOverriding; } /** * Registers a callback to receive updates once started. This should be called before * {@link #start()}. Also triggers the callback immediately if already started. Loading @@ -57,7 +73,7 @@ public abstract class Condition implements CallbackController<Condition.Callback mCallbacks.add(new WeakReference<>(callback)); if (mStarted) { callback.onConditionChanged(this, mIsConditionMet); callback.onConditionChanged(this); return; } Loading Loading @@ -107,11 +123,15 @@ public abstract class Condition implements CallbackController<Condition.Callback if (cb == null) { iterator.remove(); } else { cb.onConditionChanged(this, mIsConditionMet); cb.onConditionChanged(this); } } } public boolean isConditionMet() { return mIsConditionMet; } private boolean shouldLog() { return Log.isLoggable(mTag, Log.DEBUG); } Loading @@ -124,8 +144,7 @@ public abstract class Condition implements CallbackController<Condition.Callback * Called when the fulfillment of the condition changes. * * @param condition The condition in question. * @param isConditionMet True if the condition has been fulfilled. False otherwise. */ void onConditionChanged(Condition condition, boolean isConditionMet); void onConditionChanged(Condition condition); } }
packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java +91 −46 Original line number Diff line number Diff line Loading @@ -18,15 +18,17 @@ package com.android.systemui.util.condition; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.policy.CallbackController; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.Executor; import java.util.stream.Collectors; import javax.inject.Inject; Loading @@ -41,9 +43,7 @@ public class Monitor implements CallbackController<Monitor.Callback> { // Set of all conditions that need to be monitored. private final Set<Condition> mConditions; // Map of values of each condition. private final HashMap<Condition, Boolean> mConditionsMap = new HashMap<>(); private final Executor mExecutor; // Whether all conditions have been met. private boolean mAllConditionsMet = false; Loading @@ -52,10 +52,43 @@ public class Monitor implements CallbackController<Monitor.Callback> { private boolean mHaveConditionsStarted = false; // Callback for when each condition has been updated. private final Condition.Callback mConditionCallback = (condition, isConditionMet) -> { mConditionsMap.put(condition, isConditionMet); private final Condition.Callback mConditionCallback = new Condition.Callback() { @Override public void onConditionChanged(Condition condition) { mExecutor.execute(() -> updateConditionMetState()); } }; @Inject public Monitor(Executor executor, Set<Condition> conditions, Set<Callback> callbacks) { mConditions = new HashSet<>(); mExecutor = executor; if (conditions != null) { mConditions.addAll(conditions); } if (callbacks == null) { return; } for (Callback callback : callbacks) { addCallbackLocked(callback); } } private void updateConditionMetState() { // Overriding conditions do not override each other final Collection<Condition> overridingConditions = mConditions.stream() .filter(Condition::isOverridingCondition).collect(Collectors.toSet()); final boolean newAllConditionsMet = !mConditionsMap.containsValue(false); final Collection<Condition> targetCollection = overridingConditions.isEmpty() ? mConditions : overridingConditions; final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection .stream() .map(Condition::isConditionMet) .allMatch(conditionMet -> conditionMet); if (newAllConditionsMet == mAllConditionsMet) { return; Loading @@ -74,32 +107,44 @@ public class Monitor implements CallbackController<Monitor.Callback> { callback.onConditionsChanged(mAllConditionsMet); } } }; } @Inject public Monitor(Set<Condition> conditions, Set<Callback> callbacks) { mConditions = conditions; private void addConditionLocked(@NotNull Condition condition) { mConditions.add(condition); // If there is no condition, give green pass. if (mConditions.isEmpty()) { mAllConditionsMet = true; if (!mHaveConditionsStarted) { return; } // Initializes the conditions map and registers a callback for each condition. mConditions.forEach((condition -> mConditionsMap.put(condition, false))); condition.addCallback(mConditionCallback); updateConditionMetState(); } if (callbacks == null) { return; /** * Adds a condition for the monitor to listen to and consider when determining whether the * overall condition state is met. */ public void addCondition(@NotNull Condition condition) { mExecutor.execute(() -> addConditionLocked(condition)); } for (Callback callback : callbacks) { addCallback(callback); /** * Removes a condition from further consideration. */ public void removeCondition(@NotNull Condition condition) { mExecutor.execute(() -> { mConditions.remove(condition); if (!mHaveConditionsStarted) { return; } condition.removeCallback(mConditionCallback); updateConditionMetState(); }); } @Override public void addCallback(@NotNull Callback callback) { private void addCallbackLocked(@NotNull Callback callback) { if (shouldLog()) Log.d(mTag, "adding callback"); mCallbacks.add(callback); Loading @@ -109,12 +154,19 @@ public class Monitor implements CallbackController<Monitor.Callback> { if (!mHaveConditionsStarted) { if (shouldLog()) Log.d(mTag, "starting all conditions"); mConditions.forEach(condition -> condition.addCallback(mConditionCallback)); updateConditionMetState(); mHaveConditionsStarted = true; } } @Override public void addCallback(@NotNull Callback callback) { mExecutor.execute(() -> addCallbackLocked(callback)); } @Override public void removeCallback(@NotNull Callback callback) { mExecutor.execute(() -> { if (shouldLog()) Log.d(mTag, "removing callback"); final Iterator<Callback> iterator = mCallbacks.iterator(); while (iterator.hasNext()) { Loading @@ -131,14 +183,7 @@ public class Monitor implements CallbackController<Monitor.Callback> { mAllConditionsMet = false; mHaveConditionsStarted = false; } } /** * Force updates each condition to the value provided. */ @VisibleForTesting public void overrideAllConditionsMet(boolean value) { mConditions.forEach(condition -> condition.updateCondition(value)); }); } private boolean shouldLog() { Loading
packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.communal; import static org.mockito.ArgumentMatchers.anyBoolean; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; Loading Loading @@ -59,7 +60,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { final Condition.Callback callback = mock(Condition.Callback.class); mCondition.addCallback(callback); verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -68,7 +70,7 @@ public class CommunalSettingConditionTest extends SysuiTestCase { final Condition.Callback callback = mock(Condition.Callback.class); mCondition.addCallback(callback); verify(callback, never()).onConditionChanged(eq(mCondition), anyBoolean()); verify(callback, never()).onConditionChanged(eq(mCondition)); } @Test Loading @@ -80,7 +82,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(true); verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -92,7 +95,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(false); verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } @Test Loading @@ -104,7 +108,8 @@ public class CommunalSettingConditionTest extends SysuiTestCase { clearInvocations(callback); updateCommunalSetting(true); verify(callback, never()).onConditionChanged(mCondition, true); verify(callback, never()).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } private void updateCommunalSetting(boolean value) { Loading
packages/SystemUI/tests/src/com/android/systemui/communal/CommunalTrustedNetworkConditionTest.java +11 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package com.android.systemui.communal; import static org.mockito.ArgumentMatchers.anyBoolean; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.clearInvocations; Loading Loading @@ -49,6 +50,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @SmallTest Loading Loading @@ -89,7 +91,8 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1)); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, true); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isTrue(); } @Test Loading @@ -110,7 +113,7 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi2)); // Verifies that the callback is not triggered. verify(callback, never()).onConditionChanged(eq(mCondition), anyBoolean()); verify(callback, never()).onConditionChanged(eq(mCondition)); } @Test Loading @@ -126,11 +129,13 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onAvailable(network); networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1)); Mockito.clearInvocations(callback); // Connected to non-trusted Wi-Fi network. networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities("random-wifi")); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } @Test Loading @@ -151,7 +156,8 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { networkCallback.onLost(network); // Verifies that the callback is triggered. verify(callback).onConditionChanged(mCondition, false); verify(callback).onConditionChanged(mCondition); assertThat(mCondition.isConditionMet()).isFalse(); } // Captures and returns the network callback, assuming it is registered with the connectivity Loading