Merge "Move posting logic from PerDisplay to DisplayWIndowInsetsControllerImpl." into rvc-qpr-dev

This commit is contained in:
Youngjun Kwak
2021-03-05 22:39:32 +00:00
committed by Android (Google) Code Review
3 changed files with 136 additions and 80 deletions

View File

@@ -16,12 +16,14 @@
package com.android.systemui.wm; package com.android.systemui.wm;
import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.IDisplayWindowInsetsController; import android.view.IDisplayWindowInsetsController;
import android.view.IWindowManager;
import android.view.InsetsController; import android.view.InsetsController;
import android.view.InsetsSourceControl; import android.view.InsetsSourceControl;
import android.view.InsetsState; import android.view.InsetsState;
@@ -48,30 +50,32 @@ public class DisplaySystemBarsController extends DisplayImeController {
private static final String TAG = "DisplaySystemBarsController"; private static final String TAG = "DisplaySystemBarsController";
private final Context mContext;
private final Handler mHandler;
private SparseArray<PerDisplay> mPerDisplaySparseArray; private SparseArray<PerDisplay> mPerDisplaySparseArray;
@Inject @Inject
public DisplaySystemBarsController( public DisplaySystemBarsController(
SystemWindows syswin, Context context,
IWindowManager wmService,
DisplayController displayController, DisplayController displayController,
@Main Handler mainHandler, @Main Handler mainHandler,
TransactionPool transactionPool) { TransactionPool transactionPool) {
super(syswin, displayController, mainHandler, transactionPool); super(wmService, displayController, mainHandler::post, transactionPool);
mContext = context;
mHandler = mainHandler;
} }
@Override @Override
public void onDisplayAdded(int displayId) { public void onDisplayAdded(int displayId) {
PerDisplay pd = new PerDisplay(displayId); PerDisplay pd = new PerDisplay(displayId);
try { pd.register();
mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, pd);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to set insets controller on display " + displayId);
}
// Lazy loading policy control filters instead of during boot. // Lazy loading policy control filters instead of during boot.
if (mPerDisplaySparseArray == null) { if (mPerDisplaySparseArray == null) {
mPerDisplaySparseArray = new SparseArray<>(); mPerDisplaySparseArray = new SparseArray<>();
BarControlPolicy.reloadFromSetting(mSystemWindows.mContext); BarControlPolicy.reloadFromSetting(mContext);
BarControlPolicy.registerContentObserver(mSystemWindows.mContext, mHandler, () -> { BarControlPolicy.registerContentObserver(mContext, mHandler, () -> {
int size = mPerDisplaySparseArray.size(); int size = mPerDisplaySparseArray.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
mPerDisplaySparseArray.valueAt(i).modifyDisplayWindowInsets(); mPerDisplaySparseArray.valueAt(i).modifyDisplayWindowInsets();
@@ -84,7 +88,7 @@ public class DisplaySystemBarsController extends DisplayImeController {
@Override @Override
public void onDisplayRemoved(int displayId) { public void onDisplayRemoved(int displayId) {
try { try {
mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, null); mWmService.setDisplayWindowInsetsController(displayId, null);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Unable to remove insets controller on display " + displayId); Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
} }
@@ -100,11 +104,10 @@ public class DisplaySystemBarsController extends DisplayImeController {
String mPackageName; String mPackageName;
PerDisplay(int displayId) { PerDisplay(int displayId) {
super(displayId, super(displayId, mDisplayController.getDisplayLayout(displayId).rotation());
mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation());
mDisplayId = displayId; mDisplayId = displayId;
mInsetsController = new InsetsController( mInsetsController = new InsetsController(
new DisplaySystemBarsInsetsControllerHost(mHandler, this)); new DisplaySystemBarsInsetsControllerHost(mHandler, mInsetsControllerImpl));
} }
@Override @Override
@@ -166,7 +169,7 @@ public class DisplaySystemBarsController extends DisplayImeController {
showInsets(barVisibilities[0], /* fromIme= */ false); showInsets(barVisibilities[0], /* fromIme= */ false);
hideInsets(barVisibilities[1], /* fromIme= */ false); hideInsets(barVisibilities[1], /* fromIme= */ false);
try { try {
mSystemWindows.mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState); mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Unable to update window manager service."); Slog.w(TAG, "Unable to update window manager service.");
} }

View File

@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.car.settings.CarSettings; import android.car.settings.CarSettings;
import android.os.Handler; import android.os.Handler;
@@ -29,6 +30,7 @@ import android.provider.Settings;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper; import android.testing.TestableLooper;
import android.view.IWindowManager; import android.view.IWindowManager;
import android.view.Surface;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -60,15 +62,20 @@ public class DisplaySystemBarsControllerTest extends SysuiTestCase {
private Handler mHandler; private Handler mHandler;
@Mock @Mock
private TransactionPool mTransactionPool; private TransactionPool mTransactionPool;
@Mock
private DisplayLayout mDisplayLayout;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mSystemWindows.mContext = mContext; mSystemWindows.mContext = mContext;
mSystemWindows.mWmService = mIWindowManager; mSystemWindows.mWmService = mIWindowManager;
when(mDisplayLayout.rotation()).thenReturn(Surface.ROTATION_0);
when(mDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mDisplayLayout);
mController = new DisplaySystemBarsController( mController = new DisplaySystemBarsController(
mSystemWindows, mContext,
mIWindowManager,
mDisplayController, mDisplayController,
mHandler, mHandler,
mTransactionPool mTransactionPool
@@ -81,7 +88,8 @@ public class DisplaySystemBarsControllerTest extends SysuiTestCase {
mController.onDisplayAdded(DISPLAY_ID); mController.onDisplayAdded(DISPLAY_ID);
verify(mIWindowManager).setDisplayWindowInsetsController( verify(mIWindowManager).setDisplayWindowInsetsController(
eq(DISPLAY_ID), any(DisplaySystemBarsController.PerDisplay.class)); eq(DISPLAY_ID),
any(DisplayImeController.PerDisplay.DisplayWindowInsetsControllerImpl.class));
} }
@Test @Test

View File

@@ -24,12 +24,12 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.IDisplayWindowInsetsController; import android.view.IDisplayWindowInsetsController;
import android.view.IWindowManager;
import android.view.InsetsSource; import android.view.InsetsSource;
import android.view.InsetsSourceControl; import android.view.InsetsSourceControl;
import android.view.InsetsState; import android.view.InsetsState;
@@ -39,11 +39,15 @@ import android.view.WindowInsets;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator; import android.view.animation.PathInterpolator;
import androidx.annotation.BinderThread;
import androidx.annotation.VisibleForTesting;
import com.android.internal.view.IInputMethodManager; import com.android.internal.view.IInputMethodManager;
import com.android.systemui.TransactionPool; import com.android.systemui.TransactionPool;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -66,20 +70,22 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
private static final int DIRECTION_HIDE = 2; private static final int DIRECTION_HIDE = 2;
private static final int FLOATING_IME_BOTTOM_INSET = -80; private static final int FLOATING_IME_BOTTOM_INSET = -80;
SystemWindows mSystemWindows; protected final IWindowManager mWmService;
final Handler mHandler; protected final Executor mMainExecutor;
final TransactionPool mTransactionPool; final TransactionPool mTransactionPool;
final DisplayController mDisplayController;
final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>(); final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>(); final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();
@Inject @Inject
public DisplayImeController(SystemWindows syswin, DisplayController displayController, public DisplayImeController(IWindowManager wmService, DisplayController displayController,
@Main Handler mainHandler, TransactionPool transactionPool) { @Main Executor mainExecutor, TransactionPool transactionPool) {
mHandler = mainHandler; mWmService = wmService;
mSystemWindows = syswin; mMainExecutor = mainExecutor;
mTransactionPool = transactionPool; mTransactionPool = transactionPool;
mDisplayController = displayController;
displayController.addDisplayWindowListener(this); displayController.addDisplayWindowListener(this);
} }
@@ -88,12 +94,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
// Add's a system-ui window-manager specifically for ime. This type is special because // Add's a system-ui window-manager specifically for ime. This type is special because
// WM will defer IME inset handling to it in multi-window scenarious. // WM will defer IME inset handling to it in multi-window scenarious.
PerDisplay pd = new PerDisplay(displayId, PerDisplay pd = new PerDisplay(displayId,
mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation()); mDisplayController.getDisplayLayout(displayId).rotation());
try { pd.register();
mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, pd);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to set insets controller on display " + displayId);
}
mImePerDisplay.put(displayId, pd); mImePerDisplay.put(displayId, pd);
} }
@@ -103,7 +105,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
if (pd == null) { if (pd == null) {
return; return;
} }
if (mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation() if (mDisplayController.getDisplayLayout(displayId).rotation()
!= pd.mRotation && isImeShowing(displayId)) { != pd.mRotation && isImeShowing(displayId)) {
pd.startAnimation(true, false /* forceRestart */); pd.startAnimation(true, false /* forceRestart */);
} }
@@ -112,7 +114,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
@Override @Override
public void onDisplayRemoved(int displayId) { public void onDisplayRemoved(int displayId) {
try { try {
mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, null); mWmService.setDisplayWindowInsetsController(displayId, null);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Unable to remove insets controller on display " + displayId); Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
} }
@@ -180,9 +182,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
} }
} }
class PerDisplay extends IDisplayWindowInsetsController.Stub { /** An implementation of {@link IDisplayWindowInsetsController} for a given display id. */
public class PerDisplay {
final int mDisplayId; final int mDisplayId;
final InsetsState mInsetsState = new InsetsState(); final InsetsState mInsetsState = new InsetsState();
protected final DisplayWindowInsetsControllerImpl mInsetsControllerImpl =
new DisplayWindowInsetsControllerImpl();
InsetsSourceControl mImeSourceControl = null; InsetsSourceControl mImeSourceControl = null;
int mAnimationDirection = DIRECTION_NONE; int mAnimationDirection = DIRECTION_NONE;
ValueAnimator mAnimation = null; ValueAnimator mAnimation = null;
@@ -196,28 +201,32 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
mRotation = initialRotation; mRotation = initialRotation;
} }
@Override public void register() {
public void insetsChanged(InsetsState insetsState) { try {
mHandler.post(() -> { mWmService.setDisplayWindowInsetsController(mDisplayId, mInsetsControllerImpl);
if (mInsetsState.equals(insetsState)) { } catch (RemoteException e) {
return; Slog.w(TAG, "Unable to set insets controller on display " + mDisplayId);
} }
}
mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);
public void insetsChanged(InsetsState insetsState) {
final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME); if (mInsetsState.equals(insetsState)) {
final Rect newFrame = newSource.getFrame(); return;
final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame(); }
mInsetsState.set(insetsState, true /* copySources */); mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);
if (mImeShowing && !newFrame.equals(oldFrame) && newSource.isVisible()) {
if (DEBUG) Slog.d(TAG, "insetsChanged when IME showing, restart animation"); final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
startAnimation(mImeShowing, true /* forceRestart */); final Rect newFrame = newSource.getFrame();
} final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame();
});
mInsetsState.set(insetsState, true /* copySources */);
if (mImeShowing && !newFrame.equals(oldFrame) && newSource.isVisible()) {
if (DEBUG) Slog.d(TAG, "insetsChanged when IME showing, restart animation");
startAnimation(mImeShowing, true /* forceRestart */);
}
} }
@Override
public void insetsControlChanged(InsetsState insetsState, public void insetsControlChanged(InsetsState insetsState,
InsetsSourceControl[] activeControls) { InsetsSourceControl[] activeControls) {
insetsChanged(insetsState); insetsChanged(insetsState);
@@ -227,27 +236,25 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
continue; continue;
} }
if (activeControl.getType() == InsetsState.ITYPE_IME) { if (activeControl.getType() == InsetsState.ITYPE_IME) {
mHandler.post(() -> { final Point lastSurfacePosition = mImeSourceControl != null
final Point lastSurfacePosition = mImeSourceControl != null ? mImeSourceControl.getSurfacePosition() : null;
? mImeSourceControl.getSurfacePosition() : null; final boolean positionChanged =
final boolean positionChanged = !activeControl.getSurfacePosition().equals(lastSurfacePosition);
!activeControl.getSurfacePosition().equals(lastSurfacePosition); final boolean leashChanged =
final boolean leashChanged = !haveSameLeash(mImeSourceControl, activeControl);
!haveSameLeash(mImeSourceControl, activeControl); mImeSourceControl = activeControl;
mImeSourceControl = activeControl; if (mAnimation != null) {
if (mAnimation != null) { if (positionChanged) {
if (positionChanged) { startAnimation(mImeShowing, true /* forceRestart */);
startAnimation(mImeShowing, true /* forceRestart */);
}
} else {
if (leashChanged) {
applyVisibilityToLeash();
}
if (!mImeShowing) {
removeImeSurface();
}
} }
}); } else {
if (leashChanged) {
applyVisibilityToLeash();
}
if (!mImeShowing) {
removeImeSurface();
}
}
} }
} }
} }
@@ -267,25 +274,22 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
} }
} }
@Override
public void showInsets(int types, boolean fromIme) { public void showInsets(int types, boolean fromIme) {
if ((types & WindowInsets.Type.ime()) == 0) { if ((types & WindowInsets.Type.ime()) == 0) {
return; return;
} }
if (DEBUG) Slog.d(TAG, "Got showInsets for ime"); if (DEBUG) Slog.d(TAG, "Got showInsets for ime");
mHandler.post(() -> startAnimation(true /* show */, false /* forceRestart */)); startAnimation(true /* show */, false /* forceRestart */);
} }
@Override
public void hideInsets(int types, boolean fromIme) { public void hideInsets(int types, boolean fromIme) {
if ((types & WindowInsets.Type.ime()) == 0) { if ((types & WindowInsets.Type.ime()) == 0) {
return; return;
} }
if (DEBUG) Slog.d(TAG, "Got hideInsets for ime"); if (DEBUG) Slog.d(TAG, "Got hideInsets for ime");
mHandler.post(() -> startAnimation(false /* show */, false /* forceRestart */)); startAnimation(false /* show */, false /* forceRestart */);
} }
@Override
public void topFocusedWindowChanged(String packageName) { public void topFocusedWindowChanged(String packageName) {
// no-op // no-op
} }
@@ -296,7 +300,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
private void setVisibleDirectly(boolean visible) { private void setVisibleDirectly(boolean visible) {
mInsetsState.getSource(InsetsState.ITYPE_IME).setVisible(visible); mInsetsState.getSource(InsetsState.ITYPE_IME).setVisible(visible);
try { try {
mSystemWindows.mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState); mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -315,7 +319,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
// an IME inset). For now, we assume that no non-floating IME will be <= this nav bar // an IME inset). For now, we assume that no non-floating IME will be <= this nav bar
// frame height so any reported frame that is <= nav-bar frame height is assumed to // frame height so any reported frame that is <= nav-bar frame height is assumed to
// be floating. // be floating.
return frame.height() <= mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId) return frame.height() <= mDisplayController.getDisplayLayout(mDisplayId)
.navBarFrameHeight(); .navBarFrameHeight();
} }
@@ -331,7 +335,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
// pretend the ime has some size just below the screen. // pretend the ime has some size just below the screen.
mImeFrame.set(newFrame); mImeFrame.set(newFrame);
final int floatingInset = (int) ( final int floatingInset = (int) (
mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId).density() mDisplayController.getDisplayLayout(mDisplayId).density()
* FLOATING_IME_BOTTOM_INSET); * FLOATING_IME_BOTTOM_INSET);
mImeFrame.bottom -= floatingInset; mImeFrame.bottom -= floatingInset;
} else if (newFrame.height() != 0) { } else if (newFrame.height() != 0) {
@@ -448,6 +452,47 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
setVisibleDirectly(true /* visible */); setVisibleDirectly(true /* visible */);
} }
} }
@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() { void removeImeSurface() {