Skip to content

Commit a492c3a

Browse files
author
Jeff Brown
committed
Initial draft of high-level multi-display APIs.
This patch introduces the ability to create a Context that is bound to a Display. The context gets its configuration and metrics from that display and is able to provide a WindowManager that is bound to the display. To make it easier to use, we also add a new kind of Dialog called a Presentation. Presentation takes care of setting up the context as needed and watches for significant changes in the display configuration. If the display is removed, then the presentation simply dismisses itself. Change-Id: Idc54b4ec84b1ff91505cfb78910cf8cd09696d7d
1 parent 00453e7 commit a492c3a

File tree

21 files changed

+600
-93
lines changed

21 files changed

+600
-93
lines changed

api/current.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ package android {
773773
field public static final int preferenceLayoutChild = 16842900; // 0x1010094
774774
field public static final int preferenceScreenStyle = 16842891; // 0x101008b
775775
field public static final int preferenceStyle = 16842894; // 0x101008e
776+
field public static final int presentationTheme = 16843712; // 0x10103c0
776777
field public static final int previewImage = 16843482; // 0x10102da
777778
field public static final int priority = 16842780; // 0x101001c
778779
field public static final int privateImeOptions = 16843299; // 0x1010223
@@ -3901,6 +3902,15 @@ package android.app {
39013902
method public abstract void onSendFinished(android.app.PendingIntent, android.content.Intent, int, java.lang.String, android.os.Bundle);
39023903
}
39033904

3905+
public class Presentation extends android.app.Dialog {
3906+
ctor public Presentation(android.content.Context, android.view.Display);
3907+
ctor public Presentation(android.content.Context, android.view.Display, int);
3908+
method public android.view.Display getDisplay();
3909+
method public android.content.res.Resources getResources();
3910+
method public void onDisplayChanged();
3911+
method public void onDisplayRemoved();
3912+
}
3913+
39043914
public class ProgressDialog extends android.app.AlertDialog {
39053915
ctor public ProgressDialog(android.content.Context);
39063916
ctor public ProgressDialog(android.content.Context, int);
@@ -5268,6 +5278,7 @@ package android.content {
52685278
method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
52695279
method public abstract deprecated void clearWallpaper() throws java.io.IOException;
52705280
method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
5281+
method public abstract android.content.Context createDisplayContext(android.view.Display);
52715282
method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
52725283
method public abstract java.lang.String[] databaseList();
52735284
method public abstract boolean deleteDatabase(java.lang.String);
@@ -5417,6 +5428,7 @@ package android.content {
54175428
method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
54185429
method public void clearWallpaper() throws java.io.IOException;
54195430
method public android.content.Context createConfigurationContext(android.content.res.Configuration);
5431+
method public android.content.Context createDisplayContext(android.view.Display);
54205432
method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
54215433
method public java.lang.String[] databaseList();
54225434
method public boolean deleteDatabase(java.lang.String);
@@ -21228,6 +21240,7 @@ package android.test.mock {
2122821240
method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
2122921241
method public void clearWallpaper();
2123021242
method public android.content.Context createConfigurationContext(android.content.res.Configuration);
21243+
method public android.content.Context createDisplayContext(android.view.Display);
2123121244
method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
2123221245
method public java.lang.String[] databaseList();
2123321246
method public boolean deleteDatabase(java.lang.String);
@@ -22911,6 +22924,7 @@ package android.util {
2291122924

2291222925
public class DisplayMetrics {
2291322926
ctor public DisplayMetrics();
22927+
method public boolean equals(android.util.DisplayMetrics);
2291422928
method public void setTo(android.util.DisplayMetrics);
2291522929
method public void setToDefaults();
2291622930
field public static final int DENSITY_DEFAULT = 160; // 0xa0

core/java/android/app/ActivityThread.java

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public final class ActivityThread {
203203
= new HashMap<String, WeakReference<LoadedApk>>();
204204
final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
205205
= new HashMap<String, WeakReference<LoadedApk>>();
206-
final HashMap<CompatibilityInfo, DisplayMetrics> mDisplayMetrics
206+
final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
207207
= new HashMap<CompatibilityInfo, DisplayMetrics>();
208208
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
209209
= new HashMap<ResourcesKey, WeakReference<Resources> >();
@@ -1475,12 +1475,14 @@ public final boolean queueIdle() {
14751475

14761476
private static class ResourcesKey {
14771477
final private String mResDir;
1478+
final private int mDisplayId;
14781479
final private Configuration mOverrideConfiguration;
14791480
final private float mScale;
14801481
final private int mHash;
14811482

1482-
ResourcesKey(String resDir, Configuration overrideConfiguration, float scale) {
1483+
ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
14831484
mResDir = resDir;
1485+
mDisplayId = displayId;
14841486
if (overrideConfiguration != null) {
14851487
if (Configuration.EMPTY.equals(overrideConfiguration)) {
14861488
overrideConfiguration = null;
@@ -1490,6 +1492,7 @@ private static class ResourcesKey {
14901492
mScale = scale;
14911493
int hash = 17;
14921494
hash = 31 * hash + mResDir.hashCode();
1495+
hash = 31 * hash + mDisplayId;
14931496
hash = 31 * hash + (mOverrideConfiguration != null
14941497
? mOverrideConfiguration.hashCode() : 0);
14951498
hash = 31 * hash + Float.floatToIntBits(mScale);
@@ -1510,6 +1513,9 @@ public boolean equals(Object obj) {
15101513
if (!mResDir.equals(peer.mResDir)) {
15111514
return false;
15121515
}
1516+
if (mDisplayId != peer.mDisplayId) {
1517+
return false;
1518+
}
15131519
if (mOverrideConfiguration != peer.mOverrideConfiguration) {
15141520
if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
15151521
return false;
@@ -1552,28 +1558,32 @@ public static IPackageManager getPackageManager() {
15521558
return sPackageManager;
15531559
}
15541560

1555-
DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate) {
1556-
DisplayMetrics dm = mDisplayMetrics.get(ci);
1557-
if (dm != null && !forceUpdate) {
1561+
private void flushDisplayMetricsLocked() {
1562+
mDefaultDisplayMetrics.clear();
1563+
}
1564+
1565+
DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1566+
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1567+
DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1568+
if (dm != null) {
15581569
return dm;
15591570
}
1571+
dm = new DisplayMetrics();
15601572

15611573
DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
15621574
if (displayManager == null) {
15631575
// may be null early in system startup
1564-
dm = new DisplayMetrics();
15651576
dm.setToDefaults();
15661577
return dm;
15671578
}
15681579

1569-
if (dm == null) {
1570-
dm = new DisplayMetrics();
1571-
mDisplayMetrics.put(ci, dm);
1580+
if (isDefaultDisplay) {
1581+
mDefaultDisplayMetrics.put(ci, dm);
15721582
}
15731583

15741584
CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
15751585
cih.set(ci);
1576-
Display d = displayManager.getCompatibleDisplay(Display.DEFAULT_DISPLAY, cih);
1586+
Display d = displayManager.getCompatibleDisplay(displayId, cih);
15771587
d.getMetrics(dm);
15781588
//Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
15791589
// + metrics.heightPixels + " den=" + metrics.density
@@ -1602,9 +1612,11 @@ Configuration applyConfigCompatMainThread(int displayDensity, Configuration conf
16021612
* @param compInfo the compability info. It will use the default compatibility info when it's
16031613
* null.
16041614
*/
1605-
Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
1615+
Resources getTopLevelResources(String resDir,
1616+
int displayId, Configuration overrideConfiguration,
16061617
CompatibilityInfo compInfo) {
1607-
ResourcesKey key = new ResourcesKey(resDir, overrideConfiguration,
1618+
ResourcesKey key = new ResourcesKey(resDir,
1619+
displayId, overrideConfiguration,
16081620
compInfo.applicationScale);
16091621
Resources r;
16101622
synchronized (mPackages) {
@@ -1636,15 +1648,21 @@ Resources getTopLevelResources(String resDir, Configuration overrideConfiguratio
16361648
}
16371649

16381650
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
1639-
DisplayMetrics metrics = getDisplayMetricsLocked(null, false);
1651+
DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
16401652
Configuration config;
1641-
if (key.mOverrideConfiguration != null) {
1653+
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1654+
if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
16421655
config = new Configuration(getConfiguration());
1643-
config.updateFrom(key.mOverrideConfiguration);
1656+
if (!isDefaultDisplay) {
1657+
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1658+
}
1659+
if (key.mOverrideConfiguration != null) {
1660+
config.updateFrom(key.mOverrideConfiguration);
1661+
}
16441662
} else {
16451663
config = getConfiguration();
16461664
}
1647-
r = new Resources(assets, metrics, config, compInfo);
1665+
r = new Resources(assets, dm, config, compInfo);
16481666
if (false) {
16491667
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
16501668
+ r.getConfiguration() + " appScale="
@@ -1670,9 +1688,10 @@ Resources getTopLevelResources(String resDir, Configuration overrideConfiguratio
16701688
/**
16711689
* Creates the top level resources for the given package.
16721690
*/
1673-
Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
1691+
Resources getTopLevelResources(String resDir,
1692+
int displayId, Configuration overrideConfiguration,
16741693
LoadedApk pkgInfo) {
1675-
return getTopLevelResources(resDir, overrideConfiguration,
1694+
return getTopLevelResources(resDir, displayId, overrideConfiguration,
16761695
pkgInfo.mCompatibilityInfo.get());
16771696
}
16781697

@@ -1844,7 +1863,8 @@ public ContextImpl getSystemContext() {
18441863
context.init(info, null, this);
18451864
context.getResources().updateConfiguration(
18461865
getConfiguration(), getDisplayMetricsLocked(
1847-
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, false));
1866+
Display.DEFAULT_DISPLAY,
1867+
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
18481868
mSystemContext = context;
18491869
//Slog.i(TAG, "Created system resources " + context.getResources()
18501870
// + ": " + context.getResources().getConfiguration());
@@ -3707,7 +3727,9 @@ final boolean applyConfigurationToResourcesLocked(Configuration config,
37073727
return false;
37083728
}
37093729
int changes = mResConfiguration.updateFrom(config);
3710-
DisplayMetrics dm = getDisplayMetricsLocked(null, true);
3730+
flushDisplayMetricsLocked();
3731+
DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3732+
Display.DEFAULT_DISPLAY, null);
37113733

37123734
if (compat != null && (mResCompatibilityInfo == null ||
37133735
!mResCompatibilityInfo.equals(compat))) {
@@ -3722,7 +3744,7 @@ final boolean applyConfigurationToResourcesLocked(Configuration config,
37223744
Locale.setDefault(config.locale);
37233745
}
37243746

3725-
Resources.updateSystemConfiguration(config, dm, compat);
3747+
Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
37263748

37273749
ApplicationPackageManager.configurationChanged();
37283750
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
@@ -3737,13 +3759,22 @@ final boolean applyConfigurationToResourcesLocked(Configuration config,
37373759
if (r != null) {
37383760
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
37393761
+ r + " config to: " + config);
3740-
Configuration override = entry.getKey().mOverrideConfiguration;
3741-
if (override != null) {
3762+
int displayId = entry.getKey().mDisplayId;
3763+
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3764+
DisplayMetrics dm = defaultDisplayMetrics;
3765+
Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3766+
if (!isDefaultDisplay || overrideConfig != null) {
37423767
if (tmpConfig == null) {
37433768
tmpConfig = new Configuration();
37443769
}
37453770
tmpConfig.setTo(config);
3746-
tmpConfig.updateFrom(override);
3771+
if (!isDefaultDisplay) {
3772+
dm = getDisplayMetricsLocked(displayId, null);
3773+
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3774+
}
3775+
if (overrideConfig != null) {
3776+
tmpConfig.updateFrom(overrideConfig);
3777+
}
37473778
r.updateConfiguration(tmpConfig, dm, compat);
37483779
} else {
37493780
r.updateConfiguration(config, dm, compat);
@@ -3759,6 +3790,22 @@ final boolean applyConfigurationToResourcesLocked(Configuration config,
37593790
return changes != 0;
37603791
}
37613792

3793+
final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3794+
DisplayMetrics dm, Configuration config) {
3795+
config.screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE
3796+
| Configuration.SCREENLAYOUT_LONG_NO;
3797+
config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
3798+
config.orientation = (dm.widthPixels >= dm.heightPixels) ?
3799+
Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
3800+
config.densityDpi = dm.densityDpi;
3801+
config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3802+
config.screenHeightDp = (int)(dm.heightPixels / dm.density);
3803+
config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3804+
config.compatScreenWidthDp = config.screenWidthDp;
3805+
config.compatScreenHeightDp = config.screenHeightDp;
3806+
config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3807+
}
3808+
37623809
final Configuration applyCompatConfiguration(int displayDensity) {
37633810
Configuration config = mConfiguration;
37643811
if (mCompatConfiguration == null) {

core/java/android/app/AlertDialog.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ protected AlertDialog(Context context, int theme) {
110110
this(context, theme, true);
111111
}
112112

113-
AlertDialog(Context context, int theme, boolean createContextWrapper) {
114-
super(context, resolveDialogTheme(context, theme), createContextWrapper);
113+
AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
114+
super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);
115+
115116
mWindow.alwaysReadCloseOnTouchAttr();
116117
mAlert = new AlertController(getContext(), this, getWindow());
117118
}

core/java/android/app/ApplicationPackageManager.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import android.os.RemoteException;
5555
import android.os.UserHandle;
5656
import android.util.Log;
57+
import android.view.Display;
5758

5859
import java.lang.ref.WeakReference;
5960
import java.util.ArrayList;
@@ -722,8 +723,8 @@ public Drawable getApplicationLogo(String packageName)
722723
return mContext.mMainThread.getSystemContext().getResources();
723724
}
724725
Resources r = mContext.mMainThread.getTopLevelResources(
725-
app.uid == Process.myUid() ? app.sourceDir
726-
: app.publicSourceDir, null, mContext.mPackageInfo);
726+
app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
727+
Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
727728
if (r != null) {
728729
return r;
729730
}

0 commit comments

Comments
 (0)