summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Diego Vela <diegovela@google.com> 2022-03-14 17:52:20 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-03-14 17:52:20 +0000
commita4b205e2a5912f96e1eb4dba905f28c9e5d5744e (patch)
tree7415be6ceb8c32cfe851b621dcb5f33429558b27
parent037cc9fb09def89bf23b2f8bc89d7b9974f782b8 (diff)
parent6c39d4fb3c851b024498c271d5660ac773d4f2fc (diff)
Merge changes from topic "wm-config-change-fix" into sc-v2-dev
* changes: DO NOT MERGE Listen for config changes when updating features. DO NOT MERGE Add LifecycleCallback adapter. DO NOT MERGE Merge state producer and feature producer. DO NOT MERGE Remove DisplayFeature from common package.
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java)119
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java)30
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java60
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java55
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java74
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java96
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java36
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java33
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java146
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java98
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java2
11 files changed, 321 insertions, 428 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index eb9429747b66..624d130e8698 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -18,17 +18,73 @@ package androidx.window.common;
import static androidx.window.util.ExtensionHelper.isZero;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
+import android.util.Log;
import androidx.annotation.NonNull;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-final class CommonDisplayFeature implements DisplayFeature {
+/** A representation of a folding feature for both Extension and Sidecar.
+ * For Sidecar this is the same as combining {@link androidx.window.sidecar.SidecarDeviceState} and
+ * {@link androidx.window.sidecar.SidecarDisplayFeature}. For Extensions this is the mirror of
+ * {@link androidx.window.extensions.layout.FoldingFeature}.
+ */
+public final class CommonFoldingFeature {
+
+ private static final boolean DEBUG = false;
+
+ public static final String TAG = CommonFoldingFeature.class.getSimpleName();
+
+ /**
+ * A common type to represent a hinge where the screen is continuous.
+ */
+ public static final int COMMON_TYPE_FOLD = 1;
+
+ /**
+ * A common type to represent a hinge where there is a physical gap separating multiple
+ * displays.
+ */
+ public static final int COMMON_TYPE_HINGE = 2;
+
+ @IntDef({COMMON_TYPE_FOLD, COMMON_TYPE_HINGE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {
+ }
+
+ /**
+ * A common state to represent when the state is not known. One example is if the device is
+ * closed. We do not emit this value for developers but is useful for implementation reasons.
+ */
+ public static final int COMMON_STATE_UNKNOWN = -1;
+
+ /**
+ * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
+ * and Extensions do not match exactly.
+ */
+ public static final int COMMON_STATE_FLAT = 3;
+ /**
+ * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
+ * Sidecar and Extensions do not match exactly.
+ */
+ public static final int COMMON_STATE_HALF_OPENED = 2;
+
+ /**
+ * The possible states for a folding hinge.
+ */
+ @IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface State {
+ }
+
private static final Pattern FEATURE_PATTERN =
Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]-?(flat|half-opened)?");
@@ -38,17 +94,49 @@ final class CommonDisplayFeature implements DisplayFeature {
private static final String PATTERN_STATE_FLAT = "flat";
private static final String PATTERN_STATE_HALF_OPENED = "half-opened";
- // TODO(b/183049815): Support feature strings that include the state of the feature.
+ /**
+ * Parse a {@link List} of {@link CommonFoldingFeature} from a {@link String}.
+ * @param value a {@link String} representation of multiple {@link CommonFoldingFeature}
+ * separated by a ":".
+ * @param hingeState a global fallback value for a {@link CommonFoldingFeature} if one is not
+ * specified in the input.
+ * @throws IllegalArgumentException if the provided string is improperly formatted or could not
+ * otherwise be parsed.
+ * @see #FEATURE_PATTERN
+ * @return {@link List} of {@link CommonFoldingFeature}.
+ */
+ static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
+ @State int hingeState) {
+ List<CommonFoldingFeature> features = new ArrayList<>();
+ String[] featureStrings = value.split(";");
+ for (String featureString : featureStrings) {
+ CommonFoldingFeature feature;
+ try {
+ feature = CommonFoldingFeature.parseFromString(featureString, hingeState);
+ } catch (IllegalArgumentException e) {
+ if (DEBUG) {
+ Log.w(TAG, "Failed to parse display feature: " + featureString, e);
+ }
+ continue;
+ }
+ features.add(feature);
+ }
+ return features;
+ }
/**
* Parses a display feature from a string.
*
+ * @param string A {@link String} representation of a {@link CommonFoldingFeature}.
+ * @param hingeState A fallback value for the {@link State} if it is not specified in the input.
* @throws IllegalArgumentException if the provided string is improperly formatted or could not
* otherwise be parsed.
+ * @return {@link CommonFoldingFeature} represented by the {@link String} value.
* @see #FEATURE_PATTERN
*/
@NonNull
- static CommonDisplayFeature parseFromString(@NonNull String string) {
+ private static CommonFoldingFeature parseFromString(@NonNull String string,
+ @State int hingeState) {
Matcher featureMatcher = FEATURE_PATTERN.matcher(string);
if (!featureMatcher.matches()) {
throw new IllegalArgumentException("Malformed feature description format: " + string);
@@ -59,10 +147,10 @@ final class CommonDisplayFeature implements DisplayFeature {
int type;
switch (featureType) {
case FEATURE_TYPE_FOLD:
- type = 1 /* TYPE_FOLD */;
+ type = COMMON_TYPE_FOLD;
break;
case FEATURE_TYPE_HINGE:
- type = 2 /* TYPE_HINGE */;
+ type = COMMON_TYPE_HINGE;
break;
default: {
throw new IllegalArgumentException("Malformed feature type: " + featureType);
@@ -79,7 +167,7 @@ final class CommonDisplayFeature implements DisplayFeature {
}
String stateString = featureMatcher.group(6);
stateString = stateString == null ? "" : stateString;
- Integer state;
+ final int state;
switch (stateString) {
case PATTERN_STATE_FLAT:
state = COMMON_STATE_FLAT;
@@ -88,10 +176,10 @@ final class CommonDisplayFeature implements DisplayFeature {
state = COMMON_STATE_HALF_OPENED;
break;
default:
- state = null;
+ state = hingeState;
break;
}
- return new CommonDisplayFeature(type, state, featureRect);
+ return new CommonFoldingFeature(type, state, featureRect);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Malformed feature description: " + string, e);
}
@@ -99,11 +187,11 @@ final class CommonDisplayFeature implements DisplayFeature {
private final int mType;
@Nullable
- private final Integer mState;
+ private final int mState;
@NonNull
private final Rect mRect;
- CommonDisplayFeature(int type, @Nullable Integer state, @NonNull Rect rect) {
+ CommonFoldingFeature(int type, int state, @NonNull Rect rect) {
assertValidState(state);
this.mType = type;
this.mState = state;
@@ -114,16 +202,19 @@ final class CommonDisplayFeature implements DisplayFeature {
this.mRect = rect;
}
+ /** Returns the type of the feature. */
+ @Type
public int getType() {
return mType;
}
/** Returns the state of the feature, or {@code null} if the feature has no state. */
- @Nullable
- public Integer getState() {
+ @State
+ public int getState() {
return mState;
}
+ /** Returns the bounds of the feature. */
@NonNull
public Rect getRect() {
return mRect;
@@ -133,7 +224,7 @@ final class CommonDisplayFeature implements DisplayFeature {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- CommonDisplayFeature that = (CommonDisplayFeature) o;
+ CommonFoldingFeature that = (CommonFoldingFeature) o;
return mType == that.mType
&& Objects.equals(mState, that.mState)
&& mRect.equals(that.mRect);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index fa9a5a8b7a1b..6987401525b4 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -18,11 +18,15 @@ package androidx.window.common;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
@@ -30,6 +34,7 @@ import androidx.window.util.BaseDataProducer;
import com.android.internal.R;
+import java.util.List;
import java.util.Optional;
/**
@@ -37,10 +42,13 @@ import java.util.Optional;
* by mapping the state returned from {@link DeviceStateManager} to values provided in the resources
* config at {@link R.array#config_device_state_postures}.
*/
-public final class DeviceStateManagerPostureProducer extends BaseDataProducer<Integer> {
- private static final String TAG = "ConfigDevicePostureProducer";
+public final class DeviceStateManagerFoldingFeatureProducer extends
+ BaseDataProducer<List<CommonFoldingFeature>> {
+ private static final String TAG =
+ 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;
@@ -50,7 +58,8 @@ public final class DeviceStateManagerPostureProducer extends BaseDataProducer<In
notifyDataChanged();
};
- public DeviceStateManagerPostureProducer(@NonNull Context context) {
+ public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
+ mContext = context;
String[] deviceStatePosturePairs = context.getResources()
.getStringArray(R.array.config_device_state_postures);
for (String deviceStatePosturePair : deviceStatePosturePairs) {
@@ -86,8 +95,17 @@ public final class DeviceStateManagerPostureProducer extends BaseDataProducer<In
@Override
@Nullable
- public Optional<Integer> getData() {
- final int posture = mDeviceStateToPostureMap.get(mCurrentDeviceState, -1);
- return posture != -1 ? Optional.of(posture) : Optional.empty();
+ public Optional<List<CommonFoldingFeature>> getData() {
+ final int globalHingeState = globalHingeState();
+ String displayFeaturesString = mContext.getResources().getString(
+ R.string.config_display_features);
+ if (TextUtils.isEmpty(displayFeaturesString)) {
+ return Optional.empty();
+ }
+ return Optional.of(parseListFromString(displayFeaturesString, globalHingeState));
+ }
+
+ private int globalHingeState() {
+ return mDeviceStateToPostureMap.get(mCurrentDeviceState, COMMON_STATE_UNKNOWN);
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
deleted file mode 100644
index 573641857b99..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
+++ /dev/null
@@ -1,60 +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.common;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-public interface DisplayFeature {
- /** Returns the type of the feature. */
- int getType();
-
- /** Returns the state of the feature, or {@code null} if the feature has no state. */
- @Nullable
- @State
- Integer getState();
-
- /** Returns the bounds of the feature. */
- @NonNull
- Rect getRect();
-
- /**
- * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
- * and Extensions do not match exactly.
- */
- int COMMON_STATE_FLAT = 3;
- /**
- * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
- * Sidecar and Extensions do not match exactly.
- */
- int COMMON_STATE_HALF_OPENED = 2;
-
- /**
- * The possible states for a folding hinge.
- */
- @IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
- @Retention(RetentionPolicy.SOURCE)
- @interface State {}
-
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
new file mode 100644
index 000000000000..f2e403b4f792
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * 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.common;
+
+import android.app.Activity;
+import android.app.Application;
+import android.os.Bundle;
+
+/**
+ * An empty implementation of {@link Application.ActivityLifecycleCallbacks} derived classes can
+ * implement the methods necessary.
+ */
+public class EmptyLifecycleCallbacksAdapter implements Application.ActivityLifecycleCallbacks {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
deleted file mode 100644
index cd2cadc082e1..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
+++ /dev/null
@@ -1,74 +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.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.window.util.BaseDataProducer;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in the resources config at
- * {@link R.string#config_display_features}.
- */
-public final class ResourceConfigDisplayFeatureProducer extends
- BaseDataProducer<List<DisplayFeature>> {
- private static final boolean DEBUG = false;
- private static final String TAG = "ResourceConfigDisplayFeatureProducer";
-
- private final Context mContext;
-
- public ResourceConfigDisplayFeatureProducer(@NonNull Context context) {
- mContext = context;
- }
-
- @Override
- @Nullable
- public Optional<List<DisplayFeature>> getData() {
- String displayFeaturesString = mContext.getResources().getString(
- R.string.config_display_features);
- if (TextUtils.isEmpty(displayFeaturesString)) {
- return Optional.empty();
- }
-
- List<DisplayFeature> features = new ArrayList<>();
- String[] featureStrings = displayFeaturesString.split(";");
- for (String featureString : featureStrings) {
- CommonDisplayFeature feature;
- try {
- feature = CommonDisplayFeature.parseFromString(featureString);
- } catch (IllegalArgumentException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to parse display feature: " + featureString, e);
- }
- continue;
- }
- features.add(feature);
- }
- return Optional.of(features);
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
deleted file mode 100644
index 2026df3fa979..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
+++ /dev/null
@@ -1,96 +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.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-
-import androidx.window.util.BaseDataProducer;
-
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that provides the device posture
- * as an {@link Integer} from a value stored in {@link Settings}.
- */
-public final class SettingsDevicePostureProducer extends BaseDataProducer<Integer> {
- private static final String DEVICE_POSTURE = "device_posture";
-
- private final Uri mDevicePostureUri =
- Settings.Global.getUriFor(DEVICE_POSTURE);
-
- private final ContentResolver mResolver;
- private final ContentObserver mObserver;
- private boolean mRegisteredObservers;
-
- public SettingsDevicePostureProducer(@NonNull Context context) {
- mResolver = context.getContentResolver();
- mObserver = new SettingsObserver();
- }
-
- @Override
- @Nullable
- public Optional<Integer> getData() {
- int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, -1);
- return posture == -1 ? Optional.empty() : Optional.of(posture);
- }
-
- /**
- * Registers settings observers, if needed. When settings observers are registered for this
- * producer callbacks for changes in data will be triggered.
- */
- public void registerObserversIfNeeded() {
- if (mRegisteredObservers) {
- return;
- }
- mRegisteredObservers = true;
- mResolver.registerContentObserver(mDevicePostureUri, false /* notifyForDescendants */,
- mObserver /* ContentObserver */);
- }
-
- /**
- * 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() {
- if (!mRegisteredObservers) {
- return;
- }
- mRegisteredObservers = false;
- mResolver.unregisterContentObserver(mObserver);
- }
-
- private final class SettingsObserver extends ContentObserver {
- SettingsObserver() {
- super(new Handler(Looper.getMainLooper()));
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (mDevicePostureUri.equals(uri)) {
- notifyDataChanged();
- }
- }
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
index 040662657a74..e9d213e06fa9 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
@@ -16,8 +16,10 @@
package androidx.window.common;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -26,22 +28,19 @@ import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.Log;
import androidx.window.util.BaseDataProducer;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in {@link Settings}.
+ * {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
*/
public final class SettingsDisplayFeatureProducer
- extends BaseDataProducer<List<DisplayFeature>> {
- private static final boolean DEBUG = false;
- private static final String TAG = "SettingsDisplayFeatureProducer";
+ extends BaseDataProducer<List<CommonFoldingFeature>> {
private static final String DISPLAY_FEATURES = "display_features";
private final Uri mDisplayFeaturesUri =
@@ -57,32 +56,17 @@ public final class SettingsDisplayFeatureProducer
}
@Override
- @Nullable
- public Optional<List<DisplayFeature>> getData() {
+ @NonNull
+ public Optional<List<CommonFoldingFeature>> getData() {
String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
if (displayFeaturesString == null) {
return Optional.empty();
}
- List<DisplayFeature> features = new ArrayList<>();
if (TextUtils.isEmpty(displayFeaturesString)) {
- return Optional.of(features);
- }
- String[] featureStrings = displayFeaturesString.split(";");
-
- for (String featureString : featureStrings) {
- CommonDisplayFeature feature;
- try {
- feature = CommonDisplayFeature.parseFromString(featureString);
- } catch (IllegalArgumentException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to parse display feature: " + featureString, e);
- }
- continue;
- }
- features.add(feature);
+ return Optional.of(Collections.emptyList());
}
- return Optional.of(features);
+ return Optional.of(parseListFromString(displayFeaturesString, COMMON_STATE_UNKNOWN));
}
/**
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 8f368c2bee22..be8b35d80326 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -28,7 +28,6 @@ import android.app.Activity;
import android.app.ActivityClient;
import android.app.ActivityOptions;
import android.app.ActivityThread;
-import android.app.Application.ActivityLifecycleCallbacks;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
@@ -41,6 +40,8 @@ import android.os.Looper;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -759,11 +760,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return shouldRetainAssociatedContainer(finishingContainer, associatedContainer);
}
- private final class LifecycleCallbacks implements ActivityLifecycleCallbacks {
-
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
- }
+ private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
@Override
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
@@ -775,30 +772,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
@Override
- public void onActivityStarted(Activity activity) {
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- }
-
- @Override
public void onActivityConfigurationChanged(Activity activity) {
SplitController.this.onActivityConfigurationChanged(activity);
}
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 fe9ce971d4d9..ee8cb48e3c4c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -18,22 +18,24 @@ package androidx.window.extensions.layout;
import static android.view.Display.DEFAULT_DISPLAY;
-import static androidx.window.common.DisplayFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.DisplayFeature.COMMON_STATE_HALF_OPENED;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
import android.annotation.Nullable;
import android.app.Activity;
+import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;
@@ -56,36 +58,27 @@ import java.util.function.Consumer;
*/
public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private static final String TAG = "SampleExtension";
- private static WindowLayoutComponent sInstance;
private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
new HashMap<>();
- private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
- private final DataProducer<Integer> mDevicePostureProducer;
-
private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
- private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+ private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
public WindowLayoutComponentImpl(Context context) {
- mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
- mDevicePostureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDevicePostureProducer,
- new DeviceStateManagerPostureProducer(context)
- ));
-
+ ((Application) context.getApplicationContext())
+ .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
+ mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
mSettingsDisplayFeatureProducer,
- new ResourceConfigDisplayFeatureProducer(context)
+ new DeviceStateManagerFoldingFeatureProducer(context)
));
-
- mDevicePostureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+ mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
/**
* Adds a listener interested in receiving updates to {@link WindowLayoutInfo}
+ *
* @param activity hosting a {@link android.view.Window}
* @param consumer interested in receiving updates to {@link WindowLayoutInfo}
*/
@@ -97,6 +90,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
/**
* Removes a listener no longer interested in receiving updates.
+ *
* @param consumer no longer interested in receiving updates to {@link WindowLayoutInfo}
*/
public void removeWindowLayoutInfoListener(
@@ -118,43 +112,34 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return mWindowLayoutChangeListeners.keySet();
}
- protected boolean hasListeners() {
- return !mWindowLayoutChangeListeners.isEmpty();
+ @NonNull
+ private Boolean isListeningForLayoutChanges(IBinder token) {
+ for (Activity activity: getActivitiesListeningForLayoutChanges()) {
+ if (token.equals(activity.getWindow().getAttributes().token)) {
+ return true;
+ }
+ }
+ return false;
}
- /**
- * Calculate the {@link DisplayFeature.State} from the feature or the device posture producer.
- * If the given {@link DisplayFeature.State} is not valid then {@code null} will be returned.
- * The {@link FoldingFeature} should be ignored in the case of an invalid
- * {@link DisplayFeature.State}.
- *
- * @param feature a {@link DisplayFeature} to provide the feature state if present.
- * @return {@link DisplayFeature.State} of the hinge if present or the state from the posture
- * produce if present.
- */
- @Nullable
- private Integer getFeatureState(DisplayFeature feature) {
- Integer featureState = feature.getState();
- Optional<Integer> posture = mDevicePostureProducer.getData();
- Integer state = featureState == null ? posture.orElse(null) : featureState;
- return convertToExtensionState(state);
+ protected boolean hasListeners() {
+ return !mWindowLayoutChangeListeners.isEmpty();
}
/**
* A convenience method to translate from the common feature state to the extensions feature
- * state. More specifically, translates from {@link DisplayFeature.State} to
+ * state. More specifically, translates from {@link CommonFoldingFeature.State} to
* {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED}. If it is not
* possible to translate, then we will return a {@code null} value.
*
- * @param state if it matches a value in {@link DisplayFeature.State}, {@code null} otherwise.
- * @return a {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED} if
- * the given state matches a value in {@link DisplayFeature.State} and {@code null} otherwise.
+ * @param state if it matches a value in {@link CommonFoldingFeature.State}, {@code null}
+ * otherwise. @return a {@link FoldingFeature.STATE_FLAT} or
+ * {@link FoldingFeature.STATE_HALF_OPENED} if the given state matches a value in
+ * {@link CommonFoldingFeature.State} and {@code null} otherwise.
*/
@Nullable
- private Integer convertToExtensionState(@Nullable Integer state) {
- if (state == null) { // The null check avoids a NullPointerException.
- return null;
- } else if (state == COMMON_STATE_FLAT) {
+ private Integer convertToExtensionState(int state) {
+ if (state == COMMON_STATE_FLAT) {
return FoldingFeature.STATE_FLAT;
} else if (state == COMMON_STATE_HALF_OPENED) {
return FoldingFeature.STATE_HALF_OPENED;
@@ -172,33 +157,30 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
@NonNull
private WindowLayoutInfo getWindowLayoutInfo(@NonNull Activity activity) {
- List<androidx.window.extensions.layout.DisplayFeature> displayFeatures =
- getDisplayFeatures(activity);
+ List<DisplayFeature> displayFeatures = getDisplayFeatures(activity);
return new WindowLayoutInfo(displayFeatures);
}
/**
- * Translate from the {@link DisplayFeature} to
- * {@link androidx.window.extensions.layout.DisplayFeature} for a given {@link Activity}. If a
- * {@link DisplayFeature} is not valid then it will be omitted.
+ * Translate from the {@link CommonFoldingFeature} to
+ * {@link DisplayFeature} for a given {@link Activity}. If a
+ * {@link CommonFoldingFeature} is not valid then it will be omitted.
*
* For a {@link FoldingFeature} the bounds are localized into the {@link Activity} window
- * coordinate space and the state is calculated either from {@link DisplayFeature#getState()} or
- * {@link #mDisplayFeatureProducer}. The state from {@link #mDisplayFeatureProducer} may not be
- * valid since {@link #mDisplayFeatureProducer} is a general state controller. If the state is
- * not valid, the {@link FoldingFeature} is omitted from the {@link List} of
- * {@link androidx.window.extensions.layout.DisplayFeature}. If the bounds are not valid,
- * constructing a {@link FoldingFeature} will throw an {@link IllegalArgumentException} since
- * this can cause negative UI effects down stream.
+ * coordinate space and the state is calculated from {@link CommonFoldingFeature#getState()}.
+ * The state from {@link #mFoldingFeatureProducer} may not be valid since
+ * {@link #mFoldingFeatureProducer} is a general state controller. If the state is not valid,
+ * the {@link FoldingFeature} is omitted from the {@link List} of {@link DisplayFeature}. If
+ * the bounds are not valid, constructing a {@link FoldingFeature} will throw an
+ * {@link IllegalArgumentException} since this can cause negative UI effects down stream.
*
* @param activity a proxy for the {@link android.view.Window} that contains the
- * {@link androidx.window.extensions.layout.DisplayFeature}.
- * @return a {@link List} of valid {@link androidx.window.extensions.layout.DisplayFeature} that
+ * {@link DisplayFeature}.
+ * @return a {@link List} of valid {@link DisplayFeature} that
* are within the {@link android.view.Window} of the {@link Activity}
*/
- private List<androidx.window.extensions.layout.DisplayFeature> getDisplayFeatures(
- @NonNull Activity activity) {
- List<androidx.window.extensions.layout.DisplayFeature> features = new ArrayList<>();
+ private List<DisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
+ List<DisplayFeature> features = new ArrayList<>();
int displayId = activity.getDisplay().getDisplayId();
if (displayId != DEFAULT_DISPLAY) {
Log.w(TAG, "This sample doesn't support display features on secondary displays");
@@ -211,11 +193,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return features;
}
- Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+ Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
if (storedFeatures.isPresent()) {
-
- for (DisplayFeature baseFeature : storedFeatures.get()) {
- Integer state = getFeatureState(baseFeature);
+ for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
+ Integer state = convertToExtensionState(baseFeature.getState());
if (state == null) {
continue;
}
@@ -223,8 +204,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
rotateRectToDisplayRotation(displayId, featureRect);
transformToWindowSpaceRect(activity, featureRect);
- features.add(new FoldingFeature(featureRect, baseFeature.getType(),
- getFeatureState(baseFeature)));
+ features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
}
}
return features;
@@ -232,13 +212,31 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private void updateRegistrations() {
if (hasListeners()) {
- mSettingsDevicePostureProducer.registerObserversIfNeeded();
mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
} else {
- mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
}
-
onDisplayFeaturesChanged();
}
+
+ private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ super.onActivityCreated(activity, savedInstanceState);
+ onDisplayFeaturesChangedIfListening(activity);
+ }
+
+ @Override
+ public void onActivityConfigurationChanged(Activity activity) {
+ super.onActivityConfigurationChanged(activity);
+ onDisplayFeaturesChangedIfListening(activity);
+ }
+
+ private void onDisplayFeaturesChangedIfListening(Activity activity) {
+ IBinder token = activity.getWindow().getAttributes().token;
+ if (token == null || isListeningForLayoutChanges(token)) {
+ onDisplayFeaturesChanged();
+ }
+ }
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index aa949f126154..c7b709347060 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -23,16 +23,17 @@ import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
import android.app.Activity;
import android.app.ActivityThread;
+import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;
@@ -48,36 +49,25 @@ import java.util.Optional;
*/
class SampleSidecarImpl extends StubSidecar {
private static final String TAG = "SampleSidecar";
- private static final boolean DEBUG = false;
- private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
- private final DataProducer<Integer> mDevicePostureProducer;
+ private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
- private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
- private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+ private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
SampleSidecarImpl(Context context) {
- mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
- mDevicePostureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDevicePostureProducer,
- new DeviceStateManagerPostureProducer(context)
+ ((Application) context.getApplicationContext())
+ .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
+ mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
+ mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
+ mSettingsFoldingFeatureProducer,
+ new DeviceStateManagerFoldingFeatureProducer(context)
));
- mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
- mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
- mSettingsDisplayFeatureProducer,
- new ResourceConfigDisplayFeatureProducer(context)
- ));
-
- mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged);
- mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- }
-
- private void onDevicePostureChanged() {
- updateDeviceState(getDeviceState());
+ mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
private void onDisplayFeaturesChanged() {
+ updateDeviceState(getDeviceState());
for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
updateWindowLayout(windowToken, newLayout);
@@ -87,27 +77,21 @@ class SampleSidecarImpl extends StubSidecar {
@NonNull
@Override
public SidecarDeviceState getDeviceState() {
- Optional<Integer> posture = mDevicePostureProducer.getData();
-
SidecarDeviceState deviceState = new SidecarDeviceState();
- deviceState.posture = posture.orElse(deviceStateFromFeature());
+ deviceState.posture = deviceStateFromFeature();
return deviceState;
}
private int deviceStateFromFeature() {
- List<DisplayFeature> storedFeatures = mDisplayFeatureProducer.getData()
+ List<CommonFoldingFeature> storedFeatures = mFoldingFeatureProducer.getData()
.orElse(Collections.emptyList());
for (int i = 0; i < storedFeatures.size(); i++) {
- DisplayFeature feature = storedFeatures.get(i);
- final int state = feature.getState() == null ? -1 : feature.getState();
- if (DEBUG && feature.getState() == null) {
- Log.d(TAG, "feature#getState was null for DisplayFeature: " + feature);
- }
-
+ CommonFoldingFeature feature = storedFeatures.get(i);
+ final int state = feature.getState();
switch (state) {
- case DisplayFeature.COMMON_STATE_FLAT:
+ case CommonFoldingFeature.COMMON_STATE_FLAT:
return SidecarDeviceState.POSTURE_OPENED;
- case DisplayFeature.COMMON_STATE_HALF_OPENED:
+ case CommonFoldingFeature.COMMON_STATE_HALF_OPENED:
return SidecarDeviceState.POSTURE_HALF_OPENED;
}
}
@@ -127,22 +111,22 @@ class SampleSidecarImpl extends StubSidecar {
}
private List<SidecarDisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
- List<SidecarDisplayFeature> features = new ArrayList<SidecarDisplayFeature>();
int displayId = activity.getDisplay().getDisplayId();
if (displayId != DEFAULT_DISPLAY) {
Log.w(TAG, "This sample doesn't support display features on secondary displays");
- return features;
+ return Collections.emptyList();
}
if (activity.isInMultiWindowMode()) {
// It is recommended not to report any display features in multi-window mode, since it
// won't be possible to synchronize the display feature positions with window movement.
- return features;
+ return Collections.emptyList();
}
- Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+ Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
+ List<SidecarDisplayFeature> features = new ArrayList<>();
if (storedFeatures.isPresent()) {
- for (DisplayFeature baseFeature : storedFeatures.get()) {
+ for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
SidecarDisplayFeature feature = new SidecarDisplayFeature();
Rect featureRect = baseFeature.getRect();
rotateRectToDisplayRotation(displayId, featureRect);
@@ -152,17 +136,37 @@ class SampleSidecarImpl extends StubSidecar {
features.add(feature);
}
}
- return features;
+ return Collections.unmodifiableList(features);
}
@Override
protected void onListenersChanged() {
if (hasListeners()) {
- mSettingsDevicePostureProducer.registerObserversIfNeeded();
- mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
+ mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
+ onDisplayFeaturesChanged();
} else {
- mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
- mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
+ mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
+ }
+ }
+
+ private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ super.onActivityCreated(activity, savedInstanceState);
+ onDisplayFeaturesChangedForActivity(activity);
+ }
+
+ @Override
+ public void onActivityConfigurationChanged(Activity activity) {
+ super.onActivityConfigurationChanged(activity);
+ onDisplayFeaturesChangedForActivity(activity);
+ }
+
+ private void onDisplayFeaturesChangedForActivity(@NonNull Activity activity) {
+ IBinder token = activity.getWindow().getAttributes().token;
+ if (token == null || mWindowLayoutChangeListenerTokens.contains(token)) {
+ onDisplayFeaturesChanged();
+ }
}
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
index 199c37315c07..b9c808a6569b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
@@ -30,7 +30,7 @@ import java.util.Set;
abstract class StubSidecar implements SidecarInterface {
private SidecarCallback mSidecarCallback;
- private final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
+ final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
private boolean mDeviceStateChangeListenerRegistered;
StubSidecar() {