Merge change 5091 into donut
* changes: * new screen resolution support impl. * use full window for activities, and shift & clip the content * refactored the compatibility code, and introdcued Translator class to handle cooridnate translations. * removed a workaround to handle an activity with configChagne=rotation in old implementation. * I'll fix background issue on rotation in next CL.
This commit is contained in:
@@ -17,8 +17,15 @@
|
||||
package android.content.res;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
|
||||
/**
|
||||
* CompatibilityInfo class keeps the information about compatibility mode that the application is
|
||||
@@ -27,6 +34,9 @@ import android.view.Gravity;
|
||||
* {@hide}
|
||||
*/
|
||||
public class CompatibilityInfo {
|
||||
private static final boolean DBG = false;
|
||||
private static final String TAG = "CompatibilityInfo";
|
||||
|
||||
/** default compatibility info object for compatible applications */
|
||||
public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo();
|
||||
|
||||
@@ -40,37 +50,76 @@ 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 compatibilityFlags;
|
||||
|
||||
/**
|
||||
* A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f)
|
||||
* {@see compatibilityFlag}
|
||||
*/
|
||||
private static final int SCALING_REQUIRED = 1;
|
||||
|
||||
/**
|
||||
* A flag mask to indicates that the application can expand over the original size.
|
||||
* The flag is set to true if
|
||||
* 1) Application declares its expandable in manifest file using <expandable /> or
|
||||
* 2) The screen size is same as (320 x 480) * density.
|
||||
* {@see compatibilityFlag}
|
||||
*/
|
||||
private static final int EXPANDABLE = 2;
|
||||
|
||||
/**
|
||||
* A flag mask to tell if the application is configured to be expandable. This differs
|
||||
* from EXPANDABLE in that the application that is not expandable will be
|
||||
* marked as expandable if it runs in (320x 480) * density screen size.
|
||||
*/
|
||||
private static final int CONFIGURED_EXPANDABLE = 4;
|
||||
|
||||
private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;
|
||||
|
||||
/**
|
||||
* Application's scale.
|
||||
*/
|
||||
public final float mApplicationScale;
|
||||
public final float applicationScale;
|
||||
|
||||
/**
|
||||
* Application's inverted scale.
|
||||
*/
|
||||
public final float mApplicationInvertedScale;
|
||||
|
||||
/**
|
||||
* A boolean flag to indicates that the application can expand over the original size.
|
||||
* The flag is set to true if
|
||||
* 1) Application declares its expandable in manifest file using <expandable /> or
|
||||
* 2) The screen size is same as (320 x 480) * density.
|
||||
*/
|
||||
public boolean mExpandable;
|
||||
public final float applicationInvertedScale;
|
||||
|
||||
|
||||
/**
|
||||
* A expandable flag in the configuration.
|
||||
* Window size in Compatibility Mode, in real pixels. This is updated by
|
||||
* {@link DisplayMetrics#updateMetrics}.
|
||||
*/
|
||||
public final boolean mConfiguredExpandable;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
/**
|
||||
* A boolean flag to tell if the application needs scaling (when mApplicationScale != 1.0f)
|
||||
* 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.
|
||||
*/
|
||||
public final boolean mScalingRequired;
|
||||
private int mXOffset;
|
||||
|
||||
public CompatibilityInfo(ApplicationInfo appInfo) {
|
||||
mExpandable = mConfiguredExpandable =
|
||||
(appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0;
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
|
||||
compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
|
||||
}
|
||||
|
||||
float packageDensityScale = -1.0f;
|
||||
if (appInfo.supportsDensities != null) {
|
||||
@@ -93,23 +142,323 @@ public class CompatibilityInfo {
|
||||
}
|
||||
}
|
||||
if (packageDensityScale > 0.0f) {
|
||||
mApplicationScale = packageDensityScale;
|
||||
applicationScale = packageDensityScale;
|
||||
} else {
|
||||
mApplicationScale = DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
|
||||
applicationScale =
|
||||
DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
|
||||
}
|
||||
applicationInvertedScale = 1.0f / applicationScale;
|
||||
if (applicationScale != 1.0f) {
|
||||
compatibilityFlags |= SCALING_REQUIRED;
|
||||
}
|
||||
mApplicationInvertedScale = 1.0f / mApplicationScale;
|
||||
mScalingRequired = mApplicationScale != 1.0f;
|
||||
}
|
||||
|
||||
private CompatibilityInfo() {
|
||||
mApplicationScale = mApplicationInvertedScale = 1.0f;
|
||||
mExpandable = mConfiguredExpandable = true;
|
||||
mScalingRequired = false;
|
||||
applicationScale = applicationInvertedScale = 1.0f;
|
||||
compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (expandable) {
|
||||
compatibilityFlags |= CompatibilityInfo.EXPANDABLE;
|
||||
} else {
|
||||
compatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the application is configured to be expandable.
|
||||
*/
|
||||
public boolean isConfiguredExpandable() {
|
||||
return (compatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the scaling is required
|
||||
*/
|
||||
public boolean isScalingRequired() {
|
||||
return (compatibilityFlags & SCALING_REQUIRED) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompatibilityInfo{scale=" + mApplicationScale +
|
||||
", expandable=" + mExpandable + "}";
|
||||
return "CompatibilityInfo{scale=" + applicationScale +
|
||||
", compatibility flag=" + compatibilityFlags + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if ( (compatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
|
||||
== CompatibilityInfo.EXPANDABLE) {
|
||||
if (DBG) Log.d(TAG, "no translation required");
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((compatibilityFlags & 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 {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper object to translate the screen and window coordinates back and forth.
|
||||
* @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;
|
||||
|
||||
Translator(int shiftMode, boolean scalingRequired, float applicationScale,
|
||||
float applicationInvertedScale) {
|
||||
mShiftMode = shiftMode;
|
||||
this.scalingRequired = scalingRequired;
|
||||
this.applicationScale = applicationScale;
|
||||
this.applicationInvertedScale = applicationInvertedScale;
|
||||
}
|
||||
|
||||
Translator(int shiftMode) {
|
||||
this(shiftMode,
|
||||
isScalingRequired(),
|
||||
CompatibilityInfo.this.applicationScale,
|
||||
CompatibilityInfo.this.applicationInvertedScale);
|
||||
}
|
||||
|
||||
Translator() {
|
||||
this(X_SHIFT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the window's layout parameter, from application's view to
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the location of the sub window.
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the content insets in application window to Screen. This uses
|
||||
* the internal buffer for content insets to avoid extra object allocation.
|
||||
*/
|
||||
public Rect getTranslatedContentInsets(Rect contentInsets) {
|
||||
if (mContentInsetsBuffer == null) mContentInsetsBuffer = new Rect();
|
||||
mContentInsetsBuffer.set(contentInsets);
|
||||
translateRectInAppWindowToScreen(mContentInsetsBuffer);
|
||||
return mContentInsetsBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the visible insets in application window to Screen. This uses
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,10 +158,10 @@ public class Resources {
|
||||
}
|
||||
updateConfiguration(config, metrics);
|
||||
assets.ensureStringBlocks();
|
||||
if (!mCompatibilityInfo.mScalingRequired) {
|
||||
mPreloadedDrawables = sPreloadedDrawables;
|
||||
} else {
|
||||
if (mCompatibilityInfo.isScalingRequired()) {
|
||||
mPreloadedDrawables = emptySparseArray();
|
||||
} else {
|
||||
mPreloadedDrawables = sPreloadedDrawables;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,16 +106,8 @@ public class DisplayMetrics {
|
||||
* {@hide}
|
||||
*/
|
||||
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
|
||||
if (compatibilityInfo.mScalingRequired) {
|
||||
float invertedRatio = compatibilityInfo.mApplicationInvertedScale;
|
||||
density *= invertedRatio;
|
||||
scaledDensity *= invertedRatio;
|
||||
xdpi *= invertedRatio;
|
||||
ydpi *= invertedRatio;
|
||||
widthPixels *= invertedRatio;
|
||||
heightPixels *= invertedRatio;
|
||||
}
|
||||
if (!compatibilityInfo.mConfiguredExpandable) {
|
||||
int xOffset = 0;
|
||||
if (!compatibilityInfo.isConfiguredExpandable()) {
|
||||
// Note: this assume that configuration is updated before calling
|
||||
// updateMetrics method.
|
||||
int defaultWidth;
|
||||
@@ -141,11 +133,13 @@ public class DisplayMetrics {
|
||||
|
||||
if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
|
||||
// the screen size is same as expected size. make it expandable
|
||||
compatibilityInfo.mExpandable = true;
|
||||
compatibilityInfo.setExpandable(true);
|
||||
} else {
|
||||
compatibilityInfo.mExpandable = false;
|
||||
compatibilityInfo.setExpandable(false);
|
||||
// adjust the size only when the device's screen is bigger.
|
||||
if (defaultWidth < widthPixels) {
|
||||
// content/window's x offset in original pixels
|
||||
xOffset = ((widthPixels - defaultWidth) / 2);
|
||||
widthPixels = defaultWidth;
|
||||
}
|
||||
if (defaultHeight < heightPixels) {
|
||||
@@ -153,8 +147,19 @@ public class DisplayMetrics {
|
||||
}
|
||||
}
|
||||
}
|
||||
compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
|
||||
if (compatibilityInfo.isScalingRequired()) {
|
||||
float invertedRatio = compatibilityInfo.applicationInvertedScale;
|
||||
density *= invertedRatio;
|
||||
scaledDensity *= invertedRatio;
|
||||
xdpi *= invertedRatio;
|
||||
ydpi *= invertedRatio;
|
||||
widthPixels *= invertedRatio;
|
||||
heightPixels *= invertedRatio;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DisplayMetrics{density=" + density + ", width=" + widthPixels +
|
||||
", height=" + heightPixels + ", scaledDensity=" + scaledDensity +
|
||||
|
||||
@@ -212,28 +212,47 @@ public final class MotionEvent implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales down the cood of this event by the given scale.
|
||||
* Scales down the coordination of this event by the given scale.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void scale(float scale) {
|
||||
if (scale != 1.0f) {
|
||||
mX *= scale;
|
||||
mY *= scale;
|
||||
mRawX *= scale;
|
||||
mRawY *= scale;
|
||||
mSize *= scale;
|
||||
mXPrecision *= scale;
|
||||
mYPrecision *= scale;
|
||||
if (mHistory != null) {
|
||||
float[] history = mHistory;
|
||||
int length = history.length;
|
||||
for (int i = 0; i < length; i += 4) {
|
||||
history[i] *= scale; // X
|
||||
// history[i + 2] == pressure
|
||||
history[i + 1] *= scale; // Y
|
||||
history[i + 3] *= scale; // Size, TODO: square this?
|
||||
}
|
||||
mX *= scale;
|
||||
mY *= scale;
|
||||
mRawX *= scale;
|
||||
mRawY *= scale;
|
||||
mSize *= scale;
|
||||
mXPrecision *= scale;
|
||||
mYPrecision *= scale;
|
||||
if (mHistory != null) {
|
||||
float[] history = mHistory;
|
||||
int length = history.length;
|
||||
for (int i = 0; i < length; i += 4) {
|
||||
history[i] *= scale; // X
|
||||
history[i + 1] *= scale; // Y
|
||||
// no need to scale pressure ([i+2])
|
||||
history[i + 3] *= scale; // Size, TODO: square this?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the coordination of the event by given x and y.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void translate(float dx, float dy) {
|
||||
mX += dx;
|
||||
mY += dy;
|
||||
mRawX += dx;
|
||||
mRawY += dx;
|
||||
if (mHistory != null) {
|
||||
float[] history = mHistory;
|
||||
int length = history.length;
|
||||
for (int i = 0; i < length; i += 4) {
|
||||
history[i] += dx; // X
|
||||
history[i + 1] += dy; // Y
|
||||
// no need to translate pressure (i+2) and size (i+3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.CompatibilityInfo.Translator;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
@@ -138,24 +139,21 @@ public class SurfaceView extends View {
|
||||
int mFormat = -1;
|
||||
int mType = -1;
|
||||
final Rect mSurfaceFrame = new Rect();
|
||||
private final CompatibilityInfo mCompatibilityInfo;
|
||||
private Translator mTranslator;
|
||||
|
||||
public SurfaceView(Context context) {
|
||||
super(context);
|
||||
setWillNotDraw(true);
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public SurfaceView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(true);
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setWillNotDraw(true);
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,9 +256,9 @@ public class SurfaceView extends View {
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
// SurfaceView uses pre-scaled size unless fixed size is requested. This hook
|
||||
// scales the event back to the pre-scaled coordinates for such surface.
|
||||
if (mRequestedWidth < 0 && mCompatibilityInfo.mScalingRequired) {
|
||||
if (mRequestedWidth < 0 && mTranslator != null) {
|
||||
MotionEvent scaledBack = MotionEvent.obtain(event);
|
||||
scaledBack.scale(mCompatibilityInfo.mApplicationScale);
|
||||
scaledBack.scale(mTranslator.applicationScale);
|
||||
try {
|
||||
return super.dispatchTouchEvent(scaledBack);
|
||||
} finally {
|
||||
@@ -297,15 +295,18 @@ public class SurfaceView extends View {
|
||||
if (!mHaveFrame) {
|
||||
return;
|
||||
}
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
mTranslator = ((ViewRoot)getRootView().getParent()).mTranslator;
|
||||
|
||||
float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
|
||||
|
||||
int myWidth = mRequestedWidth;
|
||||
if (myWidth <= 0) myWidth = getWidth();
|
||||
int myHeight = mRequestedHeight;
|
||||
if (myHeight <= 0) myHeight = getHeight();
|
||||
|
||||
// Use original size for surface unless fixed size is requested.
|
||||
if (mRequestedWidth <= 0 && mCompatibilityInfo.mScalingRequired) {
|
||||
// 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) {
|
||||
myWidth *= appScale;
|
||||
myHeight *= appScale;
|
||||
}
|
||||
@@ -325,7 +326,7 @@ public class SurfaceView extends View {
|
||||
+ " visible=" + visibleChanged
|
||||
+ " left=" + (mLeft != mLocation[0])
|
||||
+ " top=" + (mTop != mLocation[1]));
|
||||
|
||||
|
||||
try {
|
||||
final boolean visible = mVisible = mRequestedVisible;
|
||||
mLeft = mLocation[0];
|
||||
@@ -335,16 +336,23 @@ public class SurfaceView extends View {
|
||||
mFormat = mRequestedFormat;
|
||||
mType = mRequestedType;
|
||||
|
||||
// Scaling window's layout here because mLayout is not used elsewhere.
|
||||
mLayout.x = (int) (mLeft * appScale);
|
||||
mLayout.y = (int) (mTop * appScale);
|
||||
mLayout.width = (int) (getWidth() * appScale);
|
||||
mLayout.height = (int) (getHeight() * appScale);
|
||||
// Scaling/Translate window's layout here because mLayout is not used elsewhere.
|
||||
|
||||
// Places the window relative
|
||||
mLayout.x = mLeft;
|
||||
mLayout.y = mTop;
|
||||
mLayout.width = getWidth();
|
||||
mLayout.height = getHeight();
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
|
||||
}
|
||||
|
||||
mLayout.format = mRequestedFormat;
|
||||
mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||
| WindowManager.LayoutParams.FLAG_SCALED
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||
| WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING
|
||||
;
|
||||
|
||||
mLayout.memoryType = mRequestedType;
|
||||
@@ -371,13 +379,6 @@ public class SurfaceView extends View {
|
||||
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
|
||||
mVisibleInsets, mSurface);
|
||||
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
mContentInsets.scale(invertedScale);
|
||||
mVisibleInsets.scale(invertedScale);
|
||||
mWinFrame.scale(invertedScale);
|
||||
}
|
||||
|
||||
if (localLOGV) Log.i(TAG, "New surface: " + mSurface
|
||||
+ ", vis=" + visible + ", frame=" + mWinFrame);
|
||||
mSurfaceFrame.left = 0;
|
||||
@@ -446,24 +447,14 @@ public class SurfaceView extends View {
|
||||
|
||||
private static class MyWindow extends IWindow.Stub {
|
||||
private final WeakReference<SurfaceView> mSurfaceView;
|
||||
private final CompatibilityInfo mCompatibilityInfo;
|
||||
|
||||
public MyWindow(SurfaceView surfaceView) {
|
||||
mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
|
||||
mCompatibilityInfo = surfaceView.getContext().getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public void resized(int w, int h, Rect coveredInsets,
|
||||
Rect visibleInsets, boolean reportDraw) {
|
||||
SurfaceView surfaceView = mSurfaceView.get();
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
float scale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
w *= scale;
|
||||
h *= scale;
|
||||
coveredInsets.scale(scale);
|
||||
visibleInsets.scale(scale);
|
||||
}
|
||||
|
||||
if (surfaceView != null) {
|
||||
if (localLOGV) Log.v(
|
||||
"SurfaceView", surfaceView + " got resized: w=" +
|
||||
@@ -626,9 +617,6 @@ public class SurfaceView extends View {
|
||||
Canvas c = null;
|
||||
if (!mDrawingStopped && mWindow != null) {
|
||||
Rect frame = dirty != null ? dirty : mSurfaceFrame;
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
frame.scale(mCompatibilityInfo.mApplicationScale);
|
||||
}
|
||||
try {
|
||||
c = mSurface.lockCanvas(frame);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -6543,7 +6543,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
boolean changed = false;
|
||||
|
||||
if (DBG) {
|
||||
System.out.println(this + " View.setFrame(" + left + "," + top + ","
|
||||
Log.d("View", this + " View.setFrame(" + left + "," + top + ","
|
||||
+ right + "," + bottom + ")");
|
||||
}
|
||||
|
||||
|
||||
@@ -128,13 +128,12 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
Rect mDirty; // will be a graphics.Region soon
|
||||
boolean mIsAnimating;
|
||||
|
||||
private CompatibilityInfo mCompatibilityInfo;
|
||||
CompatibilityInfo.Translator mTranslator;
|
||||
|
||||
final View.AttachInfo mAttachInfo;
|
||||
|
||||
final Rect mTempRect; // used in the transaction to not thrash the heap.
|
||||
final Rect mVisRect; // used to retrieve visible rect of focused view.
|
||||
final Point mVisPoint; // used to retrieve global offset of focused view.
|
||||
|
||||
boolean mTraversalScheduled;
|
||||
boolean mWillDrawSoon;
|
||||
@@ -218,7 +217,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mDirty = new Rect();
|
||||
mTempRect = new Rect();
|
||||
mVisRect = new Rect();
|
||||
mVisPoint = new Point();
|
||||
mWinFrame = new Rect();
|
||||
mWindow = new W(this, context);
|
||||
mInputMethodCallback = new InputMethodCallback(this);
|
||||
@@ -387,20 +385,25 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
if (mView == null) {
|
||||
mView = view;
|
||||
mWindowAttributes.copyFrom(attrs);
|
||||
mCompatibilityInfo = mView.getContext().getResources().getCompatibilityInfo();
|
||||
|
||||
CompatibilityInfo compatibilityInfo =
|
||||
mView.getContext().getResources().getCompatibilityInfo();
|
||||
mTranslator = compatibilityInfo.getTranslator(attrs);
|
||||
boolean restore = false;
|
||||
if (mCompatibilityInfo.mScalingRequired || !mCompatibilityInfo.mExpandable) {
|
||||
if (attrs != null && mTranslator != null) {
|
||||
restore = true;
|
||||
mWindowAttributes.backup();
|
||||
}
|
||||
if (!mCompatibilityInfo.mExpandable) {
|
||||
adjustWindowAttributesForCompatibleMode(mWindowAttributes);
|
||||
attrs.backup();
|
||||
mTranslator.translateWindowLayout(attrs);
|
||||
}
|
||||
if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
|
||||
|
||||
mSoftInputMode = attrs.softInputMode;
|
||||
mWindowAttributesChanged = true;
|
||||
mAttachInfo.mRootView = view;
|
||||
mAttachInfo.mScalingRequired = mCompatibilityInfo.mScalingRequired;
|
||||
mAttachInfo.mApplicationScale = mCompatibilityInfo.mApplicationScale;
|
||||
mAttachInfo.mScalingRequired =
|
||||
mTranslator == null ? false : mTranslator.scalingRequired;
|
||||
mAttachInfo.mApplicationScale =
|
||||
mTranslator == null ? 1.0f : mTranslator.applicationScale;
|
||||
if (panelParentView != null) {
|
||||
mAttachInfo.mPanelParentWindowToken
|
||||
= panelParentView.getApplicationWindowToken();
|
||||
@@ -421,15 +424,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mAttachInfo.mRootView = null;
|
||||
unscheduleTraversals();
|
||||
throw new RuntimeException("Adding window failed", e);
|
||||
} finally {
|
||||
if (restore) {
|
||||
attrs.restore();
|
||||
}
|
||||
}
|
||||
|
||||
if (restore) {
|
||||
mWindowAttributes.restore();
|
||||
}
|
||||
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
mAttachInfo.mContentInsets.scale(
|
||||
mCompatibilityInfo.mApplicationInvertedScale);
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
|
||||
}
|
||||
mPendingContentInsets.set(mAttachInfo.mContentInsets);
|
||||
mPendingVisibleInsets.set(0, 0, 0, 0);
|
||||
@@ -541,14 +543,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|
||||
public void invalidateChild(View child, Rect dirty) {
|
||||
checkThread();
|
||||
if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty);
|
||||
if (mCurScrollY != 0 || mCompatibilityInfo.mScalingRequired) {
|
||||
if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
|
||||
if (mCurScrollY != 0 || mTranslator != null) {
|
||||
mTempRect.set(dirty);
|
||||
if (mCurScrollY != 0) {
|
||||
mTempRect.offset(0, -mCurScrollY);
|
||||
}
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
mTempRect.scale(mCompatibilityInfo.mApplicationScale);
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateRectInAppWindowToScreen(mTempRect);
|
||||
}
|
||||
dirty = mTempRect;
|
||||
}
|
||||
@@ -567,7 +569,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
|
||||
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
|
||||
if (child != mView) {
|
||||
throw new RuntimeException("child is not mine, honest!");
|
||||
}
|
||||
@@ -628,14 +630,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
boolean viewVisibilityChanged = mViewVisibility != viewVisibility
|
||||
|| mNewSurfaceNeeded;
|
||||
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
float appScale = mAttachInfo.mApplicationScale;
|
||||
|
||||
WindowManager.LayoutParams params = null;
|
||||
if (mWindowAttributesChanged) {
|
||||
mWindowAttributesChanged = false;
|
||||
params = lp;
|
||||
}
|
||||
|
||||
Rect frame = mWinFrame;
|
||||
if (mFirst) {
|
||||
fullRedrawNeeded = true;
|
||||
mLayoutRequested = true;
|
||||
@@ -660,11 +662,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
//Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
|
||||
|
||||
} else {
|
||||
desiredWindowWidth = mWinFrame.width();
|
||||
desiredWindowHeight = mWinFrame.height();
|
||||
desiredWindowWidth = frame.width();
|
||||
desiredWindowHeight = frame.height();
|
||||
if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
|
||||
if (DEBUG_ORIENTATION) Log.v("ViewRoot",
|
||||
"View " + host + " resized to: " + mWinFrame);
|
||||
"View " + host + " resized to: " + frame);
|
||||
fullRedrawNeeded = true;
|
||||
mLayoutRequested = true;
|
||||
windowResizesToFitContent = true;
|
||||
@@ -810,7 +812,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
final Rect frame = mWinFrame;
|
||||
boolean initialized = false;
|
||||
boolean contentInsetsChanged = false;
|
||||
boolean visibleInsetsChanged;
|
||||
@@ -883,7 +884,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
if (DEBUG_ORIENTATION) Log.v(
|
||||
"ViewRoot", "Relayout returned: frame=" + mWinFrame + ", surface=" + mSurface);
|
||||
"ViewRoot", "Relayout returned: frame=" + frame + ", surface=" + mSurface);
|
||||
|
||||
attachInfo.mWindowLeft = frame.left;
|
||||
attachInfo.mWindowTop = frame.top;
|
||||
@@ -958,7 +959,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
if (Config.DEBUG && ViewDebug.profileLayout) {
|
||||
startTime = SystemClock.elapsedRealtime();
|
||||
}
|
||||
|
||||
host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);
|
||||
|
||||
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
|
||||
@@ -985,7 +985,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mTmpLocation[1] + host.mBottom - host.mTop);
|
||||
|
||||
host.gatherTransparentRegion(mTransparentRegion);
|
||||
mTransparentRegion.scale(appScale);
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateRegionInWindowToScreen(mTransparentRegion);
|
||||
}
|
||||
|
||||
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
|
||||
mPreviousTransparentRegion.set(mTransparentRegion);
|
||||
// reconfigure window manager
|
||||
@@ -1016,15 +1019,17 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
= givenContent.bottom = givenVisible.left = givenVisible.top
|
||||
= givenVisible.right = givenVisible.bottom = 0;
|
||||
attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
insets.contentInsets.scale(appScale);
|
||||
insets.visibleInsets.scale(appScale);
|
||||
Rect contentInsets = insets.contentInsets;
|
||||
Rect visibleInsets = insets.visibleInsets;
|
||||
if (mTranslator != null) {
|
||||
contentInsets = mTranslator.getTranslatedContentInsets(contentInsets);
|
||||
visibleInsets = mTranslator.getTranslatedVisbileInsets(visibleInsets);
|
||||
}
|
||||
if (insetsPending || !mLastGivenInsets.equals(insets)) {
|
||||
mLastGivenInsets.set(insets);
|
||||
try {
|
||||
sWindowSession.setInsets(mWindow, insets.mTouchableInsets,
|
||||
insets.contentInsets, insets.visibleInsets);
|
||||
contentInsets, visibleInsets);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@@ -1167,8 +1172,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mCurScrollY = yoff;
|
||||
fullRedrawNeeded = true;
|
||||
}
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
|
||||
float appScale = mAttachInfo.mApplicationScale;
|
||||
boolean scalingRequired = mAttachInfo.mScalingRequired;
|
||||
|
||||
Rect dirty = mDirty;
|
||||
if (mUseGL) {
|
||||
@@ -1187,8 +1192,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
try {
|
||||
canvas.translate(0, -yoff);
|
||||
if (scalingRequired) {
|
||||
canvas.scale(appScale, appScale);
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateCanvas(canvas);
|
||||
}
|
||||
mView.draw(canvas);
|
||||
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
|
||||
@@ -1239,7 +1244,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
int top = dirty.top;
|
||||
int right = dirty.right;
|
||||
int bottom = dirty.bottom;
|
||||
|
||||
canvas = surface.lockCanvas(dirty);
|
||||
|
||||
if (left != dirty.left || top != dirty.top || right != dirty.right ||
|
||||
@@ -1295,8 +1299,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
try {
|
||||
canvas.translate(0, -yoff);
|
||||
if (scalingRequired) {
|
||||
canvas.scale(appScale, appScale);
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateCanvas(canvas);
|
||||
}
|
||||
mView.draw(canvas);
|
||||
} finally {
|
||||
@@ -1599,10 +1603,9 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
} else {
|
||||
didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
|
||||
}
|
||||
if (event != null && mCompatibilityInfo.mScalingRequired) {
|
||||
event.scale(mCompatibilityInfo.mApplicationInvertedScale);
|
||||
if (event != null && mTranslator != null) {
|
||||
mTranslator.translateEventInScreenToAppWindow(event);
|
||||
}
|
||||
|
||||
try {
|
||||
boolean handled;
|
||||
if (mView != null && mAdded && event != null) {
|
||||
@@ -1688,6 +1691,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
case RESIZED:
|
||||
Rect coveredInsets = ((Rect[])msg.obj)[0];
|
||||
Rect visibleInsets = ((Rect[])msg.obj)[1];
|
||||
|
||||
if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2
|
||||
&& mPendingContentInsets.equals(coveredInsets)
|
||||
&& mPendingVisibleInsets.equals(visibleInsets)) {
|
||||
@@ -1722,7 +1726,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
if (mGlWanted && !mUseGL) {
|
||||
initializeGL();
|
||||
if (mGlCanvas != null) {
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
float appScale = mAttachInfo.mApplicationScale;
|
||||
mGlCanvas.setViewport(
|
||||
(int) (mWidth * appScale), (int) (mHeight * appScale));
|
||||
}
|
||||
@@ -2356,18 +2360,16 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|
||||
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
|
||||
boolean insetsPending) throws RemoteException {
|
||||
|
||||
float appScale = mAttachInfo.mApplicationScale;
|
||||
boolean restore = false;
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
|
||||
if (params != null && !mCompatibilityInfo.mExpandable) {
|
||||
if (params != null && mTranslator != null) {
|
||||
restore = true;
|
||||
params.backup();
|
||||
adjustWindowAttributesForCompatibleMode(params);
|
||||
mTranslator.translateWindowLayout(params);
|
||||
}
|
||||
if (params != null && scalingRequired) {
|
||||
if (!restore) params.backup();
|
||||
restore = true;
|
||||
params.scale(appScale);
|
||||
if (params != null) {
|
||||
if (DBG) Log.d(TAG, "WindowLayout in layoutWindow:" + params);
|
||||
}
|
||||
int relayoutResult = sWindowSession.relayout(
|
||||
mWindow, params,
|
||||
@@ -2378,43 +2380,15 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
if (restore) {
|
||||
params.restore();
|
||||
}
|
||||
if (scalingRequired) {
|
||||
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
mPendingContentInsets.scale(invertedScale);
|
||||
mPendingVisibleInsets.scale(invertedScale);
|
||||
mWinFrame.scale(invertedScale);
|
||||
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);
|
||||
mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets);
|
||||
mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets);
|
||||
}
|
||||
return relayoutResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the window's layout parameter for compatibility mode. It replaces FILL_PARENT
|
||||
* with the default window size, and centers if the window wanted to fill
|
||||
* horizontally.
|
||||
*
|
||||
* @param attrs the window's layout params to adjust
|
||||
*/
|
||||
private void adjustWindowAttributesForCompatibleMode(WindowManager.LayoutParams attrs) {
|
||||
// fix app windows only
|
||||
if (attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
|
||||
DisplayMetrics metrics = mView.getContext().getResources().getDisplayMetrics();
|
||||
// TODO: improve gravity logic
|
||||
if (attrs.width == ViewGroup.LayoutParams.FILL_PARENT) {
|
||||
attrs.width = metrics.widthPixels;
|
||||
attrs.gravity |= Gravity.CENTER_HORIZONTAL;
|
||||
mWindowAttributesChanged = attrs == mWindowAttributes;
|
||||
}
|
||||
if (attrs.height == ViewGroup.LayoutParams.FILL_PARENT) {
|
||||
attrs.height = metrics.heightPixels;
|
||||
attrs.gravity |= Gravity.TOP;
|
||||
mWindowAttributesChanged = attrs == mWindowAttributes;
|
||||
}
|
||||
if (DEBUG_LAYOUT) {
|
||||
Log.d(TAG, "Adjusted Attributes for compatibility : " + attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -2518,16 +2492,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
+ " visibleInsets=" + visibleInsets.toShortString()
|
||||
+ " reportDraw=" + reportDraw);
|
||||
Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
coveredInsets.scale(invertedScale);
|
||||
visibleInsets.scale(invertedScale);
|
||||
msg.arg1 = (int) (w * invertedScale);
|
||||
msg.arg2 = (int) (h * invertedScale);
|
||||
} else {
|
||||
msg.arg1 = w;
|
||||
msg.arg2 = h;
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateRectInScreenToAppWindow(coveredInsets);
|
||||
mTranslator.translateRectInScreenToAppWindow(visibleInsets);
|
||||
w *= mTranslator.applicationInvertedScale;
|
||||
h *= mTranslator.applicationInvertedScale;
|
||||
}
|
||||
msg.arg1 = w;
|
||||
msg.arg2 = h;
|
||||
msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) };
|
||||
sendMessage(msg);
|
||||
}
|
||||
|
||||
@@ -483,6 +483,12 @@ public interface WindowManager extends ViewManager {
|
||||
* {@hide} */
|
||||
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.
|
||||
*
|
||||
* {@hide} */
|
||||
public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
|
||||
|
||||
/** Window flag: a special option intended for system dialogs. When
|
||||
* this flag is set, the window will demand focus unconditionally when
|
||||
* it is created.
|
||||
@@ -978,8 +984,9 @@ public interface WindowManager extends ViewManager {
|
||||
|
||||
/**
|
||||
* Scale the layout params' coordinates and size.
|
||||
* @hide
|
||||
*/
|
||||
void scale(float scale) {
|
||||
public void scale(float scale) {
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
if (width > 0) {
|
||||
@@ -997,14 +1004,13 @@ public interface WindowManager extends ViewManager {
|
||||
void backup() {
|
||||
int[] backup = mCompatibilityParamsBackup;
|
||||
if (backup == null) {
|
||||
// we backup 5 elements, x, y, width, height and gravity.
|
||||
backup = mCompatibilityParamsBackup = new int[5];
|
||||
// we backup 4 elements, x, y, width, height
|
||||
backup = mCompatibilityParamsBackup = new int[4];
|
||||
}
|
||||
backup[0] = x;
|
||||
backup[1] = y;
|
||||
backup[2] = width;
|
||||
backup[3] = height;
|
||||
backup[4] = gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1018,7 +1024,6 @@ public interface WindowManager extends ViewManager {
|
||||
y = backup[1];
|
||||
width = backup[2];
|
||||
height = backup[3];
|
||||
gravity = backup[4];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -990,7 +990,7 @@ public class PopupWindow {
|
||||
|
||||
int bottomEdge = displayFrame.bottom;
|
||||
if (ignoreBottomDecorations) {
|
||||
bottomEdge = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight();
|
||||
bottomEdge = anchor.getContext().getResources().getDisplayMetrics().heightPixels;
|
||||
}
|
||||
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
|
||||
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
|
||||
|
||||
@@ -968,35 +968,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
|
||||
if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a);
|
||||
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
|
||||
ActivityInfo ainfo = PackageParser.generateActivityInfo(a, flags);
|
||||
if (ainfo != null) {
|
||||
ApplicationInfo appInfo = getApplicationInfo(component.getPackageName(),
|
||||
PackageManager.GET_SUPPORTS_DENSITIES);
|
||||
if (appInfo != null &&
|
||||
(appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) == 0) {
|
||||
// Check if the screen size is same as what the application expect.
|
||||
CompatibilityInfo info = new CompatibilityInfo(appInfo);
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
metrics.setTo(mMetrics);
|
||||
int orientation = mMetrics.widthPixels > mMetrics.heightPixels ?
|
||||
Configuration.ORIENTATION_LANDSCAPE :
|
||||
Configuration.ORIENTATION_PORTRAIT;
|
||||
metrics.updateMetrics(info, orientation);
|
||||
if (!info.mExpandable) {
|
||||
// Don't allow an app that cannot expand to handle rotation.
|
||||
ainfo.configChanges &= ~ ActivityInfo.CONFIG_ORIENTATION;
|
||||
} else {
|
||||
appInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
|
||||
}
|
||||
if (DEBUG_SETTINGS) {
|
||||
Log.d(TAG, "component=" + component +
|
||||
", expandable:" +
|
||||
((appInfo.flags &
|
||||
ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ainfo;
|
||||
return PackageParser.generateActivityInfo(a, flags);
|
||||
}
|
||||
if (mResolveComponentName.equals(component)) {
|
||||
return mResolveActivity;
|
||||
|
||||
Reference in New Issue
Block a user