summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/WindowManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/WindowManagerService.java')
-rw-r--r--services/java/com/android/server/WindowManagerService.java114
1 files changed, 90 insertions, 24 deletions
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.