Merge "Adjust activity display metrics based on stack configuration."
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d781863..0289e48 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2372,35 +2372,32 @@
return activity;
}
- private Context createBaseContextForActivity(ActivityClientRecord r,
- final Activity activity) {
- ContextImpl appContext =
- ContextImpl.createActivityContext(this, r.packageInfo, r.overrideConfig);
- appContext.setOuterContext(activity);
- Context baseContext = appContext;
-
- final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
+ private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
+ int displayId = Display.DEFAULT_DISPLAY;
try {
IActivityContainer container =
ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
- final int displayId =
- container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
- if (displayId > Display.DEFAULT_DISPLAY) {
- Display display = dm.getRealDisplay(displayId, r.token);
- baseContext = appContext.createDisplayContext(display);
+ if (container != null) {
+ displayId = container.getDisplayId();
}
} catch (RemoteException e) {
}
+ ContextImpl appContext = ContextImpl.createActivityContext(
+ this, r.packageInfo, displayId, r.overrideConfig);
+ appContext.setOuterContext(activity);
+ Context baseContext = appContext;
+
+ final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
- for (int displayId : dm.getDisplayIds()) {
- if (displayId != Display.DEFAULT_DISPLAY) {
- Display display = dm.getRealDisplay(displayId, r.token);
+ for (int id : dm.getDisplayIds()) {
+ if (id != Display.DEFAULT_DISPLAY) {
+ Display display = dm.getRealDisplay(id, r.overrideConfig);
baseContext = appContext.createDisplayContext(display);
break;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 6c78cab..0098d86 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2252,7 +2252,7 @@
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
- context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
+ context.mResourcesManager.getDisplayMetricsLocked());
return context;
}
@@ -2263,9 +2263,11 @@
}
static ContextImpl createActivityContext(ActivityThread mainThread,
- LoadedApk packageInfo, Configuration overrideConfiguration) {
+ LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
- return new ContextImpl(null, mainThread, packageInfo, null, null, false, null,
+ final Display display = ResourcesManager.getInstance().getAdjustedDisplay(
+ displayId, overrideConfiguration);
+ return new ContextImpl(null, mainThread, packageInfo, null, null, false, display,
overrideConfiguration);
}
@@ -2296,7 +2298,7 @@
compatInfo = packageInfo.getCompatibilityInfo();
}
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
- mDisplayAdjustments.setActivityToken(activityToken);
+ mDisplayAdjustments.setConfiguration(overrideConfiguration);
Resources resources = packageInfo.getResources(mainThread);
if (resources != null) {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index fac40b2..17885a2 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -27,6 +27,7 @@
import android.hardware.display.DisplayManagerGlobal;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
+import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
@@ -40,11 +41,10 @@
private static final boolean DEBUG = false;
private static ResourcesManager sResourcesManager;
- final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources
- = new ArrayMap<ResourcesKey, WeakReference<Resources> >();
-
- final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
- = new ArrayMap<DisplayAdjustments, DisplayMetrics>();
+ private final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources =
+ new ArrayMap<>();
+ private final ArrayMap<Pair<Integer, Configuration>, WeakReference<Display>> mDisplays =
+ new ArrayMap<>();
CompatibilityInfo mResCompatibilityInfo;
@@ -63,46 +63,18 @@
return mResConfiguration;
}
- public void flushDisplayMetricsLocked() {
- mDefaultDisplayMetrics.clear();
+ DisplayMetrics getDisplayMetricsLocked() {
+ return getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
}
- public DisplayMetrics getDisplayMetricsLocked(int displayId) {
- return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
- }
-
- public DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
- boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
- DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
- if (dm != null) {
- return dm;
- }
- dm = new DisplayMetrics();
-
- DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
- if (displayManager == null) {
- // may be null early in system startup
- dm.setToDefaults();
- return dm;
- }
-
- if (isDefaultDisplay) {
- mDefaultDisplayMetrics.put(daj, dm);
- }
-
- Display d = displayManager.getCompatibleDisplay(displayId, daj);
- if (d != null) {
- d.getMetrics(dm);
+ DisplayMetrics getDisplayMetricsLocked(int displayId) {
+ DisplayMetrics dm = new DisplayMetrics();
+ final Display display = getAdjustedDisplay(displayId, Configuration.EMPTY);
+ if (display != null) {
+ display.getMetrics(dm);
} else {
- // Display no longer exists
- // FIXME: This would not be a problem if we kept the Display object around
- // instead of using the raw display id everywhere. The Display object caches
- // its information even after the display has been removed.
dm.setToDefaults();
}
- //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
- // + metrics.heightPixels + " den=" + metrics.density
- // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
return dm;
}
@@ -138,6 +110,37 @@
}
/**
+ * Returns an adjusted {@link Display} object based on the inputs or null if display isn't
+ * available.
+ *
+ * @param displayId display Id.
+ * @param overrideConfiguration override configurations.
+ */
+ public Display getAdjustedDisplay(final int displayId, Configuration overrideConfiguration) {
+ final Pair<Integer, Configuration> key =
+ Pair.create(displayId, new Configuration(overrideConfiguration));
+ synchronized (this) {
+ WeakReference<Display> wd = mDisplays.get(key);
+ if (wd != null) {
+ final Display display = wd.get();
+ if (display != null) {
+ return display;
+ }
+ }
+ final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
+ if (dm == null) {
+ // may be null early in system startup
+ return null;
+ }
+ final Display display = dm.getRealDisplay(displayId, key.second);
+ if (display != null) {
+ mDisplays.put(key, new WeakReference<>(display));
+ }
+ return display;
+ }
+ }
+
+ /**
* Creates the top level Resources for applications with the given compatibility info.
*
* @param resDir the resource directory.
@@ -148,7 +151,7 @@
* @param overrideConfiguration override configurations.
* @param compatInfo the compatibility info. Must not be null.
*/
- public Resources getTopLevelResources(String resDir, String[] splitResDirs,
+ Resources getTopLevelResources(String resDir, String[] splitResDirs,
String[] overlayDirs, String[] libDirs, int displayId,
Configuration overrideConfiguration, CompatibilityInfo compatInfo) {
final float scale = compatInfo.applicationScale;
@@ -247,7 +250,7 @@
}
}
- public final boolean applyConfigurationToResourcesLocked(Configuration config,
+ final boolean applyConfigurationToResourcesLocked(Configuration config,
CompatibilityInfo compat) {
if (mResConfiguration == null) {
mResConfiguration = new Configuration();
@@ -258,8 +261,9 @@
return false;
}
int changes = mResConfiguration.updateFrom(config);
- flushDisplayMetricsLocked();
- DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
+ // Things might have changed in display manager, so clear the cached displays.
+ mDisplays.clear();
+ DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked();
if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) {
@@ -281,7 +285,7 @@
Configuration tmpConfig = null;
- for (int i=mActiveResources.size()-1; i>=0; i--) {
+ for (int i = mActiveResources.size() - 1; i >= 0; i--) {
ResourcesKey key = mActiveResources.keyAt(i);
Resources r = mActiveResources.valueAt(i).get();
if (r != null) {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 0051ef5..d9f9c1e 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -17,10 +17,10 @@
package android.hardware.display;
import android.content.Context;
+import android.content.res.Configuration;
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.projection.MediaProjection;
import android.media.projection.IMediaProjection;
-import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -196,11 +196,11 @@
* 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.
+ * @param configuration the configuration.
* @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 Display getRealDisplay(int displayId, Configuration configuration) {
+ return getCompatibleDisplay(displayId, new DisplayAdjustments(configuration));
}
public void registerDisplayListener(DisplayListener listener, Handler handler) {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index cfb0297..71863b7 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -716,7 +716,7 @@
updateDisplayInfoLocked();
mDisplayInfo.getLogicalMetrics(outMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
- mDisplayAdjustments.getActivityToken());
+ mDisplayAdjustments.getConfiguration());
}
}
diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java
index 35fb504..272740f 100644
--- a/core/java/android/view/DisplayAdjustments.java
+++ b/core/java/android/view/DisplayAdjustments.java
@@ -17,7 +17,7 @@
package android.view;
import android.content.res.CompatibilityInfo;
-import android.os.IBinder;
+import android.content.res.Configuration;
import java.util.Objects;
@@ -28,22 +28,18 @@
public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
- private volatile IBinder mActivityToken;
+ private Configuration mConfiguration = Configuration.EMPTY;
public DisplayAdjustments() {
}
- public DisplayAdjustments(IBinder token) {
- mActivityToken = token;
+ public DisplayAdjustments(Configuration configuration) {
+ mConfiguration = configuration;
}
public DisplayAdjustments(DisplayAdjustments daj) {
- this (daj.getCompatibilityInfo(), daj.getActivityToken());
- }
-
- public DisplayAdjustments(CompatibilityInfo compatInfo, IBinder token) {
- setCompatibilityInfo(compatInfo);
- mActivityToken = token;
+ setCompatibilityInfo(daj.mCompatInfo);
+ mConfiguration = daj.mConfiguration;
}
public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
@@ -63,16 +59,16 @@
return mCompatInfo;
}
- public void setActivityToken(IBinder token) {
+ public void setConfiguration(Configuration configuration) {
if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
throw new IllegalArgumentException(
- "setActivityToken: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
+ "setConfiguration: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
}
- mActivityToken = token;
+ mConfiguration = configuration;
}
- public IBinder getActivityToken() {
- return mActivityToken;
+ public Configuration getConfiguration() {
+ return mConfiguration;
}
@Override
@@ -80,7 +76,7 @@
int hash = 17;
hash = hash * 31 + mCompatInfo.hashCode();
if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) {
- hash = hash * 31 + (mActivityToken == null ? 0 : mActivityToken.hashCode());
+ hash = hash * 31 + (mConfiguration == null ? 0 : mConfiguration.hashCode());
}
return hash;
}
@@ -92,6 +88,6 @@
}
DisplayAdjustments daj = (DisplayAdjustments)o;
return Objects.equals(daj.mCompatInfo, mCompatInfo) &&
- Objects.equals(daj.mActivityToken, mActivityToken);
+ Objects.equals(daj.mConfiguration, mConfiguration);
}
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 9feb681..ecf45b4 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -17,7 +17,7 @@
package android.view;
import android.content.res.CompatibilityInfo;
-import android.os.IBinder;
+import android.content.res.Configuration;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
@@ -401,16 +401,17 @@
public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
- displayAdjustments.getActivityToken(), appWidth, appHeight);
+ displayAdjustments.getConfiguration(), appWidth, appHeight);
}
- public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, IBinder token) {
- getMetricsWithSize(outMetrics, ci, token, appWidth, appHeight);
+ public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
+ Configuration configuration) {
+ getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
}
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
- IBinder token) {
- getMetricsWithSize(outMetrics, compatInfo, token, logicalWidth, logicalHeight);
+ Configuration configuration) {
+ getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
}
public int getNaturalWidth() {
@@ -431,17 +432,24 @@
}
private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
- IBinder token, int width, int height) {
+ Configuration configuration, int width, int height) {
outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
- outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
- outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
-
outMetrics.density = outMetrics.noncompatDensity =
logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
+ width = (configuration != null
+ && configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED)
+ ? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width;
+ height = (configuration != null
+ && configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED)
+ ? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height;
+
+ outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
+ outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
+
if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
compatInfo.applyToDisplayMetrics(outMetrics);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fb2a8d8..24fae8a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -478,7 +478,6 @@
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) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e88dace..99cc03e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1551,6 +1551,9 @@
pw.print(prefix); pw.print("touchable region="); pw.println(region);
}
pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
+ if (mOverrideConfig != Configuration.EMPTY) {
+ pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig);
+ }
}
pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
pw.print(" mShownFrame="); mShownFrame.printShortString(pw);