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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
mRotationListener.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a display rotation controller.
|
||||
*/
|
||||
public void removeRotationListener(OnDisplayChangingListener listener) {
|
||||
synchronized (mRotationListener) {
|
||||
mRotationListener.remove(listener);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
protected void insetsChanged(InsetsState insetsState) {
|
||||
public void unregister() {
|
||||
mDisplayInsetsController.removeInsetsChangedListener(mDisplayId, this);
|
||||
}
|
||||
|
||||
@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() {
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* 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 com.android.wm.shell.common;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.IDisplayWindowInsetsController;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
|
||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Manages insets from the core.
|
||||
*/
|
||||
public class DisplayInsetsController implements DisplayController.OnDisplaysChangedListener {
|
||||
private static final String TAG = "DisplayInsetsController";
|
||||
|
||||
private final IWindowManager mWmService;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final DisplayController mDisplayController;
|
||||
private final SparseArray<PerDisplay> mInsetsPerDisplay = new SparseArray<>();
|
||||
private final SparseArray<CopyOnWriteArrayList<OnInsetsChangedListener>> mListeners =
|
||||
new SparseArray<>();
|
||||
|
||||
public DisplayInsetsController(IWindowManager wmService, DisplayController displayController,
|
||||
ShellExecutor mainExecutor) {
|
||||
mWmService = wmService;
|
||||
mDisplayController = displayController;
|
||||
mMainExecutor = mainExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts listening for insets for each display.
|
||||
**/
|
||||
public void initialize() {
|
||||
mDisplayController.addDisplayWindowListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback to listen for insets changes for a particular display. Note that the
|
||||
* listener will not be updated with the existing state of the insets on that display.
|
||||
*/
|
||||
public void addInsetsChangedListener(int displayId, OnInsetsChangedListener listener) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(displayId);
|
||||
if (listeners == null) {
|
||||
listeners = new CopyOnWriteArrayList<>();
|
||||
mListeners.put(displayId, listeners);
|
||||
}
|
||||
if (!listeners.contains(listener)) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a callback listening for insets changes from a particular display.
|
||||
*/
|
||||
public void removeInsetsChangedListener(int displayId, OnInsetsChangedListener listener) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(displayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
PerDisplay pd = new PerDisplay(displayId);
|
||||
pd.register();
|
||||
mInsetsPerDisplay.put(displayId, pd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {
|
||||
PerDisplay pd = mInsetsPerDisplay.get(displayId);
|
||||
if (pd == null) {
|
||||
return;
|
||||
}
|
||||
pd.unregister();
|
||||
mInsetsPerDisplay.remove(displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of {@link IDisplayWindowInsetsController} for a given display id.
|
||||
**/
|
||||
public class PerDisplay {
|
||||
private final int mDisplayId;
|
||||
private final DisplayWindowInsetsControllerImpl mInsetsControllerImpl =
|
||||
new DisplayWindowInsetsControllerImpl();
|
||||
|
||||
public PerDisplay(int displayId) {
|
||||
mDisplayId = displayId;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
try {
|
||||
mWmService.setDisplayWindowInsetsController(mDisplayId, mInsetsControllerImpl);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Unable to set insets controller on display " + mDisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
try {
|
||||
mWmService.setDisplayWindowInsetsController(mDisplayId, null);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Unable to remove insets controller on display " + mDisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
private void insetsChanged(InsetsState insetsState) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
mDisplayController.updateDisplayInsets(mDisplayId, insetsState);
|
||||
for (OnInsetsChangedListener listener : listeners) {
|
||||
listener.insetsChanged(insetsState);
|
||||
}
|
||||
}
|
||||
|
||||
private void insetsControlChanged(InsetsState insetsState,
|
||||
InsetsSourceControl[] activeControls) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
for (OnInsetsChangedListener listener : listeners) {
|
||||
listener.insetsControlChanged(insetsState, activeControls);
|
||||
}
|
||||
}
|
||||
|
||||
private void showInsets(int types, boolean fromIme) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
for (OnInsetsChangedListener listener : listeners) {
|
||||
listener.showInsets(types, fromIme);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideInsets(int types, boolean fromIme) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
for (OnInsetsChangedListener listener : listeners) {
|
||||
listener.hideInsets(types, fromIme);
|
||||
}
|
||||
}
|
||||
|
||||
private void topFocusedWindowChanged(String packageName) {
|
||||
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
for (OnInsetsChangedListener listener : listeners) {
|
||||
listener.topFocusedWindowChanged(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
private 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified whenever the insets change.
|
||||
*
|
||||
* @see IDisplayWindowInsetsController
|
||||
*/
|
||||
@ShellMainThread
|
||||
public interface OnInsetsChangedListener {
|
||||
/**
|
||||
* Called when top focused window changes to determine whether or not to take over insets
|
||||
* control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false.
|
||||
* @param packageName: Passes the top package name
|
||||
*/
|
||||
void topFocusedWindowChanged(String packageName);
|
||||
|
||||
/**
|
||||
* Called when the window insets configuration has changed.
|
||||
*/
|
||||
void insetsChanged(InsetsState insetsState);
|
||||
|
||||
/**
|
||||
* Called when this window retrieved control over a specified set of insets sources.
|
||||
*/
|
||||
void insetsControlChanged(InsetsState insetsState,
|
||||
InsetsSourceControl[] activeControls);
|
||||
|
||||
/**
|
||||
* Called when a set of insets source window should be shown by policy.
|
||||
*
|
||||
* @param types internal insets types (WindowInsets.Type.InsetsType) to show
|
||||
* @param fromIme true if this request originated from IME (InputMethodService).
|
||||
*/
|
||||
void showInsets(int types, boolean fromIme);
|
||||
|
||||
/**
|
||||
* Called when a set of insets source window should be hidden by policy.
|
||||
*
|
||||
* @param types internal insets types (WindowInsets.Type.InsetsType) to hide
|
||||
* @param fromIme true if this request originated from IME (InputMethodService).
|
||||
*/
|
||||
void hideInsets(int types, boolean fromIme);
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON
|
||||
import static android.util.RotationUtils.rotateBounds;
|
||||
import static android.util.RotationUtils.rotateInsets;
|
||||
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
||||
import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
@@ -44,7 +45,10 @@ import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Gravity;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsState;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
@@ -85,6 +89,7 @@ public class DisplayLayout {
|
||||
private boolean mAllowSeamlessRotationDespiteNavBarMoving = false;
|
||||
private boolean mNavigationBarCanMove = false;
|
||||
private boolean mReverseDefaultRotation = false;
|
||||
private InsetsState mInsetsState = new InsetsState();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@@ -105,7 +110,8 @@ public class DisplayLayout {
|
||||
== other.mAllowSeamlessRotationDespiteNavBarMoving
|
||||
&& mNavigationBarCanMove == other.mNavigationBarCanMove
|
||||
&& mReverseDefaultRotation == other.mReverseDefaultRotation
|
||||
&& mNavBarFrameHeight == other.mNavBarFrameHeight;
|
||||
&& mNavBarFrameHeight == other.mNavBarFrameHeight
|
||||
&& Objects.equals(mInsetsState, other.mInsetsState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,7 +119,7 @@ public class DisplayLayout {
|
||||
return Objects.hash(mUiMode, mWidth, mHeight, mCutout, mRotation, mDensityDpi,
|
||||
mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar,
|
||||
mNavBarFrameHeight, mAllowSeamlessRotationDespiteNavBarMoving,
|
||||
mNavigationBarCanMove, mReverseDefaultRotation);
|
||||
mNavigationBarCanMove, mReverseDefaultRotation, mInsetsState);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,6 +170,7 @@ public class DisplayLayout {
|
||||
mNavBarFrameHeight = dl.mNavBarFrameHeight;
|
||||
mNonDecorInsets.set(dl.mNonDecorInsets);
|
||||
mStableInsets.set(dl.mStableInsets);
|
||||
mInsetsState.set(dl.mInsetsState, true /* copySources */);
|
||||
}
|
||||
|
||||
private void init(DisplayInfo info, Resources res, boolean hasNavigationBar,
|
||||
@@ -183,9 +190,17 @@ public class DisplayLayout {
|
||||
recalcInsets(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current insets.
|
||||
*/
|
||||
public void setInsets(Resources res, InsetsState state) {
|
||||
mInsetsState = state;
|
||||
recalcInsets(res);
|
||||
}
|
||||
|
||||
private void recalcInsets(Resources res) {
|
||||
computeNonDecorInsets(res, mRotation, mWidth, mHeight, mCutout, mUiMode, mNonDecorInsets,
|
||||
mHasNavigationBar);
|
||||
computeNonDecorInsets(res, mRotation, mWidth, mHeight, mCutout, mInsetsState, mUiMode,
|
||||
mNonDecorInsets, mHasNavigationBar);
|
||||
mStableInsets.set(mNonDecorInsets);
|
||||
if (mHasStatusBar) {
|
||||
convertNonDecorInsetsToStableInsets(res, mStableInsets, mWidth, mHeight, mHasStatusBar);
|
||||
@@ -259,7 +274,7 @@ public class DisplayLayout {
|
||||
return mWidth > mHeight;
|
||||
}
|
||||
|
||||
/** Get the navbar frame height (used by ime). */
|
||||
/** Get the navbar frame (or window) height (used by ime). */
|
||||
public int navBarFrameHeight() {
|
||||
return mNavBarFrameHeight;
|
||||
}
|
||||
@@ -328,21 +343,29 @@ public class DisplayLayout {
|
||||
* @param outInsets the insets to return
|
||||
*/
|
||||
static void computeNonDecorInsets(Resources res, int displayRotation, int displayWidth,
|
||||
int displayHeight, DisplayCutout displayCutout, int uiMode, Rect outInsets,
|
||||
boolean hasNavigationBar) {
|
||||
int displayHeight, DisplayCutout displayCutout, InsetsState insetsState, int uiMode,
|
||||
Rect outInsets, boolean hasNavigationBar) {
|
||||
outInsets.setEmpty();
|
||||
|
||||
// Only navigation bar
|
||||
if (hasNavigationBar) {
|
||||
final InsetsSource extraNavBar = insetsState.getSource(ITYPE_EXTRA_NAVIGATION_BAR);
|
||||
final boolean hasExtraNav = extraNavBar != null && extraNavBar.isVisible();
|
||||
int position = navigationBarPosition(res, displayWidth, displayHeight, displayRotation);
|
||||
int navBarSize =
|
||||
getNavigationBarSize(res, position, displayWidth > displayHeight, uiMode);
|
||||
if (position == NAV_BAR_BOTTOM) {
|
||||
outInsets.bottom = navBarSize;
|
||||
outInsets.bottom = hasExtraNav
|
||||
? Math.max(navBarSize, extraNavBar.getFrame().height())
|
||||
: navBarSize;
|
||||
} else if (position == NAV_BAR_RIGHT) {
|
||||
outInsets.right = navBarSize;
|
||||
outInsets.right = hasExtraNav
|
||||
? Math.max(navBarSize, extraNavBar.getFrame().width())
|
||||
: navBarSize;
|
||||
} else if (position == NAV_BAR_LEFT) {
|
||||
outInsets.left = navBarSize;
|
||||
outInsets.left = hasExtraNav
|
||||
? Math.max(navBarSize, extraNavBar.getFrame().width())
|
||||
: navBarSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,13 +387,13 @@ public class DisplayLayout {
|
||||
* @param outInsets the insets to return
|
||||
*/
|
||||
static void computeStableInsets(Resources res, int displayRotation, int displayWidth,
|
||||
int displayHeight, DisplayCutout displayCutout, int uiMode, Rect outInsets,
|
||||
boolean hasNavigationBar, boolean hasStatusBar) {
|
||||
int displayHeight, DisplayCutout displayCutout, InsetsState insetsState, int uiMode,
|
||||
Rect outInsets, boolean hasNavigationBar, boolean hasStatusBar) {
|
||||
outInsets.setEmpty();
|
||||
|
||||
// Navigation bar and status bar.
|
||||
computeNonDecorInsets(res, displayRotation, displayWidth, displayHeight, displayCutout,
|
||||
uiMode, outInsets, hasNavigationBar);
|
||||
insetsState, uiMode, outInsets, hasNavigationBar);
|
||||
convertNonDecorInsetsToStableInsets(res, outInsets, displayWidth, displayHeight,
|
||||
hasStatusBar);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class DisplayImeControllerTest {
|
||||
mT = mock(SurfaceControl.Transaction.class);
|
||||
mMock = mock(IInputMethodManager.class);
|
||||
mExecutor = spy(Runnable::run);
|
||||
mPerDisplay = new DisplayImeController(null, null, mExecutor, new TransactionPool() {
|
||||
mPerDisplay = new DisplayImeController(null, null, null, mExecutor, new TransactionPool() {
|
||||
@Override
|
||||
public SurfaceControl.Transaction acquire() {
|
||||
return mT;
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 com.android.wm.shell.common;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.SparseArray;
|
||||
import android.view.IDisplayWindowInsetsController;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.wm.shell.TestShellExecutor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
public class DisplayInsetsControllerTest {
|
||||
|
||||
private static final int SECOND_DISPLAY = DEFAULT_DISPLAY + 10;
|
||||
|
||||
@Mock
|
||||
private IWindowManager mWm;
|
||||
@Mock
|
||||
private DisplayController mDisplayController;
|
||||
private DisplayInsetsController mController;
|
||||
private SparseArray<IDisplayWindowInsetsController> mInsetsControllersByDisplayId;
|
||||
private TestShellExecutor mExecutor;
|
||||
|
||||
private ArgumentCaptor<Integer> mDisplayIdCaptor;
|
||||
private ArgumentCaptor<IDisplayWindowInsetsController> mInsetsControllerCaptor;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mExecutor = new TestShellExecutor();
|
||||
mInsetsControllersByDisplayId = new SparseArray<>();
|
||||
mDisplayIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||
mInsetsControllerCaptor = ArgumentCaptor.forClass(IDisplayWindowInsetsController.class);
|
||||
mController = new DisplayInsetsController(mWm, mDisplayController, mExecutor);
|
||||
addDisplay(DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnDisplayAdded_setsDisplayWindowInsetsControllerOnWMService()
|
||||
throws RemoteException {
|
||||
addDisplay(SECOND_DISPLAY);
|
||||
|
||||
verify(mWm).setDisplayWindowInsetsController(eq(SECOND_DISPLAY), notNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnDisplayRemoved_unsetsDisplayWindowInsetsControllerInWMService()
|
||||
throws RemoteException {
|
||||
addDisplay(SECOND_DISPLAY);
|
||||
removeDisplay(SECOND_DISPLAY);
|
||||
|
||||
verify(mWm).setDisplayWindowInsetsController(SECOND_DISPLAY, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerDisplayListenerCallback() throws RemoteException {
|
||||
TrackedListener defaultListener = new TrackedListener();
|
||||
TrackedListener secondListener = new TrackedListener();
|
||||
addDisplay(SECOND_DISPLAY);
|
||||
mController.addInsetsChangedListener(DEFAULT_DISPLAY, defaultListener);
|
||||
mController.addInsetsChangedListener(SECOND_DISPLAY, secondListener);
|
||||
|
||||
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).topFocusedWindowChanged(null);
|
||||
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).insetsChanged(null);
|
||||
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).insetsControlChanged(null, null);
|
||||
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).showInsets(0, false);
|
||||
mInsetsControllersByDisplayId.get(DEFAULT_DISPLAY).hideInsets(0, false);
|
||||
mExecutor.flushAll();
|
||||
|
||||
assertTrue(defaultListener.topFocusedWindowChangedCount == 1);
|
||||
assertTrue(defaultListener.insetsChangedCount == 1);
|
||||
assertTrue(defaultListener.insetsControlChangedCount == 1);
|
||||
assertTrue(defaultListener.showInsetsCount == 1);
|
||||
assertTrue(defaultListener.hideInsetsCount == 1);
|
||||
|
||||
assertTrue(secondListener.topFocusedWindowChangedCount == 0);
|
||||
assertTrue(secondListener.insetsChangedCount == 0);
|
||||
assertTrue(secondListener.insetsControlChangedCount == 0);
|
||||
assertTrue(secondListener.showInsetsCount == 0);
|
||||
assertTrue(secondListener.hideInsetsCount == 0);
|
||||
|
||||
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).topFocusedWindowChanged(null);
|
||||
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).insetsChanged(null);
|
||||
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).insetsControlChanged(null, null);
|
||||
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).showInsets(0, false);
|
||||
mInsetsControllersByDisplayId.get(SECOND_DISPLAY).hideInsets(0, false);
|
||||
mExecutor.flushAll();
|
||||
|
||||
assertTrue(defaultListener.topFocusedWindowChangedCount == 1);
|
||||
assertTrue(defaultListener.insetsChangedCount == 1);
|
||||
assertTrue(defaultListener.insetsControlChangedCount == 1);
|
||||
assertTrue(defaultListener.showInsetsCount == 1);
|
||||
assertTrue(defaultListener.hideInsetsCount == 1);
|
||||
|
||||
assertTrue(secondListener.topFocusedWindowChangedCount == 1);
|
||||
assertTrue(secondListener.insetsChangedCount == 1);
|
||||
assertTrue(secondListener.insetsControlChangedCount == 1);
|
||||
assertTrue(secondListener.showInsetsCount == 1);
|
||||
assertTrue(secondListener.hideInsetsCount == 1);
|
||||
}
|
||||
|
||||
private void addDisplay(int displayId) throws RemoteException {
|
||||
mController.onDisplayAdded(displayId);
|
||||
verify(mWm, times(mInsetsControllersByDisplayId.size() + 1))
|
||||
.setDisplayWindowInsetsController(mDisplayIdCaptor.capture(),
|
||||
mInsetsControllerCaptor.capture());
|
||||
List<Integer> displayIds = mDisplayIdCaptor.getAllValues();
|
||||
List<IDisplayWindowInsetsController> insetsControllers =
|
||||
mInsetsControllerCaptor.getAllValues();
|
||||
for (int i = 0; i < displayIds.size(); i++) {
|
||||
mInsetsControllersByDisplayId.put(displayIds.get(i), insetsControllers.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDisplay(int displayId) {
|
||||
mController.onDisplayRemoved(displayId);
|
||||
mInsetsControllersByDisplayId.remove(displayId);
|
||||
}
|
||||
|
||||
private static class TrackedListener implements
|
||||
DisplayInsetsController.OnInsetsChangedListener {
|
||||
int topFocusedWindowChangedCount = 0;
|
||||
int insetsChangedCount = 0;
|
||||
int insetsControlChangedCount = 0;
|
||||
int showInsetsCount = 0;
|
||||
int hideInsetsCount = 0;
|
||||
|
||||
@Override
|
||||
public void topFocusedWindowChanged(String packageName) {
|
||||
topFocusedWindowChangedCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insetsChanged(InsetsState insetsState) {
|
||||
insetsChangedCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insetsControlChanged(InsetsState insetsState,
|
||||
InsetsSourceControl[] activeControls) {
|
||||
insetsControlChangedCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showInsets(int types, boolean fromIme) {
|
||||
showInsetsCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideInsets(int types, boolean fromIme) {
|
||||
hideInsetsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -685,6 +685,7 @@ public class ShellTransitionTests {
|
||||
// No remote stuff happening, so this can't be hit
|
||||
}
|
||||
DisplayController out = new DisplayController(mContext, mockWM, mMainExecutor);
|
||||
out.initialize();
|
||||
try {
|
||||
displayListener[0].onDisplayAdded(DEFAULT_DISPLAY);
|
||||
mMainExecutor.flushAll();
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.systemui.dagger.WMSingleton;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
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.SyncTransactionQueue;
|
||||
import com.android.wm.shell.common.SystemWindows;
|
||||
@@ -58,10 +59,10 @@ public class TvWMShellModule {
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
|
||||
DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor,
|
||||
TransactionPool transactionPool) {
|
||||
return new DisplayImeController(wmService, displayController, mainExecutor,
|
||||
transactionPool);
|
||||
DisplayController displayController, DisplayInsetsController displayInsetsController,
|
||||
@ShellMainThread ShellExecutor mainExecutor, TransactionPool transactionPool) {
|
||||
return new DisplayImeController(wmService, displayController, displayInsetsController,
|
||||
mainExecutor, transactionPool);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.android.wm.shell.bubbles.BubbleController;
|
||||
import com.android.wm.shell.bubbles.Bubbles;
|
||||
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.DisplayLayout;
|
||||
import com.android.wm.shell.common.FloatingContentCoordinator;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
@@ -108,6 +109,14 @@ public abstract class WMShellBaseModule {
|
||||
return new DisplayController(context, wmService, mainExecutor);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static DisplayInsetsController provideDisplayInsetsController( IWindowManager wmService,
|
||||
DisplayController displayController,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new DisplayInsetsController(wmService, displayController, mainExecutor);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static DisplayLayout provideDisplayLayout() {
|
||||
@@ -452,7 +461,9 @@ public abstract class WMShellBaseModule {
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static ShellInitImpl provideShellInitImpl(DisplayImeController displayImeController,
|
||||
static ShellInitImpl provideShellInitImpl(DisplayController displayController,
|
||||
DisplayImeController displayImeController,
|
||||
DisplayInsetsController displayInsetsController,
|
||||
DragAndDropController dragAndDropController,
|
||||
ShellTaskOrganizer shellTaskOrganizer,
|
||||
Optional<BubbleController> bubblesOptional,
|
||||
@@ -465,7 +476,9 @@ public abstract class WMShellBaseModule {
|
||||
Transitions transitions,
|
||||
StartingWindowController startingWindow,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new ShellInitImpl(displayImeController,
|
||||
return new ShellInitImpl(displayController,
|
||||
displayImeController,
|
||||
displayInsetsController,
|
||||
dragAndDropController,
|
||||
shellTaskOrganizer,
|
||||
bubblesOptional,
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.wm.shell.WindowManagerShellWrapper;
|
||||
import com.android.wm.shell.apppairs.AppPairsController;
|
||||
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.FloatingContentCoordinator;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
@@ -83,10 +84,11 @@ public class WMShellModule {
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
|
||||
DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor,
|
||||
DisplayController displayController, DisplayInsetsController displayInsetsController,
|
||||
@ShellMainThread ShellExecutor mainExecutor,
|
||||
TransactionPool transactionPool) {
|
||||
return new DisplayImeController(wmService, displayController, mainExecutor,
|
||||
transactionPool);
|
||||
return new DisplayImeController(wmService, displayController, displayInsetsController,
|
||||
mainExecutor, transactionPool);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user