Merge "Add flag listeners." into sc-v2-dev am: 64eea77e08
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15405312 Change-Id: Iae2f9b70f5ef583b3e5077d28aff3d5c5f30bcc2
This commit is contained in:
@@ -56,4 +56,16 @@ public interface FlagReaderPlugin extends Plugin {
|
||||
default double getValue(int id, double def) {
|
||||
return def;
|
||||
}
|
||||
|
||||
/** Add a listener to be alerted when any flag changes. */
|
||||
default void addListener(Listener listener) {}
|
||||
|
||||
/** Remove a listener to be alerted when any flag changes. */
|
||||
default void removeListener(Listener listener) {}
|
||||
|
||||
/** A simple listener to be alerted when a flag changes. */
|
||||
interface Listener {
|
||||
/** */
|
||||
void onFlagChanged(int id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,14 @@ public class FeatureFlagReader {
|
||||
return mPlugin.getValue(flag.getId(), flag.getDefault());
|
||||
}
|
||||
|
||||
void addListener(FlagReaderPlugin.Listener listener) {
|
||||
mPlugin.addListener(listener);
|
||||
}
|
||||
|
||||
void removeListener(FlagReaderPlugin.Listener listener) {
|
||||
mPlugin.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified feature flag has been enabled.
|
||||
*
|
||||
|
||||
@@ -19,11 +19,14 @@ package com.android.systemui.flags;
|
||||
import android.content.Context;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.plugins.FlagReaderPlugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -37,11 +40,26 @@ import javax.inject.Inject;
|
||||
public class FeatureFlags {
|
||||
private final FeatureFlagReader mFlagReader;
|
||||
private final Context mContext;
|
||||
private final Map<Integer, Flag<?>> mFlagMap = new HashMap<>();
|
||||
private final Map<Integer, List<Listener>> mListeners = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public FeatureFlags(FeatureFlagReader flagReader, Context context) {
|
||||
mFlagReader = flagReader;
|
||||
mContext = context;
|
||||
|
||||
flagReader.addListener(mListener);
|
||||
}
|
||||
|
||||
private final FlagReaderPlugin.Listener mListener = id -> {
|
||||
if (mListeners.containsKey(id) && mFlagMap.containsKey(id)) {
|
||||
mListeners.get(id).forEach(listener -> listener.onFlagChanged(mFlagMap.get(id)));
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
void addFlag(Flag flag) {
|
||||
mFlagMap.put(flag.getId(), flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,6 +110,20 @@ public class FeatureFlags {
|
||||
return mFlagReader.getValue(flag);
|
||||
}
|
||||
|
||||
/** Add a listener for a specific flag. */
|
||||
public void addFlagListener(Flag<?> flag, Listener listener) {
|
||||
mListeners.putIfAbsent(flag.getId(), new ArrayList<>());
|
||||
mListeners.get(flag.getId()).add(listener);
|
||||
mFlagMap.putIfAbsent(flag.getId(), flag);
|
||||
}
|
||||
|
||||
/** Remove a listener for a specific flag. */
|
||||
public void removeFlagListener(Flag<?> flag, Listener listener) {
|
||||
if (mListeners.containsKey(flag.getId())) {
|
||||
mListeners.get(flag.getId()).remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNewNotifPipelineEnabled() {
|
||||
return mFlagReader.isEnabled(R.bool.flag_notification_pipeline2);
|
||||
}
|
||||
@@ -160,27 +192,6 @@ public class FeatureFlags {
|
||||
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
|
||||
}
|
||||
|
||||
private Map<Integer, Flag<?>> collectFlags() {
|
||||
Map<Integer, Flag<?>> flags = new HashMap<>();
|
||||
|
||||
Field[] fields = this.getClass().getFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
Class<?> t = field.getType();
|
||||
if (Flag.class.isAssignableFrom(t)) {
|
||||
try {
|
||||
//flags.add((Flag<?>) field.get(null));
|
||||
Flag flag = (Flag) field.get(null);
|
||||
flags.put(flag.getId(), flag);
|
||||
} catch (IllegalAccessException e) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/** Simple interface for beinga alerted when a specific flag changes value. */
|
||||
public interface Listener {
|
||||
/** */
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.flags;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.FlagReaderPlugin;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
public class FeatureFlagsTest extends SysuiTestCase {
|
||||
|
||||
@Mock FeatureFlagReader mFeatureFlagReader;
|
||||
|
||||
private FeatureFlags mFeatureFlags;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFeatureFlags = new FeatureFlags(mFeatureFlagReader, getContext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListener() {
|
||||
Flag<?> flag = new BooleanFlag(1);
|
||||
mFeatureFlags.addFlag(flag);
|
||||
|
||||
// Assert and capture that a plugin listener was added.
|
||||
ArgumentCaptor<FlagReaderPlugin.Listener> pluginListenerCaptor =
|
||||
ArgumentCaptor.forClass(FlagReaderPlugin.Listener.class);
|
||||
|
||||
verify(mFeatureFlagReader).addListener(pluginListenerCaptor.capture());
|
||||
FlagReaderPlugin.Listener pluginListener = pluginListenerCaptor.getValue();
|
||||
|
||||
// Signal a change. No listeners, so no real effect.
|
||||
pluginListener.onFlagChanged(flag.getId());
|
||||
|
||||
// Add a listener for the flag
|
||||
final Flag<?>[] changedFlag = {null};
|
||||
FeatureFlags.Listener listener = f -> changedFlag[0] = f;
|
||||
mFeatureFlags.addFlagListener(flag, listener);
|
||||
|
||||
// No changes seen yet.
|
||||
assertThat(changedFlag[0]).isNull();
|
||||
|
||||
// Signal a change.
|
||||
pluginListener.onFlagChanged(flag.getId());
|
||||
|
||||
// Assert that the change was for the correct flag.
|
||||
assertThat(changedFlag[0]).isEqualTo(flag);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListener() {
|
||||
Flag<?> flag = new BooleanFlag(1);
|
||||
mFeatureFlags.addFlag(flag);
|
||||
|
||||
// Assert and capture that a plugin listener was added.
|
||||
ArgumentCaptor<FlagReaderPlugin.Listener> pluginListenerCaptor =
|
||||
ArgumentCaptor.forClass(FlagReaderPlugin.Listener.class);
|
||||
|
||||
verify(mFeatureFlagReader).addListener(pluginListenerCaptor.capture());
|
||||
FlagReaderPlugin.Listener pluginListener = pluginListenerCaptor.getValue();
|
||||
|
||||
// Add a listener for the flag
|
||||
final Flag<?>[] changedFlag = {null};
|
||||
FeatureFlags.Listener listener = f -> changedFlag[0] = f;
|
||||
mFeatureFlags.addFlagListener(flag, listener);
|
||||
|
||||
// Signal a change.
|
||||
pluginListener.onFlagChanged(flag.getId());
|
||||
|
||||
// Assert that the change was for the correct flag.
|
||||
assertThat(changedFlag[0]).isEqualTo(flag);
|
||||
|
||||
changedFlag[0] = null;
|
||||
|
||||
// Now remove the listener.
|
||||
mFeatureFlags.removeFlagListener(flag, listener);
|
||||
// Signal a change.
|
||||
pluginListener.onFlagChanged(flag.getId());
|
||||
// Assert that the change was not triggered
|
||||
assertThat(changedFlag[0]).isNull();
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user