DO NOT MERGE Listen for config changes when updating features.
Listen for configuration changes to push out folding feature changes. Fixes a bug where the reference implementation would not emit the correct folding feature if a configuration changed. The effect was that you would see the folding feature for portait while in landscape or vice-versa. Maintains parity with Sidecar providing updates for Activities that do not handle configuration changes. Bug: 205342008, 206697963 Test: Manual - Open the sample app and use the application that && handles configuration changes. && Expect the folding feature to match the physical orientation Test: Manual - open an app that handles PiP and folding features && Flattend the device and put app into PiP && Fold device and put PiP app in full screen. && Expect the app to react to fold. Test: atest CtsWindowManagerJetpackTestCases Change-Id: I726827c9f1482ddd0b55a6839e34660deb340767
This commit is contained in:
@@ -25,13 +25,17 @@ 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.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;
|
||||
@@ -62,6 +66,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
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,
|
||||
@@ -72,6 +78,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
@@ -83,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(
|
||||
@@ -104,6 +112,16 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
return mWindowLayoutChangeListeners.keySet();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Boolean isListeningForLayoutChanges(IBinder token) {
|
||||
for (Activity activity: getActivitiesListeningForLayoutChanges()) {
|
||||
if (token.equals(activity.getWindow().getAttributes().token)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean hasListeners() {
|
||||
return !mWindowLayoutChangeListeners.isEmpty();
|
||||
}
|
||||
@@ -115,9 +133,9 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
* possible to translate, then we will return a {@code null} value.
|
||||
*
|
||||
* @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.
|
||||
* 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(int state) {
|
||||
@@ -198,7 +216,27 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +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.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;
|
||||
@@ -52,6 +55,8 @@ class SampleSidecarImpl extends StubSidecar {
|
||||
private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
|
||||
|
||||
SampleSidecarImpl(Context context) {
|
||||
((Application) context.getApplicationContext())
|
||||
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
|
||||
mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
|
||||
mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
|
||||
mSettingsFoldingFeatureProducer,
|
||||
@@ -138,8 +143,30 @@ class SampleSidecarImpl extends StubSidecar {
|
||||
protected void onListenersChanged() {
|
||||
if (hasListeners()) {
|
||||
mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
|
||||
onDisplayFeaturesChanged();
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user