am 4f9bb17f: am c2db2144: am a429d5df: Merge "Improve compat mode scaling implementation." into honeycomb-mr2

* commit '4f9bb17f7e74746c4296100f2fbd47f0f6ead3a7':
  Improve compat mode scaling implementation.
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index c8f8ff3..118cd55 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -156,9 +156,8 @@
         }
 
         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 @@
                     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 @@
                 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 @@
         }
         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 @@
 
         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);
+    }
 }
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/FadeInOutAnimation.java b/services/java/com/android/server/wm/FadeInOutAnimation.java
deleted file mode 100644
index 06f7657..0000000
--- a/services/java/com/android/server/wm/FadeInOutAnimation.java
+++ /dev/null
@@ -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);
-    }
-}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index a3e8be0..9dc92d3 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -205,7 +205,7 @@
             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;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 56181a5..0b3f613 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -603,9 +603,6 @@
     // 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 @@
         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 @@
                     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 @@
             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 @@
     }
 
     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 @@
     }
 
     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 @@
                 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 @@
 
             final long origId = Binder.clearCallingIdentity();
             setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
-                    true, false);
+                    true);
             wtoken.updateReportedVisibilityLocked();
             Binder.restoreCallingIdentity(origId);
         }
@@ -4009,7 +4007,7 @@
             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;
@@ -4834,7 +4832,7 @@
                 
                 // 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;
@@ -5553,8 +5551,8 @@
 
         // 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);
@@ -6855,7 +6853,6 @@
                     }
                     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="
@@ -6892,7 +6889,6 @@
                     }
                     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="
@@ -7344,7 +7340,6 @@
                         LayoutParams animLp = null;
                         int bestAnimLayer = -1;
                         boolean fullscreenAnim = false;
-                        boolean needBgFiller = false;
 
                         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                                 "New wallpaper target=" + mWallpaperTarget
@@ -7382,16 +7377,8 @@
                             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) {
@@ -7453,7 +7440,7 @@
                             wtoken.inPendingTransaction = false;
                             wtoken.animation = null;
                             setTokenVisibilityLocked(wtoken, animLp, true,
-                                    transit, false, needBgFiller);
+                                    transit, false);
                             wtoken.updateReportedVisibilityLocked();
                             wtoken.waitingToShow = false;
                             wtoken.showAllWindowsLocked();
@@ -7466,7 +7453,7 @@
                             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
@@ -7633,8 +7620,6 @@
             boolean dimming = false;
             boolean covered = false;
             boolean syswin = false;
-            boolean backgroundFillerWasShown = mBackgroundFillerTarget != null;
-            mBackgroundFillerTarget = null;
 
             final int N = mWindows.size();
 
@@ -7663,8 +7648,7 @@
                     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) {
@@ -7672,13 +7656,9 @@
                         // 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) {
@@ -7745,8 +7725,8 @@
                         }
                         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
@@ -7762,6 +7742,7 @@
                             }
 
                             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
@@ -7797,7 +7778,7 @@
                                 }
                             }
                             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) {
@@ -7936,16 +7917,6 @@
 
                 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) {
@@ -7974,12 +7945,6 @@
                         // 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
@@ -8046,47 +8011,6 @@
                 }
             }
 
-            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());
@@ -8141,7 +8065,7 @@
                 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
@@ -8150,13 +8074,13 @@
                     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;
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 2014e9d..144341b 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -18,7 +18,6 @@
 
 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 @@
     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 @@
     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 @@
     // 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 @@
         mSurface = null;
         mRequestedWidth = 0;
         mRequestedHeight = 0;
-        mLastRequestedWidth = 0;
-        mLastRequestedHeight = 0;
         mXOffset = 0;
         mYOffset = 0;
         mLayer = 0;
@@ -373,23 +383,40 @@
         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 @@
         //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 @@
         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 @@
             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 @@
                 + ", 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 @@
                 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 @@
     void prelayout() {
         if (mEnforceSizeCompat) {
             mGlobalScale = mService.mCompatibleScreenScale;
+            mInvGlobalScale = 1/mGlobalScale;
         } else {
-            mGlobalScale = 1;
+            mGlobalScale = mInvGlobalScale = 1;
         }
     }
 
@@ -1334,35 +1347,9 @@
                 && 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 @@
         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 @@
         }
         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 @@
                 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=");