am 34743ac7: Merge "Add API to create new contexts with custom configurations." into jb-mr1-dev
* commit '34743ac7d688a7ecf4daec84078fc7ec74a6dac9': Add API to create new contexts with custom configurations.
This commit is contained in:
@@ -5262,6 +5262,7 @@ package android.content {
|
|||||||
method public abstract int checkUriPermission(android.net.Uri, int, int, int);
|
method public abstract int checkUriPermission(android.net.Uri, int, int, int);
|
||||||
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 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);
|
||||||
@@ -5406,6 +5407,7 @@ package android.content {
|
|||||||
method public int checkUriPermission(android.net.Uri, int, int, int);
|
method public int checkUriPermission(android.net.Uri, int, int, int);
|
||||||
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 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);
|
||||||
@@ -21148,6 +21150,7 @@ package android.test.mock {
|
|||||||
method public int checkUriPermission(android.net.Uri, int, int, int);
|
method public int checkUriPermission(android.net.Uri, int, int, int);
|
||||||
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 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);
|
||||||
@@ -23352,6 +23355,7 @@ package android.view {
|
|||||||
public class ContextThemeWrapper extends android.content.ContextWrapper {
|
public class ContextThemeWrapper extends android.content.ContextWrapper {
|
||||||
ctor public ContextThemeWrapper();
|
ctor public ContextThemeWrapper();
|
||||||
ctor public ContextThemeWrapper(android.content.Context, int);
|
ctor public ContextThemeWrapper(android.content.Context, int);
|
||||||
|
method public void applyOverrideConfiguration(android.content.res.Configuration);
|
||||||
method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean);
|
method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1471,13 +1471,25 @@ public final class ActivityThread {
|
|||||||
|
|
||||||
private static class ResourcesKey {
|
private static class ResourcesKey {
|
||||||
final private String mResDir;
|
final private String mResDir;
|
||||||
|
final private Configuration mOverrideConfiguration;
|
||||||
final private float mScale;
|
final private float mScale;
|
||||||
final private int mHash;
|
final private int mHash;
|
||||||
|
|
||||||
ResourcesKey(String resDir, float scale) {
|
ResourcesKey(String resDir, Configuration overrideConfiguration, float scale) {
|
||||||
mResDir = resDir;
|
mResDir = resDir;
|
||||||
|
if (overrideConfiguration != null) {
|
||||||
|
if (Configuration.EMPTY.equals(overrideConfiguration)) {
|
||||||
|
overrideConfiguration = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mOverrideConfiguration = overrideConfiguration;
|
||||||
mScale = scale;
|
mScale = scale;
|
||||||
mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
|
int hash = 17;
|
||||||
|
hash = 31 * hash + mResDir.hashCode();
|
||||||
|
hash = 31 * hash + (mOverrideConfiguration != null
|
||||||
|
? mOverrideConfiguration.hashCode() : 0);
|
||||||
|
hash = 31 * hash + Float.floatToIntBits(mScale);
|
||||||
|
mHash = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1491,7 +1503,21 @@ public final class ActivityThread {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ResourcesKey peer = (ResourcesKey) obj;
|
ResourcesKey peer = (ResourcesKey) obj;
|
||||||
return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
|
if (!mResDir.equals(peer.mResDir)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mOverrideConfiguration != peer.mOverrideConfiguration) {
|
||||||
|
if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mScale != peer.mScale) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,8 +1588,10 @@ 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, CompatibilityInfo compInfo) {
|
Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
|
||||||
ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
|
CompatibilityInfo compInfo) {
|
||||||
|
ResourcesKey key = new ResourcesKey(resDir, overrideConfiguration,
|
||||||
|
compInfo.applicationScale);
|
||||||
Resources r;
|
Resources r;
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
// Resources is app scale dependent.
|
// Resources is app scale dependent.
|
||||||
@@ -1595,13 +1623,20 @@ 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 metrics = getDisplayMetricsLocked(null, false);
|
||||||
r = new Resources(assets, metrics, getConfiguration(), compInfo);
|
Configuration config;
|
||||||
|
if (key.mOverrideConfiguration != null) {
|
||||||
|
config = new Configuration(getConfiguration());
|
||||||
|
config.updateFrom(key.mOverrideConfiguration);
|
||||||
|
} else {
|
||||||
|
config = getConfiguration();
|
||||||
|
}
|
||||||
|
r = new Resources(assets, metrics, 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="
|
||||||
+ r.getCompatibilityInfo().applicationScale);
|
+ r.getCompatibilityInfo().applicationScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
WeakReference<Resources> wr = mActiveResources.get(key);
|
WeakReference<Resources> wr = mActiveResources.get(key);
|
||||||
Resources existing = wr != null ? wr.get() : null;
|
Resources existing = wr != null ? wr.get() : null;
|
||||||
@@ -1621,8 +1656,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, LoadedApk pkgInfo) {
|
Resources getTopLevelResources(String resDir, Configuration overrideConfiguration,
|
||||||
return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo.get());
|
LoadedApk pkgInfo) {
|
||||||
|
return getTopLevelResources(resDir, overrideConfiguration,
|
||||||
|
pkgInfo.mCompatibilityInfo.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
final Handler getHandler() {
|
final Handler getHandler() {
|
||||||
@@ -3675,18 +3712,28 @@ public final class ActivityThread {
|
|||||||
|
|
||||||
ApplicationPackageManager.configurationChanged();
|
ApplicationPackageManager.configurationChanged();
|
||||||
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
|
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
|
||||||
|
|
||||||
Iterator<WeakReference<Resources>> it =
|
Configuration tmpConfig = null;
|
||||||
mActiveResources.values().iterator();
|
|
||||||
//Iterator<Map.Entry<String, WeakReference<Resources>>> it =
|
Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
|
||||||
// mActiveResources.entrySet().iterator();
|
mActiveResources.entrySet().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
WeakReference<Resources> v = it.next();
|
Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
|
||||||
Resources r = v.get();
|
Resources r = entry.getValue().get();
|
||||||
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);
|
||||||
r.updateConfiguration(config, dm, compat);
|
Configuration override = entry.getKey().mOverrideConfiguration;
|
||||||
|
if (override != null) {
|
||||||
|
if (tmpConfig == null) {
|
||||||
|
tmpConfig = new Configuration();
|
||||||
|
}
|
||||||
|
tmpConfig.setTo(config);
|
||||||
|
tmpConfig.updateFrom(override);
|
||||||
|
r.updateConfiguration(tmpConfig, dm, compat);
|
||||||
|
} else {
|
||||||
|
r.updateConfiguration(config, dm, compat);
|
||||||
|
}
|
||||||
//Slog.i(TAG, "Updated app resources " + v.getKey()
|
//Slog.i(TAG, "Updated app resources " + v.getKey()
|
||||||
// + " " + r + ": " + r.getConfiguration());
|
// + " " + r + ": " + r.getConfiguration());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -713,7 +713,7 @@ final class ApplicationPackageManager extends PackageManager {
|
|||||||
}
|
}
|
||||||
Resources r = mContext.mMainThread.getTopLevelResources(
|
Resources r = mContext.mMainThread.getTopLevelResources(
|
||||||
app.uid == Process.myUid() ? app.sourceDir
|
app.uid == Process.myUid() ? app.sourceDir
|
||||||
: app.publicSourceDir, mContext.mPackageInfo);
|
: app.publicSourceDir, null, mContext.mPackageInfo);
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import android.content.pm.IPackageManager;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.CompatibilityInfo;
|
import android.content.res.CompatibilityInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.DatabaseErrorHandler;
|
import android.database.DatabaseErrorHandler;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
@@ -525,7 +526,7 @@ class ContextImpl extends Context {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AssetManager getAssets() {
|
public AssetManager getAssets() {
|
||||||
return mResources.getAssets();
|
return getResources().getAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1590,6 +1591,16 @@ class ContextImpl extends Context {
|
|||||||
"Application package " + packageName + " not found");
|
"Application package " + packageName + " not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context createConfigurationContext(Configuration overrideConfiguration) {
|
||||||
|
ContextImpl c = new ContextImpl();
|
||||||
|
c.init(mPackageInfo, null, mMainThread);
|
||||||
|
c.mResources = mMainThread.getTopLevelResources(
|
||||||
|
mPackageInfo.getResDir(), overrideConfiguration,
|
||||||
|
mResources.getCompatibilityInfo());
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRestricted() {
|
public boolean isRestricted() {
|
||||||
return mRestricted;
|
return mRestricted;
|
||||||
@@ -1659,12 +1670,11 @@ class ContextImpl extends Context {
|
|||||||
" compatiblity info:" + container.getDisplayMetrics());
|
" compatiblity info:" + container.getDisplayMetrics());
|
||||||
}
|
}
|
||||||
mResources = mainThread.getTopLevelResources(
|
mResources = mainThread.getTopLevelResources(
|
||||||
mPackageInfo.getResDir(), container.getCompatibilityInfo());
|
mPackageInfo.getResDir(), null, container.getCompatibilityInfo());
|
||||||
}
|
}
|
||||||
mMainThread = mainThread;
|
mMainThread = mainThread;
|
||||||
mContentResolver = new ApplicationContentResolver(this, mainThread);
|
mContentResolver = new ApplicationContentResolver(this, mainThread);
|
||||||
|
mActivityToken = activityToken;
|
||||||
setActivityToken(activityToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void init(Resources resources, ActivityThread mainThread) {
|
final void init(Resources resources, ActivityThread mainThread) {
|
||||||
@@ -1691,10 +1701,6 @@ class ContextImpl extends Context {
|
|||||||
return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
|
return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
final void setActivityToken(IBinder token) {
|
|
||||||
mActivityToken = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
final void setOuterContext(Context context) {
|
final void setOuterContext(Context context) {
|
||||||
mOuterContext = context;
|
mOuterContext = context;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ public final class LoadedApk {
|
|||||||
|
|
||||||
public Resources getResources(ActivityThread mainThread) {
|
public Resources getResources(ActivityThread mainThread) {
|
||||||
if (mResources == null) {
|
if (mResources == null) {
|
||||||
mResources = mainThread.getTopLevelResources(mResDir, this);
|
mResources = mainThread.getTopLevelResources(mResDir, null, this);
|
||||||
}
|
}
|
||||||
return mResources;
|
return mResources;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.content;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.database.DatabaseErrorHandler;
|
import android.database.DatabaseErrorHandler;
|
||||||
@@ -2444,6 +2445,23 @@ public abstract class Context {
|
|||||||
public abstract Context createPackageContext(String packageName,
|
public abstract Context createPackageContext(String packageName,
|
||||||
int flags) throws PackageManager.NameNotFoundException;
|
int flags) throws PackageManager.NameNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* shared, however common state (ClassLoader, other Resources for the
|
||||||
|
* same configuration) may be so the Context itself can be fairly lightweight.
|
||||||
|
*
|
||||||
|
* @param overrideConfiguration A {@link Configuration} specifying what
|
||||||
|
* values to modify in the base Configuration of the original Context's
|
||||||
|
* resources. If the base configuration changes (such as due to an
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public abstract Context createConfigurationContext(Configuration overrideConfiguration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this Context is restricted.
|
* Indicates whether this Context is restricted.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.content;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.DatabaseErrorHandler;
|
import android.database.DatabaseErrorHandler;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
@@ -532,6 +533,11 @@ public class ContextWrapper extends Context {
|
|||||||
return mBase.createPackageContext(packageName, flags);
|
return mBase.createPackageContext(packageName, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context createConfigurationContext(Configuration overrideConfiguration) {
|
||||||
|
return mBase.createConfigurationContext(overrideConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRestricted() {
|
public boolean isRestricted() {
|
||||||
return mBase.isRestricted();
|
return mBase.isRestricted();
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ import java.util.Locale;
|
|||||||
* <pre>Configuration config = getResources().getConfiguration();</pre>
|
* <pre>Configuration config = getResources().getConfiguration();</pre>
|
||||||
*/
|
*/
|
||||||
public final class Configuration implements Parcelable, Comparable<Configuration> {
|
public final class Configuration implements Parcelable, Comparable<Configuration> {
|
||||||
|
/** @hide */
|
||||||
|
public static final Configuration EMPTY = new Configuration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current user preference for the scaling factor for fonts, relative
|
* Current user preference for the scaling factor for fonts, relative
|
||||||
* to the base density scaling.
|
* to the base density scaling.
|
||||||
|
|||||||
@@ -1435,9 +1435,12 @@ public class Resources {
|
|||||||
int configChanges = 0xfffffff;
|
int configChanges = 0xfffffff;
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
mTmpConfig.setTo(config);
|
mTmpConfig.setTo(config);
|
||||||
|
int density = config.densityDpi;
|
||||||
|
if (density == Configuration.DENSITY_DPI_UNDEFINED) {
|
||||||
|
density = mMetrics.noncompatDensityDpi;
|
||||||
|
}
|
||||||
if (mCompatibilityInfo != null) {
|
if (mCompatibilityInfo != null) {
|
||||||
mCompatibilityInfo.applyToConfiguration(mMetrics.noncompatDensityDpi,
|
mCompatibilityInfo.applyToConfiguration(density, mTmpConfig);
|
||||||
mTmpConfig);
|
|
||||||
}
|
}
|
||||||
if (mTmpConfig.locale == null) {
|
if (mTmpConfig.locale == null) {
|
||||||
mTmpConfig.locale = Locale.getDefault();
|
mTmpConfig.locale = Locale.getDefault();
|
||||||
@@ -1448,6 +1451,10 @@ public class Resources {
|
|||||||
if (mConfiguration.locale == null) {
|
if (mConfiguration.locale == null) {
|
||||||
mConfiguration.locale = Locale.getDefault();
|
mConfiguration.locale = Locale.getDefault();
|
||||||
}
|
}
|
||||||
|
if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
|
||||||
|
mMetrics.densityDpi = mConfiguration.densityDpi;
|
||||||
|
mMetrics.density = mConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
|
||||||
|
}
|
||||||
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
|
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
|
||||||
|
|
||||||
String locale = null;
|
String locale = null;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package android.view;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContextWrapper;
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ public class ContextThemeWrapper extends ContextWrapper {
|
|||||||
private int mThemeResource;
|
private int mThemeResource;
|
||||||
private Resources.Theme mTheme;
|
private Resources.Theme mTheme;
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
|
private Configuration mOverrideConfiguration;
|
||||||
|
private Resources mResources;
|
||||||
|
|
||||||
public ContextThemeWrapper() {
|
public ContextThemeWrapper() {
|
||||||
super(null);
|
super(null);
|
||||||
@@ -45,6 +48,41 @@ public class ContextThemeWrapper extends ContextWrapper {
|
|||||||
super.attachBaseContext(newBase);
|
super.attachBaseContext(newBase);
|
||||||
mBase = newBase;
|
mBase = newBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call to set an "override configuration" on this context -- this is
|
||||||
|
* a configuration that replies one or more values of the standard
|
||||||
|
* configuration that is applied to the context. See
|
||||||
|
* {@link Context#createConfigurationContext(Configuration)} for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* <p>This method can only be called once, and must be called before any
|
||||||
|
* calls to {@link #getResources()} are made.
|
||||||
|
*/
|
||||||
|
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
|
||||||
|
if (mResources != null) {
|
||||||
|
throw new IllegalStateException("getResources() has already been called");
|
||||||
|
}
|
||||||
|
if (mOverrideConfiguration != null) {
|
||||||
|
throw new IllegalStateException("Override configuration has already been set");
|
||||||
|
}
|
||||||
|
mOverrideConfiguration = new Configuration(overrideConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resources getResources() {
|
||||||
|
if (mResources != null) {
|
||||||
|
return mResources;
|
||||||
|
}
|
||||||
|
if (mOverrideConfiguration == null) {
|
||||||
|
mResources = super.getResources();
|
||||||
|
return mResources;
|
||||||
|
} else {
|
||||||
|
Context resc = createConfigurationContext(mOverrideConfiguration);
|
||||||
|
mResources = resc.getResources();
|
||||||
|
return mResources;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void setTheme(int resid) {
|
@Override public void setTheme(int resid) {
|
||||||
mThemeResource = resid;
|
mThemeResource = resid;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.DatabaseErrorHandler;
|
import android.database.DatabaseErrorHandler;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
@@ -476,6 +477,11 @@ public class MockContext extends Context {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context createConfigurationContext(Configuration overrideConfiguration) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRestricted() {
|
public boolean isRestricted() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|||||||
@@ -40,12 +40,16 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class ActivityTestMain extends Activity {
|
public class ActivityTestMain extends Activity {
|
||||||
static final String TAG = "ActivityTest";
|
static final String TAG = "ActivityTest";
|
||||||
|
|
||||||
|
static final String KEY_CONFIGURATION = "configuration";
|
||||||
|
|
||||||
ActivityManager mAm;
|
ActivityManager mAm;
|
||||||
|
Configuration mOverrideConfig;
|
||||||
|
|
||||||
class BroadcastResultReceiver extends BroadcastReceiver {
|
class BroadcastResultReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
@@ -111,6 +115,12 @@ public class ActivityTestMain extends Activity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
|
mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
|
||||||
|
if (mOverrideConfig != null) {
|
||||||
|
applyOverrideConfiguration(mOverrideConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -182,6 +192,21 @@ public class ActivityTestMain extends Activity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
menu.add("Density!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@Override public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
if (mOverrideConfig == null) {
|
||||||
|
mOverrideConfig = new Configuration();
|
||||||
|
}
|
||||||
|
if (mOverrideConfig.densityDpi == Configuration.DENSITY_DPI_UNDEFINED) {
|
||||||
|
mOverrideConfig.densityDpi = (getApplicationContext().getResources()
|
||||||
|
.getConfiguration().densityDpi*2)/3;
|
||||||
|
} else {
|
||||||
|
mOverrideConfig.densityDpi = Configuration.DENSITY_DPI_UNDEFINED;
|
||||||
|
}
|
||||||
|
recreate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,6 +216,14 @@ public class ActivityTestMain extends Activity {
|
|||||||
buildUi();
|
buildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if (mOverrideConfig != null) {
|
||||||
|
outState.putParcelable(KEY_CONFIGURATION, mOverrideConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private View scrollWrap(View view) {
|
private View scrollWrap(View view) {
|
||||||
ScrollView scroller = new ScrollView(this);
|
ScrollView scroller = new ScrollView(this);
|
||||||
scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT,
|
scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT,
|
||||||
|
|||||||
@@ -916,6 +916,12 @@ public final class BridgeContext extends Context {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context createConfigurationContext(Configuration overrideConfiguration) {
|
||||||
|
// pass
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] databaseList() {
|
public String[] databaseList() {
|
||||||
// pass
|
// pass
|
||||||
|
|||||||
Reference in New Issue
Block a user