use of android.view.DisplayInfo in project android_frameworks_base by DirtyUnicorns.
the class DividerSnapAlgorithm method create.
public static DividerSnapAlgorithm create(Context ctx, Rect insets) {
DisplayInfo displayInfo = new DisplayInfo();
ctx.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(displayInfo);
int dividerWindowWidth = ctx.getResources().getDimensionPixelSize(com.android.internal.R.dimen.docked_stack_divider_thickness);
int dividerInsets = ctx.getResources().getDimensionPixelSize(com.android.internal.R.dimen.docked_stack_divider_insets);
return new DividerSnapAlgorithm(ctx.getResources(), displayInfo.logicalWidth, displayInfo.logicalHeight, dividerWindowWidth - 2 * dividerInsets, ctx.getApplicationContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT, insets);
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowState method computeFrameLw.
@Override
public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf) {
if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
// appears.
return;
}
mHaveFrame = true;
final Task task = getTask();
final boolean fullscreenTask = !isInMultiWindowMode();
final boolean windowsAreFloating = task != null && task.isFloating();
// window and the child window, making them misaligned.
if (fullscreenTask) {
mInsetFrame.setEmpty();
} else {
task.getTempInsetBounds(mInsetFrame);
}
// Denotes the actual frame used to calculate the insets and to perform the layout. When
// resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the
// insets temporarily. By the notion of a task having a different layout frame, we can
// achieve that while still moving the task around.
final Rect layoutContainingFrame;
final Rect layoutDisplayFrame;
// The offset from the layout containing frame to the actual containing frame.
final int layoutXDiff;
final int layoutYDiff;
if (fullscreenTask || layoutInParentFrame()) {
// We use the parent frame as the containing frame for fullscreen and child windows
mContainingFrame.set(pf);
mDisplayFrame.set(df);
layoutDisplayFrame = df;
layoutContainingFrame = pf;
layoutXDiff = 0;
layoutYDiff = 0;
} else {
task.getBounds(mContainingFrame);
if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) {
// If the bounds are frozen, we still want to translate the window freely and only
// freeze the size.
Rect frozen = mAppToken.mFrozenBounds.peek();
mContainingFrame.right = mContainingFrame.left + frozen.width();
mContainingFrame.bottom = mContainingFrame.top + frozen.height();
}
final WindowState imeWin = mService.mInputMethodWindow;
// IME is up and obscuring this window. Adjust the window position so it is visible.
if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) {
if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) {
// In freeform we want to move the top up directly.
// TODO: Investigate why this is cf not pf.
mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
} else if (mContainingFrame.bottom > pf.bottom) {
// But in docked we want to behave like fullscreen
// and behave as if the task were given smaller bounds
// for the purposes of layout.
mContainingFrame.bottom = pf.bottom;
}
}
if (windowsAreFloating) {
// "content frame" since it is allowed to be outside the visible desktop.
if (mContainingFrame.isEmpty()) {
mContainingFrame.set(cf);
}
}
mDisplayFrame.set(mContainingFrame);
layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0;
layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
mTmpRect.set(0, 0, mDisplayContent.getDisplayInfo().logicalWidth, mDisplayContent.getDisplayInfo().logicalHeight);
subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect);
if (!layoutInParentFrame()) {
subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect);
subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect);
}
layoutDisplayFrame = df;
layoutDisplayFrame.intersect(layoutContainingFrame);
}
final int pw = mContainingFrame.width();
final int ph = mContainingFrame.height();
if (!mParentFrame.equals(pf)) {
//Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
// + " to " + pf);
mParentFrame.set(pf);
mContentChanged = true;
}
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
mLastRequestedWidth = mRequestedWidth;
mLastRequestedHeight = mRequestedHeight;
mContentChanged = true;
}
mOverscanFrame.set(of);
mContentFrame.set(cf);
mVisibleFrame.set(vf);
mDecorFrame.set(dcf);
mStableFrame.set(sf);
final boolean hasOutsets = osf != null;
if (hasOutsets) {
mOutsetFrame.set(osf);
}
final int fw = mFrame.width();
final int fh = mFrame.height();
applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame);
// Calculate the outsets before the content frame gets shrinked to the window frame.
if (hasOutsets) {
mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0), Math.max(mContentFrame.top - mOutsetFrame.top, 0), Math.max(mOutsetFrame.right - mContentFrame.right, 0), Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0));
} else {
mOutsets.set(0, 0, 0, 0);
}
// final window frame.
if (windowsAreFloating && !mFrame.isEmpty()) {
// Keep the frame out of the blocked system area, limit it in size to the content area
// and make sure that there is always a minimum visible so that the user can drag it
// into a usable area..
final int height = Math.min(mFrame.height(), mContentFrame.height());
final int width = Math.min(mContentFrame.width(), mFrame.width());
final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
final int minVisibleHeight = Math.min(height, WindowManagerService.dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics));
final int minVisibleWidth = Math.min(width, WindowManagerService.dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics));
final int top = Math.max(mContentFrame.top, Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
final int left = Math.max(mContentFrame.left + minVisibleWidth - width, Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
mFrame.set(left, top, left + width, top + height);
mContentFrame.set(mFrame);
mVisibleFrame.set(mContentFrame);
mStableFrame.set(mContentFrame);
} else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
mContentFrame.set(mFrame);
if (!mFrame.equals(mLastFrame)) {
mMovedByResize = true;
}
} else {
mContentFrame.set(Math.max(mContentFrame.left, mFrame.left), Math.max(mContentFrame.top, mFrame.top), Math.min(mContentFrame.right, mFrame.right), Math.min(mContentFrame.bottom, mFrame.bottom));
mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left), Math.max(mVisibleFrame.top, mFrame.top), Math.min(mVisibleFrame.right, mFrame.right), Math.min(mVisibleFrame.bottom, mFrame.bottom));
mStableFrame.set(Math.max(mStableFrame.left, mFrame.left), Math.max(mStableFrame.top, mFrame.top), Math.min(mStableFrame.right, mFrame.right), Math.min(mStableFrame.bottom, mFrame.bottom));
}
if (fullscreenTask && !windowsAreFloating) {
// Windows that are not fullscreen can be positioned outside of the display frame,
// but that is not a reason to provide them with overscan insets.
mOverscanInsets.set(Math.max(mOverscanFrame.left - layoutContainingFrame.left, 0), Math.max(mOverscanFrame.top - layoutContainingFrame.top, 0), Math.max(layoutContainingFrame.right - mOverscanFrame.right, 0), Math.max(layoutContainingFrame.bottom - mOverscanFrame.bottom, 0));
}
if (mAttrs.type == TYPE_DOCK_DIVIDER) {
// For the docked divider, we calculate the stable insets like a full-screen window
// so it can use it to calculate the snap positions.
mStableInsets.set(Math.max(mStableFrame.left - mDisplayFrame.left, 0), Math.max(mStableFrame.top - mDisplayFrame.top, 0), Math.max(mDisplayFrame.right - mStableFrame.right, 0), Math.max(mDisplayFrame.bottom - mStableFrame.bottom, 0));
// The divider doesn't care about insets in any case, so set it to empty so we don't
// trigger a relayout when moving it.
mContentInsets.setEmpty();
mVisibleInsets.setEmpty();
} else {
getDisplayContent().getLogicalDisplayRect(mTmpRect);
// Override right and/or bottom insets in case if the frame doesn't fit the screen in
// non-fullscreen mode.
boolean overrideRightInset = !fullscreenTask && mFrame.right > mTmpRect.right;
boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom;
mContentInsets.set(mContentFrame.left - mFrame.left, mContentFrame.top - mFrame.top, overrideRightInset ? mTmpRect.right - mContentFrame.right : mFrame.right - mContentFrame.right, overrideBottomInset ? mTmpRect.bottom - mContentFrame.bottom : mFrame.bottom - mContentFrame.bottom);
mVisibleInsets.set(mVisibleFrame.left - mFrame.left, mVisibleFrame.top - mFrame.top, overrideRightInset ? mTmpRect.right - mVisibleFrame.right : mFrame.right - mVisibleFrame.right, overrideBottomInset ? mTmpRect.bottom - mVisibleFrame.bottom : mFrame.bottom - mVisibleFrame.bottom);
mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0), Math.max(mStableFrame.top - mFrame.top, 0), overrideRightInset ? Math.max(mTmpRect.right - mStableFrame.right, 0) : Math.max(mFrame.right - mStableFrame.right, 0), overrideBottomInset ? Math.max(mTmpRect.bottom - mStableFrame.bottom, 0) : Math.max(mFrame.bottom - mStableFrame.bottom, 0));
}
// Offset the actual frame by the amount layout frame is off.
mFrame.offset(-layoutXDiff, -layoutYDiff);
mCompatFrame.offset(-layoutXDiff, -layoutYDiff);
mContentFrame.offset(-layoutXDiff, -layoutYDiff);
mVisibleFrame.offset(-layoutXDiff, -layoutYDiff);
mStableFrame.offset(-layoutXDiff, -layoutYDiff);
mCompatFrame.set(mFrame);
if (mEnforceSizeCompat) {
// If there is a size compatibility scale being applied to the
// window, we need to apply this to its insets so that they are
// reported to the app in its coordinate space.
mOverscanInsets.scale(mInvGlobalScale);
mContentInsets.scale(mInvGlobalScale);
mVisibleInsets.scale(mInvGlobalScale);
mStableInsets.scale(mInvGlobalScale);
mOutsets.scale(mInvGlobalScale);
// Also the scaled frame that we report to the app needs to be
// adjusted to be in its coordinate space.
mCompatFrame.scale(mInvGlobalScale);
}
if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) {
final DisplayContent displayContent = getDisplayContent();
if (displayContent != null) {
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
mService.mWallpaperControllerLocked.updateWallpaperOffset(this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
}
}
if (DEBUG_LAYOUT || WindowManagerService.localLOGV)
Slog.v(TAG, "Resolving (mRequestedWidth=" + mRequestedWidth + ", mRequestedheight=" + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph + "): frame=" + mFrame.toShortString() + " ci=" + mContentInsets.toShortString() + " vi=" + mVisibleInsets.toShortString() + " si=" + mStableInsets.toShortString() + " of=" + mOutsets.toShortString());
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowState method getBackdropFrame.
Rect getBackdropFrame(Rect frame) {
// When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
// start even if we haven't received the relayout window, so that the client requests
// the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen
// until the window to small size, otherwise the multithread renderer will shift last
// one or more frame to wrong offset. So here we send fullscreen backdrop if either
// isDragResizing() or isDragResizeChanged() is true.
boolean resizing = isDragResizing() || isDragResizeChanged();
if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) {
return frame;
}
DisplayInfo displayInfo = getDisplayInfo();
mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
return mTmpRect;
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowStateAnimator method calculateSurfaceWindowCrop.
void calculateSurfaceWindowCrop(Rect clipRect, Rect finalClipRect) {
final WindowState w = mWin;
final DisplayContent displayContent = w.getDisplayContent();
if (displayContent == null) {
clipRect.setEmpty();
finalClipRect.setEmpty();
return;
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
if (DEBUG_WINDOW_CROP)
Slog.d(TAG, "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);
// Need to recompute a new system decor rect each time.
if (!w.isDefaultDisplay()) {
// On a different display there is no system decor. Crop the window
// by the screen boundaries.
mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top, displayInfo.logicalWidth - w.mCompatFrame.left, displayInfo.logicalHeight - w.mCompatFrame.top);
} else if (w.mLayer >= mService.mSystemDecorLayer) {
// Above the decor layer is easy, just use the entire window.
mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
} else if (w.mDecorFrame.isEmpty()) {
// Windows without policy decor aren't cropped.
mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
} else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.isAnimating()) {
// If we're animating, the wallpaper crop should only be updated at the end of the
// animation.
mTmpClipRect.set(mSystemDecorRect);
calculateSystemDecorRect();
mSystemDecorRect.union(mTmpClipRect);
} else {
// Crop to the system decor specified by policy.
calculateSystemDecorRect();
if (DEBUG_WINDOW_CROP)
Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame=" + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
}
final boolean fullscreen = w.isFrameFullscreen(displayInfo);
final boolean isFreeformResizing = w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
// We use the clip rect as provided by the tranformation for non-fullscreen windows to
// avoid premature clipping with the system decor rect.
clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : mSystemDecorRect);
if (DEBUG_WINDOW_CROP)
Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect + " mHasClipRect=" + mHasClipRect + " fullscreen=" + fullscreen);
if (isFreeformResizing && !w.isChildWindow()) {
// For freeform resizing non child windows, we are using the big surface positioned
// at 0,0. Thus we must express the crop in that coordinate space.
clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
}
// Expand the clip rect for surface insets.
final WindowManager.LayoutParams attrs = w.mAttrs;
clipRect.left -= attrs.surfaceInsets.left;
clipRect.top -= attrs.surfaceInsets.top;
clipRect.right += attrs.surfaceInsets.right;
clipRect.bottom += attrs.surfaceInsets.bottom;
if (mHasClipRect && fullscreen) {
// We intersect the clip rect specified by the transformation with the expanded system
// decor rect to prevent artifacts from drawing during animation if the transformation
// clip rect extends outside the system decor rect.
clipRect.intersect(mClipRect);
}
// The clip rect was generated assuming (0,0) as the window origin,
// so we need to translate to match the actual surface coordinates.
clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
finalClipRect.setEmpty();
adjustCropToStackBounds(w, clipRect, finalClipRect, isFreeformResizing);
if (DEBUG_WINDOW_CROP)
Slog.d(TAG, "win=" + w + " Clip rect after stack adjustment=" + clipRect);
w.transformClipRectFromScreenToSurfaceSpace(clipRect);
// See {@link WindowState#notifyMovedInStack} for why this is necessary.
if (w.hasJustMovedInStack() && mLastClipRect.isEmpty() && !clipRect.isEmpty()) {
clipRect.setEmpty();
}
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowStateAnimator method calculateSurfaceBounds.
private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) {
if ((attrs.flags & FLAG_SCALED) != 0) {
// For a scaled surface, we always want the requested size.
mTmpSize.right = mTmpSize.left + w.mRequestedWidth;
mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight;
} else {
// buffer drops due to size mismatch.
if (w.isDragResizing()) {
if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) {
mTmpSize.left = 0;
mTmpSize.top = 0;
}
final DisplayInfo displayInfo = w.getDisplayInfo();
mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth;
mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight;
} else {
mTmpSize.right = mTmpSize.left + w.mCompatFrame.width();
mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height();
}
}
// incorrect, because it is before the first layout or draw.
if (mTmpSize.width() < 1) {
mTmpSize.right = mTmpSize.left + 1;
}
if (mTmpSize.height() < 1) {
mTmpSize.bottom = mTmpSize.top + 1;
}
// Adjust for surface insets.
mTmpSize.left -= attrs.surfaceInsets.left;
mTmpSize.top -= attrs.surfaceInsets.top;
mTmpSize.right += attrs.surfaceInsets.right;
mTmpSize.bottom += attrs.surfaceInsets.bottom;
}
Aggregations