summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java26
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java41
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java)2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java171
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java42
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java11
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java51
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java135
12 files changed, 442 insertions, 45 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index b2bc3de1e7f5..37f0067de453 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -18,8 +18,8 @@ package androidx.window.common;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
-import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.layout.CommonFoldingFeature.parseListFromString;
import android.annotation.NonNull;
import android.content.Context;
@@ -31,6 +31,9 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
+import androidx.window.common.layout.CommonFoldingFeature;
+import androidx.window.common.layout.DisplayFoldFeatureCommon;
+
import com.android.internal.R;
import java.util.ArrayList;
@@ -200,6 +203,23 @@ public final class DeviceStateManagerFoldingFeatureProducer
/**
+ * Returns the list of supported {@link DisplayFoldFeatureCommon} calculated from the
+ * {@link DeviceStateManagerFoldingFeatureProducer}.
+ */
+ @NonNull
+ public List<DisplayFoldFeatureCommon> getDisplayFeatures() {
+ final List<DisplayFoldFeatureCommon> foldFeatures = new ArrayList<>();
+ final List<CommonFoldingFeature> folds = getFoldsWithUnknownState();
+
+ final boolean isHalfOpenedSupported = isHalfOpenedSupported();
+ for (CommonFoldingFeature fold : folds) {
+ foldFeatures.add(DisplayFoldFeatureCommon.create(fold, isHalfOpenedSupported));
+ }
+ return foldFeatures;
+ }
+
+
+ /**
* Returns {@code true} if the device supports half-opened mode, {@code false} otherwise.
*/
public boolean isHalfOpenedSupported() {
@@ -211,7 +231,7 @@ public final class DeviceStateManagerFoldingFeatureProducer
* @param storeFeaturesConsumer a consumer to collect the data when it is first available.
*/
@Override
- public void getData(Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
+ public void getData(@NonNull Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
mRawFoldSupplier.getData((String displayFeaturesString) -> {
if (TextUtils.isEmpty(displayFeaturesString)) {
storeFeaturesConsumer.accept(new ArrayList<>());
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
index 6d758f1fb3c1..9651918ef5ca 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
@@ -26,6 +26,8 @@ import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
+import androidx.window.common.layout.CommonFoldingFeature;
+
import com.android.internal.R;
import java.util.Optional;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java b/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java
new file mode 100644
index 000000000000..e72459fe61bf
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java
@@ -0,0 +1,41 @@
+/*
+ * 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.common.collections;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * A class to contain utility methods for {@link List}.
+ */
+public final class ListUtil {
+
+ private ListUtil() {}
+
+ /**
+ * Returns a new {@link List} that is created by applying the {@code transformer} to the
+ * {@code source} list.
+ */
+ public static <T, U> List<U> map(List<T> source, Function<T, U> transformer) {
+ final List<U> target = new ArrayList<>();
+ for (int i = 0; i < source.size(); i++) {
+ target.add(transformer.apply(source.get(i)));
+ }
+ return target;
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java
index b95bca16ef5b..85c4fe1193ee 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.common;
+package androidx.window.common.layout;
import static androidx.window.common.ExtensionHelper.isZero;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java
new file mode 100644
index 000000000000..594bd9cc3bc6
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java
@@ -0,0 +1,171 @@
+/*
+ * 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.common.layout;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.util.ArraySet;
+
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A class that represents if a fold is part of the device.
+ */
+public final class DisplayFoldFeatureCommon {
+
+ /**
+ * Returns a new instance of {@link DisplayFoldFeatureCommon} based off of
+ * {@link CommonFoldingFeature} and whether or not half opened is supported.
+ */
+ public static DisplayFoldFeatureCommon create(CommonFoldingFeature foldingFeature,
+ boolean isHalfOpenedSupported) {
+ @FoldType
+ final int foldType;
+ if (foldingFeature.getType() == CommonFoldingFeature.COMMON_TYPE_HINGE) {
+ foldType = DISPLAY_FOLD_FEATURE_TYPE_HINGE;
+ } else {
+ foldType = DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN;
+ }
+
+ final Set<Integer> properties = new ArraySet<>();
+
+ if (isHalfOpenedSupported) {
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ }
+ return new DisplayFoldFeatureCommon(foldType, properties);
+ }
+
+ /**
+ * The type of fold is unknown. This is here for compatibility reasons if a new type is added,
+ * and cannot be reported to an incompatible application.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_UNKNOWN = 0;
+
+ /**
+ * The type of fold is a physical hinge separating two display panels.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_HINGE = 1;
+
+ /**
+ * The type of fold is a screen that folds from 0-180.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN = 2;
+
+ /**
+ * @hide
+ */
+ @IntDef(value = {DISPLAY_FOLD_FEATURE_TYPE_UNKNOWN, DISPLAY_FOLD_FEATURE_TYPE_HINGE,
+ DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN})
+ public @interface FoldType {
+ }
+
+ /**
+ * The fold supports the half opened state.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED = 1;
+
+ @IntDef(value = {DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED})
+ public @interface FoldProperty {
+ }
+
+ @FoldType
+ private final int mType;
+
+ private final Set<Integer> mProperties;
+
+ /**
+ * Creates an instance of [FoldDisplayFeature].
+ *
+ * @param type the type of fold, either [FoldDisplayFeature.TYPE_HINGE] or
+ * [FoldDisplayFeature.TYPE_FOLDABLE_SCREEN]
+ * @hide
+ */
+ public DisplayFoldFeatureCommon(@FoldType int type, @NonNull Set<Integer> properties) {
+ mType = type;
+ mProperties = new ArraySet<>();
+ assertPropertiesAreValid(properties);
+ mProperties.addAll(properties);
+ }
+
+ /**
+ * Returns the type of fold that is either a hinge or a fold.
+ */
+ @FoldType
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns {@code true} if the fold has the given property, {@code false} otherwise.
+ */
+ public boolean hasProperty(@FoldProperty int property) {
+ return mProperties.contains(property);
+ }
+ /**
+ * Returns {@code true} if the fold has all the given properties, {@code false} otherwise.
+ */
+ public boolean hasProperties(@NonNull @FoldProperty int... properties) {
+ for (int i = 0; i < properties.length; i++) {
+ if (!mProperties.contains(properties[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a copy of the set of properties.
+ * @hide
+ */
+ public Set<Integer> getProperties() {
+ return new ArraySet<>(mProperties);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DisplayFoldFeatureCommon that = (DisplayFoldFeatureCommon) o;
+ return mType == that.mType && Objects.equals(mProperties, that.mProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mProperties);
+ }
+
+ @Override
+ public String toString() {
+ return "DisplayFoldFeatureCommon{mType=" + mType + ", mProperties=" + mProperties + '}';
+ }
+
+ private static void assertPropertiesAreValid(@NonNull Set<Integer> properties) {
+ for (int property : properties) {
+ if (!isProperty(property)) {
+ throw new IllegalArgumentException("Property is not a valid type: " + property);
+ }
+ }
+ }
+
+ private static boolean isProperty(int property) {
+ if (property == DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index e5551765af05..7be14724643c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -89,9 +89,9 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+import androidx.window.common.layout.CommonFoldingFeature;
import androidx.window.extensions.WindowExtensions;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.extensions.core.util.function.Function;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
index a0f481a911ad..870c92e6fdac 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
@@ -16,48 +16,24 @@
package androidx.window.extensions.layout;
-import androidx.window.common.CommonFoldingFeature;
-import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
-
-import java.util.ArrayList;
-import java.util.List;
+import androidx.window.common.layout.DisplayFoldFeatureCommon;
/**
* Util functions for working with {@link androidx.window.extensions.layout.DisplayFoldFeature}.
*/
-public class DisplayFoldFeatureUtil {
+public final 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}.
+ * Returns a {@link DisplayFoldFeature} that matches the given {@link DisplayFoldFeatureCommon}.
*/
- 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));
+ public static DisplayFoldFeature translate(DisplayFoldFeatureCommon foldFeatureCommon) {
+ final DisplayFoldFeature.Builder builder =
+ new DisplayFoldFeature.Builder(foldFeatureCommon.getType());
+ for (int property: foldFeatureCommon.getProperties()) {
+ builder.addProperty(property);
}
- return foldFeatures;
+ return builder.build();
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index a3ef68a15196..f1ea19a60f97 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -19,11 +19,11 @@ package androidx.window.extensions.layout;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import static androidx.window.common.ExtensionHelper.isZero;
import static androidx.window.common.ExtensionHelper.rotateRectToDisplayRotation;
import static androidx.window.common.ExtensionHelper.transformToWindowSpaceRect;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import android.app.Activity;
import android.app.ActivityThread;
@@ -45,9 +45,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiContext;
import androidx.annotation.VisibleForTesting;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+import androidx.window.common.collections.ListUtil;
+import androidx.window.common.layout.CommonFoldingFeature;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.extensions.util.DeduplicateConsumer;
@@ -95,8 +96,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
mFoldingFeatureProducer = foldingFeatureProducer;
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- final List<DisplayFoldFeature> displayFoldFeatures =
- DisplayFoldFeatureUtil.extractDisplayFoldFeatures(mFoldingFeatureProducer);
+ final List<DisplayFoldFeature> displayFoldFeatures = ListUtil.map(
+ mFoldingFeatureProducer.getDisplayFeatures(), DisplayFoldFeatureUtil::translate);
mSupportedWindowFeatures = new SupportedWindowFeatures.Builder(displayFoldFeatures).build();
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index b63fd0802e5f..60bc7bedf2ed 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -26,10 +26,10 @@ import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.window.common.BaseDataProducer;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.RawFoldingFeatureProducer;
+import androidx.window.common.layout.CommonFoldingFeature;
import java.util.ArrayList;
import java.util.List;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
index 4fd03e4bdc0b..6e0e7115cfb1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
@@ -26,7 +26,7 @@ import android.app.ActivityThread;
import android.graphics.Rect;
import android.os.IBinder;
-import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.layout.CommonFoldingFeature;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java
new file mode 100644
index 000000000000..a077bdfef194
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.common.collections;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test class for {@link ListUtil}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:ListUtil
+ */
+public class ListUtilTest {
+
+ @Test
+ public void test_map_empty_returns_empty() {
+ final List<String> emptyList = new ArrayList<>();
+ final List<Integer> result = ListUtil.map(emptyList, String::length);
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ public void test_map_maintains_order() {
+ final List<String> source = new ArrayList<>();
+ source.add("a");
+ source.add("aa");
+
+ final List<Integer> result = ListUtil.map(source, String::length);
+
+ assertThat(result).containsExactly(1, 2).inOrder();
+ }
+}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java
new file mode 100644
index 000000000000..6c178511388b
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.common.layout;
+
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_TYPE_FOLD;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_TYPE_HINGE;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_HINGE;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Rect;
+import android.util.ArraySet;
+
+import org.junit.Test;
+
+import java.util.Set;
+
+/**
+ * Test class for {@link DisplayFoldFeatureCommon}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:DisplayFoldFeatureCommonTest
+ */
+public class DisplayFoldFeatureCommonTest {
+
+ @Test
+ public void test_different_type_not_equals() {
+ final Set<Integer> properties = new ArraySet<>();
+ final DisplayFoldFeatureCommon first =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+ final DisplayFoldFeatureCommon second =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN, properties);
+
+ assertThat(first).isEqualTo(second);
+ }
+
+ @Test
+ public void test_different_property_set_not_equals() {
+ final Set<Integer> firstProperties = new ArraySet<>();
+ final Set<Integer> secondProperties = new ArraySet<>();
+ secondProperties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon first =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, firstProperties);
+ final DisplayFoldFeatureCommon second =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, secondProperties);
+
+ assertThat(first).isNotEqualTo(second);
+ }
+
+ @Test
+ public void test_check_single_property_exists() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_check_multiple_properties_exists() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.hasProperties(
+ DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_properties_matches_getter() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.getProperties()).isEqualTo(properties);
+ }
+
+ @Test
+ public void test_type_matches_getter() {
+ final Set<Integer> properties = new ArraySet<>();
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_HINGE);
+ }
+
+ @Test
+ public void test_create_half_opened_feature() {
+ final CommonFoldingFeature foldingFeature =
+ new CommonFoldingFeature(COMMON_TYPE_HINGE, COMMON_STATE_UNKNOWN, new Rect());
+ final DisplayFoldFeatureCommon foldFeatureCommon = DisplayFoldFeatureCommon.create(
+ foldingFeature, true);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_HINGE);
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_create_fold_feature_no_half_opened() {
+ final CommonFoldingFeature foldingFeature =
+ new CommonFoldingFeature(COMMON_TYPE_FOLD, COMMON_STATE_UNKNOWN, new Rect());
+ final DisplayFoldFeatureCommon foldFeatureCommon = DisplayFoldFeatureCommon.create(
+ foldingFeature, true);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN);
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+}