diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ActivityThread.java | 98 | ||||
-rw-r--r-- | core/java/android/app/Application.java | 4 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 12 | ||||
-rw-r--r-- | core/java/android/app/LoadedApk.java | 11 | ||||
-rw-r--r-- | core/java/android/content/res/CompatibilityInfo.java | 3 | ||||
-rw-r--r-- | core/java/android/content/res/Configuration.java | 35 | ||||
-rwxr-xr-x | core/java/android/content/res/Resources.java | 34 | ||||
-rw-r--r-- | core/java/android/text/TextLine.java | 1 | ||||
-rw-r--r-- | core/java/android/view/CompatibilityInfoHolder.java | 45 | ||||
-rw-r--r-- | core/java/android/view/Display.java | 38 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 41 | ||||
-rw-r--r-- | core/java/android/view/Window.java | 9 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerImpl.java | 65 |
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)) { |