Merge "Improve compat mode scaling implementation." into honeycomb-mr2

This commit is contained in:
Dianne Hackborn
2011-05-17 18:38:37 -07:00
committed by Android (Google) Code Review
5 changed files with 149 additions and 281 deletions

View File

@ -156,9 +156,8 @@ class DragState {
}
if (mDragInProgress && newWin.isPotentialDragTarget()) {
DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
null, desc, null, false);
DragEvent event = obtainDragEvent(newWin, DragEvent.ACTION_DRAG_STARTED,
touchX, touchY, null, desc, null, false);
try {
newWin.mClient.dispatchDragEvent(event);
// track each window that we've notified that the drag is starting
@ -267,9 +266,8 @@ class DragState {
Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow);
}
// force DRAG_EXITED_EVENT if appropriate
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
null, null, null, false);
DragEvent evt = obtainDragEvent(mTargetWindow, DragEvent.ACTION_DRAG_EXITED,
x, y, null, null, null, false);
mTargetWindow.mClient.dispatchDragEvent(evt);
if (myPid != mTargetWindow.mSession.mPid) {
evt.recycle();
@ -279,9 +277,8 @@ class DragState {
if (false && WindowManagerService.DEBUG_DRAG) {
Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin);
}
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
null, null, null, false);
DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DRAG_LOCATION,
x, y, null, null, null, false);
touchedWin.mClient.dispatchDragEvent(evt);
if (myPid != touchedWin.mSession.mPid) {
evt.recycle();
@ -310,8 +307,7 @@ class DragState {
}
final int myPid = Process.myPid();
final IBinder token = touchedWin.mClient.asBinder();
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
null, null, mData, false);
try {
touchedWin.mClient.dispatchDragEvent(evt);
@ -365,4 +361,16 @@ class DragState {
return touchedWin;
}
private static DragEvent obtainDragEvent(WindowState win, int action,
float x, float y, Object localState,
ClipDescription description, ClipData data, boolean result) {
float winX = x - win.mFrame.left;
float winY = y - win.mFrame.top;
if (win.mEnforceSizeCompat) {
winX *= win.mGlobalScale;
winY *= win.mGlobalScale;
}
return DragEvent.obtain(action, winX, winY, localState, description, data, result);
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2011 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.server.wm;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
/**
* Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
* This is used for opening/closing transition for apps in compatible mode.
*/
class FadeInOutAnimation extends Animation {
boolean mFadeIn;
public FadeInOutAnimation(boolean fadeIn) {
setInterpolator(new AccelerateInterpolator());
setDuration(WindowManagerService.DEFAULT_FADE_IN_OUT_DURATION);
mFadeIn = fadeIn;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float x = interpolatedTime;
if (!mFadeIn) {
x = 1.0f - x; // reverse the interpolation for fade out
}
t.setAlpha(x);
}
}

View File

@ -205,7 +205,7 @@ final class InputMonitor {
inputWindow.ownerPid = child.mSession.mPid;
inputWindow.ownerUid = child.mSession.mUid;
final Rect frame = child.mScaledFrame;
final Rect frame = child.mFrame;
inputWindow.frameLeft = frame.left;
inputWindow.frameTop = frame.top;
inputWindow.frameRight = frame.right;

View File

@ -603,9 +603,6 @@ public class WindowManagerService extends IWindowManager.Stub
// The frame use to limit the size of the app running in compatibility mode.
Rect mCompatibleScreenFrame = new Rect();
float mCompatibleScreenScale;
// The surface used to fill the outer rim of the app running in compatibility mode.
Surface mBackgroundFillerSurface = null;
WindowState mBackgroundFillerTarget = null;
public static WindowManagerService main(Context context,
PowerManagerService pm, boolean haveInputMethods) {
@ -1774,7 +1771,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean rawChanged = false;
float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
int availw = wallpaperWin.mScaledFrame.right-wallpaperWin.mScaledFrame.left-dw;
int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
changed = wallpaperWin.mXOffset != offset;
if (changed) {
@ -2369,6 +2366,11 @@ public class WindowManagerService extends IWindowManager.Stub
w.mGivenVisibleInsets.set(visibleInsets);
w.mGivenTouchableRegion.set(touchableRegion);
w.mTouchableInsets = touchableInsets;
if (w.mGlobalScale != 1) {
w.mGivenContentInsets.scale(w.mGlobalScale);
w.mGivenVisibleInsets.scale(w.mGlobalScale);
w.mGivenTouchableRegion.scale(w.mGlobalScale);
}
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
@ -2704,7 +2706,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
}
outFrame.set(win.mFrame);
outFrame.set(win.mCompatFrame);
outContentInsets.set(win.mContentInsets);
outVisibleInsets.set(win.mVisibleInsets);
if (localLOGV) Slog.v(
@ -2903,18 +2905,14 @@ public class WindowManagerService extends IWindowManager.Stub
}
private boolean applyAnimationLocked(AppWindowToken wtoken,
WindowManager.LayoutParams lp, int transit, boolean enter, boolean bgFiller) {
WindowManager.LayoutParams lp, int transit, boolean enter) {
// Only apply an animation if the display isn't frozen. If it is
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
// is running.
if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Animation a;
if (bgFiller) {
a = new FadeInOutAnimation(enter);
if (DEBUG_ANIM) Slog.v(TAG,
"applying FadeInOutAnimation for a window in compatibility mode");
} else if (mNextAppTransitionPackage != null) {
if (mNextAppTransitionPackage != null) {
a = loadAnimation(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
} else {
@ -3706,7 +3704,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
boolean visible, int transit, boolean performLayout, boolean bgFiller) {
boolean visible, int transit, boolean performLayout) {
boolean delayed = false;
if (wtoken.clientHidden == visible) {
@ -3728,7 +3726,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (wtoken.animation == sDummyAnimation) {
wtoken.animation = null;
}
applyAnimationLocked(wtoken, lp, transit, visible, bgFiller);
applyAnimationLocked(wtoken, lp, transit, visible);
changed = true;
if (wtoken.animation != null) {
delayed = runningAppAnimation = true;
@ -3882,7 +3880,7 @@ public class WindowManagerService extends IWindowManager.Stub
final long origId = Binder.clearCallingIdentity();
setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
true, false);
true);
wtoken.updateReportedVisibilityLocked();
Binder.restoreCallingIdentity(origId);
}
@ -4009,7 +4007,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
delayed = setTokenVisibilityLocked(wtoken, null, false,
WindowManagerPolicy.TRANSIT_UNSET, true, false);
WindowManagerPolicy.TRANSIT_UNSET, true);
wtoken.inPendingTransaction = false;
mOpeningApps.remove(wtoken);
wtoken.waitingToShow = false;
@ -4830,7 +4828,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Don't include wallpaper in bounds calculation
if (!ws.mIsWallpaper) {
final Rect wf = ws.mScaledFrame;
final Rect wf = ws.mFrame;
final Rect cr = ws.mContentInsets;
int left = wf.left + cr.left;
int top = wf.top + cr.top;
@ -5549,8 +5547,8 @@ public class WindowManagerService extends IWindowManager.Stub
// Override display width and height with what we are computing,
// to be sure they remain consistent.
dm.widthPixels = mPolicy.getNonDecorDisplayWidth(dw);
dm.heightPixels = mPolicy.getNonDecorDisplayHeight(dh);
dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth(dw);
dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight(dh);
mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame(
dm, mCompatibleScreenFrame, null);
@ -6851,7 +6849,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.prelayout();
mPolicy.layoutWindowLw(win, win.mAttrs, null);
win.evalNeedsBackgroundFiller(innerDw, innerDh);
win.mLayoutSeq = seq;
if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+ win.mFrame + " mContainingFrame="
@ -6888,7 +6885,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.prelayout();
mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
win.evalNeedsBackgroundFiller(innerDw, innerDh);
win.mLayoutSeq = seq;
if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+ win.mFrame + " mContainingFrame="
@ -7340,7 +7336,6 @@ public class WindowManagerService extends IWindowManager.Stub
LayoutParams animLp = null;
int bestAnimLayer = -1;
boolean fullscreenAnim = false;
boolean needBgFiller = false;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New wallpaper target=" + mWallpaperTarget
@ -7378,16 +7373,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (wtoken.appFullscreen) {
WindowState ws = wtoken.findMainWindow();
if (ws != null) {
// If this is a compatibility mode
// window, we will always use its anim.
if (ws.mNeedsBackgroundFiller) {
animLp = ws.mAttrs;
bestAnimLayer = Integer.MAX_VALUE;
needBgFiller = true;
} else if (!fullscreenAnim || ws.mLayer > bestAnimLayer) {
animLp = ws.mAttrs;
bestAnimLayer = ws.mLayer;
}
animLp = ws.mAttrs;
bestAnimLayer = ws.mLayer;
fullscreenAnim = true;
}
} else if (!fullscreenAnim) {
@ -7449,7 +7436,7 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.inPendingTransaction = false;
wtoken.animation = null;
setTokenVisibilityLocked(wtoken, animLp, true,
transit, false, needBgFiller);
transit, false);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
wtoken.showAllWindowsLocked();
@ -7462,7 +7449,7 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.inPendingTransaction = false;
wtoken.animation = null;
setTokenVisibilityLocked(wtoken, animLp, false,
transit, false, needBgFiller);
transit, false);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToHide = false;
// Force the allDrawn flag, because we want to start
@ -7629,8 +7616,6 @@ public class WindowManagerService extends IWindowManager.Stub
boolean dimming = false;
boolean covered = false;
boolean syswin = false;
boolean backgroundFillerWasShown = mBackgroundFillerTarget != null;
mBackgroundFillerTarget = null;
final int N = mWindows.size();
@ -7659,8 +7644,7 @@ public class WindowManagerService extends IWindowManager.Stub
w.computeShownFrameLocked();
if (localLOGV) Slog.v(
TAG, "Placing surface #" + i + " " + w.mSurface
+ ": new=" + w.mShownFrame + ", old="
+ w.mLastShownFrame);
+ ": new=" + w.mShownFrame);
int width, height;
if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
@ -7668,13 +7652,9 @@ public class WindowManagerService extends IWindowManager.Stub
// the requested size.
width = w.mRequestedWidth;
height = w.mRequestedHeight;
w.mLastRequestedWidth = width;
w.mLastRequestedHeight = height;
w.mLastShownFrame.set(w.mShownFrame);
} else {
width = w.mShownFrame.width();
height = w.mShownFrame.height();
w.mLastShownFrame.set(w.mShownFrame);
width = w.mCompatFrame.width();
height = w.mCompatFrame.height();
}
if (w.mSurface != null) {
@ -7741,8 +7721,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (localLOGV) Slog.v(TAG, "Resizing " + w
+ ": configChanged=" + configChanged
+ " last=" + w.mLastFrame + " frame=" + w.mFrame);
boolean frameChanged = !w.mLastFrame.equals(w.mFrame);
+ " last=" + w.mLastCompatFrame + " frame=" + w.mCompatFrame);
boolean frameChanged = !w.mLastCompatFrame.equals(w.mCompatFrame);
if (frameChanged
|| w.mContentInsetsChanged
|| w.mVisibleInsetsChanged
@ -7758,6 +7738,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
w.mLastFrame.set(w.mFrame);
w.mLastCompatFrame.set(w.mCompatFrame);
w.mLastContentInsets.set(w.mContentInsets);
w.mLastVisibleInsets.set(w.mVisibleInsets);
// If the screen is currently frozen, then keep
@ -7793,7 +7774,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
"Resizing window " + w + " to " + w.mFrame);
"Resizing window " + w + " to " + w.mCompatFrame);
mResizingWindows.add(w);
} else if (w.mOrientationChanging) {
if (!w.mDrawPending && !w.mCommitDrawPending) {
@ -7932,16 +7913,6 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean obscuredChanged = w.mObscured != obscured;
if (mBackgroundFillerTarget != null) {
if (w.isAnimating()) {
// Background filler is below all other windows that
// are animating.
mBackgroundFillerTarget = w;
} else if (w.mIsWallpaper) {
mBackgroundFillerTarget = w;
}
}
// Update effect.
if (!(w.mObscured=obscured)) {
if (w.mSurface != null) {
@ -7970,12 +7941,6 @@ public class WindowManagerService extends IWindowManager.Stub
// so we want to leave all of them as unblurred (for
// performance reasons).
obscured = true;
} else if (w.mNeedsBackgroundFiller && w.mHasDrawn
&& w.mViewVisibility == View.VISIBLE
&& (canBeSeen || w.isAnimating())) {
// This window is in compatibility mode, and needs background filler.
obscured = true;
mBackgroundFillerTarget = w;
} else if (canBeSeen && !obscured &&
(attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
if (localLOGV) Slog.v(TAG, "Win " + w
@ -8042,47 +8007,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
if (mBackgroundFillerTarget != null) {
if (mBackgroundFillerSurface == null) {
try {
mBackgroundFillerSurface = new Surface(mFxSession, 0,
"BackGroundFiller",
0, dw, dh,
PixelFormat.OPAQUE,
Surface.FX_SURFACE_NORMAL);
} catch (Exception e) {
Slog.e(TAG, "Exception creating filler surface", e);
}
if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
+ mBackgroundFillerSurface + ": CREATE");
}
try {
if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
+ mBackgroundFillerSurface + " SHOW: pos=(0,0) ("
+ dw + "x" + dh + ") layer="
+ (mBackgroundFillerTarget.mLayer - 1));
mBackgroundFillerSurface.setPosition(0, 0);
mBackgroundFillerSurface.setSize(dw, dh);
// Using the same layer as Dim because they will never be shown at the
// same time. NOTE: we do NOT use mAnimLayer, because we don't
// want this surface dragged up in front of stuff that is animating.
mBackgroundFillerSurface.setLayer(mBackgroundFillerTarget.mLayer
- LAYER_OFFSET_DIM);
mBackgroundFillerSurface.show();
} catch (RuntimeException e) {
Slog.e(TAG, "Exception showing filler surface");
}
} else if (backgroundFillerWasShown) {
mBackgroundFillerTarget = null;
if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
+ mBackgroundFillerSurface + " HIDE");
try {
mBackgroundFillerSurface.hide();
} catch (RuntimeException e) {
Slog.e(TAG, "Exception hiding filler surface", e);
}
}
if (mDimAnimator != null && mDimAnimator.mDimShown) {
animating |= mDimAnimator.updateSurface(dimming, currentTime,
mDisplayFrozen || !mPolicy.isScreenOn());
@ -8137,7 +8061,7 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState win = mResizingWindows.get(i);
try {
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
"Reporting new frame to " + win + ": " + win.mFrame);
"Reporting new frame to " + win + ": " + win.mCompatFrame);
int diff = 0;
boolean configChanged =
win.mConfiguration != mCurConfiguration
@ -8146,13 +8070,13 @@ public class WindowManagerService extends IWindowManager.Stub
if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
&& configChanged) {
Slog.i(TAG, "Sending new config to window " + win + ": "
+ win.mFrame.width() + "x" + win.mFrame.height()
+ win.mCompatFrame.width() + "x" + win.mCompatFrame.height()
+ " / " + mCurConfiguration + " / 0x"
+ Integer.toHexString(diff));
}
win.mConfiguration = mCurConfiguration;
win.mClient.resized(win.mFrame.width(),
win.mFrame.height(), win.mLastContentInsets,
win.mClient.resized(win.mCompatFrame.width(),
win.mCompatFrame.height(), win.mLastContentInsets,
win.mLastVisibleInsets, win.mDrawPending,
configChanged ? win.mConfiguration : null);
win.mContentInsetsChanged = false;

View File

@ -18,7 +18,6 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@ -83,23 +82,30 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mAttachedHidden; // is our parent window hidden?
boolean mLastHidden; // was this window last hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
/**
* The window size that was requested by the application. These are in
* the application's coordinate space (without compatibility scale applied).
*/
int mRequestedWidth;
int mRequestedHeight;
int mLastRequestedWidth;
int mLastRequestedHeight;
int mLayer;
int mAnimLayer;
int mLastLayer;
boolean mHaveFrame;
boolean mObscured;
boolean mNeedsBackgroundFiller;
boolean mTurnOnScreen;
int mLayoutSeq = -1;
Configuration mConfiguration = null;
// Actual frame shown on-screen (may be modified by animation)
/**
* Actual frame shown on-screen (may be modified by animation). These
* are in the screen's coordinate space (WITH the compatibility scale
* applied).
*/
final Rect mShownFrame = new Rect();
final Rect mLastShownFrame = new Rect();
@ -110,14 +116,16 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mSurfaceResized;
/**
* Insets that determine the actually visible area
* Insets that determine the actually visible area. These are in the application's
* coordinate space (without compatibility scale applied).
*/
final Rect mVisibleInsets = new Rect();
final Rect mLastVisibleInsets = new Rect();
boolean mVisibleInsetsChanged;
/**
* Insets that are covered by system windows
* Insets that are covered by system windows. These are in the application's
* coordinate space (without compatibility scale applied).
*/
final Rect mContentInsets = new Rect();
final Rect mLastContentInsets = new Rect();
@ -157,16 +165,20 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// Current transformation being applied.
boolean mHaveMatrix;
float mGlobalScale=1;
float mInvGlobalScale=1;
float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
float mHScale=1, mVScale=1;
float mLastHScale=1, mLastVScale=1;
final Matrix mTmpMatrix = new Matrix();
// "Real" frame that the application sees.
// "Real" frame that the application sees, in display coordinate space.
final Rect mFrame = new Rect();
final Rect mLastFrame = new Rect();
final Rect mScaledFrame = new Rect();
// Frame that is scaled to the application's coordinate space when in
// screen size compatibility mode.
final Rect mCompatFrame = new Rect();
final Rect mLastCompatFrame = new Rect();
final Rect mContainingFrame = new Rect();
final Rect mDisplayFrame = new Rect();
@ -346,8 +358,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mSurface = null;
mRequestedWidth = 0;
mRequestedHeight = 0;
mLastRequestedWidth = 0;
mLastRequestedHeight = 0;
mXOffset = 0;
mYOffset = 0;
mLayer = 0;
@ -373,23 +383,40 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final Rect display = mDisplayFrame;
display.set(df);
if (mEnforceSizeCompat) {
container.intersect(mService.mCompatibleScreenFrame);
if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
display.intersect(mService.mCompatibleScreenFrame);
}
}
final int pw = container.right - container.left;
final int ph = container.bottom - container.top;
int w,h;
if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
w = mAttrs.width < 0 ? pw : mAttrs.width;
h = mAttrs.height< 0 ? ph : mAttrs.height;
if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
if (mAttrs.width < 0) {
w = pw;
} else if (mEnforceSizeCompat) {
w = (int)(mAttrs.width * mGlobalScale + .5f);
} else {
w = mAttrs.width;
}
if (mAttrs.height < 0) {
h = ph;
} else if (mEnforceSizeCompat) {
h = (int)(mAttrs.height * mGlobalScale + .5f);
} else {
h = mAttrs.height;
}
} else {
w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
w = pw;
} else if (mEnforceSizeCompat) {
w = (int)(mRequestedWidth * mGlobalScale + .5f);
} else {
w = mRequestedWidth;
}
if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
h = ph;
} else if (mEnforceSizeCompat) {
h = (int)(mRequestedHeight * mGlobalScale + .5f);
} else {
h = mRequestedHeight;
}
}
if (!mParentFrame.equals(pf)) {
@ -412,37 +439,24 @@ final class WindowState implements WindowManagerPolicy.WindowState {
//System.out.println("In: w=" + w + " h=" + h + " container=" +
// container + " x=" + mAttrs.x + " y=" + mAttrs.y);
float x, y;
if (mEnforceSizeCompat) {
x = mAttrs.x * mGlobalScale;
y = mAttrs.y * mGlobalScale;
} else {
x = mAttrs.x;
y = mAttrs.y;
}
Gravity.apply(mAttrs.gravity, w, h, container,
(int) (mAttrs.x + mAttrs.horizontalMargin * pw),
(int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
(int) (x + mAttrs.horizontalMargin * pw),
(int) (y + mAttrs.verticalMargin * ph), frame);
//System.out.println("Out: " + mFrame);
// Now make sure the window fits in the overall display.
Gravity.applyDisplay(mAttrs.gravity, df, frame);
int adjRight=0, adjBottom=0;
if (mEnforceSizeCompat) {
// Adjust window offsets by the scaling factor.
int xoff = (int)((frame.left-mService.mCompatibleScreenFrame.left)*mGlobalScale)
- (frame.left-mService.mCompatibleScreenFrame.left);
int yoff = (int)((frame.top-mService.mCompatibleScreenFrame.top)*mGlobalScale)
- (frame.top-mService.mCompatibleScreenFrame.top);
frame.offset(xoff, yoff);
// We are temporarily going to apply the compatibility scale
// to the window so that we can correctly associate it with the
// content and visible frame.
adjRight = frame.right - frame.left;
adjRight = (int)((adjRight)*mGlobalScale + .5f) - adjRight;
adjBottom = frame.bottom - frame.top;
adjBottom = (int)((adjBottom)*mGlobalScale + .5f) - adjBottom;
frame.right += adjRight;
frame.bottom += adjBottom;
}
mScaledFrame.set(frame);
// Make sure the content and visible frames are inside of the
// final window frame.
if (content.left < frame.left) content.left = frame.left;
@ -466,20 +480,17 @@ final class WindowState implements WindowManagerPolicy.WindowState {
visibleInsets.right = frame.right-visible.right;
visibleInsets.bottom = frame.bottom-visible.bottom;
mCompatFrame.set(frame);
if (mEnforceSizeCompat) {
// Scale the computed insets back to the window's compatibility
// coordinate space, and put frame back to correct size.
final float invScale = 1.0f/mGlobalScale;
contentInsets.left = (int)(contentInsets.left*invScale);
contentInsets.top = (int)(contentInsets.top*invScale);
contentInsets.right = (int)(contentInsets.right*invScale);
contentInsets.bottom = (int)(contentInsets.bottom*invScale);
visibleInsets.left = (int)(visibleInsets.left*invScale);
visibleInsets.top = (int)(visibleInsets.top*invScale);
visibleInsets.right = (int)(visibleInsets.right*invScale);
visibleInsets.bottom = (int)(visibleInsets.bottom*invScale);
frame.right -= adjRight;
frame.bottom -= adjBottom;
// 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.
contentInsets.scale(mInvGlobalScale);
visibleInsets.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 != frame.width() || fh != frame.height())) {
@ -592,12 +603,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
WindowManagerService.TAG, "Creating surface in session "
+ mSession.mSurfaceSession + " window " + this
+ " w=" + mFrame.width()
+ " h=" + mFrame.height() + " format="
+ " w=" + mCompatFrame.width()
+ " h=" + mCompatFrame.height() + " format="
+ mAttrs.format + " flags=" + flags);
int w = mFrame.width();
int h = mFrame.height();
int w = mCompatFrame.width();
int h = mCompatFrame.height();
if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
// for a scaled surface, we always want the requested
// size.
@ -650,8 +661,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
+ ", animLayer=" + mAnimLayer);
if (WindowManagerService.SHOW_TRANSACTIONS) {
Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
mFrame.width() + "x" + mFrame.height() + "), layer=" +
WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left
+ "," + mFrame.top + ") (" +
mCompatFrame.width() + "x" + mCompatFrame.height() + "), layer=" +
mAnimLayer + " HIDE", null);
}
Surface.openTransaction();
@ -862,10 +874,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (!mLocalAnimating) {
if (WindowManagerService.DEBUG_ANIM) Slog.v(
WindowManagerService.TAG, "Starting animation in " + this +
" @ " + currentTime + ": ww=" + mScaledFrame.width() +
" wh=" + mScaledFrame.height() +
" @ " + currentTime + ": ww=" + mFrame.width() +
" wh=" + mFrame.height() +
" dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
mAnimation.initialize(mScaledFrame.width(), mScaledFrame.height(), dw, dh);
mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
mAnimation.setStartTime(currentTime);
mLocalAnimating = true;
mAnimating = true;
@ -1035,8 +1047,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
void prelayout() {
if (mEnforceSizeCompat) {
mGlobalScale = mService.mCompatibleScreenScale;
mInvGlobalScale = 1/mGlobalScale;
} else {
mGlobalScale = 1;
mGlobalScale = mInvGlobalScale = 1;
}
}
@ -1334,35 +1347,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
&& mService.mPolicy.isScreenOn();
}
void evalNeedsBackgroundFiller(int screenWidth, int screenHeight) {
mNeedsBackgroundFiller =
// only if the application is requesting compatible window
mEnforceSizeCompat &&
// only if it's visible
mHasDrawn && mViewVisibility == View.VISIBLE &&
// not needed if the compat window is actually full screen
!isFullscreenIgnoringCompat(screenWidth, screenHeight) &&
// and only if the application fills the compatible screen
mFrame.left <= mService.mCompatibleScreenFrame.left &&
mFrame.top <= mService.mCompatibleScreenFrame.top &&
mFrame.right >= mService.mCompatibleScreenFrame.right &&
mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
}
boolean isFullscreen(int screenWidth, int screenHeight) {
if (mEnforceSizeCompat) {
return mFrame.left <= mService.mCompatibleScreenFrame.left &&
mFrame.top <= mService.mCompatibleScreenFrame.top &&
mFrame.right >= mService.mCompatibleScreenFrame.right &&
mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
} else {
return isFullscreenIgnoringCompat(screenWidth, screenHeight);
}
}
boolean isFullscreenIgnoringCompat(int screenWidth, int screenHeight) {
return mScaledFrame.left <= 0 && mScaledFrame.top <= 0 &&
mScaledFrame.right >= screenWidth && mScaledFrame.bottom >= screenHeight;
return mFrame.left <= 0 && mFrame.top <= 0 &&
mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
}
void removeLocked() {
@ -1492,38 +1479,28 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return true;
}
private static void applyScaledInsets(Region outRegion, Rect frame, Rect inset, float scale) {
if (scale != 1) {
outRegion.set(frame.left + (int)(inset.left*scale),
frame.top + (int)(inset.top*scale),
frame.right - (int)(inset.right*scale),
frame.bottom - (int)(inset.bottom*scale));
} else {
outRegion.set(
frame.left + inset.left, frame.top + inset.top,
frame.right - inset.right, frame.bottom - inset.bottom);
}
private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
outRegion.set(
frame.left + inset.left, frame.top + inset.top,
frame.right - inset.right, frame.bottom - inset.bottom);
}
public void getTouchableRegion(Region outRegion) {
final Rect frame = mScaledFrame;
final Rect frame = mFrame;
switch (mTouchableInsets) {
default:
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
outRegion.set(frame);
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
applyScaledInsets(outRegion, frame, mGivenContentInsets, mGlobalScale);
applyInsets(outRegion, frame, mGivenContentInsets);
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
applyScaledInsets(outRegion, frame, mGivenVisibleInsets, mGlobalScale);
applyInsets(outRegion, frame, mGivenVisibleInsets);
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
final Region givenTouchableRegion = mGivenTouchableRegion;
outRegion.set(givenTouchableRegion);
if (mGlobalScale != 1) {
outRegion.scale(mGlobalScale);
}
outRegion.translate(frame.left, frame.top);
break;
}
@ -1586,8 +1563,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
pw.print(" h="); pw.print(mRequestedHeight);
pw.print(" mLayoutSeq="); pw.print(mLayoutSeq);
pw.print(" mNeedsBackgroundFiller="); pw.println(mNeedsBackgroundFiller);
pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
if (mXOffset != 0 || mYOffset != 0) {
pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
pw.print(" y="); pw.println(mYOffset);
@ -1608,8 +1584,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.println();
pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
pw.print(" last="); mLastFrame.printShortString(pw);
pw.print(" scaled="); mScaledFrame.printShortString(pw);
pw.println();
if (mEnforceSizeCompat) {
pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
pw.print(" last="); mLastCompatFrame.printShortString(pw);
pw.println();
}
pw.print(prefix); pw.print("mContainingFrame=");
mContainingFrame.printShortString(pw);
pw.print(" mParentFrame=");