summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt14
-rw-r--r--core/java/android/app/ActivityThread.java95
-rw-r--r--core/java/android/app/AlertDialog.java5
-rw-r--r--core/java/android/app/ApplicationPackageManager.java5
-rw-r--r--core/java/android/app/ContextImpl.java50
-rw-r--r--core/java/android/app/Dialog.java20
-rw-r--r--core/java/android/app/LoadedApk.java7
-rw-r--r--core/java/android/app/Presentation.java256
-rw-r--r--core/java/android/content/Context.java29
-rw-r--r--core/java/android/content/ContextWrapper.java10
-rw-r--r--core/java/android/hardware/display/DisplayManager.java11
-rw-r--r--core/java/android/util/DisplayMetrics.java51
-rw-r--r--core/java/android/view/WindowManager.java33
-rw-r--r--core/java/android/view/WindowManagerImpl.java20
-rwxr-xr-xcore/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/styles_device_defaults.xml1
-rw-r--r--core/res/res/values/themes.xml41
-rw-r--r--core/res/res/values/themes_device_defaults.xml23
-rw-r--r--test-runner/src/android/test/mock/MockContext.java8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java9
21 files changed, 600 insertions, 93 deletions
diff --git a/api/current.txt b/api/current.txt
index 10ed68d..10a525c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -773,6 +773,7 @@ package android {
field public static final int preferenceLayoutChild = 16842900; // 0x1010094
field public static final int preferenceScreenStyle = 16842891; // 0x101008b
field public static final int preferenceStyle = 16842894; // 0x101008e
+ field public static final int presentationTheme = 16843712; // 0x10103c0
field public static final int previewImage = 16843482; // 0x10102da
field public static final int priority = 16842780; // 0x101001c
field public static final int privateImeOptions = 16843299; // 0x1010223
@@ -3901,6 +3902,15 @@ package android.app {
method public abstract void onSendFinished(android.app.PendingIntent, android.content.Intent, int, java.lang.String, android.os.Bundle);
}
+ public class Presentation extends android.app.Dialog {
+ ctor public Presentation(android.content.Context, android.view.Display);
+ ctor public Presentation(android.content.Context, android.view.Display, int);
+ method public android.view.Display getDisplay();
+ method public android.content.res.Resources getResources();
+ method public void onDisplayChanged();
+ method public void onDisplayRemoved();
+ }
+
public class ProgressDialog extends android.app.AlertDialog {
ctor public ProgressDialog(android.content.Context);
ctor public ProgressDialog(android.content.Context, int);
@@ -5268,6 +5278,7 @@ package android.content {
method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
method public abstract deprecated void clearWallpaper() throws java.io.IOException;
method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
+ method public abstract android.content.Context createDisplayContext(android.view.Display);
method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.lang.String[] databaseList();
method public abstract boolean deleteDatabase(java.lang.String);
@@ -5417,6 +5428,7 @@ package android.content {
method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
method public void clearWallpaper() throws java.io.IOException;
method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+ method public android.content.Context createDisplayContext(android.view.Display);
method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.lang.String[] databaseList();
method public boolean deleteDatabase(java.lang.String);
@@ -21228,6 +21240,7 @@ package android.test.mock {
method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
method public void clearWallpaper();
method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+ method public android.content.Context createDisplayContext(android.view.Display);
method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.lang.String[] databaseList();
method public boolean deleteDatabase(java.lang.String);
@@ -22911,6 +22924,7 @@ package android.util {
public class DisplayMetrics {
ctor public DisplayMetrics();
+ method public boolean equals(android.util.DisplayMetrics);
method public void setTo(android.util.DisplayMetrics);
method public void setToDefaults();
field public static final int DENSITY_DEFAULT = 160; // 0xa0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4a1bf75..1b788c2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -203,7 +203,7 @@ public final class ActivityThread {
= new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
= new HashMap<String, WeakReference<LoadedApk>>();
- final HashMap<CompatibilityInfo, DisplayMetrics> mDisplayMetrics
+ final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
= new HashMap<CompatibilityInfo, DisplayMetrics>();
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
= new HashMap<ResourcesKey, WeakReference<Resources> >();
@@ -1475,12 +1475,14 @@ public final class ActivityThread {
private static class ResourcesKey {
final private String mResDir;
+ final private int mDisplayId;
final private Configuration mOverrideConfiguration;
final private float mScale;
final private int mHash;
- ResourcesKey(String resDir, Configuration overrideConfiguration, float scale) {
+ ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
mResDir = resDir;
+ mDisplayId = displayId;
if (overrideConfiguration != null) {
if (Configuration.EMPTY.equals(overrideConfiguration)) {
overrideConfiguration = null;
@@ -1490,6 +1492,7 @@ public final class ActivityThread {
mScale = scale;
int hash = 17;
hash = 31 * hash + mResDir.hashCode();
+ hash = 31 * hash + mDisplayId;
hash = 31 * hash + (mOverrideConfiguration != null
? mOverrideConfiguration.hashCode() : 0);
hash = 31 * hash + Float.floatToIntBits(mScale);
@@ -1510,6 +1513,9 @@ public final class ActivityThread {
if (!mResDir.equals(peer.mResDir)) {
return false;
}
+ if (mDisplayId != peer.mDisplayId) {
+ return false;
+ }
if (mOverrideConfiguration != peer.mOverrideConfiguration) {
if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
return false;
@@ -1552,28 +1558,32 @@ public final class ActivityThread {
return sPackageManager;
}
- DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate) {
- DisplayMetrics dm = mDisplayMetrics.get(ci);
- if (dm != null && !forceUpdate) {
+ private void flushDisplayMetricsLocked() {
+ mDefaultDisplayMetrics.clear();
+ }
+
+ DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
+ boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+ DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
+ if (dm != null) {
return dm;
}
+ dm = new DisplayMetrics();
DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
if (displayManager == null) {
// may be null early in system startup
- dm = new DisplayMetrics();
dm.setToDefaults();
return dm;
}
- if (dm == null) {
- dm = new DisplayMetrics();
- mDisplayMetrics.put(ci, dm);
+ if (isDefaultDisplay) {
+ mDefaultDisplayMetrics.put(ci, dm);
}
CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
cih.set(ci);
- Display d = displayManager.getCompatibleDisplay(Display.DEFAULT_DISPLAY, cih);
+ Display d = displayManager.getCompatibleDisplay(displayId, cih);
d.getMetrics(dm);
//Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
// + metrics.heightPixels + " den=" + metrics.density
@@ -1602,9 +1612,11 @@ public final class ActivityThread {
* @param compInfo the compability info. It will use the default compatibility info when it's
* null.
*/
- Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
+ Resources getTopLevelResources(String resDir,
+ int displayId, Configuration overrideConfiguration,
CompatibilityInfo compInfo) {
- ResourcesKey key = new ResourcesKey(resDir, overrideConfiguration,
+ ResourcesKey key = new ResourcesKey(resDir,
+ displayId, overrideConfiguration,
compInfo.applicationScale);
Resources r;
synchronized (mPackages) {
@@ -1636,15 +1648,21 @@ public final class ActivityThread {
}
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
- DisplayMetrics metrics = getDisplayMetricsLocked(null, false);
+ DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
Configuration config;
- if (key.mOverrideConfiguration != null) {
+ boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+ if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
config = new Configuration(getConfiguration());
- config.updateFrom(key.mOverrideConfiguration);
+ if (!isDefaultDisplay) {
+ applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
+ }
+ if (key.mOverrideConfiguration != null) {
+ config.updateFrom(key.mOverrideConfiguration);
+ }
} else {
config = getConfiguration();
}
- r = new Resources(assets, metrics, config, compInfo);
+ r = new Resources(assets, dm, config, compInfo);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
+ r.getConfiguration() + " appScale="
@@ -1670,9 +1688,10 @@ public final class ActivityThread {
/**
* Creates the top level resources for the given package.
*/
- Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
+ Resources getTopLevelResources(String resDir,
+ int displayId, Configuration overrideConfiguration,
LoadedApk pkgInfo) {
- return getTopLevelResources(resDir, overrideConfiguration,
+ return getTopLevelResources(resDir, displayId, overrideConfiguration,
pkgInfo.mCompatibilityInfo.get());
}
@@ -1844,7 +1863,8 @@ public final class ActivityThread {
context.init(info, null, this);
context.getResources().updateConfiguration(
getConfiguration(), getDisplayMetricsLocked(
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, false));
+ Display.DEFAULT_DISPLAY,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration());
@@ -3707,7 +3727,9 @@ public final class ActivityThread {
return false;
}
int changes = mResConfiguration.updateFrom(config);
- DisplayMetrics dm = getDisplayMetricsLocked(null, true);
+ flushDisplayMetricsLocked();
+ DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
+ Display.DEFAULT_DISPLAY, null);
if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) {
@@ -3722,7 +3744,7 @@ public final class ActivityThread {
Locale.setDefault(config.locale);
}
- Resources.updateSystemConfiguration(config, dm, compat);
+ Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
ApplicationPackageManager.configurationChanged();
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
@@ -3737,13 +3759,22 @@ public final class ActivityThread {
if (r != null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
+ r + " config to: " + config);
- Configuration override = entry.getKey().mOverrideConfiguration;
- if (override != null) {
+ int displayId = entry.getKey().mDisplayId;
+ boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+ DisplayMetrics dm = defaultDisplayMetrics;
+ Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
+ if (!isDefaultDisplay || overrideConfig != null) {
if (tmpConfig == null) {
tmpConfig = new Configuration();
}
tmpConfig.setTo(config);
- tmpConfig.updateFrom(override);
+ if (!isDefaultDisplay) {
+ dm = getDisplayMetricsLocked(displayId, null);
+ applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
+ }
+ if (overrideConfig != null) {
+ tmpConfig.updateFrom(overrideConfig);
+ }
r.updateConfiguration(tmpConfig, dm, compat);
} else {
r.updateConfiguration(config, dm, compat);
@@ -3759,6 +3790,22 @@ public final class ActivityThread {
return changes != 0;
}
+ final void applyNonDefaultDisplayMetricsToConfigurationLocked(
+ DisplayMetrics dm, Configuration config) {
+ config.screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE
+ | Configuration.SCREENLAYOUT_LONG_NO;
+ config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+ config.orientation = (dm.widthPixels >= dm.heightPixels) ?
+ Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
+ config.densityDpi = dm.densityDpi;
+ config.screenWidthDp = (int)(dm.widthPixels / dm.density);
+ config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+ config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
+ config.compatScreenWidthDp = config.screenWidthDp;
+ config.compatScreenHeightDp = config.screenHeightDp;
+ config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
+ }
+
final Configuration applyCompatConfiguration(int displayDensity) {
Configuration config = mConfiguration;
if (mCompatConfiguration == null) {
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 7809e73..6ab2bd1 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -110,8 +110,9 @@ public class AlertDialog extends Dialog implements DialogInterface {
this(context, theme, true);
}
- AlertDialog(Context context, int theme, boolean createContextWrapper) {
- super(context, resolveDialogTheme(context, theme), createContextWrapper);
+ AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
+ super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);
+
mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(getContext(), this, getWindow());
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 91753aa..c4f1371 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -54,6 +54,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import android.view.Display;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -722,8 +723,8 @@ final class ApplicationPackageManager extends PackageManager {
return mContext.mMainThread.getSystemContext().getResources();
}
Resources r = mContext.mMainThread.getTopLevelResources(
- app.uid == Process.myUid() ? app.sourceDir
- : app.publicSourceDir, null, mContext.mPackageInfo);
+ app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
+ Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
if (r != null) {
return r;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1b6f84b..ea77bcd 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -168,6 +168,7 @@ class ContextImpl extends Context {
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
+ private Display mDisplay; // may be null if default display
private Context mReceiverRestrictedContext = null;
private boolean mRestricted;
@@ -502,8 +503,13 @@ class ContextImpl extends Context {
registerService(WINDOW_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
- return new WindowManagerImpl(ctx.getOuterContext(),
- Display.DEFAULT_DISPLAY);
+ Display display = ctx.mDisplay;
+ if (display == null) {
+ DisplayManager dm = (DisplayManager)ctx.getOuterContext().getSystemService(
+ Context.DISPLAY_SERVICE);
+ display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+ }
+ return new WindowManagerImpl(display);
}});
registerService(USER_SERVICE, new ServiceFetcher() {
@@ -1676,22 +1682,52 @@ class ContextImpl extends Context {
@Override
public Context createConfigurationContext(Configuration overrideConfiguration) {
+ if (overrideConfiguration == null) {
+ throw new IllegalArgumentException("overrideConfiguration must not be null");
+ }
+
ContextImpl c = new ContextImpl();
c.init(mPackageInfo, null, mMainThread);
c.mResources = mMainThread.getTopLevelResources(
- mPackageInfo.getResDir(), overrideConfiguration,
+ mPackageInfo.getResDir(),
+ getDisplayId(), overrideConfiguration,
mResources.getCompatibilityInfo());
return c;
}
@Override
+ public Context createDisplayContext(Display display) {
+ if (display == null) {
+ throw new IllegalArgumentException("display must not be null");
+ }
+
+ 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);
+ return context;
+ }
+
+ private int getDisplayId() {
+ return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+ }
+
+ @Override
public boolean isRestricted() {
return mRestricted;
}
@Override
- public CompatibilityInfoHolder getCompatibilityInfo() {
- return mPackageInfo.mCompatibilityInfo;
+ public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
+ return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
}
private File getDataDirFile() {
@@ -1735,6 +1771,7 @@ class ContextImpl extends Context {
mResources = context.mResources;
mMainThread = context.mMainThread;
mContentResolver = context.mContentResolver;
+ mDisplay = context.mDisplay;
mOuterContext = this;
}
@@ -1758,7 +1795,8 @@ class ContextImpl extends Context {
" compatiblity info:" + container.getDisplayMetrics());
}
mResources = mainThread.getTopLevelResources(
- mPackageInfo.getResDir(), null, container.getCompatibilityInfo());
+ mPackageInfo.getResDir(), Display.DEFAULT_DISPLAY,
+ null, container.getCompatibilityInfo());
}
mMainThread = mainThread;
mContentResolver = new ApplicationContentResolver(this, mainThread);
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 16112cb..b3d99c5 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -147,15 +147,19 @@ public class Dialog implements DialogInterface, Window.Callback,
this(context, theme, true);
}
- Dialog(Context context, int theme, boolean createContextWrapper) {
- if (theme == 0) {
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
- outValue, true);
- theme = outValue.resourceId;
+ Dialog(Context context, int theme, boolean createContextThemeWrapper) {
+ if (createContextThemeWrapper) {
+ if (theme == 0) {
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
+ outValue, true);
+ theme = outValue.resourceId;
+ }
+ mContext = new ContextThemeWrapper(context, theme);
+ } else {
+ mContext = context;
}
- mContext = createContextWrapper ? new ContextThemeWrapper(context, theme) : context;
mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w;
@@ -164,7 +168,7 @@ public class Dialog implements DialogInterface, Window.Callback,
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
-
+
/**
* @deprecated
* @hide
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 1e89bb2..6197b1a 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -41,6 +41,7 @@ import android.os.UserHandle;
import android.util.AndroidRuntimeException;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
+import android.view.Display;
import java.io.File;
import java.io.IOException;
@@ -139,7 +140,8 @@ public final class LoadedApk {
ContextImpl.createSystemContext(mainThread);
ActivityThread.mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(),
- mainThread.getDisplayMetricsLocked(compatInfo, false),
+ mainThread.getDisplayMetricsLocked(
+ Display.DEFAULT_DISPLAY, compatInfo),
compatInfo);
//Slog.i(TAG, "Created system resources "
// + mSystemContext.getResources() + ": "
@@ -471,7 +473,8 @@ public final class LoadedApk {
public Resources getResources(ActivityThread mainThread) {
if (mResources == null) {
- mResources = mainThread.getTopLevelResources(mResDir, null, this);
+ mResources = mainThread.getTopLevelResources(mResDir,
+ Display.DEFAULT_DISPLAY, null, this);
}
return mResources;
}
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
new file mode 100644
index 0000000..eb5a652
--- /dev/null
+++ b/core/java/android/app/Presentation.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2012 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.app;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.view.ContextThemeWrapper;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.WindowManagerImpl;
+import android.os.Handler;
+import android.os.Message;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+
+/**
+ * Base class for presentations.
+ *
+ * A presentation is a special kind of dialog whose purpose is to present
+ * content on a secondary display. A {@link Presentation} is associated with
+ * the target {@link Display} at creation time and configures its context and
+ * resource configuration according to the display's metrics.
+ *
+ * Notably, the {@link Context} of a presentation is different from the context
+ * of its containing {@link Activity}. It is important to inflate the layout
+ * of a presentation and load other resources using the presentation's own context
+ * to ensure that assets of the correct size and density for the target display
+ * are loaded.
+ *
+ * A presentation is automatically canceled (see {@link Dialog#cancel()}) when
+ * the display to which it is attached is removed. An activity should take
+ * care of pausing and resuming whatever content is playing within the presentation
+ * whenever the activity itself is paused or resume.
+ *
+ * @see {@link DisplayManager} for information on how to enumerate displays.
+ */
+public class Presentation extends Dialog {
+ private static final String TAG = "Presentation";
+
+ private static final int MSG_CANCEL = 1;
+
+ private final Display mDisplay;
+ private final DisplayManager mDisplayManager;
+
+ /**
+ * Creates a new presentation that is attached to the specified display
+ * using the default theme.
+ *
+ * @param outerContext The context of the application that is showing the presentation.
+ * The presentation will create its own context (see {@link #getContext()}) based
+ * on this context and information about the associated display.
+ * @param display The display to which the presentation should be attached.
+ */
+ public Presentation(Context outerContext, Display display) {
+ this(outerContext, display, 0);
+ }
+
+ /**
+ * Creates a new presentation that is attached to the specified display
+ * using the optionally specified theme.
+ *
+ * @param outerContext The context of the application that is showing the presentation.
+ * The presentation will create its own context (see {@link #getContext()}) based
+ * on this context and information about the associated display.
+ * @param display The display to which the presentation should be attached.
+ * @param theme A style resource describing the theme to use for the window.
+ * See <a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">
+ * Style and Theme Resources</a> for more information about defining and using
+ * styles. This theme is applied on top of the current theme in
+ * <var>outerContext</var>. If 0, the default presentation theme will be used.
+ */
+ public Presentation(Context outerContext, Display display, int theme) {
+ super(createPresentationContext(outerContext, display, theme), theme, false);
+
+ mDisplay = display;
+ mDisplayManager = (DisplayManager)getContext().getSystemService(Context.DISPLAY_SERVICE);
+
+ getWindow().setGravity(Gravity.FILL);
+ setCanceledOnTouchOutside(false);
+ }
+
+ /**
+ * Gets the {@link Display} that this presentation appears on.
+ *
+ * @return The display.
+ */
+ public Display getDisplay() {
+ return mDisplay;
+ }
+
+ /**
+ * Gets the {@link Resources} that should be used to inflate the layout of this presentation.
+ * This resources object has been configured according to the metrics of the
+ * display that the presentation appears on.
+ *
+ * @return The presentation resources object.
+ */
+ public Resources getResources() {
+ return getContext().getResources();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mDisplayManager.registerDisplayListener(mDisplayListener, null);
+
+ // Since we were not watching for display changes until just now, there is a
+ // chance that the display metrics have changed. If so, we will need to
+ // dismiss the presentation immediately. This case is expected
+ // to be rare but surprising, so we'll write a log message about it.
+ if (!isConfigurationStillValid()) {
+ Log.i(TAG, "Presentation is being immediately dismissed because the "
+ + "display metrics have changed since it was created.");
+ mHandler.sendEmptyMessage(MSG_CANCEL);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ mDisplayManager.unregisterDisplayListener(mDisplayListener);
+ super.onStop();
+ }
+
+ /**
+ * Called by the system when the {@link Display} to which the presentation
+ * is attached has been removed.
+ *
+ * The system automatically calls {@link #cancel} to dismiss the presentation
+ * after sending this event.
+ *
+ * @see #getDisplay
+ */
+ public void onDisplayRemoved() {
+ }
+
+ /**
+ * Called by the system when the properties of the {@link Display} to which
+ * the presentation is attached have changed.
+ *
+ * If the display metrics have changed (for example, if the display has been
+ * resized or rotated), then the system automatically calls
+ * {@link #cancel} to dismiss the presentation.
+ *
+ * @see #getDisplay
+ */
+ public void onDisplayChanged() {
+ }
+
+ private void handleDisplayRemoved() {
+ onDisplayRemoved();
+ cancel();
+ }
+
+ private void handleDisplayChanged() {
+ onDisplayChanged();
+
+ // We currently do not support configuration changes for presentations
+ // (although we could add that feature with a bit more work).
+ // If the display metrics have changed in any way then the current configuration
+ // is invalid and the application must recreate the presentation to get
+ // a new context.
+ if (!isConfigurationStillValid()) {
+ cancel();
+ }
+ }
+
+ private boolean isConfigurationStillValid() {
+ DisplayMetrics dm = new DisplayMetrics();
+ mDisplay.getMetrics(dm);
+ return dm.equals(getResources().getDisplayMetrics());
+ }
+
+ private static Context createPresentationContext(
+ Context outerContext, Display display, int theme) {
+ if (outerContext == null) {
+ throw new IllegalArgumentException("outerContext must not be null");
+ }
+ if (display == null) {
+ throw new IllegalArgumentException("display must not be null");
+ }
+
+ Context displayContext = outerContext.createDisplayContext(display);
+ if (theme == 0) {
+ TypedValue outValue = new TypedValue();
+ displayContext.getTheme().resolveAttribute(
+ com.android.internal.R.attr.presentationTheme, outValue, true);
+ theme = outValue.resourceId;
+ }
+
+ // Derive the display's window manager from the outer window manager.
+ // We do this because the outer window manager have some extra information
+ // such as the parent window, which is important if the presentation uses
+ // an application window type.
+ final WindowManagerImpl outerWindowManager =
+ (WindowManagerImpl)outerContext.getSystemService(Context.WINDOW_SERVICE);
+ final WindowManagerImpl displayWindowManager =
+ outerWindowManager.createPresentationWindowManager(display);
+ return new ContextThemeWrapper(displayContext, theme) {
+ @Override
+ public Object getSystemService(String name) {
+ if (Context.WINDOW_SERVICE.equals(name)) {
+ return displayWindowManager;
+ }
+ return super.getSystemService(name);
+ }
+ };
+ }
+
+ private final DisplayListener mDisplayListener = new DisplayListener() {
+ @Override
+ public void onDisplayAdded(int displayId) {
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ if (displayId == mDisplay.getDisplayId()) {
+ handleDisplayRemoved();
+ }
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId == mDisplay.getDisplayId()) {
+ handleDisplayChanged();
+ }
+ }
+ };
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CANCEL:
+ cancel();
+ break;
+ }
+ }
+ };
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c2b796a..8a4cb44 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -35,6 +35,8 @@ import android.os.Looper;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.view.CompatibilityInfoHolder;
+import android.view.Display;
+import android.view.WindowManager;
import java.io.File;
import java.io.FileInputStream;
@@ -2547,7 +2549,7 @@ public abstract class Context {
/**
* Return a new Context object for the current Context but whose resources
* are adjusted to match the given Configuration. Each call to this method
- * returns a new instance of a Contex object; Context objects are not
+ * returns a new instance of a Context object; Context objects are not
* shared, however common state (ClassLoader, other Resources for the
* same configuration) may be so the Context itself can be fairly lightweight.
*
@@ -2557,19 +2559,40 @@ public abstract class Context {
* orientation change), the resources of this context will also change except
* for those that have been explicitly overridden with a value here.
*
- * @return A Context for the application.
+ * @return A Context with the given configuration override.
*/
public abstract Context createConfigurationContext(Configuration overrideConfiguration);
/**
+ * Return a new Context object for the current Context but whose resources
+ * are adjusted to match the metrics of the given Display. Each call to this method
+ * returns a new instance of a Context object; Context objects are not
+ * shared, however common state (ClassLoader, other Resources for the
+ * same configuration) may be so the Context itself can be fairly lightweight.
+ *
+ * The returned display Context provides a {@link WindowManager}
+ * (see {@link #getSystemService(String)}) that is configured to show windows
+ * on the given display. The WindowManager's {@link WindowManager#getDefaultDisplay}
+ * method can be used to retrieve the Display from the returned Context.
+ *
+ * @param display A {@link Display} object specifying the display
+ * for whose metrics the Context's resources should be tailored and upon which
+ * new windows should be shown.
+ *
+ * @return A Context for the display.
+ */
+ 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.
*
+ * @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();
+ public abstract CompatibilityInfoHolder getCompatibilityInfo(int displayId);
/**
* Indicates whether this Context is restricted.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index e503388..e8c63d6 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -36,6 +36,7 @@ import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.view.CompatibilityInfoHolder;
+import android.view.Display;
import java.io.File;
import java.io.FileInputStream;
@@ -582,13 +583,18 @@ public class ContextWrapper extends Context {
}
@Override
+ public Context createDisplayContext(Display display) {
+ return mBase.createDisplayContext(display);
+ }
+
+ @Override
public boolean isRestricted() {
return mBase.isRestricted();
}
/** @hide */
@Override
- public CompatibilityInfoHolder getCompatibilityInfo() {
- return mBase.getCompatibilityInfo();
+ public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
+ return mBase.getCompatibilityInfo(displayId);
}
}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 74996da..2814301 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -19,7 +19,6 @@ package android.hardware.display;
import android.content.Context;
import android.os.Handler;
import android.util.SparseArray;
-import android.view.CompatibilityInfoHolder;
import android.view.Display;
/**
@@ -92,7 +91,7 @@ public final class DisplayManager {
Display display = mDisplays.get(displayId);
if (display == null) {
display = mGlobal.getCompatibleDisplay(displayId,
- getCompatibilityInfoForDisplayLocked(displayId));
+ mContext.getCompatibilityInfo(displayId));
if (display != null) {
mDisplays.put(displayId, display);
}
@@ -102,14 +101,6 @@ public final class DisplayManager {
return display;
}
- private CompatibilityInfoHolder getCompatibilityInfoForDisplayLocked(int displayId) {
- CompatibilityInfoHolder cih = null;
- if (displayId == Display.DEFAULT_DISPLAY) {
- cih = mContext.getCompatibilityInfo();
- }
- return cih;
- }
-
/**
* Registers an display listener to receive notifications about when
* displays are added, removed or changed.
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 506594b..85e4b9d 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -206,13 +206,52 @@ public class DisplayMetrics {
public void setToDefaults() {
widthPixels = 0;
heightPixels = 0;
- density = noncompatDensity = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
- densityDpi = noncompatDensityDpi = DENSITY_DEVICE;
+ density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
+ densityDpi = DENSITY_DEVICE;
scaledDensity = density;
- xdpi = noncompatXdpi = DENSITY_DEVICE;
- ydpi = noncompatYdpi = DENSITY_DEVICE;
- noncompatWidthPixels = 0;
- noncompatHeightPixels = 0;
+ xdpi = DENSITY_DEVICE;
+ ydpi = DENSITY_DEVICE;
+ noncompatWidthPixels = widthPixels;
+ noncompatHeightPixels = heightPixels;
+ noncompatDensity = density;
+ noncompatDensityDpi = densityDpi;
+ noncompatScaledDensity = scaledDensity;
+ noncompatXdpi = xdpi;
+ noncompatYdpi = ydpi;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof DisplayMetrics && equals((DisplayMetrics)o);
+ }
+
+ /**
+ * Returns true if these display metrics equal the other display metrics.
+ *
+ * @param other The display metrics with which to compare.
+ * @return True if the display metrics are equal.
+ */
+ public boolean equals(DisplayMetrics other) {
+ return other != null
+ && widthPixels == other.widthPixels
+ && heightPixels == other.heightPixels
+ && density == other.density
+ && densityDpi == other.densityDpi
+ && scaledDensity == other.scaledDensity
+ && xdpi == other.xdpi
+ && ydpi == other.ydpi
+ && noncompatWidthPixels == other.noncompatWidthPixels
+ && noncompatHeightPixels == other.noncompatHeightPixels
+ && noncompatDensity == other.noncompatDensity
+ && noncompatDensityDpi == other.noncompatDensityDpi
+ && noncompatScaledDensity == other.noncompatScaledDensity
+ && noncompatXdpi == other.noncompatXdpi
+ && noncompatYdpi == other.noncompatYdpi;
+ }
+
+ @Override
+ public int hashCode() {
+ return widthPixels * heightPixels * densityDpi;
}
@Override
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f30952c..7412f39 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -16,6 +16,8 @@
package android.view;
+import android.app.Presentation;
+import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.os.IBinder;
@@ -29,6 +31,17 @@ import android.util.Log;
* The interface that apps use to talk to the window manager.
* <p>
* Use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code> to get one of these.
+ * </p><p>
+ * Each window manager instance is bound to a particular {@link Display}.
+ * To obtain a {@link WindowManager} for a different display, use
+ * {@link Context#createDisplayContext} to obtain a {@link Context} for that
+ * display, then use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code>
+ * to get the WindowManager.
+ * </p><p>
+ * The simplest way to show a window on another display is to create a
+ * {@link Presentation}. The presentation will automatically obtain a
+ * {@link WindowManager} and {@link Context} for that display.
+ * </p>
*
* @see android.content.Context#getSystemService
* @see android.content.Context#WINDOW_SERVICE
@@ -49,12 +62,24 @@ public interface WindowManager extends ViewManager {
}
/**
- * Use this method to get the default Display object.
- *
- * @return default Display object
+ * Returns the {@link Display} upon which this {@link WindowManager} instance
+ * will create new windows.
+ * <p>
+ * Despite the name of this method, the display that is returned is not
+ * necessarily the primary display of the system (see {@link Display#DEFAULT_DISPLAY}).
+ * The returned display could instead be a secondary display that this
+ * window manager instance is managing. Think of it as the display that
+ * this {@link WindowManager} instance uses by default.
+ * </p><p>
+ * To create windows on a different display, you need to obtain a
+ * {@link WindowManager} for that {@link Display}. (See the {@link WindowManager}
+ * class documentation for more information.)
+ * </p>
+ *
+ * @return The display that this window manager is managing.
*/
public Display getDefaultDisplay();
-
+
/**
* Special variation of {@link #removeView} that immediately invokes
* the given view hierarchy's {@link View#onDetachedFromWindow()
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index aa9179f..52d79f8 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,9 +16,6 @@
package android.view;
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-
/**
* Provides low-level communication with the system window manager for
* operations that are bound to a particular context, display or parent window.
@@ -47,25 +44,24 @@ import android.hardware.display.DisplayManager;
*/
public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
- private final Context mContext;
private final Display mDisplay;
private final Window mParentWindow;
- public WindowManagerImpl(Context context, int displayId) {
- DisplayManager dm = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- mContext = context;
- mDisplay = dm.getDisplay(displayId);
- mParentWindow = null;
+ public WindowManagerImpl(Display display) {
+ this(display, null);
}
- private WindowManagerImpl(Context context, Display display, Window parentWindow) {
- mContext = context;
+ private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
- return new WindowManagerImpl(mContext, mDisplay, parentWindow);
+ return new WindowManagerImpl(mDisplay, parentWindow);
+ }
+
+ public WindowManagerImpl createPresentationWindowManager(Display display) {
+ return new WindowManagerImpl(display, mParentWindow);
}
@Override
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 209fff0..3757afc 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -768,11 +768,15 @@
<attr name="dialogCustomTitleDecorLayout" format="reference" />
<!-- Window decor layout to use in dialog mode with title only -->
<attr name="dialogTitleDecorLayout" format="reference" />
+
<!-- Theme to use for alert dialogs spawned from this theme. -->
<attr name="alertDialogTheme" format="reference" />
<!-- Icon drawable to use for alerts -->
<attr name="alertDialogIcon" format="reference" />
+ <!-- Theme to use for presentations spawned from this theme. -->
+ <attr name="presentationTheme" format="reference" />
+
<!-- Drawable to use for generic vertical dividers. -->
<attr name="dividerVertical" format="reference" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4dede0b..690d639 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3759,5 +3759,6 @@
<public type="attr" name="listPreferredItemPaddingStart" />
<public type="attr" name="listPreferredItemPaddingEnd" />
<public type="attr" name="singleUser" />
+ <public type="attr" name="presentationTheme" />
</resources>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 28fed45..d465356 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -673,7 +673,6 @@ easier.
</style>
-
<!-- Animation Styles -->
<style name="Animation.DeviceDefault.Activity" parent="Animation.Holo.Activity">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 2f93335..215551b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -186,17 +186,24 @@ please see themes_device_defaults.xml.
<item name="windowFixedHeightMinor">0dp</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog</item>
<item name="dialogTheme">@android:style/Theme.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title</item>
+
+ <!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.Dialog.Alert</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog</item>
<item name="alertDialogCenterButtons">true</item>
<item name="alertDialogIcon">@android:drawable/ic_dialog_alert</item>
+ <!-- Presentation attributes (introduced after API level 10 so does not
+ have a special old-style theme. -->
+ <item name="presentationTheme">@android:style/Theme.DeviceDefault.Dialog.Presentation</item>
+
+ <!-- Toast attributes -->
<item name="toastFrameBackground">@android:drawable/toast_frame</item>
-
+
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_background</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
@@ -1012,17 +1019,23 @@ please see themes_device_defaults.xml.
<item name="windowActionModeOverlay">false</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
<item name="dialogTheme">@android:style/Theme.Holo.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
+
+ <!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.Holo.Dialog.Alert</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
<item name="alertDialogCenterButtons">false</item>
<item name="alertDialogIcon">@android:drawable/ic_dialog_alert_holo_dark</item>
+ <!-- Presentation attributes -->
+ <item name="presentationTheme">@android:style/Theme.Holo.Dialog.Presentation</item>
+
+ <!-- Toast attributes -->
<item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
-
+
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_dark</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
@@ -1319,17 +1332,23 @@ please see themes_device_defaults.xml.
<item name="windowActionModeOverlay">false</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog.Holo.Light</item>
<item name="dialogTheme">@android:style/Theme.Holo.Light.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
- <item name="alertDialogCenterButtons">false</item>
+
+ <!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.Holo.Light.Dialog.Alert</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog.Holo.Light</item>
+ <item name="alertDialogCenterButtons">false</item>
<item name="alertDialogIcon">@android:drawable/ic_dialog_alert_holo_light</item>
+ <!-- Presentation attributes -->
+ <item name="presentationTheme">@android:style/Theme.Holo.Light.Dialog.Presentation</item>
+
+ <!-- Toast attributes -->
<item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
-
+
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_light</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
@@ -1663,6 +1682,10 @@ please see themes_device_defaults.xml.
<style name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@android:style/Theme.Holo.NoActionBar">
</style>
+ <!-- Theme for a presentation window on a secondary display. -->
+ <style name="Theme.Holo.Dialog.Presentation" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen">
+ </style>
+
<!-- Light holo dialog themes -->
<!-- Holo light theme for dialog windows and activities, which is used by the
@@ -1760,6 +1783,10 @@ please see themes_device_defaults.xml.
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
+ <!-- Theme for a presentation window on a secondary display. -->
+ <style name="Theme.Holo.Light.Dialog.Presentation" parent="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen" >
+ </style>
+
<!-- Default holographic (dark) for windows that want to have the user's selected
wallpaper appear behind them. -->
<style name="Theme.Holo.Wallpaper">
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index eef831f..2a2b9e0 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -87,9 +87,14 @@ easier.
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault</item>
<item name="dialogTheme">@android:style/Theme.DeviceDefault.Dialog</item>
+
+ <!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Dialog.Alert</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault</item>
+
+ <!-- Presentation attributes -->
+ <item name="presentationTheme">@android:style/Theme.DeviceDefault.Dialog.Presentation</item>
<!-- Text selection handle attributes -->
<item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
@@ -239,9 +244,14 @@ easier.
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault.Light</item>
<item name="dialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog</item>
+
+ <!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.Alert</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault.Light</item>
+
+ <!-- Presentation attributes -->
+ <item name="presentationTheme">@android:style/Theme.DeviceDefault.Light.Dialog.Presentation</item>
<!-- Text selection handle attributes -->
<item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
@@ -460,6 +470,15 @@ easier.
<style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Holo.Light.DialogWhenLarge.NoActionBar" >
</style>
+
+ <!-- DeviceDefault theme for a presentation window on a secondary display. -->
+ <style name="Theme.DeviceDefault.Dialog.Presentation" parent="Theme.Holo.Dialog.Presentation">
+ </style>
+
+ <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
+ <style name="Theme.DeviceDefault.Light.Dialog.Presentation" parent="Theme.Holo.Light.Dialog.Presentation">
+ </style>
+
<!-- DeviceDefault theme for panel windows. This removes all extraneous window
decorations, so you basically have an empty rectangle in which to place your content. It makes
the window floating, with a transparent background, and turns off dimming behind the window. -->
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index eb1f2d6..9004e10 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -40,6 +40,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.view.CompatibilityInfoHolder;
+import android.view.Display;
import java.io.File;
import java.io.FileInputStream;
@@ -521,13 +522,18 @@ public class MockContext extends Context {
}
@Override
+ public Context createDisplayContext(Display display) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean isRestricted() {
throw new UnsupportedOperationException();
}
/** @hide */
@Override
- public CompatibilityInfoHolder getCompatibilityInfo() {
+ public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
throw new UnsupportedOperationException();
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 260ee3e..e629b75 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -67,6 +67,7 @@ import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.BridgeInflater;
import android.view.CompatibilityInfoHolder;
+import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
@@ -925,6 +926,12 @@ public final class BridgeContext extends Context {
}
@Override
+ public Context createDisplayContext(Display display) {
+ // pass
+ return null;
+ }
+
+ @Override
public String[] databaseList() {
// pass
return null;
@@ -1357,7 +1364,7 @@ public final class BridgeContext extends Context {
}
@Override
- public CompatibilityInfoHolder getCompatibilityInfo() {
+ public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
// pass
return null;
}