Merge "Initial draft of high-level multi-display APIs." into jb-mr1-dev

This commit is contained in:
Jeff Brown
2012-08-31 15:48:25 -07:00
committed by Android (Google) Code Review
21 changed files with 600 additions and 93 deletions

View File

@ -773,6 +773,7 @@ package android {
field public static final int preferenceLayoutChild = 16842900; // 0x1010094 field public static final int preferenceLayoutChild = 16842900; // 0x1010094
field public static final int preferenceScreenStyle = 16842891; // 0x101008b field public static final int preferenceScreenStyle = 16842891; // 0x101008b
field public static final int preferenceStyle = 16842894; // 0x101008e 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 previewImage = 16843482; // 0x10102da
field public static final int priority = 16842780; // 0x101001c field public static final int priority = 16842780; // 0x101001c
field public static final int privateImeOptions = 16843299; // 0x1010223 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); 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 { public class ProgressDialog extends android.app.AlertDialog {
ctor public ProgressDialog(android.content.Context); ctor public ProgressDialog(android.content.Context);
ctor public ProgressDialog(android.content.Context, int); 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 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 deprecated void clearWallpaper() throws java.io.IOException;
method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration); 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 android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.lang.String[] databaseList(); method public abstract java.lang.String[] databaseList();
method public abstract boolean deleteDatabase(java.lang.String); 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 int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
method public void clearWallpaper() throws java.io.IOException; method public void clearWallpaper() throws java.io.IOException;
method public android.content.Context createConfigurationContext(android.content.res.Configuration); 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 android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.lang.String[] databaseList(); method public java.lang.String[] databaseList();
method public boolean deleteDatabase(java.lang.String); 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 int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
method public void clearWallpaper(); method public void clearWallpaper();
method public android.content.Context createConfigurationContext(android.content.res.Configuration); 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 android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.lang.String[] databaseList(); method public java.lang.String[] databaseList();
method public boolean deleteDatabase(java.lang.String); method public boolean deleteDatabase(java.lang.String);
@ -22911,6 +22924,7 @@ package android.util {
public class DisplayMetrics { public class DisplayMetrics {
ctor public DisplayMetrics(); ctor public DisplayMetrics();
method public boolean equals(android.util.DisplayMetrics);
method public void setTo(android.util.DisplayMetrics); method public void setTo(android.util.DisplayMetrics);
method public void setToDefaults(); method public void setToDefaults();
field public static final int DENSITY_DEFAULT = 160; // 0xa0 field public static final int DENSITY_DEFAULT = 160; // 0xa0

View File

@ -203,7 +203,7 @@ public final class ActivityThread {
= new HashMap<String, WeakReference<LoadedApk>>(); = new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<String, WeakReference<LoadedApk>> mResourcePackages final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
= new HashMap<String, WeakReference<LoadedApk>>(); = new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<CompatibilityInfo, DisplayMetrics> mDisplayMetrics final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
= new HashMap<CompatibilityInfo, DisplayMetrics>(); = new HashMap<CompatibilityInfo, DisplayMetrics>();
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
= new HashMap<ResourcesKey, WeakReference<Resources> >(); = new HashMap<ResourcesKey, WeakReference<Resources> >();
@ -1475,12 +1475,14 @@ public final class ActivityThread {
private static class ResourcesKey { private static class ResourcesKey {
final private String mResDir; final private String mResDir;
final private int mDisplayId;
final private Configuration mOverrideConfiguration; final private Configuration mOverrideConfiguration;
final private float mScale; final private float mScale;
final private int mHash; final private int mHash;
ResourcesKey(String resDir, Configuration overrideConfiguration, float scale) { ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
mResDir = resDir; mResDir = resDir;
mDisplayId = displayId;
if (overrideConfiguration != null) { if (overrideConfiguration != null) {
if (Configuration.EMPTY.equals(overrideConfiguration)) { if (Configuration.EMPTY.equals(overrideConfiguration)) {
overrideConfiguration = null; overrideConfiguration = null;
@ -1490,6 +1492,7 @@ public final class ActivityThread {
mScale = scale; mScale = scale;
int hash = 17; int hash = 17;
hash = 31 * hash + mResDir.hashCode(); hash = 31 * hash + mResDir.hashCode();
hash = 31 * hash + mDisplayId;
hash = 31 * hash + (mOverrideConfiguration != null hash = 31 * hash + (mOverrideConfiguration != null
? mOverrideConfiguration.hashCode() : 0); ? mOverrideConfiguration.hashCode() : 0);
hash = 31 * hash + Float.floatToIntBits(mScale); hash = 31 * hash + Float.floatToIntBits(mScale);
@ -1510,6 +1513,9 @@ public final class ActivityThread {
if (!mResDir.equals(peer.mResDir)) { if (!mResDir.equals(peer.mResDir)) {
return false; return false;
} }
if (mDisplayId != peer.mDisplayId) {
return false;
}
if (mOverrideConfiguration != peer.mOverrideConfiguration) { if (mOverrideConfiguration != peer.mOverrideConfiguration) {
if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) { if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
return false; return false;
@ -1552,28 +1558,32 @@ public final class ActivityThread {
return sPackageManager; return sPackageManager;
} }
DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate) { private void flushDisplayMetricsLocked() {
DisplayMetrics dm = mDisplayMetrics.get(ci); mDefaultDisplayMetrics.clear();
if (dm != null && !forceUpdate) { }
DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
if (dm != null) {
return dm; return dm;
} }
dm = new DisplayMetrics();
DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance(); DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
if (displayManager == null) { if (displayManager == null) {
// may be null early in system startup // may be null early in system startup
dm = new DisplayMetrics();
dm.setToDefaults(); dm.setToDefaults();
return dm; return dm;
} }
if (dm == null) { if (isDefaultDisplay) {
dm = new DisplayMetrics(); mDefaultDisplayMetrics.put(ci, dm);
mDisplayMetrics.put(ci, dm);
} }
CompatibilityInfoHolder cih = new CompatibilityInfoHolder(); CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
cih.set(ci); cih.set(ci);
Display d = displayManager.getCompatibleDisplay(Display.DEFAULT_DISPLAY, cih); Display d = displayManager.getCompatibleDisplay(displayId, cih);
d.getMetrics(dm); d.getMetrics(dm);
//Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h=" //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
// + metrics.heightPixels + " den=" + metrics.density // + 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 * @param compInfo the compability info. It will use the default compatibility info when it's
* null. * null.
*/ */
Resources getTopLevelResources(String resDir, Configuration overrideConfiguration, Resources getTopLevelResources(String resDir,
int displayId, Configuration overrideConfiguration,
CompatibilityInfo compInfo) { CompatibilityInfo compInfo) {
ResourcesKey key = new ResourcesKey(resDir, overrideConfiguration, ResourcesKey key = new ResourcesKey(resDir,
displayId, overrideConfiguration,
compInfo.applicationScale); compInfo.applicationScale);
Resources r; Resources r;
synchronized (mPackages) { synchronized (mPackages) {
@ -1636,15 +1648,21 @@ public final class ActivityThread {
} }
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics); //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
DisplayMetrics metrics = getDisplayMetricsLocked(null, false); DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
Configuration config; Configuration config;
if (key.mOverrideConfiguration != null) { boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
config = new Configuration(getConfiguration()); config = new Configuration(getConfiguration());
config.updateFrom(key.mOverrideConfiguration); if (!isDefaultDisplay) {
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
}
if (key.mOverrideConfiguration != null) {
config.updateFrom(key.mOverrideConfiguration);
}
} else { } else {
config = getConfiguration(); config = getConfiguration();
} }
r = new Resources(assets, metrics, config, compInfo); r = new Resources(assets, dm, config, compInfo);
if (false) { if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": " Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
+ r.getConfiguration() + " appScale=" + r.getConfiguration() + " appScale="
@ -1670,9 +1688,10 @@ public final class ActivityThread {
/** /**
* Creates the top level resources for the given package. * 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) { LoadedApk pkgInfo) {
return getTopLevelResources(resDir, overrideConfiguration, return getTopLevelResources(resDir, displayId, overrideConfiguration,
pkgInfo.mCompatibilityInfo.get()); pkgInfo.mCompatibilityInfo.get());
} }
@ -1844,7 +1863,8 @@ public final class ActivityThread {
context.init(info, null, this); context.init(info, null, this);
context.getResources().updateConfiguration( context.getResources().updateConfiguration(
getConfiguration(), getDisplayMetricsLocked( getConfiguration(), getDisplayMetricsLocked(
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, false)); Display.DEFAULT_DISPLAY,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
mSystemContext = context; mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources() //Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration()); // + ": " + context.getResources().getConfiguration());
@ -3707,7 +3727,9 @@ public final class ActivityThread {
return false; return false;
} }
int changes = mResConfiguration.updateFrom(config); int changes = mResConfiguration.updateFrom(config);
DisplayMetrics dm = getDisplayMetricsLocked(null, true); flushDisplayMetricsLocked();
DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
Display.DEFAULT_DISPLAY, null);
if (compat != null && (mResCompatibilityInfo == null || if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) { !mResCompatibilityInfo.equals(compat))) {
@ -3722,7 +3744,7 @@ public final class ActivityThread {
Locale.setDefault(config.locale); Locale.setDefault(config.locale);
} }
Resources.updateSystemConfiguration(config, dm, compat); Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
ApplicationPackageManager.configurationChanged(); ApplicationPackageManager.configurationChanged();
//Slog.i(TAG, "Configuration changed in " + currentPackageName()); //Slog.i(TAG, "Configuration changed in " + currentPackageName());
@ -3737,13 +3759,22 @@ public final class ActivityThread {
if (r != null) { if (r != null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
+ r + " config to: " + config); + r + " config to: " + config);
Configuration override = entry.getKey().mOverrideConfiguration; int displayId = entry.getKey().mDisplayId;
if (override != null) { boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = defaultDisplayMetrics;
Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
if (!isDefaultDisplay || overrideConfig != null) {
if (tmpConfig == null) { if (tmpConfig == null) {
tmpConfig = new Configuration(); tmpConfig = new Configuration();
} }
tmpConfig.setTo(config); 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); r.updateConfiguration(tmpConfig, dm, compat);
} else { } else {
r.updateConfiguration(config, dm, compat); r.updateConfiguration(config, dm, compat);
@ -3759,6 +3790,22 @@ public final class ActivityThread {
return changes != 0; 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) { final Configuration applyCompatConfiguration(int displayDensity) {
Configuration config = mConfiguration; Configuration config = mConfiguration;
if (mCompatConfiguration == null) { if (mCompatConfiguration == null) {

View File

@ -110,8 +110,9 @@ public class AlertDialog extends Dialog implements DialogInterface {
this(context, theme, true); this(context, theme, true);
} }
AlertDialog(Context context, int theme, boolean createContextWrapper) { AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
super(context, resolveDialogTheme(context, theme), createContextWrapper); super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);
mWindow.alwaysReadCloseOnTouchAttr(); mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(getContext(), this, getWindow()); mAlert = new AlertController(getContext(), this, getWindow());
} }

View File

@ -54,6 +54,7 @@ import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import android.view.Display;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
@ -722,8 +723,8 @@ final class ApplicationPackageManager extends PackageManager {
return mContext.mMainThread.getSystemContext().getResources(); return mContext.mMainThread.getSystemContext().getResources();
} }
Resources r = mContext.mMainThread.getTopLevelResources( Resources r = mContext.mMainThread.getTopLevelResources(
app.uid == Process.myUid() ? app.sourceDir app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
: app.publicSourceDir, null, mContext.mPackageInfo); Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
if (r != null) { if (r != null) {
return r; return r;
} }

View File

@ -168,6 +168,7 @@ class ContextImpl extends Context {
private int mThemeResource = 0; private int mThemeResource = 0;
private Resources.Theme mTheme = null; private Resources.Theme mTheme = null;
private PackageManager mPackageManager; private PackageManager mPackageManager;
private Display mDisplay; // may be null if default display
private Context mReceiverRestrictedContext = null; private Context mReceiverRestrictedContext = null;
private boolean mRestricted; private boolean mRestricted;
@ -502,8 +503,13 @@ class ContextImpl extends Context {
registerService(WINDOW_SERVICE, new ServiceFetcher() { registerService(WINDOW_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) { public Object getService(ContextImpl ctx) {
return new WindowManagerImpl(ctx.getOuterContext(), Display display = ctx.mDisplay;
Display.DEFAULT_DISPLAY); 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() { registerService(USER_SERVICE, new ServiceFetcher() {
@ -1676,22 +1682,52 @@ class ContextImpl extends Context {
@Override @Override
public Context createConfigurationContext(Configuration overrideConfiguration) { public Context createConfigurationContext(Configuration overrideConfiguration) {
if (overrideConfiguration == null) {
throw new IllegalArgumentException("overrideConfiguration must not be null");
}
ContextImpl c = new ContextImpl(); ContextImpl c = new ContextImpl();
c.init(mPackageInfo, null, mMainThread); c.init(mPackageInfo, null, mMainThread);
c.mResources = mMainThread.getTopLevelResources( c.mResources = mMainThread.getTopLevelResources(
mPackageInfo.getResDir(), overrideConfiguration, mPackageInfo.getResDir(),
getDisplayId(), overrideConfiguration,
mResources.getCompatibilityInfo()); mResources.getCompatibilityInfo());
return c; 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 @Override
public boolean isRestricted() { public boolean isRestricted() {
return mRestricted; return mRestricted;
} }
@Override @Override
public CompatibilityInfoHolder getCompatibilityInfo() { public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
return mPackageInfo.mCompatibilityInfo; return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
} }
private File getDataDirFile() { private File getDataDirFile() {
@ -1735,6 +1771,7 @@ class ContextImpl extends Context {
mResources = context.mResources; mResources = context.mResources;
mMainThread = context.mMainThread; mMainThread = context.mMainThread;
mContentResolver = context.mContentResolver; mContentResolver = context.mContentResolver;
mDisplay = context.mDisplay;
mOuterContext = this; mOuterContext = this;
} }
@ -1758,7 +1795,8 @@ class ContextImpl extends Context {
" compatiblity info:" + container.getDisplayMetrics()); " compatiblity info:" + container.getDisplayMetrics());
} }
mResources = mainThread.getTopLevelResources( mResources = mainThread.getTopLevelResources(
mPackageInfo.getResDir(), null, container.getCompatibilityInfo()); mPackageInfo.getResDir(), Display.DEFAULT_DISPLAY,
null, container.getCompatibilityInfo());
} }
mMainThread = mainThread; mMainThread = mainThread;
mContentResolver = new ApplicationContentResolver(this, mainThread); mContentResolver = new ApplicationContentResolver(this, mainThread);

View File

@ -147,15 +147,19 @@ public class Dialog implements DialogInterface, Window.Callback,
this(context, theme, true); this(context, theme, true);
} }
Dialog(Context context, int theme, boolean createContextWrapper) { Dialog(Context context, int theme, boolean createContextThemeWrapper) {
if (theme == 0) { if (createContextThemeWrapper) {
TypedValue outValue = new TypedValue(); if (theme == 0) {
context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme, TypedValue outValue = new TypedValue();
outValue, true); context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
theme = outValue.resourceId; 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); mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Window w = PolicyManager.makeNewWindow(mContext); Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w; mWindow = w;
@ -164,7 +168,7 @@ public class Dialog implements DialogInterface, Window.Callback,
w.setGravity(Gravity.CENTER); w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this); mListenersHandler = new ListenersHandler(this);
} }
/** /**
* @deprecated * @deprecated
* @hide * @hide

View File

@ -41,6 +41,7 @@ import android.os.UserHandle;
import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException;
import android.util.Slog; import android.util.Slog;
import android.view.CompatibilityInfoHolder; import android.view.CompatibilityInfoHolder;
import android.view.Display;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -139,7 +140,8 @@ public final class LoadedApk {
ContextImpl.createSystemContext(mainThread); ContextImpl.createSystemContext(mainThread);
ActivityThread.mSystemContext.getResources().updateConfiguration( ActivityThread.mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(), mainThread.getConfiguration(),
mainThread.getDisplayMetricsLocked(compatInfo, false), mainThread.getDisplayMetricsLocked(
Display.DEFAULT_DISPLAY, compatInfo),
compatInfo); compatInfo);
//Slog.i(TAG, "Created system resources " //Slog.i(TAG, "Created system resources "
// + mSystemContext.getResources() + ": " // + mSystemContext.getResources() + ": "
@ -471,7 +473,8 @@ public final class LoadedApk {
public Resources getResources(ActivityThread mainThread) { public Resources getResources(ActivityThread mainThread) {
if (mResources == null) { if (mResources == null) {
mResources = mainThread.getTopLevelResources(mResDir, null, this); mResources = mainThread.getTopLevelResources(mResDir,
Display.DEFAULT_DISPLAY, null, this);
} }
return mResources; return mResources;
} }

View File

@ -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;
}
}
};
}

View File

@ -35,6 +35,8 @@ import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.CompatibilityInfoHolder; import android.view.CompatibilityInfoHolder;
import android.view.Display;
import android.view.WindowManager;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -2547,7 +2549,7 @@ public abstract class Context {
/** /**
* Return a new Context object for the current Context but whose resources * Return a new Context object for the current Context but whose resources
* are adjusted to match the given Configuration. Each call to this method * 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 * shared, however common state (ClassLoader, other Resources for the
* same configuration) may be so the Context itself can be fairly lightweight. * 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 * orientation change), the resources of this context will also change except
* for those that have been explicitly overridden with a value here. * 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); 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 * Gets the compatibility info holder for this context. This information
* is provided on a per-application basis and is used to simulate lower density * is provided on a per-application basis and is used to simulate lower density
* display metrics for legacy applications. * 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. * @return The compatibility info holder, or null if not required by the application.
* @hide * @hide
*/ */
public abstract CompatibilityInfoHolder getCompatibilityInfo(); public abstract CompatibilityInfoHolder getCompatibilityInfo(int displayId);
/** /**
* Indicates whether this Context is restricted. * Indicates whether this Context is restricted.

View File

@ -36,6 +36,7 @@ import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.CompatibilityInfoHolder; import android.view.CompatibilityInfoHolder;
import android.view.Display;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -581,6 +582,11 @@ public class ContextWrapper extends Context {
return mBase.createConfigurationContext(overrideConfiguration); return mBase.createConfigurationContext(overrideConfiguration);
} }
@Override
public Context createDisplayContext(Display display) {
return mBase.createDisplayContext(display);
}
@Override @Override
public boolean isRestricted() { public boolean isRestricted() {
return mBase.isRestricted(); return mBase.isRestricted();
@ -588,7 +594,7 @@ public class ContextWrapper extends Context {
/** @hide */ /** @hide */
@Override @Override
public CompatibilityInfoHolder getCompatibilityInfo() { public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
return mBase.getCompatibilityInfo(); return mBase.getCompatibilityInfo(displayId);
} }
} }

View File

@ -19,7 +19,6 @@ package android.hardware.display;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.CompatibilityInfoHolder;
import android.view.Display; import android.view.Display;
/** /**
@ -92,7 +91,7 @@ public final class DisplayManager {
Display display = mDisplays.get(displayId); Display display = mDisplays.get(displayId);
if (display == null) { if (display == null) {
display = mGlobal.getCompatibleDisplay(displayId, display = mGlobal.getCompatibleDisplay(displayId,
getCompatibilityInfoForDisplayLocked(displayId)); mContext.getCompatibilityInfo(displayId));
if (display != null) { if (display != null) {
mDisplays.put(displayId, display); mDisplays.put(displayId, display);
} }
@ -102,14 +101,6 @@ public final class DisplayManager {
return display; 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 * Registers an display listener to receive notifications about when
* displays are added, removed or changed. * displays are added, removed or changed.

View File

@ -206,13 +206,52 @@ public class DisplayMetrics {
public void setToDefaults() { public void setToDefaults() {
widthPixels = 0; widthPixels = 0;
heightPixels = 0; heightPixels = 0;
density = noncompatDensity = DENSITY_DEVICE / (float) DENSITY_DEFAULT; density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
densityDpi = noncompatDensityDpi = DENSITY_DEVICE; densityDpi = DENSITY_DEVICE;
scaledDensity = density; scaledDensity = density;
xdpi = noncompatXdpi = DENSITY_DEVICE; xdpi = DENSITY_DEVICE;
ydpi = noncompatYdpi = DENSITY_DEVICE; ydpi = DENSITY_DEVICE;
noncompatWidthPixels = 0; noncompatWidthPixels = widthPixels;
noncompatHeightPixels = 0; 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 @Override

View File

@ -16,6 +16,8 @@
package android.view; package android.view;
import android.app.Presentation;
import android.content.Context;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.os.IBinder; import android.os.IBinder;
@ -29,6 +31,17 @@ import android.util.Log;
* The interface that apps use to talk to the window manager. * The interface that apps use to talk to the window manager.
* <p> * <p>
* Use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code> to get one of these. * 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#getSystemService
* @see android.content.Context#WINDOW_SERVICE * @see android.content.Context#WINDOW_SERVICE
@ -49,12 +62,24 @@ public interface WindowManager extends ViewManager {
} }
/** /**
* Use this method to get the default Display object. * Returns the {@link Display} upon which this {@link WindowManager} instance
* * will create new windows.
* @return default Display object * <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(); public Display getDefaultDisplay();
/** /**
* Special variation of {@link #removeView} that immediately invokes * Special variation of {@link #removeView} that immediately invokes
* the given view hierarchy's {@link View#onDetachedFromWindow() * the given view hierarchy's {@link View#onDetachedFromWindow()

View File

@ -16,9 +16,6 @@
package android.view; package android.view;
import android.content.Context;
import android.hardware.display.DisplayManager;
/** /**
* Provides low-level communication with the system window manager for * Provides low-level communication with the system window manager for
* operations that are bound to a particular context, display or parent window. * 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 { public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Context mContext;
private final Display mDisplay; private final Display mDisplay;
private final Window mParentWindow; private final Window mParentWindow;
public WindowManagerImpl(Context context, int displayId) { public WindowManagerImpl(Display display) {
DisplayManager dm = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); this(display, null);
mContext = context;
mDisplay = dm.getDisplay(displayId);
mParentWindow = null;
} }
private WindowManagerImpl(Context context, Display display, Window parentWindow) { private WindowManagerImpl(Display display, Window parentWindow) {
mContext = context;
mDisplay = display; mDisplay = display;
mParentWindow = parentWindow; mParentWindow = parentWindow;
} }
public WindowManagerImpl createLocalWindowManager(Window 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 @Override

View File

@ -768,11 +768,15 @@
<attr name="dialogCustomTitleDecorLayout" format="reference" /> <attr name="dialogCustomTitleDecorLayout" format="reference" />
<!-- Window decor layout to use in dialog mode with title only --> <!-- Window decor layout to use in dialog mode with title only -->
<attr name="dialogTitleDecorLayout" format="reference" /> <attr name="dialogTitleDecorLayout" format="reference" />
<!-- Theme to use for alert dialogs spawned from this theme. --> <!-- Theme to use for alert dialogs spawned from this theme. -->
<attr name="alertDialogTheme" format="reference" /> <attr name="alertDialogTheme" format="reference" />
<!-- Icon drawable to use for alerts --> <!-- Icon drawable to use for alerts -->
<attr name="alertDialogIcon" format="reference" /> <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. --> <!-- Drawable to use for generic vertical dividers. -->
<attr name="dividerVertical" format="reference" /> <attr name="dividerVertical" format="reference" />

View File

@ -3759,5 +3759,6 @@
<public type="attr" name="listPreferredItemPaddingStart" /> <public type="attr" name="listPreferredItemPaddingStart" />
<public type="attr" name="listPreferredItemPaddingEnd" /> <public type="attr" name="listPreferredItemPaddingEnd" />
<public type="attr" name="singleUser" /> <public type="attr" name="singleUser" />
<public type="attr" name="presentationTheme" />
</resources> </resources>

View File

@ -673,7 +673,6 @@ easier.
</style> </style>
<!-- Animation Styles --> <!-- Animation Styles -->
<style name="Animation.DeviceDefault.Activity" parent="Animation.Holo.Activity"> <style name="Animation.DeviceDefault.Activity" parent="Animation.Holo.Activity">

View File

@ -186,17 +186,24 @@ please see themes_device_defaults.xml.
<item name="windowFixedHeightMinor">0dp</item> <item name="windowFixedHeightMinor">0dp</item>
<!-- Dialog attributes --> <!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog</item>
<item name="dialogTheme">@android:style/Theme.Dialog</item> <item name="dialogTheme">@android:style/Theme.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons</item> <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title</item> <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title</item> <item name="dialogTitleDecorLayout">@layout/dialog_title</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.Dialog.Alert</item> <item name="alertDialogTheme">@android:style/Theme.Dialog.Alert</item>
<item name="alertDialogStyle">@android:style/AlertDialog</item>
<item name="alertDialogCenterButtons">true</item> <item name="alertDialogCenterButtons">true</item>
<item name="alertDialogIcon">@android:drawable/ic_dialog_alert</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> <item name="toastFrameBackground">@android:drawable/toast_frame</item>
<!-- Panel attributes --> <!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_background</item> <item name="panelBackground">@android:drawable/menu_background</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</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> <item name="windowActionModeOverlay">false</item>
<!-- Dialog attributes --> <!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
<item name="dialogTheme">@android:style/Theme.Holo.Dialog</item> <item name="dialogTheme">@android:style/Theme.Holo.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item> <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item> <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
<item name="dialogTitleDecorLayout">@layout/dialog_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="alertDialogTheme">@android:style/Theme.Holo.Dialog.Alert</item>
<item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
<item name="alertDialogCenterButtons">false</item> <item name="alertDialogCenterButtons">false</item>
<item name="alertDialogIcon">@android:drawable/ic_dialog_alert_holo_dark</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> <item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
<!-- Panel attributes --> <!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_dark</item> <item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_dark</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</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> <item name="windowActionModeOverlay">false</item>
<!-- Dialog attributes --> <!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog.Holo.Light</item>
<item name="dialogTheme">@android:style/Theme.Holo.Light.Dialog</item> <item name="dialogTheme">@android:style/Theme.Holo.Light.Dialog</item>
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item> <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item> <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
<item name="dialogTitleDecorLayout">@layout/dialog_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="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> <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> <item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
<!-- Panel attributes --> <!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_light</item> <item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_light</item>
<item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</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 name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@android:style/Theme.Holo.NoActionBar">
</style> </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 --> <!-- Light holo dialog themes -->
<!-- Holo light theme for dialog windows and activities, which is used by the <!-- 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> <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style> </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 <!-- Default holographic (dark) for windows that want to have the user's selected
wallpaper appear behind them. --> wallpaper appear behind them. -->
<style name="Theme.Holo.Wallpaper"> <style name="Theme.Holo.Wallpaper">

View File

@ -87,9 +87,14 @@ easier.
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item> <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
<!-- Dialog attributes --> <!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault</item>
<item name="dialogTheme">@android:style/Theme.DeviceDefault.Dialog</item> <item name="dialogTheme">@android:style/Theme.DeviceDefault.Dialog</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Dialog.Alert</item> <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 --> <!-- Text selection handle attributes -->
<item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item> <item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
@ -239,9 +244,14 @@ easier.
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item> <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
<!-- Dialog attributes --> <!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault.Light</item>
<item name="dialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog</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="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 --> <!-- Text selection handle attributes -->
<item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item> <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 name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Holo.Light.DialogWhenLarge.NoActionBar" >
</style> </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 <!-- 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 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. --> the window floating, with a transparent background, and turns off dimming behind the window. -->

View File

@ -40,6 +40,7 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.CompatibilityInfoHolder; import android.view.CompatibilityInfoHolder;
import android.view.Display;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -520,6 +521,11 @@ public class MockContext extends Context {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public Context createDisplayContext(Display display) {
throw new UnsupportedOperationException();
}
@Override @Override
public boolean isRestricted() { public boolean isRestricted() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -527,7 +533,7 @@ public class MockContext extends Context {
/** @hide */ /** @hide */
@Override @Override
public CompatibilityInfoHolder getCompatibilityInfo() { public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@ -67,6 +67,7 @@ import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.BridgeInflater; import android.view.BridgeInflater;
import android.view.CompatibilityInfoHolder; import android.view.CompatibilityInfoHolder;
import android.view.Display;
import android.view.Surface; import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -924,6 +925,12 @@ public final class BridgeContext extends Context {
return null; return null;
} }
@Override
public Context createDisplayContext(Display display) {
// pass
return null;
}
@Override @Override
public String[] databaseList() { public String[] databaseList() {
// pass // pass
@ -1357,7 +1364,7 @@ public final class BridgeContext extends Context {
} }
@Override @Override
public CompatibilityInfoHolder getCompatibilityInfo() { public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
// pass // pass
return null; return null;
} }