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

Commit 1d650e94 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Add per-display Configuration change reporting"

parents 54fdfa62 82207085
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -16,12 +16,16 @@

package android.view;

import android.content.res.Configuration;

/**
 * Interface to listen for changes to display window-containers.
 *
 * This differs from DisplayManager's DisplayListener:
 * This differs from DisplayManager's DisplayListener in a couple ways:
 *  - onDisplayAdded is always called after the display is actually added to the WM hierarchy.
 *    This corresponds to the DisplayContent and not the raw Dislay from DisplayManager.
 *  - onDisplayConfigurationChanged is called for all configuration changes, not just changes
 *    to displayinfo (eg. windowing-mode).
 *
 * @hide
 */
@@ -32,6 +36,11 @@ oneway interface IDisplayWindowListener {
     */
    void onDisplayAdded(int displayId);

    /**
     * Called when a display's window-container configuration has changed.
     */
    void onDisplayConfigurationChanged(int displayId, in Configuration newConfig);

    /**
     * Called when a display is removed from the hierarchy.
     */
+33 −5
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.systemui.wm;

import android.content.res.Configuration;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
import android.view.IDisplayWindowListener;
import android.view.IDisplayWindowRotationCallback;
@@ -40,6 +42,8 @@ import javax.inject.Singleton;
 */
@Singleton
public class DisplayWindowController {
    private static final String TAG = "DisplayWindowController";

    private final Handler mHandler;

    private final ArrayList<OnDisplayWindowRotationController> mRotationControllers =
@@ -84,8 +88,26 @@ public class DisplayWindowController {
                            DisplayRecord record = new DisplayRecord();
                            record.mDisplayId = displayId;
                            mDisplays.put(displayId, record);
                            for (DisplayWindowListener l : mDisplayChangedListeners) {
                                l.onDisplayAdded(displayId);
                            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
                                mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
                            }
                        }
                    });
                }

                @Override
                public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
                    mHandler.post(() -> {
                        synchronized (mDisplays) {
                            DisplayRecord dr = mDisplays.get(displayId);
                            if (dr == null) {
                                Slog.w(TAG, "Skipping Display Configuration change on non-added"
                                        + " display.");
                                return;
                            }
                            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
                                mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
                                        displayId, newConfig);
                            }
                        }
                    });
@@ -118,8 +140,8 @@ public class DisplayWindowController {
    }

    /**
     * Add a display window-container listener. It will get notified when displays are
     * added/removed from the WM hierarchy.
     * Add a display window-container listener. It will get notified whenever a display's
     * configuration changes or when displays are added/removed from the WM hierarchy.
     */
    public void addDisplayWindowListener(DisplayWindowListener listener) {
        synchronized (mDisplays) {
@@ -165,7 +187,8 @@ public class DisplayWindowController {
    }

    /**
     * Gets notified when a display is added/removed to the WM hierarchy.
     * Gets notified when a display is added/removed to the WM hierarchy and when a display's
     * window-configuration changes.
     *
     * @see IDisplayWindowListener
     */
@@ -175,6 +198,11 @@ public class DisplayWindowController {
         */
        void onDisplayAdded(int displayId);

        /**
         * Called when a display's window-container configuration changes.
         */
        void onDisplayConfigurationChanged(int displayId, Configuration newConfig);

        /**
         * Called when a display is removed.
         */
+2 −0
Original line number Diff line number Diff line
@@ -1080,6 +1080,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
                        ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
                mService.mH.sendMessage(msg);
            }
            mService.mWindowManager.mDisplayNotificationController.dispatchDisplayChanged(
                    this, getConfiguration());
        }
        return changes;
    }
+23 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import android.content.res.Configuration;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.view.IDisplayWindowListener;
@@ -62,6 +63,28 @@ class DisplayWindowListenerController {
        mDisplayListeners.finishBroadcast();
    }

    void dispatchDisplayChanged(ActivityDisplay display, Configuration newConfig) {
        // Only report changed if this has actually been added to the hierarchy already.
        boolean isInHierarchy = false;
        for (int i = 0; i < display.getParent().getChildCount(); ++i) {
            if (display.getParent().getChildAt(i) == display) {
                isInHierarchy = true;
            }
        }
        if (!isInHierarchy) {
            return;
        }
        int count = mDisplayListeners.beginBroadcast();
        for (int i = 0; i < count; ++i) {
            try {
                mDisplayListeners.getBroadcastItem(i).onDisplayConfigurationChanged(
                        display.mDisplayId, newConfig);
            } catch (RemoteException e) {
            }
        }
        mDisplayListeners.finishBroadcast();
    }

    void dispatchDisplayRemoved(ActivityDisplay display) {
        int count = mDisplayListeners.beginBroadcast();
        for (int i = 0; i < count; ++i) {
+55 −0
Original line number Diff line number Diff line
@@ -26,7 +26,9 @@ import static org.junit.Assert.assertTrue;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.view.IDisplayWindowListener;
import android.view.WindowContainerTransaction;

import androidx.test.filters.MediumTest;
@@ -35,6 +37,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;

/**
 * Tests for the {@link ActivityTaskManagerService} class.
 *
@@ -93,5 +97,56 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
        mService.applyContainerTransaction(t);
        assertEquals(newBounds, stack.getBounds());
    }

    @Test
    public void testDisplayWindowListener() {
        final ArrayList<Integer> added = new ArrayList<>();
        final ArrayList<Integer> changed = new ArrayList<>();
        final ArrayList<Integer> removed = new ArrayList<>();
        IDisplayWindowListener listener = new IDisplayWindowListener.Stub() {
            @Override
            public void onDisplayAdded(int displayId) {
                added.add(displayId);
            }

            @Override
            public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
                changed.add(displayId);
            }

            @Override
            public void onDisplayRemoved(int displayId) {
                removed.add(displayId);
            }
        };
        mService.mWindowManager.registerDisplayWindowListener(listener);
        // Check that existing displays call added
        assertEquals(1, added.size());
        assertEquals(0, changed.size());
        assertEquals(0, removed.size());
        added.clear();
        // Check adding a display
        ActivityDisplay newDisp1 = new TestActivityDisplay.Builder(mService, 600, 800).build();
        assertEquals(1, added.size());
        assertEquals(0, changed.size());
        assertEquals(0, removed.size());
        added.clear();
        // Check that changes are reported
        Configuration c = new Configuration(newDisp1.getRequestedOverrideConfiguration());
        c.windowConfiguration.setBounds(new Rect(0, 0, 1000, 1300));
        newDisp1.onRequestedOverrideConfigurationChanged(c);
        mService.mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
                newDisp1.mDisplayId, false /* markFrozenIfConfigChanged */,
                false /* deferResume */);
        assertEquals(0, added.size());
        assertEquals(1, changed.size());
        assertEquals(0, removed.size());
        changed.clear();
        // Check that removal is reported
        newDisp1.remove();
        assertEquals(0, added.size());
        assertEquals(0, changed.size());
        assertEquals(1, removed.size());
    }
}