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

Commit 0ac518cc authored by Winson Chung's avatar Winson Chung
Browse files

Extract remote insets controller out of DisplayImeController

- Moved into DisplayInsetsController so that other shell components
  can listen to changes as well
- Expose the insets to DisplayController's DisplayLayout so that we
  can account for the extra nav bar insets from the task bar

Bug: 182905588
Test: atest DisplayInsetsControllerTest
Change-Id: Ie481282c9a71e02a77ce6b2cf8c2dcf4b8e452c6
parent c57c02c7
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR

import com.android.wm.shell.apppairs.AppPairsController;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
@@ -39,7 +41,9 @@ import java.util.Optional;
public class ShellInitImpl {
    private static final String TAG = ShellInitImpl.class.getSimpleName();

    private final DisplayController mDisplayController;
    private final DisplayImeController mDisplayImeController;
    private final DisplayInsetsController mDisplayInsetsController;
    private final DragAndDropController mDragAndDropController;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<BubbleController> mBubblesOptional;
@@ -55,7 +59,10 @@ public class ShellInitImpl {

    private final InitImpl mImpl = new InitImpl();

    public ShellInitImpl(DisplayImeController displayImeController,
    public ShellInitImpl(
            DisplayController displayController,
            DisplayImeController displayImeController,
            DisplayInsetsController displayInsetsController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<BubbleController> bubblesOptional,
@@ -68,7 +75,9 @@ public class ShellInitImpl {
            Transitions transitions,
            StartingWindowController startingWindow,
            ShellExecutor mainExecutor) {
        mDisplayController = displayController;
        mDisplayImeController = displayImeController;
        mDisplayInsetsController = displayInsetsController;
        mDragAndDropController = dragAndDropController;
        mShellTaskOrganizer = shellTaskOrganizer;
        mBubblesOptional = bubblesOptional;
@@ -88,7 +97,9 @@ public class ShellInitImpl {
    }

    private void init() {
        // Start listening for display changes
        // Start listening for display and insets changes
        mDisplayController.initialize();
        mDisplayInsetsController.initialize();
        mDisplayImeController.startMonitorDisplays();

        // Setup the shell organizer
+9 −15
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.common;

import android.os.RemoteException;
import android.util.Slog;
import android.view.IDisplayWindowRotationCallback;
import android.view.IDisplayWindowRotationController;
import android.view.IWindowManager;
@@ -27,6 +28,7 @@ import androidx.annotation.BinderThread;
import com.android.wm.shell.common.annotations.ShellMainThread;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * This module deals with display rotations coming from WM. When WM starts a rotation: after it has
@@ -35,14 +37,14 @@ import java.util.ArrayList;
 * rotation.
 */
public class DisplayChangeController {
    private static final String TAG = DisplayChangeController.class.getSimpleName();

    private final ShellExecutor mMainExecutor;
    private final IWindowManager mWmService;
    private final IDisplayWindowRotationController mControllerImpl;

    private final ArrayList<OnDisplayChangingListener> mRotationListener =
            new ArrayList<>();
    private final ArrayList<OnDisplayChangingListener> mTmpListeners = new ArrayList<>();
    private final CopyOnWriteArrayList<OnDisplayChangingListener> mRotationListener =
            new CopyOnWriteArrayList<>();

    public DisplayChangeController(IWindowManager wmService, ShellExecutor mainExecutor) {
        mMainExecutor = mainExecutor;
@@ -59,34 +61,26 @@ public class DisplayChangeController {
     * Adds a display rotation controller.
     */
    public void addRotationListener(OnDisplayChangingListener listener) {
        synchronized (mRotationListener) {
        mRotationListener.add(listener);
    }
    }

    /**
     * Removes a display rotation controller.
     */
    public void removeRotationListener(OnDisplayChangingListener listener) {
        synchronized (mRotationListener) {
        mRotationListener.remove(listener);
    }
    }

    private void onRotateDisplay(int displayId, final int fromRotation, final int toRotation,
            IDisplayWindowRotationCallback callback) {
        WindowContainerTransaction t = new WindowContainerTransaction();
        synchronized (mRotationListener) {
            mTmpListeners.clear();
            // Make a local copy in case the handlers add/remove themselves.
            mTmpListeners.addAll(mRotationListener);
        }
        for (OnDisplayChangingListener c : mTmpListeners) {
        for (OnDisplayChangingListener c : mRotationListener) {
            c.onRotateDisplay(displayId, fromRotation, toRotation, t);
        }
        try {
            callback.continueRotateDisplay(toRotation, t);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to continue rotation", e);
        }
    }

+58 −25
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.IDisplayWindowListener;
import android.view.IWindowManager;
import android.view.InsetsState;

import androidx.annotation.BinderThread;

@@ -52,14 +53,6 @@ public class DisplayController {
    private final SparseArray<DisplayRecord> mDisplays = new SparseArray<>();
    private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>();

    /**
     * Gets a display by id from DisplayManager.
     */
    public Display getDisplay(int displayId) {
        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
        return displayManager.getDisplay(displayId);
    }

    public DisplayController(Context context, IWindowManager wmService,
            ShellExecutor mainExecutor) {
        mMainExecutor = mainExecutor;
@@ -67,13 +60,27 @@ public class DisplayController {
        mWmService = wmService;
        mChangeController = new DisplayChangeController(mWmService, mainExecutor);
        mDisplayContainerListener = new DisplayWindowListenerImpl();
    }

    /**
     * Initializes the window listener.
     */
    public void initialize() {
        try {
            mWmService.registerDisplayWindowListener(mDisplayContainerListener);
        } catch (RemoteException e) {
            throw new RuntimeException("Unable to register hierarchy listener");
            throw new RuntimeException("Unable to register display controller");
        }
    }

    /**
     * Gets a display by id from DisplayManager.
     */
    public Display getDisplay(int displayId) {
        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
        return displayManager.getDisplay(displayId);
    }

    /**
     * Gets the DisplayLayout associated with a display.
     */
@@ -90,6 +97,16 @@ public class DisplayController {
        return r != null ? r.mContext : null;
    }

    /**
     * Updates the insets for a given display.
     */
    public void updateDisplayInsets(int displayId, InsetsState state) {
        final DisplayRecord r = mDisplays.get(displayId);
        if (r != null) {
            r.setInsets(state);
        }
    }

    /**
     * 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.
@@ -134,17 +151,18 @@ public class DisplayController {
            if (mDisplays.get(displayId) != null) {
                return;
            }
            Display display = getDisplay(displayId);
            final Display display = getDisplay(displayId);
            if (display == null) {
                // It's likely that the display is private to some app and thus not
                // accessible by system-ui.
                return;
            }
            DisplayRecord record = new DisplayRecord();
            record.mDisplayId = displayId;
            record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext

            final Context context = (displayId == Display.DEFAULT_DISPLAY)
                    ? mContext
                    : mContext.createDisplayContext(display);
            record.mDisplayLayout = new DisplayLayout(record.mContext, display);
            final DisplayRecord record = new DisplayRecord(displayId);
            record.setDisplayLayout(context, new DisplayLayout(context, display));
            mDisplays.put(displayId, record);
            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
                mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
@@ -154,24 +172,23 @@ public class DisplayController {

    private void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
        synchronized (mDisplays) {
            DisplayRecord dr = mDisplays.get(displayId);
            final DisplayRecord dr = mDisplays.get(displayId);
            if (dr == null) {
                Slog.w(TAG, "Skipping Display Configuration change on non-added"
                        + " display.");
                return;
            }
            Display display = getDisplay(displayId);
            final Display display = getDisplay(displayId);
            if (display == null) {
                Slog.w(TAG, "Skipping Display Configuration change on invalid"
                        + " display. It may have been removed.");
                return;
            }
            Context perDisplayContext = mContext;
            if (displayId != Display.DEFAULT_DISPLAY) {
                perDisplayContext = mContext.createDisplayContext(display);
            }
            dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
            dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
            final Context perDisplayContext = (displayId == Display.DEFAULT_DISPLAY)
                    ? mContext
                    : mContext.createDisplayContext(display);
            final Context context = perDisplayContext.createConfigurationContext(newConfig);
            dr.setDisplayLayout(context, new DisplayLayout(context, display));
            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
                mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
                        displayId, newConfig);
@@ -219,9 +236,25 @@ public class DisplayController {
    }

    private static class DisplayRecord {
        int mDisplayId;
        Context mContext;
        DisplayLayout mDisplayLayout;
        private int mDisplayId;
        private Context mContext;
        private DisplayLayout mDisplayLayout;
        private InsetsState mInsetsState = new InsetsState();

        private DisplayRecord(int displayId) {
            mDisplayId = displayId;
        }

        private void setDisplayLayout(Context context, DisplayLayout displayLayout) {
            mContext = context;
            mDisplayLayout = displayLayout;
            mDisplayLayout.setInsets(mContext.getResources(), mInsetsState);
        }

        private void setInsets(InsetsState state) {
            mInsetsState = state;
            mDisplayLayout.setInsets(mContext.getResources(), state);
        }
    }

    @BinderThread
+22 −58
Original line number Diff line number Diff line
@@ -69,14 +69,17 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
    protected final Executor mMainExecutor;
    private final TransactionPool mTransactionPool;
    private final DisplayController mDisplayController;
    private final DisplayInsetsController mDisplayInsetsController;
    private final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
    private final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();


    public DisplayImeController(IWindowManager wmService, DisplayController displayController,
            DisplayInsetsController displayInsetsController,
            Executor mainExecutor, TransactionPool transactionPool) {
        mWmService = wmService;
        mDisplayController = displayController;
        mDisplayInsetsController = displayInsetsController;
        mMainExecutor = mainExecutor;
        mTransactionPool = transactionPool;
    }
@@ -110,11 +113,11 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged

    @Override
    public void onDisplayRemoved(int displayId) {
        try {
            mWmService.setDisplayWindowInsetsController(displayId, null);
        } catch (RemoteException e) {
            Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
        PerDisplay pd = mImePerDisplay.get(displayId);
        if (pd == null) {
            return;
        }
        pd.unregister();
        mImePerDisplay.remove(displayId);
    }

@@ -196,12 +199,10 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
    }

    /** An implementation of {@link IDisplayWindowInsetsController} for a given display id. */
    public class PerDisplay {
    public class PerDisplay implements DisplayInsetsController.OnInsetsChangedListener {
        final int mDisplayId;
        final InsetsState mInsetsState = new InsetsState();
        final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
        protected final DisplayWindowInsetsControllerImpl mInsetsControllerImpl =
                new DisplayWindowInsetsControllerImpl();
        InsetsSourceControl mImeSourceControl = null;
        int mAnimationDirection = DIRECTION_NONE;
        ValueAnimator mAnimation = null;
@@ -216,14 +217,15 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
        }

        public void register() {
            try {
                mWmService.setDisplayWindowInsetsController(mDisplayId, mInsetsControllerImpl);
            } catch (RemoteException e) {
                Slog.w(TAG, "Unable to set insets controller on display " + mDisplayId);
            mDisplayInsetsController.addInsetsChangedListener(mDisplayId, this);
        }

        public void unregister() {
            mDisplayInsetsController.removeInsetsChangedListener(mDisplayId, this);
        }

        protected void insetsChanged(InsetsState insetsState) {
        @Override
        public void insetsChanged(InsetsState insetsState) {
            if (mInsetsState.equals(insetsState)) {
                return;
            }
@@ -241,8 +243,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
            }
        }

        @Override
        @VisibleForTesting
        protected void insetsControlChanged(InsetsState insetsState,
        public void insetsControlChanged(InsetsState insetsState,
                InsetsSourceControl[] activeControls) {
            insetsChanged(insetsState);
            InsetsSourceControl imeSourceControl = null;
@@ -303,7 +306,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
            }
        }

        protected void showInsets(int types, boolean fromIme) {
        @Override
        public void showInsets(int types, boolean fromIme) {
            if ((types & WindowInsets.Type.ime()) == 0) {
                return;
            }
@@ -311,8 +315,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
            startAnimation(true /* show */, false /* forceRestart */);
        }


        protected void hideInsets(int types, boolean fromIme) {
        @Override
        public void hideInsets(int types, boolean fromIme) {
            if ((types & WindowInsets.Type.ime()) == 0) {
                return;
            }
@@ -320,6 +324,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
            startAnimation(false /* show */, false /* forceRestart */);
        }

        @Override
        public void topFocusedWindowChanged(String packageName) {
            // Do nothing
        }
@@ -493,47 +498,6 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                dispatchVisibilityChanged(mDisplayId, isShowing);
            }
        }

        @VisibleForTesting
        @BinderThread
        public class DisplayWindowInsetsControllerImpl
                extends IDisplayWindowInsetsController.Stub {
            @Override
            public void topFocusedWindowChanged(String packageName) throws RemoteException {
                mMainExecutor.execute(() -> {
                    PerDisplay.this.topFocusedWindowChanged(packageName);
                });
            }

            @Override
            public void insetsChanged(InsetsState insetsState) throws RemoteException {
                mMainExecutor.execute(() -> {
                    PerDisplay.this.insetsChanged(insetsState);
                });
            }

            @Override
            public void insetsControlChanged(InsetsState insetsState,
                    InsetsSourceControl[] activeControls) throws RemoteException {
                mMainExecutor.execute(() -> {
                    PerDisplay.this.insetsControlChanged(insetsState, activeControls);
                });
            }

            @Override
            public void showInsets(int types, boolean fromIme) throws RemoteException {
                mMainExecutor.execute(() -> {
                    PerDisplay.this.showInsets(types, fromIme);
                });
            }

            @Override
            public void hideInsets(int types, boolean fromIme) throws RemoteException {
                mMainExecutor.execute(() -> {
                    PerDisplay.this.hideInsets(types, fromIme);
                });
            }
        }
    }

    void removeImeSurface() {
+265 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading