summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorWale Ogunwale <ogunwale@google.com>2015-02-06 17:34:28 -0800
committerWale Ogunwale <ogunwale@google.com>2015-02-13 21:12:47 -0800
commit7c72668f19d404b01412abc67937b1b5c660df71 (patch)
treee98ddbb5e82a5a8e0e02e2fd14056cec591cb7ea /core/java
parent80955e105d6e71f7b71a63b391fd5a8adcded55e (diff)
downloadframeworks_base-7c72668f19d404b01412abc67937b1b5c660df71.zip
frameworks_base-7c72668f19d404b01412abc67937b1b5c660df71.tar.gz
frameworks_base-7c72668f19d404b01412abc67937b1b5c660df71.tar.bz2
Adjust activity display metrics based on stack configuration.
Apps normally use context.getResources().getDisplayMetrics() or getWindowManager().getDefaultDisplay() to get information about the screen dimensions. Not all the screen space is available for apps in a multi-window environment, so we limit the dimensions of the display object exposed to the app to that of the containing stack. Bug: 19225079 Bug: 19354838 Change-Id: I8dc3a6c9b99ecedcca28fc4ddaba9f31feb4f871
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityThread.java29
-rw-r--r--core/java/android/app/ContextImpl.java10
-rw-r--r--core/java/android/app/ResourcesManager.java94
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java8
-rw-r--r--core/java/android/view/Display.java2
-rw-r--r--core/java/android/view/DisplayAdjustments.java30
-rw-r--r--core/java/android/view/DisplayInfo.java28
-rw-r--r--core/java/android/view/ViewRootImpl.java1
8 files changed, 104 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) {