diff options
-rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 2 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 14 | ||||
-rw-r--r-- | core/java/android/content/res/CompatibilityInfo.java | 244 | ||||
-rw-r--r-- | core/java/android/util/DisplayMetrics.java | 3 | ||||
-rw-r--r-- | core/java/android/view/SurfaceView.java | 2 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 8 | ||||
-rw-r--r-- | core/java/android/view/WindowManager.java | 10 | ||||
-rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 114 |
8 files changed, 164 insertions, 233 deletions
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index bcf95b6..0d00f21 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -173,7 +173,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * {@hide} */ public static final int ANY_DENSITY = -1; - private static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY }; + static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY }; /** * Flags associated with the application. Any combination of diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 558b0c3..b293636 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -945,15 +945,25 @@ public class PackageParser { >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; } - + int densities[] = null; int size = pkg.supportsDensityList.size(); if (size > 0) { - int densities[] = pkg.supportsDensities = new int[size]; + densities = pkg.supportsDensities = new int[size]; List<Integer> densityList = pkg.supportsDensityList; for (int i = 0; i < size; i++) { densities[i] = densityList.get(i); } } + /** + * TODO: enable this before code freeze. b/1967935 + * * + if ((densities == null || densities.length == 0) + && (pkg.applicationInfo.targetSdkVersion + >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) { + pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY; + } + */ + return pkg; } diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index dfe304d..ebe556e 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -51,18 +51,6 @@ public class CompatibilityInfo { public static final int DEFAULT_PORTRAIT_HEIGHT = 480; /** - * The x-shift mode that controls the position of the content or the window under - * compatibility mode. - * {@see getTranslator} - * {@see Translator#mShiftMode} - */ - private static final int X_SHIFT_NONE = 0; - private static final int X_SHIFT_CONTENT = 1; - private static final int X_SHIFT_AND_CLIP_CONTENT = 2; - private static final int X_SHIFT_WINDOW = 3; - - - /** * A compatibility flags */ private int mCompatibilityFlags; @@ -106,20 +94,6 @@ public class CompatibilityInfo { */ public final int appFlags; - /** - * Window size in Compatibility Mode, in real pixels. This is updated by - * {@link DisplayMetrics#updateMetrics}. - */ - private int mWidth; - private int mHeight; - - /** - * The x offset to center the window content. In X_SHIFT_WINDOW mode, the offset is added - * to the window's layout. In X_SHIFT_CONTENT/X_SHIFT_AND_CLIP_CONTENT mode, the offset - * is used to translate the Canvas. - */ - private int mXOffset; - public CompatibilityInfo(ApplicationInfo appInfo) { appFlags = appInfo.flags; @@ -153,6 +127,7 @@ public class CompatibilityInfo { applicationScale = DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY; } + applicationInvertedScale = 1.0f / applicationScale; if (applicationScale != 1.0f) { mCompatibilityFlags |= SCALING_REQUIRED; @@ -181,23 +156,10 @@ public class CompatibilityInfo { public CompatibilityInfo copy() { CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags, applicationScale, applicationInvertedScale); - info.setVisibleRect(mXOffset, mWidth, mHeight); return info; } /** - * Sets the application's visible rect in compatibility mode. - * @param xOffset the application's x offset that is added to center the content. - * @param widthPixels the application's width in real pixels on the screen. - * @param heightPixels the application's height in real pixels on the screen. - */ - public void setVisibleRect(int xOffset, int widthPixels, int heightPixels) { - this.mXOffset = xOffset; - mWidth = widthPixels; - mHeight = heightPixels; - } - - /** * Sets expandable bit in the compatibility flag. */ public void setExpandable(boolean expandable) { @@ -222,6 +184,10 @@ public class CompatibilityInfo { return (mCompatibilityFlags & SCALING_REQUIRED) != 0; } + public boolean supportsScreen() { + return (mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) != 0; + } + @Override public String toString() { return "CompatibilityInfo{scale=" + applicationScale + @@ -231,21 +197,6 @@ public class CompatibilityInfo { /** * Returns the translator which can translate the coordinates of the window. * There are five different types of Translator. - * - * 1) {@link CompatibilityInfo#X_SHIFT_AND_CLIP_CONTENT} - * Shift and clip the content of the window at drawing time. Used for activities' - * main window (with no gravity). - * 2) {@link CompatibilityInfo#X_SHIFT_CONTENT} - * Shift the content of the window at drawing time. Used for windows that is created by - * an application and expected to be aligned with the application window. - * 3) {@link CompatibilityInfo#X_SHIFT_WINDOW} - * Create the window with adjusted x- coordinates. This is typically used - * in popup window, where it has to be placed relative to main window. - * 4) {@link CompatibilityInfo#X_SHIFT_NONE} - * No adjustment required, such as dialog. - * 5) Same as X_SHIFT_WINDOW, but no scaling. This is used by {@link SurfaceView}, which - * does not require scaling, but its window's location has to be adjusted. - * * @param params the window's parameter */ public Translator getTranslator(WindowManager.LayoutParams params) { @@ -254,35 +205,11 @@ public class CompatibilityInfo { if (DBG) Log.d(TAG, "no translation required"); return null; } - - if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) { - if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) { - if (DBG) Log.d(TAG, "translation for surface view selected"); - return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f); - } else { - int shiftMode; - if (params.gravity == Gravity.NO_GRAVITY) { - // For Regular Application window - shiftMode = X_SHIFT_AND_CLIP_CONTENT; - if (DBG) Log.d(TAG, "shift and clip translator"); - } else if (params.width == WindowManager.LayoutParams.FILL_PARENT) { - // For Regular Application window - shiftMode = X_SHIFT_CONTENT; - if (DBG) Log.d(TAG, "shift content translator"); - } else if ((params.gravity & Gravity.LEFT) != 0 && params.x > 0) { - shiftMode = X_SHIFT_WINDOW; - if (DBG) Log.d(TAG, "shift window translator"); - } else { - shiftMode = X_SHIFT_NONE; - if (DBG) Log.d(TAG, "no content/window translator"); - } - return new Translator(shiftMode); - } - } else if (isScalingRequired()) { - return new Translator(); - } else { + if (!isScalingRequired() || + (params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) { return null; } + return new Translator(); } /** @@ -290,97 +217,48 @@ public class CompatibilityInfo { * @hide */ public class Translator { - final private int mShiftMode; - final public boolean scalingRequired; final public float applicationScale; final public float applicationInvertedScale; private Rect mContentInsetsBuffer = null; - private Rect mVisibleInsets = null; + private Rect mVisibleInsetsBuffer = null; - Translator(int shiftMode, boolean scalingRequired, float applicationScale, - float applicationInvertedScale) { - mShiftMode = shiftMode; - this.scalingRequired = scalingRequired; + Translator(float applicationScale, float applicationInvertedScale) { this.applicationScale = applicationScale; this.applicationInvertedScale = applicationInvertedScale; } - Translator(int shiftMode) { - this(shiftMode, - isScalingRequired(), - CompatibilityInfo.this.applicationScale, - CompatibilityInfo.this.applicationInvertedScale); - } - Translator() { - this(X_SHIFT_NONE); + this(CompatibilityInfo.this.applicationScale, + CompatibilityInfo.this.applicationInvertedScale); } /** * Translate the screen rect to the application frame. */ public void translateRectInScreenToAppWinFrame(Rect rect) { - if (rect.isEmpty()) return; // skip if the window size is empty. - switch (mShiftMode) { - case X_SHIFT_AND_CLIP_CONTENT: - rect.intersect(0, 0, mWidth, mHeight); - break; - case X_SHIFT_CONTENT: - rect.intersect(0, 0, mWidth + mXOffset, mHeight); - break; - case X_SHIFT_WINDOW: - case X_SHIFT_NONE: - break; - } - if (scalingRequired) { - rect.scale(applicationInvertedScale); - } + rect.scale(applicationInvertedScale); } /** * Translate the region in window to screen. */ public void translateRegionInWindowToScreen(Region transparentRegion) { - switch (mShiftMode) { - case X_SHIFT_AND_CLIP_CONTENT: - case X_SHIFT_CONTENT: - transparentRegion.scale(applicationScale); - transparentRegion.translate(mXOffset, 0); - break; - case X_SHIFT_WINDOW: - case X_SHIFT_NONE: - transparentRegion.scale(applicationScale); - } + transparentRegion.scale(applicationScale); } /** * Apply translation to the canvas that is necessary to draw the content. */ public void translateCanvas(Canvas canvas) { - if (mShiftMode == X_SHIFT_CONTENT || - mShiftMode == X_SHIFT_AND_CLIP_CONTENT) { - // TODO: clear outside when rotation is changed. - - // Translate x-offset only when the content is shifted. - canvas.translate(mXOffset, 0); - } - if (scalingRequired) { - canvas.scale(applicationScale, applicationScale); - } + canvas.scale(applicationScale, applicationScale); } /** * Translate the motion event captured on screen to the application's window. */ public void translateEventInScreenToAppWindow(MotionEvent event) { - if (mShiftMode == X_SHIFT_CONTENT || - mShiftMode == X_SHIFT_AND_CLIP_CONTENT) { - event.translate(-mXOffset, 0); - } - if (scalingRequired) { - event.scale(applicationInvertedScale); - } + event.scale(applicationInvertedScale); } /** @@ -388,62 +266,21 @@ public class CompatibilityInfo { * Screen's view. */ public void translateWindowLayout(WindowManager.LayoutParams params) { - switch (mShiftMode) { - case X_SHIFT_NONE: - case X_SHIFT_AND_CLIP_CONTENT: - case X_SHIFT_CONTENT: - params.scale(applicationScale); - break; - case X_SHIFT_WINDOW: - params.scale(applicationScale); - params.x += mXOffset; - break; - } + params.scale(applicationScale); } /** * Translate a Rect in application's window to screen. */ public void translateRectInAppWindowToScreen(Rect rect) { - // TODO Auto-generated method stub - if (scalingRequired) { - rect.scale(applicationScale); - } - switch(mShiftMode) { - case X_SHIFT_NONE: - case X_SHIFT_WINDOW: - break; - case X_SHIFT_CONTENT: - case X_SHIFT_AND_CLIP_CONTENT: - rect.offset(mXOffset, 0); - break; - } + rect.scale(applicationScale); } /** * Translate a Rect in screen coordinates into the app window's coordinates. */ public void translateRectInScreenToAppWindow(Rect rect) { - switch (mShiftMode) { - case X_SHIFT_NONE: - case X_SHIFT_WINDOW: - break; - case X_SHIFT_CONTENT: { - rect.intersects(mXOffset, 0, rect.right, rect.bottom); - int dx = Math.min(mXOffset, rect.left); - rect.offset(-dx, 0); - break; - } - case X_SHIFT_AND_CLIP_CONTENT: { - rect.intersects(mXOffset, 0, mWidth + mXOffset, mHeight); - int dx = Math.min(mXOffset, rect.left); - rect.offset(-dx, 0); - break; - } - } - if (scalingRequired) { - rect.scale(applicationInvertedScale); - } + rect.scale(applicationInvertedScale); } /** @@ -451,19 +288,7 @@ public class CompatibilityInfo { * @param params */ public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) { - if (scalingRequired) { - params.scale(applicationScale); - } - switch (mShiftMode) { - // the window location on these mode does not require adjustmenet. - case X_SHIFT_NONE: - case X_SHIFT_WINDOW: - break; - case X_SHIFT_CONTENT: - case X_SHIFT_AND_CLIP_CONTENT: - params.x += mXOffset; - break; - } + params.scale(applicationScale); } /** @@ -482,10 +307,31 @@ public class CompatibilityInfo { * the internal buffer for content insets to avoid extra object allocation. */ public Rect getTranslatedVisbileInsets(Rect visibleInsets) { - if (mVisibleInsets == null) mVisibleInsets = new Rect(); - mVisibleInsets.set(visibleInsets); - translateRectInAppWindowToScreen(mVisibleInsets); - return mVisibleInsets; + if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect(); + mVisibleInsetsBuffer.set(visibleInsets); + translateRectInAppWindowToScreen(mVisibleInsetsBuffer); + return mVisibleInsetsBuffer; + } + } + + /** + * Returns the frame Rect for applications runs under compatibility mode. + * + * @param dm the display metrics used to compute the frame size. + * @param orientation the orientation of the screen. + * @param outRect the output parameter which will contain the result. + */ + public static void updateCompatibleScreenFrame(DisplayMetrics dm, int orientation, + Rect outRect) { + int width = dm.widthPixels; + int portraitHeight = (int) (DEFAULT_PORTRAIT_HEIGHT * dm.density); + int portraitWidth = (int) (DEFAULT_PORTRAIT_WIDTH * dm.density); + if (orientation == Configuration.ORIENTATION_LANDSCAPE) { + int xOffset = (width - portraitHeight) / 2 ; + outRect.set(xOffset, 0, xOffset + portraitHeight, portraitWidth); + } else { + int xOffset = (width - portraitWidth) / 2 ; + outRect.set(xOffset, 0, xOffset + portraitWidth, portraitHeight); } } } diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 4179edb..9071bf0 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -109,7 +109,6 @@ public class DisplayMetrics { */ public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation, int screenLayout) { - int xOffset = 0; if (!compatibilityInfo.isConfiguredExpandable()) { // Note: this assume that configuration is updated before calling // updateMetrics method. @@ -142,7 +141,6 @@ public class DisplayMetrics { if (defaultWidth < widthPixels) { // content/window's x offset in original pixels - xOffset = ((widthPixels - defaultWidth) / 2); widthPixels = defaultWidth; } if (defaultHeight < heightPixels) { @@ -154,7 +152,6 @@ public class DisplayMetrics { compatibilityInfo.setExpandable(true); } } - compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels); if (compatibilityInfo.isScalingRequired()) { float invertedRatio = compatibilityInfo.applicationInvertedScale; density *= invertedRatio; diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 1e2bc1f..13a6e7a 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -307,7 +307,7 @@ public class SurfaceView extends View { // Use original size if the app specified the size of the view, // and let the flinger to scale up. - if (mRequestedWidth <= 0 && mTranslator != null && mTranslator.scalingRequired) { + if (mRequestedWidth <= 0 && mTranslator != null) { myWidth *= appScale; myHeight *= appScale; } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 41cc86a..ce25913 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -392,6 +392,7 @@ public final class ViewRoot extends Handler implements ViewParent, if (mView == null) { mView = view; mWindowAttributes.copyFrom(attrs); + attrs = mWindowAttributes; CompatibilityInfo compatibilityInfo = mView.getContext().getResources().getCompatibilityInfo(); @@ -404,11 +405,14 @@ public final class ViewRoot extends Handler implements ViewParent, } if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs); + if (!compatibilityInfo.supportsScreen()) { + attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW; + } + mSoftInputMode = attrs.softInputMode; mWindowAttributesChanged = true; mAttachInfo.mRootView = view; - mAttachInfo.mScalingRequired = - mTranslator == null ? false : mTranslator.scalingRequired; + mAttachInfo.mScalingRequired = mTranslator == null ? false : true; mAttachInfo.mApplicationScale = mTranslator == null ? 1.0f : mTranslator.applicationScale; if (panelParentView != null) { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index bdb86d7..e96a15b 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -484,11 +484,19 @@ public interface WindowManager extends ViewManager { public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000; /** Window flag: special flag to let a window ignore the compatibility scaling. - * This is used by SurfaceView to create a window that does not scale the content. + * This is used by SurfaceView to pass this info into ViewRoot, and not used + * by WindowManager. * * {@hide} */ public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000; + /** Window flag: special flag to limit the size of the window to be + * original size ([320x480] x density). Used to create window for applications + * running under compatibility mode. + * + * {@hide} */ + public static final int FLAG_COMPATIBLE_WINDOW = 0x00200000; + /** Window flag: a special option intended for system dialogs. When * this flag is set, the window will demand focus unconditionally when * it is created. diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 0c75251..25aff5c 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -53,6 +53,7 @@ import android.app.IActivityManager; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Matrix; import android.graphics.PixelFormat; @@ -420,7 +421,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo final Configuration mTempConfiguration = new Configuration(); int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED; - + + // The frame use to limit the size of the app running in compatibility mode. + Rect mCompatibleScreenFrame = new Rect(); + // The surface used to fill the outer rim of the app running in compatibility mode. + Surface mBackgroundFillerSurface = null; + boolean mBackgroundFillerShown = false; + public static WindowManagerService main(Context context, PowerManagerService pm, boolean haveInputMethods) { WMThread thr = new WMThread(context, pm, haveInputMethods); @@ -3745,12 +3752,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo } config.orientation = orientation; + DisplayMetrics dm = new DisplayMetrics(); + mDisplay.getMetrics(dm); + CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame); + if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) { // Note we only do this once because at this point we don't // expect the screen to change in this way at runtime, and want // to avoid all of this computation for every config change. - DisplayMetrics dm = new DisplayMetrics(); - mDisplay.getMetrics(dm); int longSize = dw; int shortSize = dh; if (longSize < shortSize) { @@ -3760,7 +3769,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo } longSize = (int)(longSize/dm.density); shortSize = (int)(shortSize/dm.density); - + // These semi-magic numbers define our compatibility modes for // applications with different screens. Don't change unless you // make sure to test lots and lots of apps! @@ -5894,8 +5903,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) { mHaveFrame = true; - final int pw = pf.right-pf.left; - final int ph = pf.bottom-pf.top; + final Rect container = mContainingFrame; + container.set(pf); + + final Rect display = mDisplayFrame; + display.set(df); + + if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW) != 0) { + container.intersect(mCompatibleScreenFrame); + display.intersect(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) { @@ -5906,12 +5926,6 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight; } - final Rect container = mContainingFrame; - container.set(pf); - - final Rect display = mDisplayFrame; - display.set(df); - final Rect content = mContentFrame; content.set(cf); @@ -5931,7 +5945,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo // Now make sure the window fits in the overall display. Gravity.applyDisplay(mAttrs.gravity, df, frame); - + // Make sure the content and visible frames are inside of the // final window frame. if (content.left < frame.left) content.left = frame.left; @@ -6622,16 +6636,29 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo return false; } - boolean isFullscreenOpaque(int screenWidth, int screenHeight) { - if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null - || mAnimation != null || mDrawPending || mCommitDrawPending) { - return false; - } - if (mFrame.left <= 0 && mFrame.top <= 0 && - mFrame.right >= screenWidth && mFrame.bottom >= screenHeight) { - return true; - } - return false; + /** + * Return true if the window is opaque and fully drawn. + */ + boolean isOpaqueDrawn() { + return mAttrs.format == PixelFormat.OPAQUE && mSurface != null + && mAnimation == null && !mDrawPending && !mCommitDrawPending; + } + + boolean needsBackgroundFiller(int screenWidth, int screenHeight) { + return + // only if the application is requesting compatible window + (mAttrs.flags & mAttrs.FLAG_COMPATIBLE_WINDOW) != 0 && + // and only if the application wanted to fill the screen + mAttrs.width == mAttrs.FILL_PARENT && + mAttrs.height == mAttrs.FILL_PARENT && + // and only if the screen is bigger + ((mFrame.right - mFrame.right) < screenWidth || + (mFrame.bottom - mFrame.top) < screenHeight); + } + + boolean isFullscreen(int screenWidth, int screenHeight) { + return mFrame.left <= 0 && mFrame.top <= 0 && + mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; } void removeLocked() { @@ -8151,6 +8178,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo boolean dimming = false; boolean covered = false; boolean syswin = false; + boolean backgroundFillerShown = false; for (i=N-1; i>=0; i--) { WindowState w = (WindowState)mWindows.get(i); @@ -8420,11 +8448,39 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo syswin = true; } } - if (w.isFullscreenOpaque(dw, dh)) { + + boolean opaqueDrawn = w.isOpaqueDrawn(); + if (opaqueDrawn && w.isFullscreen(dw, dh)) { // This window completely covers everything behind it, // so we want to leave all of them as unblurred (for // performance reasons). obscured = true; + } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) { + if (SHOW_TRANSACTIONS) Log.d(TAG, "showing background filler"); + // This window is in compatibility mode, and needs background filler. + obscured = true; + if (mBackgroundFillerSurface == null) { + try { + mBackgroundFillerSurface = new Surface(mFxSession, 0, + 0, dw, dh, + PixelFormat.OPAQUE, + Surface.FX_SURFACE_NORMAL); + } catch (Exception e) { + Log.e(TAG, "Exception creating filler surface", e); + } + } + try { + mBackgroundFillerSurface.setPosition(0, 0); + mBackgroundFillerSurface.setSize(dw, dh); + // Using the same layer as Dim because they will never be shown at the + // same time. + mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1); + mBackgroundFillerSurface.show(); + } catch (RuntimeException e) { + Log.e(TAG, "Exception showing filler surface"); + } + backgroundFillerShown = true; + mBackgroundFillerShown = true; } else if (canBeSeen && !obscured && (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) { if (localLOGV) Log.v(TAG, "Win " + w @@ -8521,6 +8577,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo } } } + + if (backgroundFillerShown == false && mBackgroundFillerShown) { + mBackgroundFillerShown = false; + if (SHOW_TRANSACTIONS) Log.d(TAG, "hiding background filler"); + try { + mBackgroundFillerSurface.hide(); + } catch (RuntimeException e) { + Log.e(TAG, "Exception hiding filler surface", e); + } + } if (!dimming && mDimShown) { // Time to hide the dim surface... start fading. |