summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityThread.java98
-rw-r--r--core/java/android/app/Application.java4
-rw-r--r--core/java/android/app/ContextImpl.java12
-rw-r--r--core/java/android/app/LoadedApk.java11
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java3
-rw-r--r--core/java/android/content/res/Configuration.java35
-rwxr-xr-xcore/java/android/content/res/Resources.java34
-rw-r--r--core/java/android/text/TextLine.java1
-rw-r--r--core/java/android/view/CompatibilityInfoHolder.java45
-rw-r--r--core/java/android/view/Display.java38
-rw-r--r--core/java/android/view/ViewRoot.java41
-rw-r--r--core/java/android/view/Window.java9
-rw-r--r--core/java/android/view/WindowManagerImpl.java65
13 files changed, 306 insertions, 90 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a61147a..6c63c2a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -155,7 +155,9 @@ public final class ActivityThread {
= new HashMap<IBinder, Service>();
AppBindData mBoundApplication;
Configuration mConfiguration;
+ Configuration mCompatConfiguration;
Configuration mResConfiguration;
+ CompatibilityInfo mResCompatibilityInfo;
Application mInitialApplication;
final ArrayList<Application> mAllApplications
= new ArrayList<Application>();
@@ -181,8 +183,8 @@ public final class ActivityThread {
= new HashMap<String, WeakReference<LoadedApk>>();
final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
= new HashMap<String, WeakReference<LoadedApk>>();
- Display mDisplay = null;
- DisplayMetrics mDisplayMetrics = null;
+ final HashMap<CompatibilityInfo, DisplayMetrics> mDisplayMetrics
+ = new HashMap<CompatibilityInfo, DisplayMetrics>();
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
= new HashMap<ResourcesKey, WeakReference<Resources> >();
final ArrayList<ActivityClientRecord> mRelaunchingActivities
@@ -1267,20 +1269,45 @@ public final class ActivityThread {
return sPackageManager;
}
- DisplayMetrics getDisplayMetricsLocked(boolean forceUpdate) {
- if (mDisplayMetrics != null && !forceUpdate) {
- return mDisplayMetrics;
+ DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate) {
+ DisplayMetrics dm = mDisplayMetrics.get(ci);
+ if (dm != null && !forceUpdate) {
+ return dm;
}
- if (mDisplay == null) {
- WindowManager wm = WindowManagerImpl.getDefault();
- mDisplay = wm.getDefaultDisplay();
+ if (dm == null) {
+ dm = new DisplayMetrics();
+ mDisplayMetrics.put(ci, dm);
}
- DisplayMetrics metrics = mDisplayMetrics = new DisplayMetrics();
- mDisplay.getMetrics(metrics);
+ Display d = WindowManagerImpl.getDefault(ci).getDefaultDisplay();
+ d.getMetrics(dm);
//Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
// + metrics.heightPixels + " den=" + metrics.density
// + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
- return metrics;
+ return dm;
+ }
+
+ static Configuration applyConfigCompat(Configuration config, CompatibilityInfo compat) {
+ if (config == null) {
+ return null;
+ }
+ if (compat != null && !compat.supportsScreen()) {
+ config = new Configuration(config);
+ compat.applyToConfiguration(config);
+ }
+ return config;
+ }
+
+ private final Configuration mMainThreadConfig = new Configuration();
+ Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
+ if (config == null) {
+ return null;
+ }
+ if (compat != null && !compat.supportsScreen()) {
+ mMainThreadConfig.setTo(config);
+ config = mMainThreadConfig;
+ compat.applyToConfiguration(config);
+ }
+ return config;
}
/**
@@ -1322,7 +1349,7 @@ public final class ActivityThread {
}
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
- DisplayMetrics metrics = getDisplayMetricsLocked(false);
+ DisplayMetrics metrics = getDisplayMetricsLocked(compInfo, false);
r = new Resources(assets, metrics, getConfiguration(), compInfo);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
@@ -1350,7 +1377,7 @@ public final class ActivityThread {
* Creates the top level resources for the given package.
*/
Resources getTopLevelResources(String resDir, LoadedApk pkgInfo) {
- return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
+ return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo.get());
}
final Handler getHandler() {
@@ -1517,7 +1544,8 @@ public final class ActivityThread {
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
context.init(info, null, this);
context.getResources().updateConfiguration(
- getConfiguration(), getDisplayMetricsLocked(false));
+ getConfiguration(), getDisplayMetricsLocked(
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, false));
mSystemContext = context;
//Slog.i(TAG, "Created system resources " + context.getResources()
// + ": " + context.getResources().getConfiguration());
@@ -1730,7 +1758,7 @@ public final class ActivityThread {
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
- Configuration config = new Configuration(mConfiguration);
+ Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
@@ -2763,13 +2791,14 @@ public final class ActivityThread {
private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
LoadedApk apk = peekPackageInfo(data.pkg, false);
if (apk != null) {
- apk.mCompatibilityInfo = data.info;
+ apk.mCompatibilityInfo.set(data.info);
}
apk = peekPackageInfo(data.pkg, true);
if (apk != null) {
- apk.mCompatibilityInfo = data.info;
+ apk.mCompatibilityInfo.set(data.info);
}
handleConfigurationChanged(mConfiguration, data.info);
+ WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration);
}
private final void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
@@ -3192,20 +3221,22 @@ public final class ActivityThread {
ActivityClientRecord ar = it.next();
Activity a = ar.activity;
if (a != null) {
+ Configuration thisConfig = applyConfigCompatMainThread(newConfig,
+ ar.packageInfo.mCompatibilityInfo.getIfNeeded());
if (!ar.activity.mFinished && (allActivities ||
(a != null && !ar.paused))) {
// If the activity is currently resumed, its configuration
// needs to change right now.
callbacks.add(a);
- } else if (newConfig != null) {
+ } else if (thisConfig != null) {
// Otherwise, we will tell it about the change
// the next time it is resumed or shown. Note that
// the activity manager may, before then, decide the
// activity needs to be destroyed to handle its new
// configuration.
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
- + ar.activityInfo.name + " newConfig=" + newConfig);
- ar.newConfig = newConfig;
+ + ar.activityInfo.name + " newConfig=" + thisConfig);
+ ar.newConfig = thisConfig;
}
}
}
@@ -3252,7 +3283,6 @@ public final class ActivityThread {
// onConfigurationChanged
int diff = activity.mCurrentConfig.diff(config);
if (diff != 0) {
-
// If this activity doesn't handle any of the config changes
// then don't bother calling onConfigurationChanged as we're
// going to destroy it.
@@ -3296,7 +3326,15 @@ public final class ActivityThread {
return false;
}
int changes = mResConfiguration.updateFrom(config);
- DisplayMetrics dm = getDisplayMetricsLocked(true);
+ DisplayMetrics dm = getDisplayMetricsLocked(compat, true);
+
+ if (compat != null && (mResCompatibilityInfo == null ||
+ !mResCompatibilityInfo.equals(compat))) {
+ mResCompatibilityInfo = compat;
+ changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
+ | ActivityInfo.CONFIG_SCREEN_SIZE
+ | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+ }
// set it for java, this also affects newly created Resources
if (config.locale != null) {
@@ -3358,13 +3396,14 @@ public final class ActivityThread {
return;
}
mConfiguration.updateFrom(config);
- if (compat != null) {
- // Can't do this here, because it causes us to report the
- // comatible config back to the am as the current config
- // of the activity, and much unhappiness results.
- //compat.applyToConfiguration(mConfiguration);
+ if (mCompatConfiguration == null) {
+ mCompatConfiguration = new Configuration();
+ }
+ mCompatConfiguration.setTo(mConfiguration);
+ if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
+ mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
+ config = mCompatConfiguration;
}
-
callbacks = collectComponentCallbacksLocked(false, config);
}
@@ -3385,7 +3424,7 @@ public final class ActivityThread {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
+ r.activityInfo.name);
- performConfigurationChanged(r.activity, mConfiguration);
+ performConfigurationChanged(r.activity, mCompatConfiguration);
}
final void handleProfilerControl(boolean start, ProfilerControlData pcd) {
@@ -3480,6 +3519,7 @@ public final class ActivityThread {
private final void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
+ mCompatConfiguration = new Configuration(data.config);
// send up app name; do this *before* waiting for debugger
Process.setArgV0(data.processName);
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index b9ac848..10cc9f8 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -37,6 +37,8 @@ import android.content.res.Configuration;
* when first constructing the singleton.</p>
*/
public class Application extends ContextWrapper implements ComponentCallbacks {
+ /** @hide */
+ public LoadedApk mLoadedApk;
public Application() {
super(null);
@@ -75,6 +77,6 @@ public class Application extends ContextWrapper implements ComponentCallbacks {
*/
/* package */ final void attach(Context context) {
attachBaseContext(context);
+ mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
-
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 73170bb..20dc792 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -425,11 +425,19 @@ class ContextImpl extends Context {
registerService(WINDOW_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
- CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo();
- return WindowManagerImpl.getDefault(ci);
+ return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
}});
}
+ static ContextImpl getImpl(Context context) {
+ Context nextContext;
+ while ((context instanceof ContextWrapper) &&
+ (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
+ context = nextContext;
+ }
+ return (ContextImpl)context;
+ }
+
// The system service cache for the system services that are
// cached per-ContextImpl. Package-scoped to avoid accessor
// methods.
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 6287d33..2549c84 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -38,6 +38,7 @@ import android.os.RemoteException;
import android.os.StrictMode;
import android.util.AndroidRuntimeException;
import android.util.Slog;
+import android.view.CompatibilityInfoHolder;
import java.io.File;
import java.io.IOException;
@@ -64,7 +65,7 @@ final class ServiceConnectionLeaked extends AndroidRuntimeException {
* Local state maintained about a currently loaded .apk.
* @hide
*/
-final class LoadedApk {
+public final class LoadedApk {
private final ActivityThread mActivityThread;
private final ApplicationInfo mApplicationInfo;
@@ -78,10 +79,10 @@ final class LoadedApk {
private final ClassLoader mBaseClassLoader;
private final boolean mSecurityViolation;
private final boolean mIncludeCode;
+ public final CompatibilityInfoHolder mCompatibilityInfo = new CompatibilityInfoHolder();
Resources mResources;
private ClassLoader mClassLoader;
private Application mApplication;
- CompatibilityInfo mCompatibilityInfo;
private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mReceivers
= new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
@@ -121,7 +122,7 @@ final class LoadedApk {
mBaseClassLoader = baseLoader;
mSecurityViolation = securityViolation;
mIncludeCode = includeCode;
- mCompatibilityInfo = compatInfo;
+ mCompatibilityInfo.set(compatInfo);
if (mAppDir == null) {
if (ActivityThread.mSystemContext == null) {
@@ -129,7 +130,7 @@ final class LoadedApk {
ContextImpl.createSystemContext(mainThread);
ActivityThread.mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(),
- mainThread.getDisplayMetricsLocked(false),
+ mainThread.getDisplayMetricsLocked(compatInfo, false),
compatInfo);
//Slog.i(TAG, "Created system resources "
// + mSystemContext.getResources() + ": "
@@ -157,7 +158,7 @@ final class LoadedApk {
mIncludeCode = true;
mClassLoader = systemContext.getClassLoader();
mResources = systemContext.getResources();
- mCompatibilityInfo = compatInfo;
+ mCompatibilityInfo.set(compatInfo);
}
public String getPackageName() {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index b686e54..acf2f2f 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -456,6 +456,9 @@ public class CompatibilityInfo implements Parcelable {
inoutConfig.screenLayout =
(inoutConfig.screenLayout&~Configuration.SCREENLAYOUT_SIZE_MASK)
| Configuration.SCREENLAYOUT_SIZE_NORMAL;
+ inoutConfig.screenWidthDp = inoutConfig.compatScreenWidthDp;
+ inoutConfig.screenHeightDp = inoutConfig.compatScreenHeightDp;
+ inoutConfig.smallestScreenWidthDp = inoutConfig.compatSmallestScreenWidthDp;
}
}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 6409aac..e2c6483 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -269,6 +269,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public int smallestScreenWidthDp;
+ /** @hide Hack to get this information from WM to app running in compat mode. */
+ public int compatScreenWidthDp;
+ /** @hide Hack to get this information from WM to app running in compat mode. */
+ public int compatScreenHeightDp;
+ /** @hide Hack to get this information from WM to app running in compat mode. */
+ public int compatSmallestScreenWidthDp;
+
/**
* @hide Internal book-keeping.
*/
@@ -309,6 +316,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
screenWidthDp = o.screenWidthDp;
screenHeightDp = o.screenHeightDp;
smallestScreenWidthDp = o.smallestScreenWidthDp;
+ compatScreenWidthDp = o.compatScreenWidthDp;
+ compatScreenHeightDp = o.compatScreenHeightDp;
+ compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
seq = o.seq;
}
@@ -444,9 +454,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
- screenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
- screenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
- smallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
+ screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
+ screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
+ smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
seq = 0;
}
@@ -550,11 +560,18 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
screenHeightDp = delta.screenHeightDp;
}
- if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
- && smallestScreenWidthDp != delta.smallestScreenWidthDp) {
- changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+ if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
smallestScreenWidthDp = delta.smallestScreenWidthDp;
}
+ if (delta.compatScreenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
+ compatScreenWidthDp = delta.compatScreenWidthDp;
+ }
+ if (delta.compatScreenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
+ compatScreenHeightDp = delta.compatScreenHeightDp;
+ }
+ if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
+ compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
+ }
if (delta.seq != 0) {
seq = delta.seq;
@@ -739,6 +756,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(screenWidthDp);
dest.writeInt(screenHeightDp);
dest.writeInt(smallestScreenWidthDp);
+ dest.writeInt(compatScreenWidthDp);
+ dest.writeInt(compatScreenHeightDp);
+ dest.writeInt(compatSmallestScreenWidthDp);
dest.writeInt(seq);
}
@@ -763,6 +783,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
screenWidthDp = source.readInt();
screenHeightDp = source.readInt();
smallestScreenWidthDp = source.readInt();
+ compatScreenWidthDp = source.readInt();
+ compatScreenHeightDp = source.readInt();
+ compatSmallestScreenWidthDp = source.readInt();
seq = source.readInt();
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 70bf524..bd8b1a4 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1414,18 +1414,6 @@ public class Resources {
if (compat != null) {
mCompatibilityInfo = compat;
}
- int configChanges = 0xfffffff;
- if (config != null) {
- mTmpConfig.setTo(config);
- if (mCompatibilityInfo != null) {
- mCompatibilityInfo.applyToConfiguration(mTmpConfig);
- }
- configChanges = mConfiguration.updateFrom(mTmpConfig);
- configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
- }
- if (mConfiguration.locale == null) {
- mConfiguration.locale = Locale.getDefault();
- }
if (metrics != null) {
mMetrics.setTo(metrics);
// NOTE: We should re-arrange this code to create a Display
@@ -1441,7 +1429,25 @@ public class Resources {
mCompatibilityInfo.applyToDisplayMetrics(mMetrics);
}
}
+ if (mCompatibilityInfo != null) {
+ mCompatibilityInfo.applyToDisplayMetrics(mMetrics);
+ }
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
+ int configChanges = 0xfffffff;
+ if (config != null) {
+ mTmpConfig.setTo(config);
+ if (mCompatibilityInfo != null) {
+ mCompatibilityInfo.applyToConfiguration(mTmpConfig);
+ }
+ if (mTmpConfig.locale == null) {
+ mTmpConfig.locale = Locale.getDefault();
+ }
+ configChanges = mConfiguration.updateFrom(mTmpConfig);
+ configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
+ }
+ if (mConfiguration.locale == null) {
+ mConfiguration.locale = Locale.getDefault();
+ }
String locale = null;
if (mConfiguration.locale != null) {
@@ -1476,7 +1482,7 @@ public class Resources {
mConfiguration.screenLayout, mConfiguration.uiMode,
Build.VERSION.RESOURCES_SDK_INT);
- if (false) {
+ if (DEBUG_CONFIG) {
Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration
+ " final compat is " + mCompatibilityInfo);
}
@@ -1558,6 +1564,8 @@ public class Resources {
* @return The resource's current display metrics.
*/
public DisplayMetrics getDisplayMetrics() {
+ if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels
+ + "x" + mMetrics.heightPixels + " " + mMetrics.density);
return mMetrics;
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 90279d1..155870a 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -75,7 +75,6 @@ class TextLine {
}
}
tl = new TextLine();
- Log.v("TLINE", "new: " + tl);
return tl;
}
diff --git a/core/java/android/view/CompatibilityInfoHolder.java b/core/java/android/view/CompatibilityInfoHolder.java
new file mode 100644
index 0000000..fc8d684
--- /dev/null
+++ b/core/java/android/view/CompatibilityInfoHolder.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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.view;
+
+import android.content.res.CompatibilityInfo;
+
+/** @hide */
+public class CompatibilityInfoHolder {
+ private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+
+ public void set(CompatibilityInfo compatInfo) {
+ if (compatInfo != null && (compatInfo.isScalingRequired()
+ || !compatInfo.supportsScreen())) {
+ mCompatInfo = compatInfo;
+ } else {
+ mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+ }
+ }
+
+ public CompatibilityInfo get() {
+ return mCompatInfo;
+ }
+
+ public CompatibilityInfo getIfNeeded() {
+ CompatibilityInfo ci = mCompatInfo;
+ if (ci == null || ci == CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO) {
+ return null;
+ }
+ return ci;
+ }
+}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 8032546..3fa8dfd 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,6 +26,9 @@ import android.util.DisplayMetrics;
import android.util.Slog;
public class Display {
+ static final String TAG = "Display";
+ static final boolean DEBUG_COMPAT = false;
+
/**
* Specify the default Display
*/
@@ -38,7 +41,7 @@ public class Display {
* Display gives you access to some information about a particular display
* connected to the device.
*/
- Display(int display, CompatibilityInfo compatInfo) {
+ Display(int display, CompatibilityInfoHolder compatInfo) {
// initalize the statics when this class is first instansiated. This is
// done here instead of in the static block because Zygote
synchronized (sStaticInit) {
@@ -47,14 +50,19 @@ public class Display {
sInitialized = true;
}
}
+ mCompatibilityInfo = compatInfo != null ? compatInfo : new CompatibilityInfoHolder();
+ mDisplay = display;
+ init(display);
+ }
+
+ /** @hide */
+ public static void setCompatibilityInfo(CompatibilityInfo compatInfo) {
if (compatInfo != null && (compatInfo.isScalingRequired()
|| !compatInfo.supportsScreen())) {
- mCompatibilityInfo = compatInfo;
+ sCompatibilityInfo = compatInfo;
} else {
- mCompatibilityInfo = null;
+ sCompatibilityInfo = null;
}
- mDisplay = display;
- init(display);
}
/**
@@ -96,12 +104,13 @@ public class Display {
IWindowManager wm = getWindowManager();
if (wm != null) {
wm.getDisplaySize(outSize);
- if (doCompat && mCompatibilityInfo != null) {
+ CompatibilityInfo ci;
+ if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) {
synchronized (mTmpMetrics) {
mTmpMetrics.unscaledWidthPixels = outSize.x;
mTmpMetrics.unscaledHeightPixels = outSize.y;
mTmpMetrics.density = mDensity;
- mCompatibilityInfo.applyToDisplayMetrics(mTmpMetrics);
+ ci.applyToDisplayMetrics(mTmpMetrics);
outSize.x = mTmpMetrics.widthPixels;
outSize.y = mTmpMetrics.heightPixels;
}
@@ -111,6 +120,7 @@ public class Display {
// system process before the window manager is up.
outSize.y = getRealHeight();
}
+ if (DEBUG_COMPAT && doCompat) Slog.v(TAG, "Returning display size: " + outSize);
} catch (RemoteException e) {
Slog.w("Display", "Unable to get display size", e);
}
@@ -236,9 +246,13 @@ public class Display {
}
getNonSizeMetrics(outMetrics);
- if (mCompatibilityInfo != null) {
- mCompatibilityInfo.applyToDisplayMetrics(outMetrics);
+ CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
+ if (ci != null) {
+ ci.applyToDisplayMetrics(outMetrics);
}
+
+ if (DEBUG_COMPAT) Slog.v(TAG, "Returning DisplayMetrics: " + outMetrics.widthPixels
+ + "x" + outMetrics.heightPixels + " " + outMetrics.density);
}
/**
@@ -282,7 +296,7 @@ public class Display {
private native void init(int display);
- private final CompatibilityInfo mCompatibilityInfo;
+ private final CompatibilityInfoHolder mCompatibilityInfo;
private final int mDisplay;
// Following fields are initialized from native code
private int mPixelFormat;
@@ -299,11 +313,13 @@ public class Display {
private static boolean sInitialized = false;
private static IWindowManager sWindowManager;
+ private static volatile CompatibilityInfo sCompatibilityInfo;
+
/**
* Returns a display object which uses the metric's width/height instead.
* @hide
*/
- public static Display createCompatibleDisplay(int displayId, CompatibilityInfo compat) {
+ public static Display createCompatibleDisplay(int displayId, CompatibilityInfoHolder compat) {
return new Display(displayId, compat);
}
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 2098955..cdb0339 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -159,6 +159,8 @@ public final class ViewRoot extends Handler implements ViewParent,
// so the window should no longer be active.
boolean mStopped = false;
+ boolean mLastInCompatMode = false;
+
SurfaceHolder.Callback2 mSurfaceHolderCallback;
BaseSurfaceHolder mSurfaceHolder;
boolean mIsCreating;
@@ -204,6 +206,8 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean mAdded;
boolean mAddedTouchMode;
+ CompatibilityInfoHolder mCompatibilityInfo;
+
/*package*/ int mAddNesting;
// These are accessed by multiple threads.
@@ -369,8 +373,7 @@ public final class ViewRoot extends Handler implements ViewParent,
enableHardwareAcceleration(attrs);
}
- Resources resources = mView.getContext().getResources();
- CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
+ CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
mTranslator = compatibilityInfo.getTranslator();
if (mTranslator != null) {
@@ -387,6 +390,7 @@ public final class ViewRoot extends Handler implements ViewParent,
if (!compatibilityInfo.supportsScreen()) {
attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+ mLastInCompatMode = true;
}
mSoftInputMode = attrs.softInputMode;
@@ -719,6 +723,19 @@ public final class ViewRoot extends Handler implements ViewParent,
surfaceChanged = true;
params = lp;
}
+ CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
+ if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
+ params = lp;
+ fullRedrawNeeded = true;
+ mLayoutRequested = true;
+ if (mLastInCompatMode) {
+ params.flags &= ~WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+ mLastInCompatMode = false;
+ } else {
+ params.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+ mLastInCompatMode = true;
+ }
+ }
Rect frame = mWinFrame;
if (mFirst) {
fullRedrawNeeded = true;
@@ -1934,6 +1951,13 @@ public final class ViewRoot extends Handler implements ViewParent,
"Applying new config to window "
+ mWindowAttributes.getTitle()
+ ": " + config);
+
+ CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
+ if (ci != null) {
+ config = new Configuration(config);
+ ci.applyToConfiguration(config);
+ }
+
synchronized (sConfigCallbacks) {
for (int i=sConfigCallbacks.size()-1; i>=0; i--) {
sConfigCallbacks.get(i).onConfigurationChanged(config);
@@ -1995,6 +2019,7 @@ public final class ViewRoot extends Handler implements ViewParent,
public final static int DISPATCH_DRAG_LOCATION_EVENT = 1016;
public final static int DISPATCH_SYSTEM_UI_VISIBILITY = 1017;
public final static int DISPATCH_GENERIC_MOTION = 1018;
+ public final static int UPDATE_CONFIGURATION = 1019;
@Override
public void handleMessage(Message msg) {
@@ -2178,6 +2203,13 @@ public final class ViewRoot extends Handler implements ViewParent,
case DISPATCH_SYSTEM_UI_VISIBILITY: {
handleDispatchSystemUiVisibilityChanged(msg.arg1);
} break;
+ case UPDATE_CONFIGURATION: {
+ Configuration config = (Configuration)msg.obj;
+ if (config.isOtherSeqNewer(mLastConfiguration)) {
+ config = mLastConfiguration;
+ }
+ updateConfiguration(config, false);
+ } break;
}
}
@@ -3205,6 +3237,11 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
+ public void requestUpdateConfiguration(Configuration config) {
+ Message msg = obtainMessage(UPDATE_CONFIGURATION, config);
+ sendMessage(msg);
+ }
+
private void destroyHardwareRenderer() {
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 5236a9e..e07085c 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -16,6 +16,7 @@
package android.view;
+import android.app.Application;
import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -25,6 +26,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
+import android.util.Slog;
import android.view.accessibility.AccessibilityEvent;
/**
@@ -463,11 +465,16 @@ public abstract class Window {
mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);
}
+ static CompatibilityInfoHolder getCompatInfo(Context context) {
+ Application app = (Application)context.getApplicationContext();
+ return app != null ? app.mLoadedApk.mCompatibilityInfo : new CompatibilityInfoHolder();
+ }
+
private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper {
private final boolean mHardwareAccelerated;
LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) {
- super(wm, mContext.getResources().getCompatibilityInfo());
+ super(wm, getCompatInfo(mContext));
mHardwareAccelerated = hardwareAccelerated;
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 9cae75c..a853c15 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -19,11 +19,13 @@ package android.view;
import java.util.HashMap;
import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.AndroidRuntimeException;
import android.util.Config;
import android.util.Log;
+import android.util.Slog;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
@@ -88,29 +90,32 @@ public class WindowManagerImpl implements WindowManager {
= new HashMap<CompatibilityInfo, WindowManager>();
static class CompatModeWrapper implements WindowManager {
- private final WindowManager mWindowManager;
+ private final WindowManagerImpl mWindowManager;
private final Display mDefaultDisplay;
+ private final CompatibilityInfoHolder mCompatibilityInfo;
- CompatModeWrapper(WindowManager wm, CompatibilityInfo ci) {
- mWindowManager = wm;
+ CompatModeWrapper(WindowManager wm, CompatibilityInfoHolder ci) {
+ mWindowManager = wm instanceof CompatModeWrapper
+ ? ((CompatModeWrapper)wm).mWindowManager : (WindowManagerImpl)wm;
// Use the original display if there is no compatibility mode
// to apply, or the underlying window manager is already a
// compatibility mode wrapper. (We assume that if it is a
// wrapper, it is applying the same compatibility mode.)
- if (ci == null || wm instanceof CompatModeWrapper
- || (!ci.isScalingRequired() && ci.supportsScreen())) {
+ if (ci == null) {
mDefaultDisplay = mWindowManager.getDefaultDisplay();
} else {
//mDefaultDisplay = mWindowManager.getDefaultDisplay();
mDefaultDisplay = Display.createCompatibleDisplay(
mWindowManager.getDefaultDisplay().getDisplayId(), ci);
}
+
+ mCompatibilityInfo = ci;
}
@Override
public void addView(View view, android.view.ViewGroup.LayoutParams params) {
- mWindowManager.addView(view, params);
+ mWindowManager.addView(view, params, mCompatibilityInfo);
}
@Override
@@ -146,8 +151,9 @@ public class WindowManagerImpl implements WindowManager {
}
public static WindowManager getDefault(CompatibilityInfo compatInfo) {
- if (compatInfo == null || (!compatInfo.isScalingRequired()
- && compatInfo.supportsScreen())) {
+ CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
+ cih.set(compatInfo);
+ if (cih.getIfNeeded() == null) {
return sWindowManager;
}
@@ -159,35 +165,40 @@ public class WindowManagerImpl implements WindowManager {
// having to make wrappers.
WindowManager wm = sCompatWindowManagers.get(compatInfo);
if (wm == null) {
- wm = new CompatModeWrapper(sWindowManager, compatInfo);
+ wm = new CompatModeWrapper(sWindowManager, cih);
sCompatWindowManagers.put(compatInfo, wm);
}
return wm;
}
}
+
+ public static WindowManager getDefault(CompatibilityInfoHolder compatInfo) {
+ return new CompatModeWrapper(sWindowManager, compatInfo);
+ }
public boolean isHardwareAccelerated() {
return false;
}
- public void addView(View view)
- {
+ public void addView(View view) {
addView(view, new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.OPAQUE));
}
- public void addView(View view, ViewGroup.LayoutParams params)
- {
- addView(view, params, false);
+ public void addView(View view, ViewGroup.LayoutParams params) {
+ addView(view, params, null, false);
}
- public void addViewNesting(View view, ViewGroup.LayoutParams params)
- {
- addView(view, params, false);
+ public void addView(View view, ViewGroup.LayoutParams params, CompatibilityInfoHolder cih) {
+ addView(view, params, cih, false);
}
- private void addView(View view, ViewGroup.LayoutParams params, boolean nest)
- {
+ public void addViewNesting(View view, ViewGroup.LayoutParams params) {
+ addView(view, params, null, false);
+ }
+
+ private void addView(View view, ViewGroup.LayoutParams params,
+ CompatibilityInfoHolder cih, boolean nest) {
if (Config.LOGV) Log.v("WindowManager", "addView view=" + view);
if (!(params instanceof WindowManager.LayoutParams)) {
@@ -237,6 +248,11 @@ public class WindowManagerImpl implements WindowManager {
root = new ViewRoot(view.getContext());
root.mAddNesting = 1;
+ if (cih == null) {
+ root.mCompatibilityInfo = new CompatibilityInfoHolder();
+ } else {
+ root.mCompatibilityInfo = cih;
+ }
view.setLayoutParams(wparams);
@@ -402,6 +418,17 @@ public class WindowManagerImpl implements WindowManager {
}
}
+ public void reportNewConfiguration(Configuration config) {
+ synchronized (this) {
+ int count = mViews.length;
+ config = new Configuration(config);
+ for (int i=0; i<count; i++) {
+ ViewRoot root = mRoots[i];
+ root.requestUpdateConfiguration(config);
+ }
+ }
+ }
+
public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
ViewParent vp = view.getParent();
while (vp != null && !(vp instanceof ViewRoot)) {