Merge "Fix emulator not emitting folding feature." into tm-dev am: dbda026b6f am: 94d417a62c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17511593 Change-Id: Ibc0abfac92e08f547c7ff1418de0bb4771c6a48a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -31,11 +31,13 @@ import android.util.Log;
|
|||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
import androidx.window.util.BaseDataProducer;
|
import androidx.window.util.BaseDataProducer;
|
||||||
|
import androidx.window.util.DataProducer;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link androidx.window.util.DataProducer} that returns the device's posture
|
* An implementation of {@link androidx.window.util.DataProducer} that returns the device's posture
|
||||||
@@ -48,7 +50,6 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
|
|||||||
DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
|
DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
|
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
|
||||||
|
|
||||||
private int mCurrentDeviceState = INVALID_DEVICE_STATE;
|
private int mCurrentDeviceState = INVALID_DEVICE_STATE;
|
||||||
@@ -57,9 +58,12 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
|
|||||||
mCurrentDeviceState = state;
|
mCurrentDeviceState = state;
|
||||||
notifyDataChanged();
|
notifyDataChanged();
|
||||||
};
|
};
|
||||||
|
@NonNull
|
||||||
|
private final DataProducer<String> mRawFoldSupplier;
|
||||||
|
|
||||||
public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
|
public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
|
||||||
mContext = context;
|
@NonNull DataProducer<String> rawFoldSupplier) {
|
||||||
|
mRawFoldSupplier = rawFoldSupplier;
|
||||||
String[] deviceStatePosturePairs = context.getResources()
|
String[] deviceStatePosturePairs = context.getResources()
|
||||||
.getStringArray(R.array.config_device_state_postures);
|
.getStringArray(R.array.config_device_state_postures);
|
||||||
for (String deviceStatePosturePair : deviceStatePosturePairs) {
|
for (String deviceStatePosturePair : deviceStatePosturePairs) {
|
||||||
@@ -97,12 +101,21 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
|
|||||||
@Nullable
|
@Nullable
|
||||||
public Optional<List<CommonFoldingFeature>> getData() {
|
public Optional<List<CommonFoldingFeature>> getData() {
|
||||||
final int globalHingeState = globalHingeState();
|
final int globalHingeState = globalHingeState();
|
||||||
String displayFeaturesString = mContext.getResources().getString(
|
Optional<String> displayFeaturesString = mRawFoldSupplier.getData();
|
||||||
R.string.config_display_features);
|
if (displayFeaturesString.isEmpty() || TextUtils.isEmpty(displayFeaturesString.get())) {
|
||||||
if (TextUtils.isEmpty(displayFeaturesString)) {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Optional.of(parseListFromString(displayFeaturesString, globalHingeState));
|
return Optional.of(parseListFromString(displayFeaturesString.get(), globalHingeState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListenersChanged(Set<Runnable> callbacks) {
|
||||||
|
super.onListenersChanged(callbacks);
|
||||||
|
if (callbacks.isEmpty()) {
|
||||||
|
mRawFoldSupplier.removeDataChangedCallback(this::notifyDataChanged);
|
||||||
|
} else {
|
||||||
|
mRawFoldSupplier.addDataChangedCallback(this::notifyDataChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int globalHingeState() {
|
private int globalHingeState() {
|
||||||
|
|||||||
@@ -16,11 +16,6 @@
|
|||||||
|
|
||||||
package androidx.window.common;
|
package androidx.window.common;
|
||||||
|
|
||||||
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
|
|
||||||
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
|
|
||||||
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
|
|
||||||
import static androidx.window.common.CommonFoldingFeature.parseListFromString;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -33,75 +28,88 @@ import android.text.TextUtils;
|
|||||||
|
|
||||||
import androidx.window.util.BaseDataProducer;
|
import androidx.window.util.BaseDataProducer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import com.android.internal.R;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link androidx.window.util.DataProducer} that produces
|
* Implementation of {@link androidx.window.util.DataProducer} that produces a
|
||||||
* {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
|
* {@link String} that can be parsed to a {@link CommonFoldingFeature}.
|
||||||
|
* {@link RawFoldingFeatureProducer} searches for the value in two places. The first check is in
|
||||||
|
* settings where the {@link String} property is saved with the key
|
||||||
|
* {@link RawFoldingFeatureProducer#DISPLAY_FEATURES}. If this value is null or empty then the
|
||||||
|
* value in {@link android.content.res.Resources} is used. If both are empty then
|
||||||
|
* {@link RawFoldingFeatureProducer#getData()} returns an empty object.
|
||||||
|
* {@link RawFoldingFeatureProducer} listens to changes in the setting so that it can override
|
||||||
|
* the system {@link CommonFoldingFeature} data.
|
||||||
*/
|
*/
|
||||||
public final class SettingsDisplayFeatureProducer
|
public final class RawFoldingFeatureProducer extends BaseDataProducer<String> {
|
||||||
extends BaseDataProducer<List<CommonFoldingFeature>> {
|
|
||||||
private static final String DISPLAY_FEATURES = "display_features";
|
private static final String DISPLAY_FEATURES = "display_features";
|
||||||
private static final String DEVICE_POSTURE = "device_posture";
|
|
||||||
|
|
||||||
private final Uri mDevicePostureUri =
|
|
||||||
Settings.Global.getUriFor(DEVICE_POSTURE);
|
|
||||||
private final Uri mDisplayFeaturesUri =
|
private final Uri mDisplayFeaturesUri =
|
||||||
Settings.Global.getUriFor(DISPLAY_FEATURES);
|
Settings.Global.getUriFor(DISPLAY_FEATURES);
|
||||||
|
|
||||||
private final ContentResolver mResolver;
|
private final ContentResolver mResolver;
|
||||||
private final ContentObserver mObserver;
|
private final ContentObserver mObserver;
|
||||||
|
private final String mResourceFeature;
|
||||||
private boolean mRegisteredObservers;
|
private boolean mRegisteredObservers;
|
||||||
|
|
||||||
public SettingsDisplayFeatureProducer(@NonNull Context context) {
|
public RawFoldingFeatureProducer(@NonNull Context context) {
|
||||||
mResolver = context.getContentResolver();
|
mResolver = context.getContentResolver();
|
||||||
mObserver = new SettingsObserver();
|
mObserver = new SettingsObserver();
|
||||||
}
|
mResourceFeature = context.getResources().getString(R.string.config_display_features);
|
||||||
|
|
||||||
private int getPosture() {
|
|
||||||
int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, COMMON_STATE_UNKNOWN);
|
|
||||||
if (posture == COMMON_STATE_HALF_OPENED || posture == COMMON_STATE_FLAT) {
|
|
||||||
return posture;
|
|
||||||
} else {
|
|
||||||
return COMMON_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public Optional<List<CommonFoldingFeature>> getData() {
|
public Optional<String> getData() {
|
||||||
String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
|
String displayFeaturesString = getFeatureString();
|
||||||
if (displayFeaturesString == null) {
|
if (displayFeaturesString == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
return Optional.of(displayFeaturesString);
|
||||||
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(displayFeaturesString)) {
|
/**
|
||||||
return Optional.of(Collections.emptyList());
|
* Returns the {@link String} representation for a {@link CommonFoldingFeature} from settings if
|
||||||
|
* present and falls back to the resource value if empty or {@code null}.
|
||||||
|
*/
|
||||||
|
private String getFeatureString() {
|
||||||
|
String settingsFeature = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
|
||||||
|
if (TextUtils.isEmpty(settingsFeature)) {
|
||||||
|
return mResourceFeature;
|
||||||
|
}
|
||||||
|
return settingsFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListenersChanged(Set<Runnable> callbacks) {
|
||||||
|
if (callbacks.isEmpty()) {
|
||||||
|
unregisterObserversIfNeeded();
|
||||||
|
} else {
|
||||||
|
registerObserversIfNeeded();
|
||||||
}
|
}
|
||||||
return Optional.of(parseListFromString(displayFeaturesString, getPosture()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers settings observers, if needed. When settings observers are registered for this
|
* Registers settings observers, if needed. When settings observers are registered for this
|
||||||
* producer callbacks for changes in data will be triggered.
|
* producer callbacks for changes in data will be triggered.
|
||||||
*/
|
*/
|
||||||
public void registerObserversIfNeeded() {
|
private void registerObserversIfNeeded() {
|
||||||
if (mRegisteredObservers) {
|
if (mRegisteredObservers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRegisteredObservers = true;
|
mRegisteredObservers = true;
|
||||||
mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
|
mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
|
||||||
mObserver /* ContentObserver */);
|
mObserver /* ContentObserver */);
|
||||||
mResolver.registerContentObserver(mDevicePostureUri, false, mObserver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters settings observers, if needed. When settings observers are unregistered for this
|
* Unregisters settings observers, if needed. When settings observers are unregistered for this
|
||||||
* producer callbacks for changes in data will not be triggered.
|
* producer callbacks for changes in data will not be triggered.
|
||||||
*/
|
*/
|
||||||
public void unregisterObserversIfNeeded() {
|
private void unregisterObserversIfNeeded() {
|
||||||
if (!mRegisteredObservers) {
|
if (!mRegisteredObservers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -116,7 +124,7 @@ public final class SettingsDisplayFeatureProducer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange, Uri uri) {
|
public void onChange(boolean selfChange, Uri uri) {
|
||||||
if (mDisplayFeaturesUri.equals(uri) || mDevicePostureUri.equals(uri)) {
|
if (mDisplayFeaturesUri.equals(uri)) {
|
||||||
notifyDataChanged();
|
notifyDataChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,9 +37,8 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.window.common.CommonFoldingFeature;
|
import androidx.window.common.CommonFoldingFeature;
|
||||||
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
|
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
|
||||||
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
|
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
|
||||||
import androidx.window.common.SettingsDisplayFeatureProducer;
|
import androidx.window.common.RawFoldingFeatureProducer;
|
||||||
import androidx.window.util.DataProducer;
|
import androidx.window.util.DataProducer;
|
||||||
import androidx.window.util.PriorityDataProducer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,17 +61,14 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
|
private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
|
||||||
new ArrayMap<>();
|
new ArrayMap<>();
|
||||||
|
|
||||||
private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
|
|
||||||
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
|
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
|
||||||
|
|
||||||
public WindowLayoutComponentImpl(Context context) {
|
public WindowLayoutComponentImpl(Context context) {
|
||||||
((Application) context.getApplicationContext())
|
((Application) context.getApplicationContext())
|
||||||
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
|
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
|
||||||
mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
|
RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context);
|
||||||
mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
|
mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
|
||||||
mSettingsDisplayFeatureProducer,
|
foldingFeatureProducer);
|
||||||
new DeviceStateManagerFoldingFeatureProducer(context)
|
|
||||||
));
|
|
||||||
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
|
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +81,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
public void addWindowLayoutInfoListener(@NonNull Activity activity,
|
public void addWindowLayoutInfoListener(@NonNull Activity activity,
|
||||||
@NonNull Consumer<WindowLayoutInfo> consumer) {
|
@NonNull Consumer<WindowLayoutInfo> consumer) {
|
||||||
mWindowLayoutChangeListeners.put(activity, consumer);
|
mWindowLayoutChangeListeners.put(activity, consumer);
|
||||||
updateRegistrations();
|
onDisplayFeaturesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +92,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
public void removeWindowLayoutInfoListener(
|
public void removeWindowLayoutInfoListener(
|
||||||
@NonNull Consumer<WindowLayoutInfo> consumer) {
|
@NonNull Consumer<WindowLayoutInfo> consumer) {
|
||||||
mWindowLayoutChangeListeners.values().remove(consumer);
|
mWindowLayoutChangeListeners.values().remove(consumer);
|
||||||
updateRegistrations();
|
onDisplayFeaturesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateWindowLayout(@NonNull Activity activity,
|
void updateWindowLayout(@NonNull Activity activity,
|
||||||
@@ -210,15 +206,6 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRegistrations() {
|
|
||||||
if (hasListeners()) {
|
|
||||||
mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
|
|
||||||
} else {
|
|
||||||
mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
|
|
||||||
}
|
|
||||||
onDisplayFeaturesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
|
private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.window.common.CommonFoldingFeature;
|
import androidx.window.common.CommonFoldingFeature;
|
||||||
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
|
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
|
||||||
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
|
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
|
||||||
import androidx.window.common.SettingsDisplayFeatureProducer;
|
import androidx.window.common.RawFoldingFeatureProducer;
|
||||||
import androidx.window.util.DataProducer;
|
import androidx.window.util.DataProducer;
|
||||||
import androidx.window.util.PriorityDataProducer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -52,16 +51,13 @@ class SampleSidecarImpl extends StubSidecar {
|
|||||||
|
|
||||||
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
|
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
|
||||||
|
|
||||||
private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
|
|
||||||
|
|
||||||
SampleSidecarImpl(Context context) {
|
SampleSidecarImpl(Context context) {
|
||||||
((Application) context.getApplicationContext())
|
((Application) context.getApplicationContext())
|
||||||
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
|
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
|
||||||
mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
|
DataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
|
||||||
mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
|
mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
|
||||||
mSettingsFoldingFeatureProducer,
|
settingsFeatureProducer);
|
||||||
new DeviceStateManagerFoldingFeatureProducer(context)
|
|
||||||
));
|
|
||||||
|
|
||||||
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
|
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
|
||||||
}
|
}
|
||||||
@@ -142,10 +138,7 @@ class SampleSidecarImpl extends StubSidecar {
|
|||||||
@Override
|
@Override
|
||||||
protected void onListenersChanged() {
|
protected void onListenersChanged() {
|
||||||
if (hasListeners()) {
|
if (hasListeners()) {
|
||||||
mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
|
|
||||||
onDisplayFeaturesChanged();
|
onDisplayFeaturesChanged();
|
||||||
} else {
|
|
||||||
mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,17 @@ public abstract class BaseDataProducer<T> implements DataProducer<T> {
|
|||||||
@Override
|
@Override
|
||||||
public final void addDataChangedCallback(@NonNull Runnable callback) {
|
public final void addDataChangedCallback(@NonNull Runnable callback) {
|
||||||
mCallbacks.add(callback);
|
mCallbacks.add(callback);
|
||||||
|
onListenersChanged(mCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void removeDataChangedCallback(@NonNull Runnable callback) {
|
public final void removeDataChangedCallback(@NonNull Runnable callback) {
|
||||||
mCallbacks.remove(callback);
|
mCallbacks.remove(callback);
|
||||||
|
onListenersChanged(mCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onListenersChanged(Set<Runnable> callbacks) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to notify all registered callbacks that the data provided by {@link #getData()} has
|
* Called to notify all registered callbacks that the data provided by {@link #getData()} has
|
||||||
* changed.
|
* changed.
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 androidx.window.util;
|
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link DataProducer} that delegates calls to {@link #getData()} to the list of
|
|
||||||
* provided child producers.
|
|
||||||
* <p>
|
|
||||||
* The value returned is based on the precedence of the supplied children where the producer with
|
|
||||||
* index 0 has a higher precedence than producers that come later in the list. When a producer with
|
|
||||||
* a higher precedence has a non-empty value returned from {@link #getData()}, its value will be
|
|
||||||
* returned from an instance of this class, ignoring all other producers with lower precedence.
|
|
||||||
*
|
|
||||||
* @param <T> The type of data this producer returns through {@link #getData()}.
|
|
||||||
*/
|
|
||||||
public final class PriorityDataProducer<T> extends BaseDataProducer<T> {
|
|
||||||
private final List<DataProducer<T>> mChildProducers;
|
|
||||||
|
|
||||||
public PriorityDataProducer(List<DataProducer<T>> childProducers) {
|
|
||||||
mChildProducers = childProducers;
|
|
||||||
for (DataProducer<T> childProducer : mChildProducers) {
|
|
||||||
childProducer.addDataChangedCallback(this::notifyDataChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Optional<T> getData() {
|
|
||||||
for (DataProducer<T> childProducer : mChildProducers) {
|
|
||||||
final Optional<T> data = childProducer.getData();
|
|
||||||
if (data.isPresent()) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user