Loading services/core/java/com/android/server/wm/DockedStackDividerController.java +9 −0 Original line number Diff line number Diff line Loading @@ -85,9 +85,12 @@ public class DockedStackDividerController implements DimLayerUser { private static final long IME_ADJUST_DRAWN_TIMEOUT = 200; private static final int DIVIDER_WIDTH_INACTIVE_DP = 4; private final WindowManagerService mService; private final DisplayContent mDisplayContent; private int mDividerWindowWidth; private int mDividerWindowWidthInactive; private int mDividerInsets; private boolean mResizing; private WindowState mWindow; Loading Loading @@ -131,6 +134,8 @@ public class DockedStackDividerController implements DimLayerUser { com.android.internal.R.dimen.docked_stack_divider_thickness); mDividerInsets = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.docked_stack_divider_insets); mDividerWindowWidthInactive = WindowManagerService.dipToPixel( DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics()); } void onConfigurationChanged() { Loading @@ -149,6 +154,10 @@ public class DockedStackDividerController implements DimLayerUser { return mDividerInsets; } int getContentWidthInactive() { return mDividerWindowWidthInactive; } void setResizing(boolean resizing) { if (mResizing != resizing) { mResizing = resizing; Loading services/core/java/com/android/server/wm/TaskStack.java +52 −11 Original line number Diff line number Diff line Loading @@ -53,6 +53,12 @@ import java.util.ArrayList; public class TaskStack implements DimLayer.DimLayerUser, BoundsAnimationController.AnimateBoundsUser { /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to * restrict IME adjustment so that a min portion of top stack remains visible.*/ private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f; /** Dimming amount for non-focused stack when stacks are IME-adjusted. */ private static final float IME_ADJUST_DIM_AMOUNT = 0.25f; /** Unique identifier */ final int mStackId; Loading Loading @@ -249,7 +255,12 @@ public class TaskStack implements DimLayer.DimLayerUser, task.scrollLocked(mTmpRect2); } else if (task.isResizeable() && task.mOverrideConfig != Configuration.EMPTY) { task.getBounds(mTmpRect2); if (mAdjustedForIme && getDockSide() == DOCKED_TOP) { int offsetY = adjustedBounds.bottom - mTmpRect2.bottom; mTmpRect2.offset(0, offsetY); } else { mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top); } task.setTempInsetBounds(tempInsetBounds); task.resizeLocked(mTmpRect2, task.mOverrideConfig, false /* forced */); } Loading Loading @@ -882,6 +893,7 @@ public class TaskStack implements DimLayer.DimLayerUser, mImeGoingAway = false; mAdjustImeAmount = 0f; updateAdjustedBounds(); mService.setResizeDimLayer(false, mStackId, 1.0f); } else { mImeGoingAway |= mAdjustedForIme; } Loading Loading @@ -930,6 +942,11 @@ public class TaskStack implements DimLayer.DimLayerUser, } } int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) { return displayContentRect.top + (int) ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN); } private boolean adjustForIME(final WindowState imeWin) { final int dockedSide = getDockSide(); final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM; Loading @@ -953,23 +970,41 @@ public class TaskStack implements DimLayer.DimLayerUser, mLastContentBounds.set(contentBounds); final int yOffset = displayContentRect.bottom - contentBounds.bottom; final int dividerWidth = getDisplayContent().mDividerControllerLocked.getContentWidth(); final int dividerWidthInactive = getDisplayContent().mDividerControllerLocked.getContentWidthInactive(); if (dockedSide == DOCKED_TOP) { // If this stack is docked on top, we make it smaller so the bottom stack is not // occluded by IME. We shift its bottom up by the height of the IME (capped by // the display content rect). Note that we don't change the task bounds. int bottom = Math.max( mBounds.bottom - yOffset, displayContentRect.top); // occluded by IME. We shift its bottom up by the height of the IME, but // leaves at least 30% of the top stack visible. final int minTopStackBottom = getMinTopStackBottom(displayContentRect, mBounds.bottom); final int bottom = Math.max( mBounds.bottom - yOffset + dividerWidth - dividerWidthInactive, minTopStackBottom); mTmpAdjustedBounds.set(mBounds); mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount) * mBounds.bottom); mFullyAdjustedImeBounds.set(mBounds); } else { // If this stack is docked on bottom, we shift it up so that it's not occluded by // IME. We try to move it up by the height of the IME window (although the best // we could do is to make the top stack fully collapsed). final int dividerWidth = getDisplayContent().mDividerControllerLocked .getContentWidth(); int top = Math.max(mBounds.top - yOffset, displayContentRect.top + dividerWidth); final int top; final boolean isFocusedStack = mService.getFocusedStackLocked() == this; if (isFocusedStack) { // If this stack is docked on bottom and has focus, we shift it up so that it's not // occluded by IME. We try to move it up by the height of the IME window, but only // to the extent that leaves at least 30% of the top stack visible. final int minTopStackBottom = getMinTopStackBottom(displayContentRect, mBounds.top - dividerWidth); top = Math.max( mBounds.top - yOffset, minTopStackBottom + dividerWidthInactive); } else { // If this stack is docked on bottom but doesn't have focus, we don't need to adjust // for IME, but still need to apply a small adjustment due to the thinner divider. top = mBounds.top - dividerWidth + dividerWidthInactive; } mTmpAdjustedBounds.set(mBounds); mTmpAdjustedBounds.top = (int) (mAdjustImeAmount * top + (1 - mAdjustImeAmount) * mBounds.top); Loading Loading @@ -1043,6 +1078,12 @@ public class TaskStack implements DimLayer.DimLayerUser, mLastContentBounds.setEmpty(); } setAdjustedBounds(mTmpAdjustedBounds); final boolean isFocusedStack = mService.getFocusedStackLocked() == this; if (mAdjustedForIme && adjust && !isFocusedStack) { final float alpha = mAdjustImeAmount * IME_ADJUST_DIM_AMOUNT; mService.setResizeDimLayer(true, mStackId, alpha); } } boolean isAdjustedForMinimizedDockedStack() { Loading services/core/java/com/android/server/wm/WindowManagerService.java +25 −6 Original line number Diff line number Diff line Loading @@ -7445,17 +7445,16 @@ public class WindowManagerService extends IWindowManager.Stub void adjustForImeIfNeeded(final DisplayContent displayContent) { final WindowState imeWin = mInputMethodWindow; final TaskStack focusedStack = mCurrentFocus != null ? mCurrentFocus.getStack() : null; final TaskStack focusedStack = getFocusedStackLocked(); final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID); if (imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw() && dockVisible && focusedStack != null && focusedStack.getDockSide() == DOCKED_BOTTOM){ && dockVisible && focusedStack != null) { final boolean isFocusOnBottom = focusedStack.getDockSide() == DOCKED_BOTTOM; final ArrayList<TaskStack> stacks = displayContent.getStacks(); for (int i = stacks.size() - 1; i >= 0; --i) { final TaskStack stack = stacks.get(i); if (stack.isVisibleLocked()) { final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM; if (stack.isVisibleLocked() && (isFocusOnBottom || isDockedOnBottom)) { stack.setAdjustedForIme(imeWin); } } Loading Loading @@ -7599,6 +7598,10 @@ public class WindowManagerService extends IWindowManager.Stub return mCurrentFocus; } TaskStack getFocusedStackLocked() { return mCurrentFocus != null ? mCurrentFocus.getStack() : null; } private void showAuditSafeModeNotification() { PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_VIEW, Loading Loading @@ -9339,6 +9342,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState newFocus = computeFocusedWindowLocked(); if (mCurrentFocus != newFocus) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus"); TaskStack oldFocusedStack = getFocusedStackLocked(); // This check makes sure that we don't already have the focus // change message pending. mH.removeMessages(H.REPORT_FOCUS_CHANGE); Loading @@ -9360,6 +9364,7 @@ public class WindowManagerService extends IWindowManager.Stub mLosingFocus.remove(newFocus); int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); TaskStack newFocusedStack = getFocusedStackLocked(); if (imWindowChanged && oldFocus != mInputMethodWindow) { // Focus of the input method window changed. Perform layout if needed. Loading Loading @@ -9389,6 +9394,20 @@ public class WindowManagerService extends IWindowManager.Stub mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows); } // TODO: Reset and re-apply IME adjustment if needed when stack focus changed. // This makes sure divider starts an animation from pre-adjust position to final // position. Ideally we want to skip the reset and animation from current position // directly to final position. final WindowState imeWin = mInputMethodWindow; if (oldFocusedStack != null) { oldFocusedStack.resetAdjustedForIme(true); } if (newFocusedStack != null) { newFocusedStack.resetAdjustedForIme(true); } displayContent.mDividerControllerLocked.setAdjustedForIme(false, false, imeWin); adjustForImeIfNeeded(displayContent); Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); return true; } Loading Loading
services/core/java/com/android/server/wm/DockedStackDividerController.java +9 −0 Original line number Diff line number Diff line Loading @@ -85,9 +85,12 @@ public class DockedStackDividerController implements DimLayerUser { private static final long IME_ADJUST_DRAWN_TIMEOUT = 200; private static final int DIVIDER_WIDTH_INACTIVE_DP = 4; private final WindowManagerService mService; private final DisplayContent mDisplayContent; private int mDividerWindowWidth; private int mDividerWindowWidthInactive; private int mDividerInsets; private boolean mResizing; private WindowState mWindow; Loading Loading @@ -131,6 +134,8 @@ public class DockedStackDividerController implements DimLayerUser { com.android.internal.R.dimen.docked_stack_divider_thickness); mDividerInsets = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.docked_stack_divider_insets); mDividerWindowWidthInactive = WindowManagerService.dipToPixel( DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics()); } void onConfigurationChanged() { Loading @@ -149,6 +154,10 @@ public class DockedStackDividerController implements DimLayerUser { return mDividerInsets; } int getContentWidthInactive() { return mDividerWindowWidthInactive; } void setResizing(boolean resizing) { if (mResizing != resizing) { mResizing = resizing; Loading
services/core/java/com/android/server/wm/TaskStack.java +52 −11 Original line number Diff line number Diff line Loading @@ -53,6 +53,12 @@ import java.util.ArrayList; public class TaskStack implements DimLayer.DimLayerUser, BoundsAnimationController.AnimateBoundsUser { /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to * restrict IME adjustment so that a min portion of top stack remains visible.*/ private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f; /** Dimming amount for non-focused stack when stacks are IME-adjusted. */ private static final float IME_ADJUST_DIM_AMOUNT = 0.25f; /** Unique identifier */ final int mStackId; Loading Loading @@ -249,7 +255,12 @@ public class TaskStack implements DimLayer.DimLayerUser, task.scrollLocked(mTmpRect2); } else if (task.isResizeable() && task.mOverrideConfig != Configuration.EMPTY) { task.getBounds(mTmpRect2); if (mAdjustedForIme && getDockSide() == DOCKED_TOP) { int offsetY = adjustedBounds.bottom - mTmpRect2.bottom; mTmpRect2.offset(0, offsetY); } else { mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top); } task.setTempInsetBounds(tempInsetBounds); task.resizeLocked(mTmpRect2, task.mOverrideConfig, false /* forced */); } Loading Loading @@ -882,6 +893,7 @@ public class TaskStack implements DimLayer.DimLayerUser, mImeGoingAway = false; mAdjustImeAmount = 0f; updateAdjustedBounds(); mService.setResizeDimLayer(false, mStackId, 1.0f); } else { mImeGoingAway |= mAdjustedForIme; } Loading Loading @@ -930,6 +942,11 @@ public class TaskStack implements DimLayer.DimLayerUser, } } int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) { return displayContentRect.top + (int) ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN); } private boolean adjustForIME(final WindowState imeWin) { final int dockedSide = getDockSide(); final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM; Loading @@ -953,23 +970,41 @@ public class TaskStack implements DimLayer.DimLayerUser, mLastContentBounds.set(contentBounds); final int yOffset = displayContentRect.bottom - contentBounds.bottom; final int dividerWidth = getDisplayContent().mDividerControllerLocked.getContentWidth(); final int dividerWidthInactive = getDisplayContent().mDividerControllerLocked.getContentWidthInactive(); if (dockedSide == DOCKED_TOP) { // If this stack is docked on top, we make it smaller so the bottom stack is not // occluded by IME. We shift its bottom up by the height of the IME (capped by // the display content rect). Note that we don't change the task bounds. int bottom = Math.max( mBounds.bottom - yOffset, displayContentRect.top); // occluded by IME. We shift its bottom up by the height of the IME, but // leaves at least 30% of the top stack visible. final int minTopStackBottom = getMinTopStackBottom(displayContentRect, mBounds.bottom); final int bottom = Math.max( mBounds.bottom - yOffset + dividerWidth - dividerWidthInactive, minTopStackBottom); mTmpAdjustedBounds.set(mBounds); mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount) * mBounds.bottom); mFullyAdjustedImeBounds.set(mBounds); } else { // If this stack is docked on bottom, we shift it up so that it's not occluded by // IME. We try to move it up by the height of the IME window (although the best // we could do is to make the top stack fully collapsed). final int dividerWidth = getDisplayContent().mDividerControllerLocked .getContentWidth(); int top = Math.max(mBounds.top - yOffset, displayContentRect.top + dividerWidth); final int top; final boolean isFocusedStack = mService.getFocusedStackLocked() == this; if (isFocusedStack) { // If this stack is docked on bottom and has focus, we shift it up so that it's not // occluded by IME. We try to move it up by the height of the IME window, but only // to the extent that leaves at least 30% of the top stack visible. final int minTopStackBottom = getMinTopStackBottom(displayContentRect, mBounds.top - dividerWidth); top = Math.max( mBounds.top - yOffset, minTopStackBottom + dividerWidthInactive); } else { // If this stack is docked on bottom but doesn't have focus, we don't need to adjust // for IME, but still need to apply a small adjustment due to the thinner divider. top = mBounds.top - dividerWidth + dividerWidthInactive; } mTmpAdjustedBounds.set(mBounds); mTmpAdjustedBounds.top = (int) (mAdjustImeAmount * top + (1 - mAdjustImeAmount) * mBounds.top); Loading Loading @@ -1043,6 +1078,12 @@ public class TaskStack implements DimLayer.DimLayerUser, mLastContentBounds.setEmpty(); } setAdjustedBounds(mTmpAdjustedBounds); final boolean isFocusedStack = mService.getFocusedStackLocked() == this; if (mAdjustedForIme && adjust && !isFocusedStack) { final float alpha = mAdjustImeAmount * IME_ADJUST_DIM_AMOUNT; mService.setResizeDimLayer(true, mStackId, alpha); } } boolean isAdjustedForMinimizedDockedStack() { Loading
services/core/java/com/android/server/wm/WindowManagerService.java +25 −6 Original line number Diff line number Diff line Loading @@ -7445,17 +7445,16 @@ public class WindowManagerService extends IWindowManager.Stub void adjustForImeIfNeeded(final DisplayContent displayContent) { final WindowState imeWin = mInputMethodWindow; final TaskStack focusedStack = mCurrentFocus != null ? mCurrentFocus.getStack() : null; final TaskStack focusedStack = getFocusedStackLocked(); final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID); if (imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw() && dockVisible && focusedStack != null && focusedStack.getDockSide() == DOCKED_BOTTOM){ && dockVisible && focusedStack != null) { final boolean isFocusOnBottom = focusedStack.getDockSide() == DOCKED_BOTTOM; final ArrayList<TaskStack> stacks = displayContent.getStacks(); for (int i = stacks.size() - 1; i >= 0; --i) { final TaskStack stack = stacks.get(i); if (stack.isVisibleLocked()) { final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM; if (stack.isVisibleLocked() && (isFocusOnBottom || isDockedOnBottom)) { stack.setAdjustedForIme(imeWin); } } Loading Loading @@ -7599,6 +7598,10 @@ public class WindowManagerService extends IWindowManager.Stub return mCurrentFocus; } TaskStack getFocusedStackLocked() { return mCurrentFocus != null ? mCurrentFocus.getStack() : null; } private void showAuditSafeModeNotification() { PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_VIEW, Loading Loading @@ -9339,6 +9342,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState newFocus = computeFocusedWindowLocked(); if (mCurrentFocus != newFocus) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus"); TaskStack oldFocusedStack = getFocusedStackLocked(); // This check makes sure that we don't already have the focus // change message pending. mH.removeMessages(H.REPORT_FOCUS_CHANGE); Loading @@ -9360,6 +9364,7 @@ public class WindowManagerService extends IWindowManager.Stub mLosingFocus.remove(newFocus); int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); TaskStack newFocusedStack = getFocusedStackLocked(); if (imWindowChanged && oldFocus != mInputMethodWindow) { // Focus of the input method window changed. Perform layout if needed. Loading Loading @@ -9389,6 +9394,20 @@ public class WindowManagerService extends IWindowManager.Stub mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows); } // TODO: Reset and re-apply IME adjustment if needed when stack focus changed. // This makes sure divider starts an animation from pre-adjust position to final // position. Ideally we want to skip the reset and animation from current position // directly to final position. final WindowState imeWin = mInputMethodWindow; if (oldFocusedStack != null) { oldFocusedStack.resetAdjustedForIme(true); } if (newFocusedStack != null) { newFocusedStack.resetAdjustedForIme(true); } displayContent.mDividerControllerLocked.setAdjustedForIme(false, false, imeWin); adjustForImeIfNeeded(displayContent); Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); return true; } Loading