Merge "Move condition logic to shared lib so it can be reused in DockSetup apk" into tm-qpr-dev am: 3a1994eac8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20639742

Change-Id: Ib6d279520ac833de8f2eedb796cdbc3f43293faa
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Lucas Silva
2022-12-08 23:38:45 +00:00
committed by Automerger Merge Worker
7 changed files with 138 additions and 64 deletions

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.util.condition
package com.android.systemui.shared.condition
/**
* A higher order [Condition] which combines multiple conditions with a specified

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,14 @@
* limitations under the License.
*/
package com.android.systemui.util.condition;
package com.android.systemui.shared.condition;
import android.util.Log;
import com.android.systemui.statusbar.policy.CallbackController;
import org.jetbrains.annotations.NotNull;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -33,7 +34,7 @@ import java.util.List;
* Base class for a condition that needs to be fulfilled in order for {@link Monitor} to inform
* its callbacks.
*/
public abstract class Condition implements CallbackController<Condition.Callback> {
public abstract class Condition {
private final String mTag = getClass().getSimpleName();
private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
@@ -79,8 +80,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
* Registers a callback to receive updates once started. This should be called before
* {@link #start()}. Also triggers the callback immediately if already started.
*/
@Override
public void addCallback(@NotNull Callback callback) {
public void addCallback(@NonNull Callback callback) {
if (shouldLog()) Log.d(mTag, "adding callback");
mCallbacks.add(new WeakReference<>(callback));
@@ -96,8 +96,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
/**
* Removes the provided callback from further receiving updates.
*/
@Override
public void removeCallback(@NotNull Callback callback) {
public void removeCallback(@NonNull Callback callback) {
if (shouldLog()) Log.d(mTag, "removing callback");
final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
while (iterator.hasNext()) {
@@ -115,6 +114,29 @@ public abstract class Condition implements CallbackController<Condition.Callback
mStarted = false;
}
/**
* Wrapper to {@link #addCallback(Callback)} when a lifecycle is in the resumed state
* and {@link #removeCallback(Callback)} when not resumed automatically.
*/
public Callback observe(LifecycleOwner owner, Callback listener) {
return observe(owner.getLifecycle(), listener);
}
/**
* Wrapper to {@link #addCallback(Callback)} when a lifecycle is in the resumed state
* and {@link #removeCallback(Condition.Callback)} when not resumed automatically.
*/
public Callback observe(Lifecycle lifecycle, Callback listener) {
lifecycle.addObserver((LifecycleEventObserver) (lifecycleOwner, event) -> {
if (event == Lifecycle.Event.ON_RESUME) {
addCallback(listener);
} else if (event == Lifecycle.Event.ON_PAUSE) {
removeCallback(listener);
}
});
return listener;
}
/**
* Updates the value for whether the condition has been fulfilled, and sends an update if the
* value changes and any callback is registered.
@@ -187,7 +209,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
* Creates a new condition which will only be true when both this condition and all the provided
* conditions are true.
*/
public Condition and(Collection<Condition> others) {
public Condition and(@NonNull Collection<Condition> others) {
final List<Condition> conditions = new ArrayList<>(others);
conditions.add(this);
return new CombinedCondition(conditions, Evaluator.OP_AND);
@@ -197,7 +219,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
* Creates a new condition which will only be true when both this condition and the provided
* condition is true.
*/
public Condition and(Condition other) {
public Condition and(@NonNull Condition other) {
return new CombinedCondition(Arrays.asList(this, other), Evaluator.OP_AND);
}
@@ -205,7 +227,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
* Creates a new condition which will only be true when either this condition or any of the
* provided conditions are true.
*/
public Condition or(Collection<Condition> others) {
public Condition or(@NonNull Collection<Condition> others) {
final List<Condition> conditions = new ArrayList<>(others);
conditions.add(this);
return new CombinedCondition(conditions, Evaluator.OP_OR);
@@ -215,7 +237,7 @@ public abstract class Condition implements CallbackController<Condition.Callback
* Creates a new condition which will only be true when either this condition or the provided
* condition is true.
*/
public Condition or(Condition other) {
public Condition or(@NonNull Condition other) {
return new CombinedCondition(Arrays.asList(this, other), Evaluator.OP_OR);
}

View File

@@ -1,4 +1,20 @@
package com.android.systemui.util.condition
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.shared.condition
import android.annotation.IntDef

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,14 @@
* limitations under the License.
*/
package com.android.systemui.util.condition;
package com.android.systemui.shared.condition;
import android.util.ArraySet;
import android.util.Log;
import com.android.systemui.dagger.qualifiers.Main;
import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
import com.android.systemui.dagger.qualifiers.Main;
import java.util.ArrayList;
import java.util.Collections;
@@ -100,7 +100,7 @@ public class Monitor {
* @param subscription A {@link Subscription} detailing the desired conditions and callback.
* @return A {@link Subscription.Token} that can be used to remove the subscription.
*/
public Subscription.Token addSubscription(@NotNull Subscription subscription) {
public Subscription.Token addSubscription(@NonNull Subscription subscription) {
final Subscription.Token token = new Subscription.Token();
final SubscriptionState state = new SubscriptionState(subscription);
@@ -131,7 +131,7 @@ public class Monitor {
* @param token The {@link Subscription.Token} returned when the {@link Subscription} was
* originally added.
*/
public void removeSubscription(@NotNull Subscription.Token token) {
public void removeSubscription(@NonNull Subscription.Token token) {
mExecutor.execute(() -> {
if (shouldLog()) Log.d(mTag, "removing subscription");
if (!mSubscriptions.containsKey(token)) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.util.condition;
package com.android.systemui.shared.condition;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -68,13 +68,15 @@ public class ConditionMonitorTest extends SysuiTestCase {
mConditionMonitor = new Monitor(mExecutor);
}
public Monitor.Subscription.Builder getDefaultBuilder(Monitor.Callback callback) {
public Monitor.Subscription.Builder getDefaultBuilder(
Monitor.Callback callback) {
return new Monitor.Subscription.Builder(callback)
.addConditions(mConditions);
}
private Condition createMockCondition() {
final Condition condition = Mockito.mock(Condition.class);
final Condition condition = Mockito.mock(
Condition.class);
when(condition.isConditionSet()).thenReturn(true);
return condition;
}
@@ -83,11 +85,14 @@ public class ConditionMonitorTest extends SysuiTestCase {
public void testOverridingCondition() {
final Condition overridingCondition = createMockCondition();
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);
final Monitor monitor = new Monitor(mExecutor);
final Monitor
monitor = new Monitor(mExecutor);
monitor.addSubscription(getDefaultBuilder(callback)
.addCondition(overridingCondition)
@@ -136,9 +141,11 @@ public class ConditionMonitorTest extends SysuiTestCase {
final Condition overridingCondition = createMockCondition();
final Condition overridingCondition2 = createMockCondition();
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);
monitor.addSubscription(getDefaultBuilder(callback)
.addCondition(overridingCondition)
@@ -211,9 +218,11 @@ public class ConditionMonitorTest extends SysuiTestCase {
public void addCallback_addSecondCallback_reportWithExistingValue() {
final Monitor.Callback callback1 =
mock(Monitor.Callback.class);
final Condition condition = mock(Condition.class);
final Condition condition = mock(
Condition.class);
when(condition.isConditionMet()).thenReturn(true);
final Monitor monitor = new Monitor(mExecutor);
final Monitor
monitor = new Monitor(mExecutor);
monitor.addSubscription(new Monitor.Subscription.Builder(callback1)
.addCondition(condition)
.build());
@@ -229,8 +238,10 @@ public class ConditionMonitorTest extends SysuiTestCase {
@Test
public void addCallback_noConditions_reportAllConditionsMet() {
final Monitor monitor = new Monitor(mExecutor);
final Monitor.Callback callback = mock(Monitor.Callback.class);
final Monitor
monitor = new Monitor(mExecutor);
final Monitor.Callback callback = mock(
Monitor.Callback.class);
monitor.addSubscription(new Monitor.Subscription.Builder(callback).build());
mExecutor.runAllReady();
@@ -239,8 +250,10 @@ public class ConditionMonitorTest extends SysuiTestCase {
@Test
public void removeCallback_noFailureOnDoubleRemove() {
final Condition condition = mock(Condition.class);
final Monitor monitor = new Monitor(mExecutor);
final Condition condition = mock(
Condition.class);
final Monitor
monitor = new Monitor(mExecutor);
final Monitor.Callback callback =
mock(Monitor.Callback.class);
final Monitor.Subscription.Token token = monitor.addSubscription(
@@ -255,8 +268,10 @@ public class ConditionMonitorTest extends SysuiTestCase {
@Test
public void removeCallback_shouldNoLongerReceiveUpdate() {
final Condition condition = mock(Condition.class);
final Monitor monitor = new Monitor(mExecutor);
final Condition condition = mock(
Condition.class);
final Monitor
monitor = new Monitor(mExecutor);
final Monitor.Callback callback =
mock(Monitor.Callback.class);
final Monitor.Subscription.Token token = monitor.addSubscription(

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.util.condition;
package com.android.systemui.shared.condition;
import static com.google.common.truth.Truth.assertThat;
@@ -47,16 +47,20 @@ public class ConditionTest extends SysuiTestCase {
@Test
public void addCallback_addFirstCallback_triggerStart() {
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
verify(mCondition).start();
}
@Test
public void addCallback_addMultipleCallbacks_triggerStartOnlyOnce() {
final Condition.Callback callback1 = mock(Condition.Callback.class);
final Condition.Callback callback2 = mock(Condition.Callback.class);
final Condition.Callback callback3 = mock(Condition.Callback.class);
final Condition.Callback callback1 = mock(
Condition.Callback.class);
final Condition.Callback callback2 = mock(
Condition.Callback.class);
final Condition.Callback callback3 = mock(
Condition.Callback.class);
mCondition.addCallback(callback1);
mCondition.addCallback(callback2);
@@ -67,12 +71,14 @@ public class ConditionTest extends SysuiTestCase {
@Test
public void addCallback_alreadyStarted_triggerUpdate() {
final Condition.Callback callback1 = mock(Condition.Callback.class);
final Condition.Callback callback1 = mock(
Condition.Callback.class);
mCondition.addCallback(callback1);
mCondition.fakeUpdateCondition(true);
final Condition.Callback callback2 = mock(Condition.Callback.class);
final Condition.Callback callback2 = mock(
Condition.Callback.class);
mCondition.addCallback(callback2);
verify(callback2).onConditionChanged(mCondition);
assertThat(mCondition.isConditionMet()).isTrue();
@@ -80,7 +86,8 @@ public class ConditionTest extends SysuiTestCase {
@Test
public void removeCallback_removeLastCallback_triggerStop() {
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
verify(mCondition, never()).stop();
@@ -92,7 +99,8 @@ public class ConditionTest extends SysuiTestCase {
public void updateCondition_falseToTrue_reportTrue() {
mCondition.fakeUpdateCondition(false);
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
mCondition.fakeUpdateCondition(true);
@@ -104,7 +112,8 @@ public class ConditionTest extends SysuiTestCase {
public void updateCondition_trueToFalse_reportFalse() {
mCondition.fakeUpdateCondition(true);
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
mCondition.fakeUpdateCondition(false);
@@ -116,7 +125,8 @@ public class ConditionTest extends SysuiTestCase {
public void updateCondition_trueToTrue_reportNothing() {
mCondition.fakeUpdateCondition(true);
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
mCondition.fakeUpdateCondition(true);
@@ -127,7 +137,8 @@ public class ConditionTest extends SysuiTestCase {
public void updateCondition_falseToFalse_reportNothing() {
mCondition.fakeUpdateCondition(false);
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
mCondition.addCallback(callback);
mCondition.fakeUpdateCondition(false);
@@ -149,7 +160,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.or(
new FakeCondition(/* initialValue= */ false));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -164,7 +176,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.or(
new FakeCondition(/* initialValue= */ true));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -179,7 +192,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.or(
new FakeCondition(/* initialValue= */ true));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -195,7 +209,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.or(
new FakeCondition(/* initialValue= */ null));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -211,7 +226,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.or(
new FakeCondition(/* initialValue= */ null));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isFalse();
@@ -226,7 +242,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.and(
new FakeCondition(/* initialValue= */ false));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -241,7 +258,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.and(
new FakeCondition(/* initialValue= */ true));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -256,7 +274,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.and(
new FakeCondition(/* initialValue= */ false));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();
@@ -272,7 +291,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.and(
new FakeCondition(/* initialValue= */ null));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isFalse();
@@ -288,7 +308,8 @@ public class ConditionTest extends SysuiTestCase {
final Condition combinedCondition = mCondition.and(
new FakeCondition(/* initialValue= */ null));
final Condition.Callback callback = mock(Condition.Callback.class);
final Condition.Callback callback = mock(
Condition.Callback.class);
combinedCondition.addCallback(callback);
assertThat(combinedCondition.isConditionSet()).isTrue();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 The Android Open Source Project
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.util.condition;
package com.android.systemui.shared.condition;
/**
* Fake implementation of {@link Condition}, and provides a way for tests to update