use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowStateAnimator method calculateSystemDecorRect.
private void calculateSystemDecorRect() {
final WindowState w = mWin;
final Rect decorRect = w.mDecorFrame;
final int width = w.mFrame.width();
final int height = w.mFrame.height();
// Compute the offset of the window in relation to the decor rect.
final int left = w.mXOffset + w.mFrame.left;
final int top = w.mYOffset + w.mFrame.top;
// Initialize the decor rect to the entire frame.
if (w.isDockedResizing() || (w.isChildWindow() && w.mAttachedWindow.isDockedResizing())) {
// If we are resizing with the divider, the task bounds might be smaller than the
// stack bounds. The system decor is used to clip to the task bounds, which we don't
// want in this case in order to avoid holes.
//
// We take care to not shrink the width, for surfaces which are larger than
// the display region. Of course this area will not eventually be visible
// but if we truncate the width now, we will calculate incorrectly
// when adjusting to the stack bounds.
final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
mSystemDecorRect.set(0, 0, Math.max(width, displayInfo.logicalWidth), Math.max(height, displayInfo.logicalHeight));
} else {
mSystemDecorRect.set(0, 0, width, height);
}
// If a freeform window is animating from a position where it would be cutoff, it would be
// cutoff during the animation. We don't want that, so for the duration of the animation
// we ignore the decor cropping and depend on layering to position windows correctly.
final boolean cropToDecor = !(w.inFreeformWorkspace() && w.isAnimatingLw());
if (cropToDecor) {
// Intersect with the decor rect, offsetted by window position.
mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top, decorRect.right - left, decorRect.bottom - top);
}
// much and hide part of the window that should be seen.
if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
final float scale = w.mInvGlobalScale;
mSystemDecorRect.left = (int) (mSystemDecorRect.left * scale - 0.5f);
mSystemDecorRect.top = (int) (mSystemDecorRect.top * scale - 0.5f);
mSystemDecorRect.right = (int) ((mSystemDecorRect.right + 1) * scale - 0.5f);
mSystemDecorRect.bottom = (int) ((mSystemDecorRect.bottom + 1) * scale - 0.5f);
}
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowSurfacePlacer method createThumbnailAppAnimator.
private void createThumbnailAppAnimator(int transit, AppWindowToken appToken, int openingLayer, int closingLayer) {
AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
if (openingAppAnimator == null || openingAppAnimator.animation == null) {
return;
}
final int taskId = appToken.mTask.mTaskId;
Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
if (DEBUG_APP_TRANSITIONS)
Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
return;
}
// This thumbnail animation is very special, we need to have
// an extra surface with the thumbnail included with the animation.
Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
try {
// TODO(multi-display): support other displays
final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
final Display display = displayContent.getDisplay();
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
// Create a new surface for the thumbnail
SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession, "thumbnail anim", dirty.width(), dirty.height(), PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
surfaceControl.setLayerStack(display.getLayerStack());
if (SHOW_TRANSACTIONS) {
Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
}
// Draw the thumbnail onto the surface
Surface drawSurface = new Surface();
drawSurface.copyFrom(surfaceControl);
Canvas c = drawSurface.lockCanvas(dirty);
c.drawBitmap(thumbnailHeader, 0, 0, null);
drawSurface.unlockCanvasAndPost(c);
drawSurface.release();
// Get the thumbnail animation
Animation anim;
if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
// If this is a multi-window scenario, we use the windows frame as
// destination of the thumbnail header animation. If this is a full screen
// window scenario, we use the whole display as the target.
WindowState win = appToken.findMainWindow();
Rect appRect = win != null ? win.getContentFrameLw() : new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Rect insets = win != null ? win.mContentInsets : null;
// For the new aspect-scaled transition, we want it to always show
// above the animating opening/closing window, and we want to
// synchronize its thumbnail surface with the surface for the
// open/close animation (only on the way down)
anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect, insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode, mService.mCurConfiguration.orientation);
openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
openingAppAnimator.deferThumbnailDestruction = !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
} else {
anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
}
anim.restrictDuration(MAX_ANIMATION_DURATION);
anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
openingAppAnimator.thumbnail = surfaceControl;
openingAppAnimator.thumbnailLayer = openingLayer;
openingAppAnimator.thumbnailAnimation = anim;
mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
} catch (Surface.OutOfResourcesException e) {
Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width() + " h=" + dirty.height(), e);
openingAppAnimator.clearThumbnail();
}
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowSurfacePlacer method performLayoutLockedInner.
final void performLayoutLockedInner(final DisplayContent displayContent, boolean initial, boolean updateInputWindows) {
if (!displayContent.layoutNeeded) {
return;
}
displayContent.layoutNeeded = false;
WindowList windows = displayContent.getWindowList();
boolean isDefaultDisplay = displayContent.isDefaultDisplay;
DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
if (mService.mInputConsumer != null) {
mService.mInputConsumer.layout(dw, dh);
}
if (mService.mWallpaperInputConsumer != null) {
mService.mWallpaperInputConsumer.layout(dw, dh);
}
final int N = windows.size();
int i;
if (DEBUG_LAYOUT) {
Slog.v(TAG, "-------------------------------------");
Slog.v(TAG, "performLayout: needed=" + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
}
mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation, mService.mCurConfiguration.uiMode);
if (isDefaultDisplay) {
// Not needed on non-default displays.
mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
mService.mScreenRect.set(0, 0, dw, dh);
}
mService.mPolicy.getContentRectLw(mTmpContentRect);
displayContent.resize(mTmpContentRect);
int seq = mService.mLayoutSeq + 1;
if (seq < 0)
seq = 0;
mService.mLayoutSeq = seq;
boolean behindDream = false;
// First perform layout of any root windows (not attached
// to another window).
int topAttached = -1;
for (i = N - 1; i >= 0; i--) {
final WindowState win = windows.get(i);
// Don't do layout of a window if it is not visible, or
// soon won't be visible, to avoid wasting time and funky
// changes while a window is animating away.
final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) || win.isGoneForLayoutLw();
if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame + " mLayoutAttached=" + win.mLayoutAttached + " screen changed=" + win.isConfigChanged());
final AppWindowToken atoken = win.mAppToken;
if (gone)
Slog.v(TAG, " GONE: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mRootToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " mAttachedHidden=" + win.mAttachedHidden);
else
Slog.v(TAG, " VIS: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mRootToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " mAttachedHidden=" + win.mAttachedHidden);
}
// just don't display").
if (!gone || !win.mHaveFrame || win.mLayoutNeeded || ((win.isConfigChanged() || win.setReportResizeHints()) && !win.isGoneForLayoutLw() && ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || (win.mHasSurface && win.mAppToken != null && win.mAppToken.layoutConfigChanges)))) {
if (!win.mLayoutAttached) {
if (initial) {
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
if (win.mAttrs.type == TYPE_DREAM) {
// Don't layout windows behind a dream, so that if it
// does stuff like hide the status bar we won't get a
// bad transition when it goes away.
behindDream = true;
}
win.mLayoutNeeded = false;
win.prelayout();
mService.mPolicy.layoutWindowLw(win, null);
win.mLayoutSeq = seq;
// Window frames may have changed. Update dim layer with the new bounds.
final Task task = win.getTask();
if (task != null) {
displayContent.mDimLayerController.updateDimLayer(task);
}
if (DEBUG_LAYOUT)
Slog.v(TAG, " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame=" + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
} else {
if (topAttached < 0)
topAttached = i;
}
}
}
boolean attachedBehindDream = false;
// that are themselves attached.
for (i = topAttached; i >= 0; i--) {
final WindowState win = windows.get(i);
if (win.mLayoutAttached) {
if (DEBUG_LAYOUT)
Slog.v(TAG, "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
// just don't display").
if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
continue;
}
if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled) || !win.mHaveFrame || win.mLayoutNeeded) {
if (initial) {
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
win.mLayoutNeeded = false;
win.prelayout();
mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
win.mLayoutSeq = seq;
if (DEBUG_LAYOUT)
Slog.v(TAG, " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame=" + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
}
} else if (win.mAttrs.type == TYPE_DREAM) {
// Don't layout windows behind a dream, so that if it
// does stuff like hide the status bar we won't get a
// bad transition when it goes away.
attachedBehindDream = behindDream;
}
}
// Window frames may have changed. Tell the input dispatcher about it.
mService.mInputMonitor.setUpdateInputWindowsNeededLw();
if (updateInputWindows) {
mService.mInputMonitor.updateInputWindowsLw(false);
}
mService.mPolicy.finishLayoutLw();
mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WallpaperController method updateWallpaperWindowsPlacement.
boolean updateWallpaperWindowsPlacement(WindowList windows, WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
// TODO(multidisplay): Wallpapers on main screen only.
final DisplayInfo displayInfo = mService.getDefaultDisplayContentLocked().getDisplayInfo();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
// Start stepping backwards from here, ensuring that our wallpaper windows
// are correctly placed.
boolean changed = false;
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
WindowToken token = mWallpaperTokens.get(curTokenNdx);
if (token.hidden == visible) {
if (DEBUG_WALLPAPER_LIGHT)
Slog.d(TAG, "Wallpaper token " + token + " hidden=" + !visible);
token.hidden = !visible;
// Need to do a layout to ensure the wallpaper now has the correct size.
mService.getDefaultDisplayContentLocked().layoutNeeded = true;
}
final WindowList tokenWindows = token.windows;
for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
WindowState wallpaper = tokenWindows.get(wallpaperNdx);
if (visible) {
updateWallpaperOffset(wallpaper, dw, dh, false);
}
// First, make sure the client has the current visibility state.
dispatchWallpaperVisibility(wallpaper, visible);
wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT)
Slog.v(TAG, "adjustWallpaper win " + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
// First, if this window is at the current index, then all is well.
if (wallpaper == wallpaperTarget) {
wallpaperTargetIndex--;
wallpaperTarget = wallpaperTargetIndex > 0 ? windows.get(wallpaperTargetIndex - 1) : null;
continue;
}
// The window didn't match... the current wallpaper window,
// wherever it is, is in the wrong place, so make sure it is not in the list.
int oldIndex = windows.indexOf(wallpaper);
if (oldIndex >= 0) {
if (DEBUG_WINDOW_MOVEMENT)
Slog.v(TAG, "Wallpaper removing at " + oldIndex + ": " + wallpaper);
windows.remove(oldIndex);
mService.mWindowsChanged = true;
if (oldIndex < wallpaperTargetIndex) {
wallpaperTargetIndex--;
}
}
// Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
// layer. For keyguard over wallpaper put the wallpaper under the lowest window that
// is currently on screen, i.e. not hidden by policy.
int insertionIndex = 0;
if (visible && wallpaperTarget != null) {
final int type = wallpaperTarget.mAttrs.type;
final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || type == TYPE_KEYGUARD_SCRIM) {
insertionIndex = Math.min(windows.indexOf(wallpaperTarget), findLowestWindowOnScreen(windows));
}
}
if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || (DEBUG_ADD_REMOVE && oldIndex != insertionIndex))
Slog.v(TAG, "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + insertionIndex);
windows.add(insertionIndex, wallpaper);
mService.mWindowsChanged = true;
changed = true;
}
}
return changed;
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WallpaperController method updateWallpaperVisibility.
void updateWallpaperVisibility() {
final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
if (displayContent == null) {
return;
}
final boolean visible = isWallpaperVisible(mWallpaperTarget);
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
WindowToken token = mWallpaperTokens.get(curTokenNdx);
if (token.hidden == visible) {
token.hidden = !visible;
// Need to do a layout to ensure the wallpaper now has the
// correct size.
displayContent.layoutNeeded = true;
}
final WindowList windows = token.windows;
for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
WindowState wallpaper = windows.get(wallpaperNdx);
if (visible) {
updateWallpaperOffset(wallpaper, dw, dh, false);
}
dispatchWallpaperVisibility(wallpaper, visible);
}
}
}
Aggregations