Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea77d35e authored by Diego Vela's avatar Diego Vela Committed by Automerger Merge Worker
Browse files

Merge "Fix emulator not emitting folding feature." into tm-dev am: dbda026b...

Merge "Fix emulator not emitting folding feature." into tm-dev am: dbda026b am: 94d417a6 am: cb6030ab

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



Change-Id: Ia4505506850c369e5c0487ce83182a970e29f4a2
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 05eb71b2 cb6030ab
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -31,11 +31,13 @@ import android.util.Log;
import android.util.SparseIntArray;

import androidx.window.util.BaseDataProducer;
import androidx.window.util.DataProducer;

import com.android.internal.R;

import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 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();
    private static final boolean DEBUG = false;

    private final Context mContext;
    private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();

    private int mCurrentDeviceState = INVALID_DEVICE_STATE;
@@ -57,9 +58,12 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
        mCurrentDeviceState = state;
        notifyDataChanged();
    };
    @NonNull
    private final DataProducer<String> mRawFoldSupplier;

    public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
        mContext = context;
    public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
            @NonNull DataProducer<String> rawFoldSupplier) {
        mRawFoldSupplier = rawFoldSupplier;
        String[] deviceStatePosturePairs = context.getResources()
                .getStringArray(R.array.config_device_state_postures);
        for (String deviceStatePosturePair : deviceStatePosturePairs) {
@@ -97,12 +101,21 @@ public final class DeviceStateManagerFoldingFeatureProducer extends
    @Nullable
    public Optional<List<CommonFoldingFeature>> getData() {
        final int globalHingeState = globalHingeState();
        String displayFeaturesString = mContext.getResources().getString(
                R.string.config_display_features);
        if (TextUtils.isEmpty(displayFeaturesString)) {
        Optional<String> displayFeaturesString = mRawFoldSupplier.getData();
        if (displayFeaturesString.isEmpty() || TextUtils.isEmpty(displayFeaturesString.get())) {
            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() {
+41 −33
Original line number Diff line number Diff line
@@ -16,11 +16,6 @@

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.content.ContentResolver;
import android.content.Context;
@@ -33,75 +28,88 @@ import android.text.TextUtils;

import androidx.window.util.BaseDataProducer;

import java.util.Collections;
import java.util.List;
import com.android.internal.R;

import java.util.Optional;
import java.util.Set;

/**
 * Implementation of {@link androidx.window.util.DataProducer} that produces
 * {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
 * Implementation of {@link androidx.window.util.DataProducer} that produces a
 * {@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
        extends BaseDataProducer<List<CommonFoldingFeature>> {
public final class RawFoldingFeatureProducer extends BaseDataProducer<String> {
    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 =
            Settings.Global.getUriFor(DISPLAY_FEATURES);

    private final ContentResolver mResolver;
    private final ContentObserver mObserver;
    private final String mResourceFeature;
    private boolean mRegisteredObservers;

    public SettingsDisplayFeatureProducer(@NonNull Context context) {
    public RawFoldingFeatureProducer(@NonNull Context context) {
        mResolver = context.getContentResolver();
        mObserver = new SettingsObserver();
    }

    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;
        }
        mResourceFeature = context.getResources().getString(R.string.config_display_features);
    }

    @Override
    @NonNull
    public Optional<List<CommonFoldingFeature>> getData() {
        String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
    public Optional<String> getData() {
        String displayFeaturesString = getFeatureString();
        if (displayFeaturesString == null) {
            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
     * producer callbacks for changes in data will be triggered.
     */
    public void registerObserversIfNeeded() {
    private void registerObserversIfNeeded() {
        if (mRegisteredObservers) {
            return;
        }
        mRegisteredObservers = true;
        mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
                mObserver /* ContentObserver */);
        mResolver.registerContentObserver(mDevicePostureUri, false, mObserver);
    }

    /**
     * Unregisters settings observers, if needed. When settings observers are unregistered for this
     * producer callbacks for changes in data will not be triggered.
     */
    public void unregisterObserversIfNeeded() {
    private void unregisterObserversIfNeeded() {
        if (!mRegisteredObservers) {
            return;
        }
@@ -116,7 +124,7 @@ public final class SettingsDisplayFeatureProducer

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            if (mDisplayFeaturesUri.equals(uri) || mDevicePostureUri.equals(uri)) {
            if (mDisplayFeaturesUri.equals(uri)) {
                notifyDataChanged();
            }
        }
+6 −19
Original line number Diff line number Diff line
@@ -37,9 +37,8 @@ import androidx.annotation.NonNull;
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;

import java.util.ArrayList;
import java.util.List;
@@ -62,17 +61,14 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
            new ArrayMap<>();

    private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;

    public WindowLayoutComponentImpl(Context context) {
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
        mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
        mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
                mSettingsDisplayFeatureProducer,
                new DeviceStateManagerFoldingFeatureProducer(context)
        ));
        RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context);
        mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
                foldingFeatureProducer);
        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
    }

@@ -85,7 +81,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    public void addWindowLayoutInfoListener(@NonNull Activity activity,
            @NonNull Consumer<WindowLayoutInfo> consumer) {
        mWindowLayoutChangeListeners.put(activity, consumer);
        updateRegistrations();
        onDisplayFeaturesChanged();
    }

    /**
@@ -96,7 +92,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    public void removeWindowLayoutInfoListener(
            @NonNull Consumer<WindowLayoutInfo> consumer) {
        mWindowLayoutChangeListeners.values().remove(consumer);
        updateRegistrations();
        onDisplayFeaturesChanged();
    }

    void updateWindowLayout(@NonNull Activity activity,
@@ -210,15 +206,6 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
        return features;
    }

    private void updateRegistrations() {
        if (hasListeners()) {
            mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
        } else {
            mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
        }
        onDisplayFeaturesChanged();
    }

    private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+4 −11
Original line number Diff line number Diff line
@@ -34,9 +34,8 @@ import androidx.annotation.NonNull;
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;

import java.util.ArrayList;
import java.util.Collections;
@@ -52,16 +51,13 @@ class SampleSidecarImpl extends StubSidecar {

    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;

    private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;

    SampleSidecarImpl(Context context) {
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
        mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
        mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
                mSettingsFoldingFeatureProducer,
                new DeviceStateManagerFoldingFeatureProducer(context)
        ));
        DataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
        mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
                settingsFeatureProducer);

        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
    }
@@ -142,10 +138,7 @@ class SampleSidecarImpl extends StubSidecar {
    @Override
    protected void onListenersChanged() {
        if (hasListeners()) {
            mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
            onDisplayFeaturesChanged();
        } else {
            mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
        }
    }

+4 −0
Original line number Diff line number Diff line
@@ -33,13 +33,17 @@ public abstract class BaseDataProducer<T> implements DataProducer<T> {
    @Override
    public final void addDataChangedCallback(@NonNull Runnable callback) {
        mCallbacks.add(callback);
        onListenersChanged(mCallbacks);
    }

    @Override
    public final void removeDataChangedCallback(@NonNull Runnable 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
     * changed.
Loading