* Moved supports-density tag under manifest
* Refactored Compatibility code * Added CompatibilityInfo class * Removed getApplicationScale from Context * Added Resources#getCompatibilityInfo so that RootView can get the compatibility info w/o going through Context * Expandable support * Added expandable tag under manifest * Old application w/o expandable is given the default screen size ([320, 480] x density). * The non-expandable window is centered.
This commit is contained in:
@ -34943,6 +34943,16 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="expandable"
|
||||
type="boolean"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="flags"
|
||||
type="int"
|
||||
transient="false"
|
||||
@ -36787,6 +36797,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="GET_EXPANDABLE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="131072"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="GET_GIDS"
|
||||
type="int"
|
||||
transient="false"
|
||||
|
@ -162,7 +162,7 @@ public final class ActivityThread {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
Resources getTopLevelResources(String appDir, float applicationScale) {
|
||||
Resources getTopLevelResources(String appDir, PackageInfo pkgInfo) {
|
||||
synchronized (mPackages) {
|
||||
//Log.w(TAG, "getTopLevelResources: " + appDir);
|
||||
WeakReference<Resources> wr = mActiveResources.get(appDir);
|
||||
@ -181,23 +181,17 @@ public final class ActivityThread {
|
||||
if (assets.addAssetPath(appDir) == 0) {
|
||||
return null;
|
||||
}
|
||||
DisplayMetrics metrics = getDisplayMetricsLocked(false);
|
||||
// density used to load resources
|
||||
// scaledDensity is calculated in Resources constructor
|
||||
//
|
||||
boolean usePreloaded = true;
|
||||
|
||||
// TODO: use explicit flag to indicate the compatibility mode.
|
||||
if (applicationScale != 1.0f) {
|
||||
usePreloaded = false;
|
||||
DisplayMetrics newMetrics = new DisplayMetrics();
|
||||
newMetrics.setTo(metrics);
|
||||
float newDensity = metrics.density / applicationScale;
|
||||
newMetrics.updateDensity(newDensity);
|
||||
metrics = newMetrics;
|
||||
ApplicationInfo appInfo;
|
||||
try {
|
||||
appInfo = getPackageManager().getApplicationInfo(
|
||||
pkgInfo.getPackageName(),
|
||||
PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE);
|
||||
} catch (RemoteException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
//Log.i(TAG, "Resource:" + appDir + ", display metrics=" + metrics);
|
||||
r = new Resources(assets, metrics, getConfiguration(), usePreloaded);
|
||||
DisplayMetrics metrics = getDisplayMetricsLocked(false);
|
||||
r = new Resources(assets, metrics, getConfiguration(), appInfo);
|
||||
//Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());
|
||||
// XXX need to remove entries when weak references go away
|
||||
mActiveResources.put(appDir, new WeakReference<Resources>(r));
|
||||
@ -225,7 +219,6 @@ public final class ActivityThread {
|
||||
private Resources mResources;
|
||||
private ClassLoader mClassLoader;
|
||||
private Application mApplication;
|
||||
private float mApplicationScale;
|
||||
|
||||
private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
|
||||
= new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>();
|
||||
@ -268,8 +261,6 @@ public final class ActivityThread {
|
||||
mClassLoader = mSystemContext.getClassLoader();
|
||||
mResources = mSystemContext.getResources();
|
||||
}
|
||||
|
||||
mApplicationScale = -1.0f;
|
||||
}
|
||||
|
||||
public PackageInfo(ActivityThread activityThread, String name,
|
||||
@ -288,7 +279,6 @@ public final class ActivityThread {
|
||||
mIncludeCode = true;
|
||||
mClassLoader = systemContext.getClassLoader();
|
||||
mResources = systemContext.getResources();
|
||||
mApplicationScale = systemContext.getApplicationScale();
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
@ -299,45 +289,6 @@ public final class ActivityThread {
|
||||
return mSecurityViolation;
|
||||
}
|
||||
|
||||
public float getApplicationScale() {
|
||||
if (mApplicationScale > 0.0f) {
|
||||
return mApplicationScale;
|
||||
}
|
||||
DisplayMetrics metrics = mActivityThread.getDisplayMetricsLocked(false);
|
||||
// Find out the density scale (relative to 160) of the supported density that
|
||||
// is closest to the system's density.
|
||||
try {
|
||||
ApplicationInfo ai = getPackageManager().getApplicationInfo(
|
||||
mPackageName, PackageManager.GET_SUPPORTS_DENSITIES);
|
||||
|
||||
float appScale = -1.0f;
|
||||
if (ai.supportsDensities != null) {
|
||||
int minDiff = Integer.MAX_VALUE;
|
||||
for (int density : ai.supportsDensities) {
|
||||
int tmpDiff = (int) Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
|
||||
if (tmpDiff == 0) {
|
||||
appScale = 1.0f;
|
||||
break;
|
||||
}
|
||||
// prefer higher density (appScale>1.0), unless that's only option.
|
||||
if (tmpDiff < minDiff && appScale < 1.0f) {
|
||||
appScale = DisplayMetrics.DEVICE_DENSITY / density;
|
||||
minDiff = tmpDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (appScale < 0.0f) {
|
||||
mApplicationScale = metrics.density;
|
||||
} else {
|
||||
mApplicationScale = appScale;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
if (localLOGV) Log.v(TAG, "appScale=" + mApplicationScale + ", pkg=" + mPackageName);
|
||||
return mApplicationScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of shared libraries that are listed as
|
||||
* used by the given package.
|
||||
@ -495,7 +446,7 @@ public final class ActivityThread {
|
||||
|
||||
public Resources getResources(ActivityThread mainThread) {
|
||||
if (mResources == null) {
|
||||
mResources = mainThread.getTopLevelResources(mResDir, getApplicationScale());
|
||||
mResources = mainThread.getTopLevelResources(mResDir, this);
|
||||
}
|
||||
return mResources;
|
||||
}
|
||||
@ -3606,8 +3557,6 @@ public final class ActivityThread {
|
||||
}
|
||||
mConfiguration.updateFrom(config);
|
||||
DisplayMetrics dm = getDisplayMetricsLocked(true);
|
||||
DisplayMetrics appDm = new DisplayMetrics();
|
||||
appDm.setTo(dm);
|
||||
|
||||
// set it for java, this also affects newly created Resources
|
||||
if (config.locale != null) {
|
||||
@ -3627,11 +3576,7 @@ public final class ActivityThread {
|
||||
WeakReference<Resources> v = it.next();
|
||||
Resources r = v.get();
|
||||
if (r != null) {
|
||||
// keep the original density based on application cale.
|
||||
appDm.updateDensity(r.getDisplayMetrics().density);
|
||||
r.updateConfiguration(config, appDm);
|
||||
// reset
|
||||
appDm.setTo(dm);
|
||||
r.updateConfiguration(config, dm);
|
||||
//Log.i(TAG, "Updated app resources " + v.getKey()
|
||||
// + " " + r + ": " + r.getConfiguration());
|
||||
} else {
|
||||
|
@ -551,19 +551,6 @@ class ApplicationContext extends Context {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public float getApplicationScale() {
|
||||
if (mPackageInfo != null) {
|
||||
return mPackageInfo.getApplicationScale();
|
||||
} else {
|
||||
// same as system density
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWallpaper(Bitmap bitmap) throws IOException {
|
||||
try {
|
||||
@ -2028,8 +2015,7 @@ class ApplicationContext extends Context {
|
||||
ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app);
|
||||
Resources r = mContext.mMainThread.getTopLevelResources(
|
||||
app.uid == Process.myUid() ? app.sourceDir
|
||||
: app.publicSourceDir,
|
||||
pi.getApplicationScale());
|
||||
: app.publicSourceDir, pi);
|
||||
if (r != null) {
|
||||
return r;
|
||||
}
|
||||
|
@ -526,16 +526,6 @@ public abstract class Context {
|
||||
*/
|
||||
public abstract int getWallpaperDesiredMinimumHeight();
|
||||
|
||||
/**
|
||||
* Returns the scale in which the application will be drawn on the
|
||||
* screen. This is usually 1.0f if the application supports the device's
|
||||
* resolution/density. This will be 1.5f, for example, if the application
|
||||
* that supports only 160 density runs on 240 density screen.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract float getApplicationScale();
|
||||
|
||||
/**
|
||||
* Change the current system wallpaper to a bitmap. The given bitmap is
|
||||
* converted to a PNG and stored as the wallpaper. On success, the intent
|
||||
|
@ -419,12 +419,4 @@ public class ContextWrapper extends Context {
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return mBase.createPackageContext(packageName, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public float getApplicationScale() {
|
||||
return mBase.getApplicationScale();
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
*/
|
||||
public int uid;
|
||||
|
||||
|
||||
/**
|
||||
* The list of densities in DPI that application supprots. This
|
||||
* field is only set if the {@link PackageManager#GET_SUPPORTS_DENSITIES} flag was
|
||||
@ -194,6 +193,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
*/
|
||||
public int[] supportsDensities;
|
||||
|
||||
/**
|
||||
* True when the application's window can be expanded over default window
|
||||
* size in target density (320x480 for 1.0 density, 480x720 for 1.5 density etc)
|
||||
*/
|
||||
public boolean expandable = false;
|
||||
|
||||
/**
|
||||
* The minimum SDK version this application targets. It may run on earilier
|
||||
* versions, but it knows how to work with any new behavior added at this
|
||||
@ -228,6 +233,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
|
||||
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
|
||||
pw.println(prefix + "supportsDensities=" + supportsDensities);
|
||||
pw.println(prefix + "expandable=" + expandable);
|
||||
super.dumpBack(pw, prefix);
|
||||
}
|
||||
|
||||
@ -275,6 +281,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
manageSpaceActivityName = orig.manageSpaceActivityName;
|
||||
descriptionRes = orig.descriptionRes;
|
||||
supportsDensities = orig.supportsDensities;
|
||||
expandable = orig.expandable;
|
||||
}
|
||||
|
||||
|
||||
@ -307,6 +314,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
dest.writeString(backupAgentName);
|
||||
dest.writeInt(descriptionRes);
|
||||
dest.writeIntArray(supportsDensities);
|
||||
dest.writeInt(expandable ? 1 : 0);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ApplicationInfo> CREATOR
|
||||
@ -338,6 +346,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
backupAgentName = source.readString();
|
||||
descriptionRes = source.readInt();
|
||||
supportsDensities = source.createIntArray();
|
||||
expandable = source.readInt() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,6 +179,12 @@ public abstract class PackageManager {
|
||||
*/
|
||||
public static final int MATCH_DEFAULT_ONLY = 0x00010000;
|
||||
|
||||
/**
|
||||
* {@link ApplicationInfo} flag: return the
|
||||
* {link ApplicationInfo#expandable} boolean flag of the package.
|
||||
*/
|
||||
public static final int GET_EXPANDABLE = 0x00020000;
|
||||
|
||||
/**
|
||||
* Permission check result: this is returned by {@link #checkPermission}
|
||||
* if the permission has been granted to the given package.
|
||||
|
@ -835,6 +835,26 @@ public class PackageParser {
|
||||
+ parser.getName();
|
||||
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
|
||||
return null;
|
||||
|
||||
|
||||
} else if (tagName.equals("supports-density")) {
|
||||
sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.AndroidManifestSupportsDensity);
|
||||
|
||||
int density = sa.getInteger(
|
||||
com.android.internal.R.styleable.AndroidManifestSupportsDensity_density, -1);
|
||||
|
||||
sa.recycle();
|
||||
|
||||
if (density != -1 && !pkg.supportsDensityList.contains(density)) {
|
||||
pkg.supportsDensityList.add(density);
|
||||
}
|
||||
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
|
||||
} else if (tagName.equals("expandable")) {
|
||||
pkg.expandable = true;
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
} else {
|
||||
Log.w(TAG, "Bad element under <manifest>: "
|
||||
+ parser.getName());
|
||||
@ -866,7 +886,8 @@ public class PackageParser {
|
||||
pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
|
||||
pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
|
||||
}
|
||||
|
||||
// TODO: enable all density & expandable if target sdk is higher than donut
|
||||
|
||||
int size = pkg.supportsDensityList.size();
|
||||
if (size > 0) {
|
||||
int densities[] = pkg.supportsDensities = new int[size];
|
||||
@ -1345,21 +1366,6 @@ public class PackageParser {
|
||||
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
|
||||
} else if (tagName.equals("supports-density")) {
|
||||
sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.AndroidManifestSupportsDensity);
|
||||
|
||||
int density = sa.getInteger(
|
||||
com.android.internal.R.styleable.AndroidManifestSupportsDensity_density, -1);
|
||||
|
||||
sa.recycle();
|
||||
|
||||
if (density != -1 && !owner.supportsDensityList.contains(density)) {
|
||||
owner.supportsDensityList.add(density);
|
||||
}
|
||||
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
|
||||
} else {
|
||||
if (!RIGID_PARSER) {
|
||||
Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
|
||||
@ -2244,6 +2250,9 @@ public class PackageParser {
|
||||
public final ArrayList<Integer> supportsDensityList = new ArrayList<Integer>();
|
||||
public int[] supportsDensities = null;
|
||||
|
||||
// If the application's window is expandable.
|
||||
public boolean expandable;
|
||||
|
||||
// If this is a 3rd party app, this is the path of the zip file.
|
||||
public String mPath;
|
||||
|
||||
@ -2415,7 +2424,10 @@ public class PackageParser {
|
||||
return true;
|
||||
}
|
||||
if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0
|
||||
&& p.supportsDensities != null) {
|
||||
&& p.supportsDensities != null) {
|
||||
return true;
|
||||
}
|
||||
if ((flags & PackageManager.GET_EXPANDABLE) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -2438,6 +2450,9 @@ public class PackageParser {
|
||||
if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0) {
|
||||
ai.supportsDensities = p.supportsDensities;
|
||||
}
|
||||
if ((flags & PackageManager.GET_EXPANDABLE) != 0) {
|
||||
ai.expandable = p.expandable;
|
||||
}
|
||||
return ai;
|
||||
}
|
||||
|
||||
|
102
core/java/android/content/res/CompatibilityInfo.java
Normal file
102
core/java/android/content/res/CompatibilityInfo.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
|
||||
/**
|
||||
* CompatibilityInfo class keeps the information about compatibility mode that the application is
|
||||
* running under.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class CompatibilityInfo {
|
||||
/** default compatibility info object for compatible applications */
|
||||
public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo();
|
||||
|
||||
/**
|
||||
* The default width of the screen in portrait mode.
|
||||
*/
|
||||
public static final int DEFAULT_PORTRAIT_WIDTH = 320;
|
||||
|
||||
/**
|
||||
* The default height of the screen in portrait mode.
|
||||
*/
|
||||
public static final int DEFAULT_PORTRAIT_HEIGHT = 480;
|
||||
|
||||
/**
|
||||
* Application's scale.
|
||||
*/
|
||||
public final float mApplicationScale;
|
||||
|
||||
/**
|
||||
* Application's inverted scale.
|
||||
*/
|
||||
public final float mApplicationInvertedScale;
|
||||
|
||||
/**
|
||||
*
|
||||
* A boolean flag to indicates that the application can expand over the original size.
|
||||
*/
|
||||
public final boolean mExpandable;
|
||||
|
||||
/**
|
||||
* A boolean flag to tell if the application needs scaling (when mApplicationScale != 1.0f)
|
||||
*/
|
||||
public final boolean mScalingRequired;
|
||||
|
||||
public CompatibilityInfo(ApplicationInfo appInfo) {
|
||||
mExpandable = appInfo.expandable;
|
||||
float packageDensityScale = -1.0f;
|
||||
if (appInfo.supportsDensities != null) {
|
||||
int minDiff = Integer.MAX_VALUE;
|
||||
for (int density : appInfo.supportsDensities) {
|
||||
int tmpDiff = Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
|
||||
if (tmpDiff == 0) {
|
||||
packageDensityScale = 1.0f;
|
||||
break;
|
||||
}
|
||||
// prefer higher density (appScale>1.0), unless that's only option.
|
||||
if (tmpDiff < minDiff && packageDensityScale < 1.0f) {
|
||||
packageDensityScale = DisplayMetrics.DEVICE_DENSITY / (float) density;
|
||||
minDiff = tmpDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packageDensityScale > 0.0f) {
|
||||
mApplicationScale = packageDensityScale;
|
||||
} else {
|
||||
mApplicationScale = DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
|
||||
}
|
||||
mApplicationInvertedScale = 1.0f / mApplicationScale;
|
||||
mScalingRequired = mApplicationScale != 1.0f;
|
||||
}
|
||||
|
||||
private CompatibilityInfo() {
|
||||
mApplicationScale = mApplicationInvertedScale = 1.0f;
|
||||
mExpandable = true;
|
||||
mScalingRequired = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompatibilityInfo{scale=" + mApplicationScale +
|
||||
", expandable=" + mExpandable + "}";
|
||||
}
|
||||
}
|
@ -22,6 +22,8 @@ import com.android.internal.util.XmlUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.app.ActivityThread.PackageInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.Movie;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
@ -84,7 +86,9 @@ public class Resources {
|
||||
private final Configuration mConfiguration = new Configuration();
|
||||
/*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
|
||||
PluralRules mPluralRule;
|
||||
|
||||
|
||||
private final CompatibilityInfo mCompatibilityInfo;
|
||||
|
||||
private static final SparseArray<Object> EMPTY_ARRAY = new SparseArray<Object>() {
|
||||
@Override
|
||||
public void put(int k, Object o) {
|
||||
@ -126,23 +130,36 @@ public class Resources {
|
||||
*/
|
||||
public Resources(AssetManager assets, DisplayMetrics metrics,
|
||||
Configuration config) {
|
||||
this(assets, metrics, config, true);
|
||||
this(assets, metrics, config, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a resource with an additional flag for preloaded
|
||||
* drawable cache. Used by {@link ActivityThread}.
|
||||
*
|
||||
* Creates a new Resources object with ApplicationInfo.
|
||||
*
|
||||
* @param assets Previously created AssetManager.
|
||||
* @param metrics Current display metrics to consider when
|
||||
* selecting/computing resource values.
|
||||
* @param config Desired device configuration to consider when
|
||||
* selecting/computing resource values (optional).
|
||||
* @param appInfo this resource's application info.
|
||||
* @hide
|
||||
*/
|
||||
public Resources(AssetManager assets, DisplayMetrics metrics,
|
||||
Configuration config, boolean usePreloadedCache) {
|
||||
Configuration config, ApplicationInfo appInfo) {
|
||||
mAssets = assets;
|
||||
mConfiguration.setToDefaults();
|
||||
mMetrics.setToDefaults();
|
||||
if (appInfo != null) {
|
||||
mCompatibilityInfo = new CompatibilityInfo(appInfo);
|
||||
if (DEBUG_CONFIG) {
|
||||
Log.d(TAG, "compatibility for " + appInfo.packageName + " : " + mCompatibilityInfo);
|
||||
}
|
||||
} else {
|
||||
mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
|
||||
}
|
||||
updateConfiguration(config, metrics);
|
||||
assets.ensureStringBlocks();
|
||||
if (usePreloadedCache) {
|
||||
if (!mCompatibilityInfo.mScalingRequired) {
|
||||
mPreloadedDrawables = sPreloadedDrawables;
|
||||
} else {
|
||||
mPreloadedDrawables = emptySparseArray();
|
||||
@ -1251,6 +1268,7 @@ public class Resources {
|
||||
}
|
||||
if (metrics != null) {
|
||||
mMetrics.setTo(metrics);
|
||||
mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration);
|
||||
}
|
||||
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
|
||||
|
||||
@ -1356,6 +1374,17 @@ public class Resources {
|
||||
public Configuration getConfiguration() {
|
||||
return mConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the compatibility mode information for the application.
|
||||
* The returned object should be treated as read-only.
|
||||
*
|
||||
* @return compatibility info. null if the app does not require compatibility mode.
|
||||
* @hide
|
||||
*/
|
||||
public CompatibilityInfo getCompatibilityInfo() {
|
||||
return mCompatibilityInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resource identifier for the given resource name. A fully
|
||||
@ -1920,5 +1949,6 @@ public class Resources {
|
||||
updateConfiguration(null, null);
|
||||
mAssets.ensureStringBlocks();
|
||||
mPreloadedDrawables = sPreloadedDrawables;
|
||||
mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package android.util;
|
||||
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.*;
|
||||
|
||||
|
||||
@ -101,17 +103,46 @@ public class DisplayMetrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display metrics' density and update parameters depend on it.
|
||||
* @hide
|
||||
* Update the display metrics based on the compatibility info and configuration.
|
||||
* {@hide}
|
||||
*/
|
||||
public void updateDensity(float newDensity) {
|
||||
float ratio = newDensity / density;
|
||||
density = newDensity;
|
||||
scaledDensity = density;
|
||||
widthPixels *= ratio;
|
||||
heightPixels *= ratio;
|
||||
xdpi *= ratio;
|
||||
ydpi *= ratio;
|
||||
public void updateMetrics(CompatibilityInfo compatibilityInfo, Configuration configuration) {
|
||||
if (compatibilityInfo.mScalingRequired) {
|
||||
float invertedRatio = compatibilityInfo.mApplicationInvertedScale;
|
||||
density *= invertedRatio;
|
||||
scaledDensity *= invertedRatio;
|
||||
xdpi *= invertedRatio;
|
||||
ydpi *= invertedRatio;
|
||||
widthPixels *= invertedRatio;
|
||||
heightPixels *= invertedRatio;
|
||||
}
|
||||
if (!compatibilityInfo.mExpandable) {
|
||||
// Note: this assume that configuration is updated before calling
|
||||
// updateMetrics method.
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
switch (configuration.orientation) {
|
||||
case Configuration.ORIENTATION_LANDSCAPE: {
|
||||
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
|
||||
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
|
||||
break;
|
||||
}
|
||||
case Configuration.ORIENTATION_UNDEFINED:
|
||||
case Configuration.ORIENTATION_PORTRAIT:
|
||||
case Configuration.ORIENTATION_SQUARE:
|
||||
default: {
|
||||
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
|
||||
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
|
||||
}
|
||||
}
|
||||
// adjust the size only when the device's screen is bigger.
|
||||
if (defaultWidth < widthPixels) {
|
||||
widthPixels = defaultWidth;
|
||||
}
|
||||
if (defaultHeight < heightPixels) {
|
||||
heightPixels = defaultHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
package android.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
@ -137,28 +138,24 @@ public class SurfaceView extends View {
|
||||
int mFormat = -1;
|
||||
int mType = -1;
|
||||
final Rect mSurfaceFrame = new Rect();
|
||||
private final float mAppScale;
|
||||
private final float mAppScaleInverted;
|
||||
private final CompatibilityInfo mCompatibilityInfo;
|
||||
|
||||
public SurfaceView(Context context) {
|
||||
super(context);
|
||||
setWillNotDraw(true);
|
||||
mAppScale = context.getApplicationScale();
|
||||
mAppScaleInverted = 1.0f / mAppScale;
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public SurfaceView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(true);
|
||||
mAppScale = context.getApplicationScale();
|
||||
mAppScaleInverted = 1.0f / mAppScale;
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setWillNotDraw(true);
|
||||
mAppScale = context.getApplicationScale();
|
||||
mAppScaleInverted = 1.0f / mAppScale;
|
||||
mCompatibilityInfo = context.getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,9 +258,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 && mAppScale != 1.0f) {
|
||||
if (mRequestedWidth < 0 && mCompatibilityInfo.mScalingRequired) {
|
||||
MotionEvent scaledBack = MotionEvent.obtain(event);
|
||||
scaledBack.scale(mAppScale);
|
||||
scaledBack.scale(mCompatibilityInfo.mApplicationScale);
|
||||
try {
|
||||
return super.dispatchTouchEvent(scaledBack);
|
||||
} finally {
|
||||
@ -300,6 +297,7 @@ public class SurfaceView extends View {
|
||||
if (!mHaveFrame) {
|
||||
return;
|
||||
}
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
|
||||
int myWidth = mRequestedWidth;
|
||||
if (myWidth <= 0) myWidth = getWidth();
|
||||
@ -307,9 +305,9 @@ public class SurfaceView extends View {
|
||||
if (myHeight <= 0) myHeight = getHeight();
|
||||
|
||||
// Use original size for surface unless fixed size is requested.
|
||||
if (mRequestedWidth <= 0) {
|
||||
myWidth *= mAppScale;
|
||||
myHeight *= mAppScale;
|
||||
if (mRequestedWidth <= 0 && mCompatibilityInfo.mScalingRequired) {
|
||||
myWidth *= appScale;
|
||||
myHeight *= appScale;
|
||||
}
|
||||
|
||||
getLocationInWindow(mLocation);
|
||||
@ -337,11 +335,11 @@ public class SurfaceView extends View {
|
||||
mFormat = mRequestedFormat;
|
||||
mType = mRequestedType;
|
||||
|
||||
// Scaling window's layout here beause mLayout is not used elsewhere.
|
||||
mLayout.x = (int) (mLeft * mAppScale);
|
||||
mLayout.y = (int) (mTop * mAppScale);
|
||||
mLayout.width = (int) (getWidth() * mAppScale);
|
||||
mLayout.height = (int) (getHeight() * mAppScale);
|
||||
// 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);
|
||||
mLayout.format = mRequestedFormat;
|
||||
mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||
| WindowManager.LayoutParams.FLAG_SCALED
|
||||
@ -367,14 +365,18 @@ public class SurfaceView extends View {
|
||||
|
||||
mSurfaceLock.lock();
|
||||
mDrawingStopped = !visible;
|
||||
|
||||
final int relayoutResult = mSession.relayout(
|
||||
mWindow, mLayout, mWidth, mHeight,
|
||||
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
|
||||
mVisibleInsets, mSurface);
|
||||
|
||||
mContentInsets.scale(mAppScaleInverted);
|
||||
mVisibleInsets.scale(mAppScaleInverted);
|
||||
mWinFrame.scale(mAppScaleInverted);
|
||||
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);
|
||||
@ -444,23 +446,23 @@ public class SurfaceView extends View {
|
||||
|
||||
private static class MyWindow extends IWindow.Stub {
|
||||
private final WeakReference<SurfaceView> mSurfaceView;
|
||||
private final float mAppScale;
|
||||
private final float mAppScaleInverted;
|
||||
private final CompatibilityInfo mCompatibilityInfo;
|
||||
|
||||
public MyWindow(SurfaceView surfaceView) {
|
||||
mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
|
||||
mAppScale = surfaceView.getContext().getApplicationScale();
|
||||
mAppScaleInverted = 1.0f / mAppScale;
|
||||
mCompatibilityInfo = surfaceView.getContext().getResources().getCompatibilityInfo();
|
||||
}
|
||||
|
||||
public void resized(int w, int h, Rect coveredInsets,
|
||||
Rect visibleInsets, boolean reportDraw) {
|
||||
SurfaceView surfaceView = mSurfaceView.get();
|
||||
float scale = mAppScaleInverted;
|
||||
w *= scale;
|
||||
h *= scale;
|
||||
coveredInsets.scale(scale);
|
||||
visibleInsets.scale(scale);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
float scale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
w *= scale;
|
||||
h *= scale;
|
||||
coveredInsets.scale(scale);
|
||||
visibleInsets.scale(scale);
|
||||
}
|
||||
|
||||
if (surfaceView != null) {
|
||||
if (localLOGV) Log.v(
|
||||
@ -624,7 +626,9 @@ public class SurfaceView extends View {
|
||||
Canvas c = null;
|
||||
if (!mDrawingStopped && mWindow != null) {
|
||||
Rect frame = dirty != null ? dirty : mSurfaceFrame;
|
||||
frame.scale(mAppScale);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
frame.scale(mCompatibilityInfo.mApplicationScale);
|
||||
}
|
||||
try {
|
||||
c = mSurface.lockCanvas(frame);
|
||||
} catch (Exception e) {
|
||||
|
@ -30,6 +30,7 @@ import android.os.Process;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.Config;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.EventLog;
|
||||
import android.util.SparseArray;
|
||||
@ -40,6 +41,7 @@ import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Scroller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.Context;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.Manifest;
|
||||
@ -125,9 +127,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
int mHeight;
|
||||
Rect mDirty; // will be a graphics.Region soon
|
||||
boolean mIsAnimating;
|
||||
// TODO: change these to scalar class.
|
||||
private float mAppScale;
|
||||
private float mAppScaleInverted; // = 1.0f / mAppScale
|
||||
|
||||
private CompatibilityInfo mCompatibilityInfo;
|
||||
private int[] mWindowLayoutParamsBackup = null;
|
||||
|
||||
final View.AttachInfo mAttachInfo;
|
||||
@ -386,12 +387,15 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
synchronized (this) {
|
||||
if (mView == null) {
|
||||
mView = view;
|
||||
mAppScale = mView.getContext().getApplicationScale();
|
||||
if (mAppScale != 1.0f) {
|
||||
mWindowAttributes.copyFrom(attrs);
|
||||
mCompatibilityInfo =
|
||||
mView.getContext().getResources().getCompatibilityInfo();
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
mWindowLayoutParamsBackup = new int[4];
|
||||
}
|
||||
mAppScaleInverted = 1.0f / mAppScale;
|
||||
mWindowAttributes.copyFrom(attrs);
|
||||
if (!mCompatibilityInfo.mExpandable) {
|
||||
adjustWindowAttributesForCompatibleMode(mWindowAttributes);
|
||||
}
|
||||
mSoftInputMode = attrs.softInputMode;
|
||||
mWindowAttributesChanged = true;
|
||||
mAttachInfo.mRootView = view;
|
||||
@ -406,9 +410,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
// manager, to make sure we do the relayout before receiving
|
||||
// any other events from the system.
|
||||
requestLayout();
|
||||
|
||||
try {
|
||||
res = sWindowSession.add(mWindow, attrs,
|
||||
res = sWindowSession.add(mWindow, mWindowAttributes,
|
||||
getHostVisibility(), mAttachInfo.mContentInsets);
|
||||
} catch (RemoteException e) {
|
||||
mAdded = false;
|
||||
@ -417,7 +420,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
unscheduleTraversals();
|
||||
throw new RuntimeException("Adding window failed", e);
|
||||
}
|
||||
mAttachInfo.mContentInsets.scale(mAppScaleInverted);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
mAttachInfo.mContentInsets.scale(
|
||||
mCompatibilityInfo.mApplicationInvertedScale);
|
||||
}
|
||||
mPendingContentInsets.set(mAttachInfo.mContentInsets);
|
||||
mPendingVisibleInsets.set(0, 0, 0, 0);
|
||||
if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow);
|
||||
@ -529,13 +535,13 @@ 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 || mAppScale != 1.0f) {
|
||||
if (mCurScrollY != 0 || mCompatibilityInfo.mScalingRequired) {
|
||||
mTempRect.set(dirty);
|
||||
if (mCurScrollY != 0) {
|
||||
mTempRect.offset(0, -mCurScrollY);
|
||||
}
|
||||
if (mAppScale != 1.0f) {
|
||||
mTempRect.scale(mAppScale);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
mTempRect.scale(mCompatibilityInfo.mApplicationScale);
|
||||
}
|
||||
dirty = mTempRect;
|
||||
}
|
||||
@ -615,6 +621,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
boolean viewVisibilityChanged = mViewVisibility != viewVisibility
|
||||
|| mNewSurfaceNeeded;
|
||||
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
|
||||
WindowManager.LayoutParams params = null;
|
||||
if (mWindowAttributesChanged) {
|
||||
mWindowAttributesChanged = false;
|
||||
@ -625,9 +633,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
fullRedrawNeeded = true;
|
||||
mLayoutRequested = true;
|
||||
|
||||
Display d = new Display(0);
|
||||
desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted);
|
||||
desiredWindowHeight = (int) (d.getHeight() * mAppScaleInverted);
|
||||
DisplayMetrics packageMetrics =
|
||||
mView.getContext().getResources().getDisplayMetrics();
|
||||
desiredWindowWidth = packageMetrics.widthPixels;
|
||||
desiredWindowHeight = packageMetrics.heightPixels;
|
||||
|
||||
// For the very first time, tell the view hierarchy that it
|
||||
// is attached to the window. Note that at this point the surface
|
||||
@ -696,9 +705,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|| lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
windowResizesToFitContent = true;
|
||||
|
||||
Display d = new Display(0);
|
||||
desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted);
|
||||
desiredWindowHeight = (int) (d.getHeight() * mAppScaleInverted);
|
||||
DisplayMetrics packageMetrics =
|
||||
mView.getContext().getResources().getDisplayMetrics();
|
||||
desiredWindowWidth = packageMetrics.widthPixels;
|
||||
desiredWindowHeight = packageMetrics.heightPixels;
|
||||
}
|
||||
}
|
||||
|
||||
@ -878,7 +888,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mHeight = frame.height();
|
||||
|
||||
if (initialized) {
|
||||
mGlCanvas.setViewport((int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
|
||||
mGlCanvas.setViewport((int) (mWidth * appScale), (int) (mHeight * appScale));
|
||||
}
|
||||
|
||||
boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
|
||||
@ -968,11 +978,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mTmpLocation[1] + host.mBottom - host.mTop);
|
||||
|
||||
host.gatherTransparentRegion(mTransparentRegion);
|
||||
|
||||
// TODO: scale the region, like:
|
||||
// Region uses native methods. We probabl should have ScalableRegion class.
|
||||
|
||||
// Region does not have equals method ?
|
||||
mTransparentRegion.scale(appScale);
|
||||
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
|
||||
mPreviousTransparentRegion.set(mTransparentRegion);
|
||||
// reconfigure window manager
|
||||
@ -983,7 +989,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (DBG) {
|
||||
System.out.println("======================================");
|
||||
System.out.println("performTraversals -- after setFrame");
|
||||
@ -1003,10 +1008,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
givenContent.left = givenContent.top = givenContent.right
|
||||
= givenContent.bottom = givenVisible.left = givenVisible.top
|
||||
= givenVisible.right = givenVisible.bottom = 0;
|
||||
insets.contentInsets.scale(mAppScale);
|
||||
insets.visibleInsets.scale(mAppScale);
|
||||
|
||||
attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
|
||||
if (mCompatibilityInfo.mScalingRequired) {
|
||||
insets.contentInsets.scale(appScale);
|
||||
insets.visibleInsets.scale(appScale);
|
||||
}
|
||||
if (insetsPending || !mLastGivenInsets.equals(insets)) {
|
||||
mLastGivenInsets.set(insets);
|
||||
try {
|
||||
@ -1154,6 +1160,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mCurScrollY = yoff;
|
||||
fullRedrawNeeded = true;
|
||||
}
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
|
||||
|
||||
Rect dirty = mDirty;
|
||||
if (mUseGL) {
|
||||
@ -1169,12 +1177,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mAttachInfo.mIgnoreDirtyState = true;
|
||||
mView.mPrivateFlags |= View.DRAWN;
|
||||
|
||||
float scale = mAppScale;
|
||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
try {
|
||||
canvas.translate(0, -yoff);
|
||||
if (scale != 1.0f) {
|
||||
canvas.scale(scale, scale);
|
||||
if (scalingRequired) {
|
||||
canvas.scale(appScale, appScale);
|
||||
}
|
||||
mView.draw(canvas);
|
||||
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
|
||||
@ -1206,8 +1213,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
|
||||
if (fullRedrawNeeded) {
|
||||
mAttachInfo.mIgnoreDirtyState = true;
|
||||
dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
|
||||
mAttachInfo.mIgnoreDirtyState = true;
|
||||
dirty.union(0, 0, (int) (mWidth * appScale), (int) (mHeight * appScale));
|
||||
}
|
||||
|
||||
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
|
||||
@ -1215,7 +1222,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
+ mWindowAttributes.getTitle()
|
||||
+ ": dirty={" + dirty.left + "," + dirty.top
|
||||
+ "," + dirty.right + "," + dirty.bottom + "} surface="
|
||||
+ surface + " surface.isValid()=" + surface.isValid());
|
||||
+ surface + " surface.isValid()=" + surface.isValid() + ", appScale:" +
|
||||
appScale + ", width=" + mWidth + ", height=" + mHeight);
|
||||
}
|
||||
|
||||
Canvas canvas;
|
||||
@ -1272,18 +1280,16 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
|
||||
mView.mPrivateFlags |= View.DRAWN;
|
||||
|
||||
float scale = mAppScale;
|
||||
if (DEBUG_DRAW) {
|
||||
Context cxt = mView.getContext();
|
||||
Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
|
||||
", appScale=" + mAppScale);
|
||||
", metrics=" + mView.getContext().getResources().getDisplayMetrics());
|
||||
}
|
||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
try {
|
||||
canvas.translate(0, -yoff);
|
||||
if (scale != 1.0f) {
|
||||
// re-scale this
|
||||
canvas.scale(scale, scale);
|
||||
if (scalingRequired) {
|
||||
canvas.scale(appScale, appScale);
|
||||
}
|
||||
mView.draw(canvas);
|
||||
} finally {
|
||||
@ -1586,8 +1592,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
} else {
|
||||
didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
|
||||
}
|
||||
if (event != null) {
|
||||
event.scale(mAppScaleInverted);
|
||||
if (event != null && mCompatibilityInfo.mScalingRequired) {
|
||||
event.scale(mCompatibilityInfo.mApplicationInvertedScale);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -1709,8 +1715,9 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
if (mGlWanted && !mUseGL) {
|
||||
initializeGL();
|
||||
if (mGlCanvas != null) {
|
||||
mGlCanvas.setViewport((int) (mWidth * mAppScale),
|
||||
(int) (mHeight * mAppScale));
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
mGlCanvas.setViewport(
|
||||
(int) (mWidth * appScale), (int) (mHeight * appScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1914,8 +1921,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
} else {
|
||||
didFinish = false;
|
||||
}
|
||||
if (event != null) {
|
||||
event.scale(mAppScaleInverted);
|
||||
if (event != null && mCompatibilityInfo.mScalingRequired) {
|
||||
event.scale(mCompatibilityInfo.mApplicationInvertedScale);
|
||||
}
|
||||
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
|
||||
@ -2345,27 +2352,59 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|
||||
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
|
||||
boolean insetsPending) throws RemoteException {
|
||||
|
||||
boolean restore = false;
|
||||
if (params != null && mAppScale != 1.0f) {
|
||||
float appScale = mCompatibilityInfo.mApplicationScale;
|
||||
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
|
||||
|
||||
if (params != null && !mCompatibilityInfo.mExpandable) {
|
||||
adjustWindowAttributesForCompatibleMode(params);
|
||||
}
|
||||
if (params != null && scalingRequired) {
|
||||
restore = true;
|
||||
params.scale(mAppScale, mWindowLayoutParamsBackup);
|
||||
params.scale(appScale, mWindowLayoutParamsBackup);
|
||||
}
|
||||
int relayoutResult = sWindowSession.relayout(
|
||||
mWindow, params,
|
||||
(int) (mView.mMeasuredWidth * mAppScale),
|
||||
(int) (mView.mMeasuredHeight * mAppScale),
|
||||
(int) (mView.mMeasuredWidth * appScale),
|
||||
(int) (mView.mMeasuredHeight * appScale),
|
||||
viewVisibility, insetsPending, mWinFrame,
|
||||
mPendingContentInsets, mPendingVisibleInsets, mSurface);
|
||||
if (restore) {
|
||||
params.restore(mWindowLayoutParamsBackup);
|
||||
}
|
||||
|
||||
mPendingContentInsets.scale(mAppScaleInverted);
|
||||
mPendingVisibleInsets.scale(mAppScaleInverted);
|
||||
mWinFrame.scale(mAppScaleInverted);
|
||||
if (scalingRequired) {
|
||||
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
|
||||
mPendingContentInsets.scale(invertedScale);
|
||||
mPendingVisibleInsets.scale(invertedScale);
|
||||
mWinFrame.scale(invertedScale);
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (attrs.height == ViewGroup.LayoutParams.FILL_PARENT) {
|
||||
attrs.height = metrics.heightPixels;
|
||||
}
|
||||
if (DEBUG_LAYOUT) {
|
||||
Log.d(TAG, "Attributes fixed for compatibility : " + attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@ -2470,11 +2509,16 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
+ " visibleInsets=" + visibleInsets.toShortString()
|
||||
+ " reportDraw=" + reportDraw);
|
||||
Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED);
|
||||
|
||||
coveredInsets.scale(mAppScaleInverted);
|
||||
visibleInsets.scale(mAppScaleInverted);
|
||||
msg.arg1 = (int) (w * mAppScaleInverted);
|
||||
msg.arg2 = (int) (h * mAppScaleInverted);
|
||||
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;
|
||||
}
|
||||
msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) };
|
||||
sendMessage(msg);
|
||||
}
|
||||
|
@ -810,12 +810,19 @@
|
||||
<!-- The <code>supports-density</code> specifies a screen density that this
|
||||
package supports. Application can specify multiple densities it supports.
|
||||
<p>This appears as a child tag of the
|
||||
{@link #AndroidManifestApplication application} tag. -->
|
||||
<declare-styleable name="AndroidManifestSupportsDensity" parent="AndroidManifestApplication">
|
||||
{@link #AndroidManifest manifest} tag. -->
|
||||
<declare-styleable name="AndroidManifestSupportsDensity" parent="AndroidManifest">
|
||||
<!-- Required value of the density in dip (device independent pixel). -->
|
||||
<attr name="density" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>expandable</code> specifies if this package supports screen metrics
|
||||
other than 320x480 dip.
|
||||
<p>This appears as a child tag of the
|
||||
{@link #AndroidManifest manifest} tag. -->
|
||||
<declare-styleable name="AndroidManifestExpandable" parent="AndroidManifest">
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>provider</code> tag declares a
|
||||
{@link android.content.ContentProvider} class that is available
|
||||
as part of the package's application components, supplying structured
|
||||
|
@ -183,7 +183,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
|
||||
// The flags that are set for all calls we make to the package manager.
|
||||
static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES
|
||||
| PackageManager.GET_SUPPORTS_DENSITIES;
|
||||
| PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE;
|
||||
|
||||
private static final String SYSTEM_SECURE = "ro.secure";
|
||||
|
||||
|
@ -386,12 +386,4 @@ public class MockContext extends Context {
|
||||
throws PackageManager.NameNotFoundException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public float getApplicationScale() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -1145,12 +1145,4 @@ public final class BridgeContext extends Context {
|
||||
public Context getApplicationContext() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public float getApplicationScale() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user