Merge "Add activity token to display system."

This commit is contained in:
Craig Mautner
2013-06-24 18:31:54 +00:00
committed by Android (Google) Code Review
16 changed files with 271 additions and 166 deletions

View File

@ -16,6 +16,8 @@
package android.app;
import static android.view.DisplayAdjustments.DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN;
import android.app.backup.BackupAgent;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
@ -75,7 +77,7 @@ import android.util.Log;
import android.util.LogPrinter;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.HardwareRenderer;
import android.view.View;
@ -209,8 +211,8 @@ public final class ActivityThread {
= new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
= new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
= new HashMap<CompatibilityInfo, DisplayMetrics>();
final HashMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
= new HashMap<DisplayAdjustments, DisplayMetrics>();
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
= new HashMap<ResourcesKey, WeakReference<Resources> >();
final ArrayList<ActivityClientRecord> mRelaunchingActivities
@ -1554,6 +1556,7 @@ public final class ActivityThread {
}
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
@ -1592,6 +1595,7 @@ public final class ActivityThread {
}
final class GcIdler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
doGcIfNeeded();
return false;
@ -1604,8 +1608,10 @@ public final class ActivityThread {
final private Configuration mOverrideConfiguration;
final private float mScale;
final private int mHash;
final private IBinder mToken;
ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
float scale, IBinder token) {
mResDir = resDir;
mDisplayId = displayId;
if (overrideConfiguration != null) {
@ -1621,6 +1627,12 @@ public final class ActivityThread {
hash = 31 * hash + (mOverrideConfiguration != null
? mOverrideConfiguration.hashCode() : 0);
hash = 31 * hash + Float.floatToIntBits(mScale);
if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) {
mToken = token;
hash = 31 * hash + (mToken == null ? 0 : mToken.hashCode());
} else {
mToken = null;
}
mHash = hash;
}
@ -1693,9 +1705,13 @@ public final class ActivityThread {
mDefaultDisplayMetrics.clear();
}
DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
DisplayMetrics getDisplayMetricsLocked(int displayId) {
return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
}
DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
if (dm != null) {
return dm;
}
@ -1709,12 +1725,10 @@ public final class ActivityThread {
}
if (isDefaultDisplay) {
mDefaultDisplayMetrics.put(ci, dm);
mDefaultDisplayMetrics.put(daj, dm);
}
CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
cih.set(ci);
Display d = displayManager.getCompatibleDisplay(displayId, cih);
Display d = displayManager.getCompatibleDisplay(displayId, daj);
if (d != null) {
d.getMetrics(dm);
} else {
@ -1736,7 +1750,7 @@ public final class ActivityThread {
if (config == null) {
return null;
}
if (compat != null && !compat.supportsScreen()) {
if (!compat.supportsScreen()) {
mMainThreadConfig.setTo(config);
config = mMainThreadConfig;
compat.applyToConfiguration(displayDensity, config);
@ -1748,21 +1762,19 @@ public final class ActivityThread {
* Creates the top level Resources for applications with the given compatibility info.
*
* @param resDir the resource directory.
* @param compInfo the compability info. It will use the default compatibility info when it's
* null.
* @param compatInfo the compability info. Must not be null.
* @param token the application token for determining stack bounds.
*/
Resources getTopLevelResources(String resDir,
int displayId, Configuration overrideConfiguration,
CompatibilityInfo compInfo) {
ResourcesKey key = new ResourcesKey(resDir,
displayId, overrideConfiguration,
compInfo.applicationScale);
Resources getTopLevelResources(String resDir, int displayId,
Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
final float scale = compatInfo.applicationScale;
ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
token);
Resources r;
synchronized (mPackages) {
// Resources is app scale dependent.
if (false) {
Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
+ compInfo.applicationScale);
Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
}
WeakReference<Resources> wr = mActiveResources.get(key);
r = wr != null ? wr.get() : null;
@ -1787,7 +1799,7 @@ public final class ActivityThread {
}
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
DisplayMetrics dm = getDisplayMetricsLocked(displayId);
Configuration config;
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
@ -1801,7 +1813,7 @@ public final class ActivityThread {
} else {
config = getConfiguration();
}
r = new Resources(assets, dm, config, compInfo);
r = new Resources(assets, dm, config, compatInfo, token);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
+ r.getConfiguration() + " appScale="
@ -1831,7 +1843,7 @@ public final class ActivityThread {
int displayId, Configuration overrideConfiguration,
LoadedApk pkgInfo) {
return getTopLevelResources(resDir, displayId, overrideConfiguration,
pkgInfo.mCompatibilityInfo.get());
pkgInfo.getCompatibilityInfo(), null);
}
final Handler getHandler() {
@ -2005,10 +2017,8 @@ public final class ActivityThread {
LoadedApk info = new LoadedApk(this, "android", context, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
context.init(info, null, this);
context.getResources().updateConfiguration(
getConfiguration(), getDisplayMetricsLocked(
Display.DEFAULT_DISPLAY,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
context.getResources().updateConfiguration(getConfiguration(),
getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration());
@ -2034,7 +2044,7 @@ public final class ActivityThread {
dalvik.system.VMRuntime.getRuntime().startJitCompilation();
}
}
void scheduleGcIdler() {
if (!mGcIdlerScheduled) {
mGcIdlerScheduled = true;
@ -2301,7 +2311,7 @@ public final class ActivityThread {
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
for (int displayId : dm.getDisplayIds()) {
if (displayId != Display.DEFAULT_DISPLAY) {
Display display = dm.getRealDisplay(displayId);
Display display = dm.getRealDisplay(displayId, r.token);
baseContext = appContext.createDisplayContext(display);
break;
}
@ -3408,11 +3418,11 @@ public final class ActivityThread {
private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
LoadedApk apk = peekPackageInfo(data.pkg, false);
if (apk != null) {
apk.mCompatibilityInfo.set(data.info);
apk.setCompatibilityInfo(data.info);
}
apk = peekPackageInfo(data.pkg, true);
if (apk != null) {
apk.mCompatibilityInfo.set(data.info);
apk.setCompatibilityInfo(data.info);
}
handleConfigurationChanged(mConfiguration, data.info);
WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
@ -3844,8 +3854,9 @@ public final class ActivityThread {
for (ActivityClientRecord ar : mActivities.values()) {
Activity a = ar.activity;
if (a != null) {
Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
Configuration thisConfig = applyConfigCompatMainThread(
mCurDefaultDisplayDpi, newConfig,
ar.packageInfo.getCompatibilityInfo());
if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
// If the activity is currently resumed, its configuration
// needs to change right now.
@ -3945,8 +3956,7 @@ public final class ActivityThread {
}
int changes = mResConfiguration.updateFrom(config);
flushDisplayMetricsLocked();
DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
Display.DEFAULT_DISPLAY, null);
DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) {
@ -3986,7 +3996,7 @@ public final class ActivityThread {
}
tmpConfig.setTo(config);
if (!isDefaultDisplay) {
dm = getDisplayMetricsLocked(displayId, null);
dm = getDisplayMetricsLocked(displayId);
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
}
if (overrideConfig != null) {

View File

@ -99,7 +99,7 @@ import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.WindowManagerImpl;
@ -205,6 +205,8 @@ class ContextImpl extends Context {
private static final String[] EMPTY_FILE_LIST = {};
final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
/**
* Override this class when the system service constructor needs a
* ContextImpl. Else, use StaticServiceFetcher below.
@ -1830,10 +1832,8 @@ class ContextImpl extends Context {
ContextImpl c = new ContextImpl();
c.init(mPackageInfo, null, mMainThread);
c.mResources = mMainThread.getTopLevelResources(
mPackageInfo.getResDir(),
getDisplayId(), overrideConfiguration,
mResources.getCompatibilityInfo());
c.mResources = mMainThread.getTopLevelResources(mPackageInfo.getResDir(), getDisplayId(),
overrideConfiguration, mResources.getCompatibilityInfo(), mActivityToken);
return c;
}
@ -1844,17 +1844,13 @@ class ContextImpl extends Context {
}
int displayId = display.getDisplayId();
CompatibilityInfo ci = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
CompatibilityInfoHolder cih = getCompatibilityInfo(displayId);
if (cih != null) {
ci = cih.get();
}
ContextImpl context = new ContextImpl();
context.init(mPackageInfo, null, mMainThread);
context.mDisplay = display;
context.mResources = mMainThread.getTopLevelResources(
mPackageInfo.getResDir(), displayId, null, ci);
DisplayAdjustments daj = getDisplayAdjustments(displayId);
context.mResources = mMainThread.getTopLevelResources(mPackageInfo.getResDir(), displayId,
null, daj.getCompatibilityInfo(), null);
return context;
}
@ -1868,8 +1864,8 @@ class ContextImpl extends Context {
}
@Override
public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
public DisplayAdjustments getDisplayAdjustments(int displayId) {
return mDisplayAdjustments;
}
private File getDataDirFile() {
@ -1921,6 +1917,7 @@ class ContextImpl extends Context {
mUser = context.mUser;
mDisplay = context.mDisplay;
mOuterContext = this;
mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
}
final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
@ -1933,16 +1930,26 @@ class ContextImpl extends Context {
mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
mResources = mPackageInfo.getResources(mainThread);
if (mResources != null && container != null
&& container.getCompatibilityInfo().applicationScale !=
mResources.getCompatibilityInfo().applicationScale) {
CompatibilityInfo compatInfo =
container == null ? null : container.getCompatibilityInfo();
if (mResources != null &&
((compatInfo != null && compatInfo.applicationScale !=
mResources.getCompatibilityInfo().applicationScale)
|| activityToken != null)) {
if (DEBUG) {
Log.d(TAG, "loaded context has different scaling. Using container's" +
" compatiblity info:" + container.getDisplayMetrics());
}
mResources = mainThread.getTopLevelResources(
mPackageInfo.getResDir(), Display.DEFAULT_DISPLAY,
null, container.getCompatibilityInfo());
if (compatInfo == null) {
compatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
}
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
mDisplayAdjustments.setActivityToken(activityToken);
mResources = mainThread.getTopLevelResources(mPackageInfo.getResDir(),
Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
} else {
mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
mDisplayAdjustments.setActivityToken(activityToken);
}
mMainThread = mainThread;
mActivityToken = activityToken;

View File

@ -40,7 +40,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.util.AndroidRuntimeException;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import java.io.File;
@ -84,7 +84,7 @@ public final class LoadedApk {
private final ClassLoader mBaseClassLoader;
private final boolean mSecurityViolation;
private final boolean mIncludeCode;
public final CompatibilityInfoHolder mCompatibilityInfo = new CompatibilityInfoHolder();
private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Resources mResources;
private ClassLoader mClassLoader;
private Application mApplication;
@ -132,7 +132,7 @@ public final class LoadedApk {
mBaseClassLoader = baseLoader;
mSecurityViolation = securityViolation;
mIncludeCode = includeCode;
mCompatibilityInfo.set(compatInfo);
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
if (mAppDir == null) {
if (ActivityThread.mSystemContext == null) {
@ -141,7 +141,7 @@ public final class LoadedApk {
ActivityThread.mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(),
mainThread.getDisplayMetricsLocked(
Display.DEFAULT_DISPLAY, compatInfo),
Display.DEFAULT_DISPLAY, mDisplayAdjustments),
compatInfo);
//Slog.i(TAG, "Created system resources "
// + mSystemContext.getResources() + ": "
@ -169,7 +169,7 @@ public final class LoadedApk {
mIncludeCode = true;
mClassLoader = systemContext.getClassLoader();
mResources = systemContext.getResources();
mCompatibilityInfo.set(compatInfo);
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
}
public String getPackageName() {
@ -184,6 +184,14 @@ public final class LoadedApk {
return mSecurityViolation;
}
public CompatibilityInfo getCompatibilityInfo() {
return mDisplayAdjustments.getCompatibilityInfo();
}
public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
}
/**
* Gets the array of shared libraries that are listed as
* used by the given package.

View File

@ -35,7 +35,7 @@ import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.WindowManager;
@ -2760,15 +2760,15 @@ public abstract class Context {
public abstract Context createDisplayContext(Display display);
/**
* Gets the compatibility info holder for this context. This information
* is provided on a per-application basis and is used to simulate lower density
* display metrics for legacy applications.
* Gets the display adjustments holder for this context. This information
* is provided on a per-application or activity basis and is used to simulate lower density
* display metrics for legacy applications and restricted screen sizes.
*
* @param displayId The display id for which to get compatibility info.
* @return The compatibility info holder, or null if not required by the application.
* @hide
*/
public abstract CompatibilityInfoHolder getCompatibilityInfo(int displayId);
public abstract DisplayAdjustments getDisplayAdjustments(int displayId);
/**
* Indicates whether this Context is restricted.

View File

@ -35,7 +35,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import java.io.File;
@ -646,7 +646,7 @@ public class ContextWrapper extends Context {
/** @hide */
@Override
public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
return mBase.getCompatibilityInfo(displayId);
public DisplayAdjustments getDisplayAdjustments(int displayId) {
return mBase.getDisplayAdjustments(displayId);
}
}

View File

@ -471,8 +471,7 @@ public class CompatibilityInfo implements Parcelable {
* Compute the frame Rect for applications runs under compatibility mode.
*
* @param dm the display metrics used to compute the frame size.
* @param orientation the orientation of the screen.
* @param outRect the output parameter which will contain the result.
* @param outDm If non-null the width and height will be set to their scaled values.
* @return Returns the scaling factor for the window.
*/
public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) {
@ -518,6 +517,9 @@ public class CompatibilityInfo implements Parcelable {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
try {
CompatibilityInfo oc = (CompatibilityInfo)o;
if (mCompatibilityFlags != oc.mCompatibilityFlags) return false;
@ -579,10 +581,12 @@ public class CompatibilityInfo implements Parcelable {
public static final Parcelable.Creator<CompatibilityInfo> CREATOR
= new Parcelable.Creator<CompatibilityInfo>() {
@Override
public CompatibilityInfo createFromParcel(Parcel source) {
return new CompatibilityInfo(source);
}
@Override
public CompatibilityInfo[] newArray(int size) {
return new CompatibilityInfo[size];
}

View File

@ -28,6 +28,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@ -35,6 +36,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
import android.util.LongSparseArray;
import android.view.DisplayAdjustments;
import java.io.IOException;
import java.io.InputStream;
@ -117,8 +119,9 @@ public class Resources {
private final Configuration mConfiguration = new Configuration();
/*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
private NativePluralRules mPluralRule;
private CompatibilityInfo mCompatibilityInfo;
private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
private WeakReference<IBinder> mToken;
static {
sPreloadedDrawables = new LongSparseArray[2];
@ -173,7 +176,7 @@ public class Resources {
* selecting/computing resource values (optional).
*/
public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
this(assets, metrics, config, null);
this(assets, metrics, config, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
}
/**
@ -184,15 +187,16 @@ public class Resources {
* selecting/computing resource values.
* @param config Desired device configuration to consider when
* selecting/computing resource values (optional).
* @param compInfo this resource's compatibility info. It will use the default compatibility
* info when it's null.
* @param compatInfo this resource's compatibility info. Must not be null.
* @param token The Activity token for determining stack affiliation. Usually null.
* @hide
*/
public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config, CompatibilityInfo compInfo) {
public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config,
CompatibilityInfo compatInfo, IBinder token) {
mAssets = assets;
mMetrics.setToDefaults();
mCompatibilityInfo = compInfo;
mCompatibilityInfo = compatInfo;
mToken = new WeakReference<IBinder>(token);
updateConfiguration(config, metrics);
assets.ensureStringBlocks();
}

View File

@ -159,7 +159,7 @@ public final class DisplayManager {
Display display = mDisplays.get(displayId);
if (display == null) {
display = mGlobal.getCompatibleDisplay(displayId,
mContext.getCompatibilityInfo(displayId));
mContext.getDisplayAdjustments(displayId));
if (display != null) {
mDisplays.put(displayId, display);
}

View File

@ -28,7 +28,7 @@ import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
@ -164,18 +164,18 @@ public final class DisplayManagerGlobal {
* Gets information about a logical display.
*
* The display metrics may be adjusted to provide compatibility
* for legacy applications.
* for legacy applications or limited screen areas.
*
* @param displayId The logical display id.
* @param cih The compatibility info, or null if none is required.
* @param daj The compatibility info and activityToken.
* @return The display object, or null if there is no display with the given id.
*/
public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) {
public Display getCompatibleDisplay(int displayId, DisplayAdjustments daj) {
DisplayInfo displayInfo = getDisplayInfo(displayId);
if (displayInfo == null) {
return null;
}
return new Display(this, displayId, displayInfo, cih);
return new Display(this, displayId, displayInfo, daj);
}
/**
@ -185,7 +185,18 @@ public final class DisplayManagerGlobal {
* @return The display object, or null if there is no display with the given id.
*/
public Display getRealDisplay(int displayId) {
return getCompatibleDisplay(displayId, null);
return getCompatibleDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
}
/**
* Gets information about a logical display without applying any compatibility metrics.
*
* @param displayId The logical display id.
* @param IBinder the activity token for this display.
* @return The display object, or null if there is no display with the given id.
*/
public Display getRealDisplay(int displayId, IBinder token) {
return getCompatibleDisplay(displayId, new DisplayAdjustments(token));
}
public void registerDisplayListener(DisplayListener listener, Handler handler) {

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2011 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.view;
import android.content.res.CompatibilityInfo;
/** @hide */
public class CompatibilityInfoHolder {
private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
public void set(CompatibilityInfo compatInfo) {
if (compatInfo != null && (compatInfo.isScalingRequired()
|| !compatInfo.supportsScreen())) {
mCompatInfo = compatInfo;
} else {
mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
}
}
public CompatibilityInfo get() {
return mCompatInfo;
}
public CompatibilityInfo getIfNeeded() {
CompatibilityInfo ci = mCompatInfo;
if (ci == null || ci == CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO) {
return null;
}
return ci;
}
}

View File

@ -16,6 +16,7 @@
package android.view;
import android.content.res.CompatibilityInfo;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@ -60,7 +61,7 @@ public final class Display {
private final String mAddress;
private final int mOwnerUid;
private final String mOwnerPackageName;
private final CompatibilityInfoHolder mCompatibilityInfo;
private final DisplayAdjustments mDisplayAdjustments;
private DisplayInfo mDisplayInfo; // never null
private boolean mIsValid;
@ -203,11 +204,11 @@ public final class Display {
*/
public Display(DisplayManagerGlobal global,
int displayId, DisplayInfo displayInfo /*not null*/,
CompatibilityInfoHolder compatibilityInfo) {
DisplayAdjustments daj) {
mGlobal = global;
mDisplayId = displayId;
mDisplayInfo = displayInfo;
mCompatibilityInfo = compatibilityInfo;
mDisplayAdjustments = daj;
mIsValid = true;
// Cache properties that cannot change as long as the display is valid.
@ -348,11 +349,11 @@ public final class Display {
/**
* Gets the compatibility info used by this display instance.
*
* @return The compatibility info holder, or null if none is required.
* @return The display adjustments holder, or null if none is required.
* @hide
*/
public CompatibilityInfoHolder getCompatibilityInfo() {
return mCompatibilityInfo;
public DisplayAdjustments getDisplayAdjustments() {
return mDisplayAdjustments;
}
/**
@ -393,7 +394,7 @@ public final class Display {
public void getSize(Point outSize) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
outSize.x = mTempMetrics.widthPixels;
outSize.y = mTempMetrics.heightPixels;
}
@ -408,7 +409,7 @@ public final class Display {
public void getRectSize(Rect outSize) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
}
}
@ -573,7 +574,7 @@ public final class Display {
public void getMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo);
mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
}
}
@ -611,7 +612,9 @@ public final class Display {
public void getRealMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getLogicalMetrics(outMetrics, null);
mDisplayInfo.getLogicalMetrics(outMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
mDisplayAdjustments.getActivityToken());
}
}
@ -658,7 +661,7 @@ public final class Display {
long now = SystemClock.uptimeMillis();
if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
mCachedAppWidthCompat = mTempMetrics.widthPixels;
mCachedAppHeightCompat = mTempMetrics.heightPixels;
mLastCachedAppSizeUpdate = now;
@ -670,7 +673,7 @@ public final class Display {
public String toString() {
synchronized (this) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
return "Display id " + mDisplayId + ": " + mDisplayInfo
+ ", " + mTempMetrics + ", isValid=" + mIsValid;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2011 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.view;
import android.content.res.CompatibilityInfo;
import android.os.IBinder;
import com.android.internal.util.Objects;
/** @hide */
public class DisplayAdjustments {
public static final boolean DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN = false;
public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
private volatile IBinder mActivityToken;
public DisplayAdjustments() {
}
public DisplayAdjustments(IBinder token) {
mActivityToken = token;
}
public DisplayAdjustments(CompatibilityInfo compatInfo, IBinder token) {
setCompatibilityInfo(compatInfo);
mActivityToken = token;
}
public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
throw new IllegalArgumentException(
"setCompatbilityInfo: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
}
if (compatInfo != null && (compatInfo.isScalingRequired()
|| !compatInfo.supportsScreen())) {
mCompatInfo = compatInfo;
} else {
mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
}
}
public CompatibilityInfo getCompatibilityInfo() {
return mCompatInfo;
}
public void setActivityToken(IBinder token) {
if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
throw new IllegalArgumentException(
"setActivityToken: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
}
mActivityToken = token;
}
public IBinder getActivityToken() {
return mActivityToken;
}
@Override
public int hashCode() {
int hash = 17;
hash = hash * 31 + mCompatInfo.hashCode();
if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) {
hash = hash * 31 + (mActivityToken == null ? 0 : mActivityToken.hashCode());
}
return hash;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof DisplayAdjustments)) {
return false;
}
DisplayAdjustments daj = (DisplayAdjustments)o;
return Objects.equal(daj.mCompatInfo, mCompatInfo) &&
Objects.equal(daj.mActivityToken, mActivityToken);
}
}

View File

@ -17,6 +17,7 @@
package android.view;
import android.content.res.CompatibilityInfo;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
@ -343,12 +344,22 @@ public final class DisplayInfo implements Parcelable {
return 0;
}
public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
public void getAppMetrics(DisplayMetrics outMetrics) {
getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
}
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
displayAdjustments.getActivityToken(), appWidth, appHeight);
}
public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, IBinder token) {
getMetricsWithSize(outMetrics, ci, token, appWidth, appHeight);
}
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
IBinder token) {
getMetricsWithSize(outMetrics, compatInfo, token, logicalWidth, logicalHeight);
}
public int getNaturalWidth() {
@ -368,8 +379,8 @@ public final class DisplayInfo implements Parcelable {
return Display.hasAccess(uid, flags, ownerUid);
}
private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
int width, int height) {
private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
IBinder token, int width, int height) {
outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
@ -380,11 +391,8 @@ public final class DisplayInfo implements Parcelable {
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
if (cih != null) {
CompatibilityInfo ci = cih.getIfNeeded();
if (ci != null) {
ci.applyToDisplayMetrics(outMetrics);
}
if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
compatInfo.applyToDisplayMetrics(outMetrics);
}
}

View File

@ -239,7 +239,7 @@ public final class ViewRootImpl implements ViewParent,
boolean mAdded;
boolean mAddedTouchMode;
final CompatibilityInfoHolder mCompatibilityInfo;
final DisplayAdjustments mDisplayAdjustments;
// These are accessed by multiple threads.
final Rect mWinFrame; // frame given by window manager.
@ -336,8 +336,7 @@ public final class ViewRootImpl implements ViewParent,
mDisplay = display;
mBasePackageName = context.getBasePackageName();
CompatibilityInfoHolder cih = display.getCompatibilityInfo();
mCompatibilityInfo = cih != null ? cih : new CompatibilityInfoHolder();
mDisplayAdjustments = display.getDisplayAdjustments();
mThread = Thread.currentThread();
mLocation = new WindowLeaked(null);
@ -444,8 +443,9 @@ public final class ViewRootImpl implements ViewParent,
}
}
CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator();
mDisplayAdjustments.setActivityToken(attrs.token);
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
@ -1136,7 +1136,7 @@ public final class ViewRootImpl implements ViewParent,
surfaceChanged = true;
params = lp;
}
CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
params = lp;
mFullRedrawNeeded = true;
@ -2847,8 +2847,8 @@ public final class ViewRootImpl implements ViewParent,
+ mWindowAttributes.getTitle()
+ ": " + config);
CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
if (ci != null) {
CompatibilityInfo ci = mDisplayAdjustments.getCompatibilityInfo();
if (!ci.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
config = new Configuration(config);
ci.applyToConfiguration(mNoncompatDensity, config);
}

View File

@ -97,6 +97,7 @@ import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IApplicationToken;
@ -6609,8 +6610,9 @@ public class WindowManagerService extends IWindowManager.Stub
displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
displayInfo.appWidth = appWidth;
displayInfo.appHeight = appHeight;
displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
displayInfo.getAppMetrics(mDisplayMetrics, null);
displayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
displayInfo.getAppMetrics(mDisplayMetrics);
mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
displayContent.getDisplayId(), displayInfo);
}

View File

@ -39,7 +39,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.view.CompatibilityInfoHolder;
import android.view.DisplayAdjustments;
import android.view.Display;
import java.io.File;
@ -574,7 +574,7 @@ public class MockContext extends Context {
/** @hide */
@Override
public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
public DisplayAdjustments getDisplayAdjustments(int displayId) {
throw new UnsupportedOperationException();
}
}