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

Commit fbca6e54 authored by Diego Vela's avatar Diego Vela Committed by Android (Google) Code Review
Browse files

Merge "Report folds in SupportedWindowFeatures." into main

parents 2b9ce83b 4bc4a9cd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ public final class CommonFoldingFeature {
     * @see #FEATURE_PATTERN
     * @return {@link List} of {@link CommonFoldingFeature}.
     */
    static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
    public static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
            @State int hingeState) {
        List<CommonFoldingFeature> features = new ArrayList<>();
        String[] featureStrings =  value.split(";");
+36 −5
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import androidx.window.util.BaseDataProducer;
import com.android.internal.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -78,7 +79,9 @@ public final class DeviceStateManagerFoldingFeatureProducer
    private int mCurrentBaseDeviceState = INVALID_DEVICE_STATE;

    @NonNull
    private final BaseDataProducer<String> mRawFoldSupplier;
    private final RawFoldingFeatureProducer mRawFoldSupplier;

    private final boolean mIsHalfOpenedSupported;

    private final DeviceStateCallback mDeviceStateCallback = new DeviceStateCallback() {
        @Override
@@ -101,10 +104,12 @@ public final class DeviceStateManagerFoldingFeatureProducer
    };

    public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
            @NonNull BaseDataProducer<String> rawFoldSupplier) {
            @NonNull RawFoldingFeatureProducer rawFoldSupplier,
            @NonNull DeviceStateManager deviceStateManager) {
        mRawFoldSupplier = rawFoldSupplier;
        String[] deviceStatePosturePairs = context.getResources()
                .getStringArray(R.array.config_device_state_postures);
        boolean isHalfOpenedSupported = false;
        for (String deviceStatePosturePair : deviceStatePosturePairs) {
            String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
            if (deviceStatePostureMapping.length != 2) {
@@ -128,12 +133,13 @@ public final class DeviceStateManagerFoldingFeatureProducer
                }
                continue;
            }

            isHalfOpenedSupported = isHalfOpenedSupported
                    || posture == CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
            mDeviceStateToPostureMap.put(deviceState, posture);
        }

        mIsHalfOpenedSupported = isHalfOpenedSupported;
        if (mDeviceStateToPostureMap.size() > 0) {
            Objects.requireNonNull(context.getSystemService(DeviceStateManager.class))
            Objects.requireNonNull(deviceStateManager)
                    .registerCallback(context.getMainExecutor(), mDeviceStateCallback);
        }
    }
@@ -187,6 +193,31 @@ public final class DeviceStateManagerFoldingFeatureProducer
        }
    }

    /**
     * Returns a {@link List} of all the {@link CommonFoldingFeature} with the state set to
     * {@link CommonFoldingFeature#COMMON_STATE_UNKNOWN}. This method parses a {@link String} so a
     * caller should consider caching the value or the derived value.
     */
    @NonNull
    public List<CommonFoldingFeature> getFoldsWithUnknownState() {
        Optional<String> optionalFoldingFeatureString = mRawFoldSupplier.getCurrentData();

        if (optionalFoldingFeatureString.isPresent()) {
            return CommonFoldingFeature.parseListFromString(
                    optionalFoldingFeatureString.get(), CommonFoldingFeature.COMMON_STATE_UNKNOWN
            );
        }
        return Collections.emptyList();
    }


    /**
     * Returns {@code true} if the device supports half-opened mode, {@code false} otherwise.
     */
    public boolean isHalfOpenedSupported() {
        return mIsHalfOpenedSupported;
    }

    /**
     * Adds the data to the storeFeaturesConsumer when the data is ready.
     * @param storeFeaturesConsumer a consumer to collect the data when it is first available.
+7 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.util.Log;

import androidx.annotation.NonNull;
@@ -63,6 +64,11 @@ public class WindowExtensionsImpl implements WindowExtensions {
        return Objects.requireNonNull(ActivityThread.currentApplication());
    }

    @NonNull
    private DeviceStateManager getDeviceStateManager() {
        return Objects.requireNonNull(getApplication().getSystemService(DeviceStateManager.class));
    }

    @NonNull
    private DeviceStateManagerFoldingFeatureProducer getFoldingFeatureProducer() {
        if (mFoldingFeatureProducer == null) {
@@ -73,7 +79,7 @@ public class WindowExtensionsImpl implements WindowExtensions {
                            new RawFoldingFeatureProducer(context);
                    mFoldingFeatureProducer =
                            new DeviceStateManagerFoldingFeatureProducer(context,
                                    foldingFeatureProducer);
                                    foldingFeatureProducer, getDeviceStateManager());
                }
            }
        }
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.extensions.layout;

import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;

import java.util.ArrayList;
import java.util.List;

/**
 * Util functions for working with {@link androidx.window.extensions.layout.DisplayFoldFeature}.
 */
public class DisplayFoldFeatureUtil {

    private DisplayFoldFeatureUtil() {}

    private static DisplayFoldFeature create(CommonFoldingFeature foldingFeature,
            boolean isHalfOpenedSupported) {
        final int foldType;
        if (foldingFeature.getType() == CommonFoldingFeature.COMMON_TYPE_HINGE) {
            foldType = DisplayFoldFeature.TYPE_HINGE;
        } else {
            foldType = DisplayFoldFeature.TYPE_SCREEN_FOLD_IN;
        }
        DisplayFoldFeature.Builder featureBuilder = new DisplayFoldFeature.Builder(foldType);

        if (isHalfOpenedSupported) {
            featureBuilder.addProperty(DisplayFoldFeature.FOLD_PROPERTY_SUPPORTS_HALF_OPENED);
        }
        return featureBuilder.build();
    }

    /**
     * Returns the list of supported {@link DisplayFeature} calculated from the
     * {@link DeviceStateManagerFoldingFeatureProducer}.
     */
    public static List<DisplayFoldFeature> extractDisplayFoldFeatures(
            DeviceStateManagerFoldingFeatureProducer producer) {
        List<DisplayFoldFeature> foldFeatures = new ArrayList<>();
        List<CommonFoldingFeature> folds = producer.getFoldsWithUnknownState();

        final boolean isHalfOpenedSupported = producer.isHalfOpenedSupported();
        for (CommonFoldingFeature fold : folds) {
            foldFeatures.add(DisplayFoldFeatureUtil.create(fold, isHalfOpenedSupported));
        }
        return foldFeatures;
    }
}
+15 −6
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.util.DataProducer;

import java.util.ArrayList;
import java.util.Collections;
@@ -56,10 +55,6 @@ import java.util.Set;
/**
 * Reference implementation of androidx.window.extensions.layout OEM interface for use with
 * WindowManager Jetpack.
 *
 * NOTE: This version is a work in progress and under active development. It MUST NOT be used in
 * production builds since the interface can still change before reaching stable version.
 * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead.
 */
public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    private static final String TAG = WindowLayoutComponentImpl.class.getSimpleName();
@@ -71,7 +66,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
            new ArrayMap<>();

    @GuardedBy("mLock")
    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
    private final DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer;

    @GuardedBy("mLock")
    private final List<CommonFoldingFeature> mLastReportedFoldingFeatures = new ArrayList<>();
@@ -87,12 +82,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    private final RawConfigurationChangedListener mRawConfigurationChangedListener =
            new RawConfigurationChangedListener();

    private final SupportedWindowFeatures mSupportedWindowFeatures;

    public WindowLayoutComponentImpl(@NonNull Context context,
            @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
        mFoldingFeatureProducer = foldingFeatureProducer;
        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
        final List<DisplayFoldFeature> displayFoldFeatures =
                DisplayFoldFeatureUtil.extractDisplayFoldFeatures(mFoldingFeatureProducer);
        mSupportedWindowFeatures = new SupportedWindowFeatures.Builder(displayFoldFeatures).build();
    }

    /**
@@ -283,6 +283,15 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
        }
    }

    /**
     * Returns the {@link SupportedWindowFeatures} for the device. This list does not change over
     * time.
     */
    @NonNull
    public SupportedWindowFeatures getSupportedWindowFeatures() {
        return mSupportedWindowFeatures;
    }

    /** @see #getWindowLayoutInfo(Context, List) */
    private WindowLayoutInfo getWindowLayoutInfo(int displayId,
            @NonNull WindowConfiguration windowConfiguration,
Loading