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

Commit 6cdd1323 authored by Diego Vela's avatar Diego Vela
Browse files

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
parent 3b9f2b53
Loading
Loading
Loading
Loading
+44 −6
Original line number Diff line number Diff line
@@ -25,19 +25,23 @@ 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.ArrayMap;
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;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -56,12 +60,14 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
    private static final String TAG = "SampleExtension";

    private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
            new HashMap<>();
            new ArrayMap<>();

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

    public WindowLayoutComponentImpl(Context context) {
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
        mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
        mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
                mSettingsDisplayFeatureProducer,
@@ -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();
    }
@@ -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();
            }
        }
    }
}
+27 −0
Original line number Diff line number Diff line
@@ -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();
            }
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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() {