diff options
-rw-r--r-- | core/java/android/app/ActivityThread.java | 29 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 10 | ||||
-rw-r--r-- | core/java/android/app/ResourcesManager.java | 94 | ||||
-rw-r--r-- | core/java/android/hardware/display/DisplayManagerGlobal.java | 8 | ||||
-rw-r--r-- | core/java/android/view/Display.java | 2 | ||||
-rw-r--r-- | core/java/android/view/DisplayAdjustments.java | 30 | ||||
-rw-r--r-- | core/java/android/view/DisplayInfo.java | 28 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java | 3 |
9 files changed, 107 insertions, 98 deletions
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 @@ public final class ActivityThread { 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 @@ class ContextImpl extends Context { 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 @@ class ContextImpl extends Context { } 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 @@ class ContextImpl extends Context { 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.content.res.ResourcesKey; 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 @@ public class ResourcesManager { 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 @@ public class ResourcesManager { return mResConfiguration; } - public void flushDisplayMetricsLocked() { - mDefaultDisplayMetrics.clear(); - } - - public DisplayMetrics getDisplayMetricsLocked(int displayId) { - return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); + DisplayMetrics getDisplayMetricsLocked() { + return getDisplayMetricsLocked(Display.DEFAULT_DISPLAY); } - 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 @@ public class ResourcesManager { } /** + * 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 @@ public class ResourcesManager { * @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 class ResourcesManager { } } - public final boolean applyConfigurationToResourcesLocked(Configuration config, + final boolean applyConfigurationToResourcesLocked(Configuration config, CompatibilityInfo compat) { if (mResConfiguration == null) { mResConfiguration = new Configuration(); @@ -258,8 +261,9 @@ public class ResourcesManager { 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 @@ public class ResourcesManager { 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 @@ public final class DisplayManagerGlobal { * 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 @@ public final class Display { 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 class DisplayAdjustments { 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 @@ public class DisplayAdjustments { 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 @@ public class DisplayAdjustments { 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 @@ public class DisplayAdjustments { } 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 final class DisplayInfo implements Parcelable { 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 @@ public final class DisplayInfo implements Parcelable { } 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { 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); |