Re-implementation of large screen support using window manager.
* added background filler surface to fill the outer rim. Using the same layer as dim surface because they never co-exists (in the same window) * clean up the obsolete code in CompatibiltyMode/ViewRoot for support large screen support.
This commit is contained in:
@@ -173,7 +173,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
|||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public static final int ANY_DENSITY = -1;
|
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
|
* Flags associated with the application. Any combination of
|
||||||
|
|||||||
@@ -945,15 +945,25 @@ public class PackageParser {
|
|||||||
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
|
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
|
||||||
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
|
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
|
||||||
}
|
}
|
||||||
|
int densities[] = null;
|
||||||
int size = pkg.supportsDensityList.size();
|
int size = pkg.supportsDensityList.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
int densities[] = pkg.supportsDensities = new int[size];
|
densities = pkg.supportsDensities = new int[size];
|
||||||
List<Integer> densityList = pkg.supportsDensityList;
|
List<Integer> densityList = pkg.supportsDensityList;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
densities[i] = densityList.get(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;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,18 +50,6 @@ public class CompatibilityInfo {
|
|||||||
*/
|
*/
|
||||||
public static final int DEFAULT_PORTRAIT_HEIGHT = 480;
|
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
|
* A compatibility flags
|
||||||
*/
|
*/
|
||||||
@@ -106,20 +94,6 @@ public class CompatibilityInfo {
|
|||||||
*/
|
*/
|
||||||
public final int appFlags;
|
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) {
|
public CompatibilityInfo(ApplicationInfo appInfo) {
|
||||||
appFlags = appInfo.flags;
|
appFlags = appInfo.flags;
|
||||||
|
|
||||||
@@ -153,6 +127,7 @@ public class CompatibilityInfo {
|
|||||||
applicationScale =
|
applicationScale =
|
||||||
DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
|
DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationInvertedScale = 1.0f / applicationScale;
|
applicationInvertedScale = 1.0f / applicationScale;
|
||||||
if (applicationScale != 1.0f) {
|
if (applicationScale != 1.0f) {
|
||||||
mCompatibilityFlags |= SCALING_REQUIRED;
|
mCompatibilityFlags |= SCALING_REQUIRED;
|
||||||
@@ -181,22 +156,9 @@ public class CompatibilityInfo {
|
|||||||
public CompatibilityInfo copy() {
|
public CompatibilityInfo copy() {
|
||||||
CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
|
CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
|
||||||
applicationScale, applicationInvertedScale);
|
applicationScale, applicationInvertedScale);
|
||||||
info.setVisibleRect(mXOffset, mWidth, mHeight);
|
|
||||||
return info;
|
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.
|
* Sets expandable bit in the compatibility flag.
|
||||||
*/
|
*/
|
||||||
@@ -222,6 +184,10 @@ public class CompatibilityInfo {
|
|||||||
return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
|
return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean supportsScreen() {
|
||||||
|
return (mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CompatibilityInfo{scale=" + applicationScale +
|
return "CompatibilityInfo{scale=" + applicationScale +
|
||||||
@@ -231,21 +197,6 @@ public class CompatibilityInfo {
|
|||||||
/**
|
/**
|
||||||
* Returns the translator which can translate the coordinates of the window.
|
* Returns the translator which can translate the coordinates of the window.
|
||||||
* There are five different types of Translator.
|
* 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
|
* @param params the window's parameter
|
||||||
*/
|
*/
|
||||||
public Translator getTranslator(WindowManager.LayoutParams params) {
|
public Translator getTranslator(WindowManager.LayoutParams params) {
|
||||||
@@ -254,35 +205,11 @@ public class CompatibilityInfo {
|
|||||||
if (DBG) Log.d(TAG, "no translation required");
|
if (DBG) Log.d(TAG, "no translation required");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (!isScalingRequired() ||
|
||||||
if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
|
(params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 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 {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return new Translator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,181 +217,79 @@ public class CompatibilityInfo {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class Translator {
|
public class Translator {
|
||||||
final private int mShiftMode;
|
|
||||||
final public boolean scalingRequired;
|
|
||||||
final public float applicationScale;
|
final public float applicationScale;
|
||||||
final public float applicationInvertedScale;
|
final public float applicationInvertedScale;
|
||||||
|
|
||||||
private Rect mContentInsetsBuffer = null;
|
private Rect mContentInsetsBuffer = null;
|
||||||
private Rect mVisibleInsets = null;
|
private Rect mVisibleInsetsBuffer = null;
|
||||||
|
|
||||||
Translator(int shiftMode, boolean scalingRequired, float applicationScale,
|
Translator(float applicationScale, float applicationInvertedScale) {
|
||||||
float applicationInvertedScale) {
|
|
||||||
mShiftMode = shiftMode;
|
|
||||||
this.scalingRequired = scalingRequired;
|
|
||||||
this.applicationScale = applicationScale;
|
this.applicationScale = applicationScale;
|
||||||
this.applicationInvertedScale = applicationInvertedScale;
|
this.applicationInvertedScale = applicationInvertedScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator(int shiftMode) {
|
|
||||||
this(shiftMode,
|
|
||||||
isScalingRequired(),
|
|
||||||
CompatibilityInfo.this.applicationScale,
|
|
||||||
CompatibilityInfo.this.applicationInvertedScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
Translator() {
|
Translator() {
|
||||||
this(X_SHIFT_NONE);
|
this(CompatibilityInfo.this.applicationScale,
|
||||||
|
CompatibilityInfo.this.applicationInvertedScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate the screen rect to the application frame.
|
* Translate the screen rect to the application frame.
|
||||||
*/
|
*/
|
||||||
public void translateRectInScreenToAppWinFrame(Rect rect) {
|
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.
|
* Translate the region in window to screen.
|
||||||
*/
|
*/
|
||||||
public void translateRegionInWindowToScreen(Region transparentRegion) {
|
public void translateRegionInWindowToScreen(Region transparentRegion) {
|
||||||
switch (mShiftMode) {
|
|
||||||
case X_SHIFT_AND_CLIP_CONTENT:
|
|
||||||
case X_SHIFT_CONTENT:
|
|
||||||
transparentRegion.scale(applicationScale);
|
transparentRegion.scale(applicationScale);
|
||||||
transparentRegion.translate(mXOffset, 0);
|
|
||||||
break;
|
|
||||||
case X_SHIFT_WINDOW:
|
|
||||||
case X_SHIFT_NONE:
|
|
||||||
transparentRegion.scale(applicationScale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply translation to the canvas that is necessary to draw the content.
|
* Apply translation to the canvas that is necessary to draw the content.
|
||||||
*/
|
*/
|
||||||
public void translateCanvas(Canvas canvas) {
|
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.
|
* Translate the motion event captured on screen to the application's window.
|
||||||
*/
|
*/
|
||||||
public void translateEventInScreenToAppWindow(MotionEvent event) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate the window's layout parameter, from application's view to
|
* Translate the window's layout parameter, from application's view to
|
||||||
* Screen's view.
|
* Screen's view.
|
||||||
*/
|
*/
|
||||||
public void translateWindowLayout(WindowManager.LayoutParams params) {
|
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);
|
params.scale(applicationScale);
|
||||||
break;
|
|
||||||
case X_SHIFT_WINDOW:
|
|
||||||
params.scale(applicationScale);
|
|
||||||
params.x += mXOffset;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate a Rect in application's window to screen.
|
* Translate a Rect in application's window to screen.
|
||||||
*/
|
*/
|
||||||
public void translateRectInAppWindowToScreen(Rect rect) {
|
public void translateRectInAppWindowToScreen(Rect rect) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
if (scalingRequired) {
|
|
||||||
rect.scale(applicationScale);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate a Rect in screen coordinates into the app window's coordinates.
|
* Translate a Rect in screen coordinates into the app window's coordinates.
|
||||||
*/
|
*/
|
||||||
public void translateRectInScreenToAppWindow(Rect rect) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate the location of the sub window.
|
* Translate the location of the sub window.
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) {
|
public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) {
|
||||||
if (scalingRequired) {
|
|
||||||
params.scale(applicationScale);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate the content insets in application window to Screen. This uses
|
* Translate the content insets in application window to Screen. This uses
|
||||||
@@ -482,10 +307,31 @@ public class CompatibilityInfo {
|
|||||||
* the internal buffer for content insets to avoid extra object allocation.
|
* the internal buffer for content insets to avoid extra object allocation.
|
||||||
*/
|
*/
|
||||||
public Rect getTranslatedVisbileInsets(Rect visibleInsets) {
|
public Rect getTranslatedVisbileInsets(Rect visibleInsets) {
|
||||||
if (mVisibleInsets == null) mVisibleInsets = new Rect();
|
if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect();
|
||||||
mVisibleInsets.set(visibleInsets);
|
mVisibleInsetsBuffer.set(visibleInsets);
|
||||||
translateRectInAppWindowToScreen(mVisibleInsets);
|
translateRectInAppWindowToScreen(mVisibleInsetsBuffer);
|
||||||
return mVisibleInsets;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ public class DisplayMetrics {
|
|||||||
*/
|
*/
|
||||||
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
|
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
|
||||||
int screenLayout) {
|
int screenLayout) {
|
||||||
int xOffset = 0;
|
|
||||||
if (!compatibilityInfo.isConfiguredExpandable()) {
|
if (!compatibilityInfo.isConfiguredExpandable()) {
|
||||||
// Note: this assume that configuration is updated before calling
|
// Note: this assume that configuration is updated before calling
|
||||||
// updateMetrics method.
|
// updateMetrics method.
|
||||||
@@ -142,7 +141,6 @@ public class DisplayMetrics {
|
|||||||
|
|
||||||
if (defaultWidth < widthPixels) {
|
if (defaultWidth < widthPixels) {
|
||||||
// content/window's x offset in original pixels
|
// content/window's x offset in original pixels
|
||||||
xOffset = ((widthPixels - defaultWidth) / 2);
|
|
||||||
widthPixels = defaultWidth;
|
widthPixels = defaultWidth;
|
||||||
}
|
}
|
||||||
if (defaultHeight < heightPixels) {
|
if (defaultHeight < heightPixels) {
|
||||||
@@ -154,7 +152,6 @@ public class DisplayMetrics {
|
|||||||
compatibilityInfo.setExpandable(true);
|
compatibilityInfo.setExpandable(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
|
|
||||||
if (compatibilityInfo.isScalingRequired()) {
|
if (compatibilityInfo.isScalingRequired()) {
|
||||||
float invertedRatio = compatibilityInfo.applicationInvertedScale;
|
float invertedRatio = compatibilityInfo.applicationInvertedScale;
|
||||||
density *= invertedRatio;
|
density *= invertedRatio;
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ public class SurfaceView extends View {
|
|||||||
|
|
||||||
// Use original size if the app specified the size of the view,
|
// Use original size if the app specified the size of the view,
|
||||||
// and let the flinger to scale up.
|
// and let the flinger to scale up.
|
||||||
if (mRequestedWidth <= 0 && mTranslator != null && mTranslator.scalingRequired) {
|
if (mRequestedWidth <= 0 && mTranslator != null) {
|
||||||
myWidth *= appScale;
|
myWidth *= appScale;
|
||||||
myHeight *= appScale;
|
myHeight *= appScale;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,6 +385,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
if (mView == null) {
|
if (mView == null) {
|
||||||
mView = view;
|
mView = view;
|
||||||
mWindowAttributes.copyFrom(attrs);
|
mWindowAttributes.copyFrom(attrs);
|
||||||
|
attrs = mWindowAttributes;
|
||||||
|
|
||||||
CompatibilityInfo compatibilityInfo =
|
CompatibilityInfo compatibilityInfo =
|
||||||
mView.getContext().getResources().getCompatibilityInfo();
|
mView.getContext().getResources().getCompatibilityInfo();
|
||||||
@@ -397,11 +398,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
}
|
}
|
||||||
if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
|
if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
|
||||||
|
|
||||||
|
if (!compatibilityInfo.supportsScreen()) {
|
||||||
|
attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
|
||||||
|
}
|
||||||
|
|
||||||
mSoftInputMode = attrs.softInputMode;
|
mSoftInputMode = attrs.softInputMode;
|
||||||
mWindowAttributesChanged = true;
|
mWindowAttributesChanged = true;
|
||||||
mAttachInfo.mRootView = view;
|
mAttachInfo.mRootView = view;
|
||||||
mAttachInfo.mScalingRequired =
|
mAttachInfo.mScalingRequired = mTranslator == null ? false : true;
|
||||||
mTranslator == null ? false : mTranslator.scalingRequired;
|
|
||||||
mAttachInfo.mApplicationScale =
|
mAttachInfo.mApplicationScale =
|
||||||
mTranslator == null ? 1.0f : mTranslator.applicationScale;
|
mTranslator == null ? 1.0f : mTranslator.applicationScale;
|
||||||
if (panelParentView != null) {
|
if (panelParentView != null) {
|
||||||
|
|||||||
@@ -484,11 +484,19 @@ public interface WindowManager extends ViewManager {
|
|||||||
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
|
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
|
||||||
|
|
||||||
/** Window flag: special flag to let a window ignore the compatibility scaling.
|
/** 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} */
|
* {@hide} */
|
||||||
public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
|
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
|
/** Window flag: a special option intended for system dialogs. When
|
||||||
* this flag is set, the window will demand focus unconditionally when
|
* this flag is set, the window will demand focus unconditionally when
|
||||||
* it is created.
|
* it is created.
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import android.app.IActivityManager;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.CompatibilityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
@@ -418,6 +419,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
final Configuration mTempConfiguration = new Configuration();
|
final Configuration mTempConfiguration = new Configuration();
|
||||||
int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
|
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,
|
public static WindowManagerService main(Context context,
|
||||||
PowerManagerService pm, boolean haveInputMethods) {
|
PowerManagerService pm, boolean haveInputMethods) {
|
||||||
WMThread thr = new WMThread(context, pm, haveInputMethods);
|
WMThread thr = new WMThread(context, pm, haveInputMethods);
|
||||||
@@ -3738,12 +3745,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
}
|
}
|
||||||
config.orientation = orientation;
|
config.orientation = orientation;
|
||||||
|
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
mDisplay.getMetrics(dm);
|
||||||
|
CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
|
||||||
|
|
||||||
if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
|
if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
|
||||||
// Note we only do this once because at this point we don't
|
// 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
|
// expect the screen to change in this way at runtime, and want
|
||||||
// to avoid all of this computation for every config change.
|
// to avoid all of this computation for every config change.
|
||||||
DisplayMetrics dm = new DisplayMetrics();
|
|
||||||
mDisplay.getMetrics(dm);
|
|
||||||
int longSize = dw;
|
int longSize = dw;
|
||||||
int shortSize = dh;
|
int shortSize = dh;
|
||||||
if (longSize < shortSize) {
|
if (longSize < shortSize) {
|
||||||
@@ -5845,8 +5854,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
|
public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
|
||||||
mHaveFrame = true;
|
mHaveFrame = true;
|
||||||
|
|
||||||
final int pw = pf.right-pf.left;
|
final Rect container = mContainingFrame;
|
||||||
final int ph = pf.bottom-pf.top;
|
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;
|
int w,h;
|
||||||
if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
|
if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
|
||||||
@@ -5857,12 +5877,6 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight;
|
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;
|
final Rect content = mContentFrame;
|
||||||
content.set(cf);
|
content.set(cf);
|
||||||
|
|
||||||
@@ -6573,16 +6587,29 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isFullscreenOpaque(int screenWidth, int screenHeight) {
|
/**
|
||||||
if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null
|
* Return true if the window is opaque and fully drawn.
|
||||||
|| mAnimation != null || mDrawPending || mCommitDrawPending) {
|
*/
|
||||||
return false;
|
boolean isOpaqueDrawn() {
|
||||||
|
return mAttrs.format == PixelFormat.OPAQUE && mSurface != null
|
||||||
|
&& mAnimation == null && !mDrawPending && !mCommitDrawPending;
|
||||||
}
|
}
|
||||||
if (mFrame.left <= 0 && mFrame.top <= 0 &&
|
|
||||||
mFrame.right >= screenWidth && mFrame.bottom >= screenHeight) {
|
boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
|
||||||
return true;
|
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);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
boolean isFullscreen(int screenWidth, int screenHeight) {
|
||||||
|
return mFrame.left <= 0 && mFrame.top <= 0 &&
|
||||||
|
mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeLocked() {
|
void removeLocked() {
|
||||||
@@ -8102,6 +8129,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
boolean dimming = false;
|
boolean dimming = false;
|
||||||
boolean covered = false;
|
boolean covered = false;
|
||||||
boolean syswin = false;
|
boolean syswin = false;
|
||||||
|
boolean backgroundFillerShown = false;
|
||||||
|
|
||||||
for (i=N-1; i>=0; i--) {
|
for (i=N-1; i>=0; i--) {
|
||||||
WindowState w = (WindowState)mWindows.get(i);
|
WindowState w = (WindowState)mWindows.get(i);
|
||||||
@@ -8371,11 +8399,39 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
|
|||||||
syswin = true;
|
syswin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w.isFullscreenOpaque(dw, dh)) {
|
|
||||||
|
boolean opaqueDrawn = w.isOpaqueDrawn();
|
||||||
|
if (opaqueDrawn && w.isFullscreen(dw, dh)) {
|
||||||
// This window completely covers everything behind it,
|
// This window completely covers everything behind it,
|
||||||
// so we want to leave all of them as unblurred (for
|
// so we want to leave all of them as unblurred (for
|
||||||
// performance reasons).
|
// performance reasons).
|
||||||
obscured = true;
|
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 &&
|
} else if (canBeSeen && !obscured &&
|
||||||
(attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
|
(attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
|
||||||
if (localLOGV) Log.v(TAG, "Win " + w
|
if (localLOGV) Log.v(TAG, "Win " + w
|
||||||
@@ -8473,6 +8529,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) {
|
if (!dimming && mDimShown) {
|
||||||
// Time to hide the dim surface... start fading.
|
// Time to hide the dim surface... start fading.
|
||||||
if (mDimTargetAlpha != 0) {
|
if (mDimTargetAlpha != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user