am 7322e557: am a4cfcf10: am 75d6b3c2: Merge "Fix issue #4502672: Wrong xml resources used for homescreen widgets." into honeycomb-mr2

* commit '7322e557cfe42da42779625d69ced2db74a9df90':
  Fix issue #4502672: Wrong xml resources used for homescreen widgets.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7e20c75..51c7a0a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -172,6 +172,11 @@
     // These can be accessed by multiple threads; mPackages is the lock.
     // XXX For now we keep around information about all packages we have
     // seen, not removing entries from this map.
+    // NOTE: The activity manager in its process needs to call in to
+    // ActivityThread to do things like update resource configurations,
+    // which means this lock gets held while the activity manager holds its
+    // own lock.  Thus you MUST NEVER call back into the activity manager
+    // or anything that depends on it while holding this lock.
     final HashMap<String, WeakReference<LoadedApk>> mPackages
             = new HashMap<String, WeakReference<LoadedApk>>();
     final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
@@ -1489,7 +1494,7 @@
     }
 
     public Configuration getConfiguration() {
-        return mConfiguration;
+        return mResConfiguration;
     }
 
     public boolean isProfiling() {
@@ -1534,7 +1539,7 @@
         synchronized (this) {
             ContextImpl context = getSystemContext();
             context.init(new LoadedApk(this, "android", context, info,
-                    new CompatibilityInfo(info, 0, 0, false)), null, this);
+                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
         }
     }
 
@@ -3293,6 +3298,12 @@
         }
     }
 
+    public final void applyConfigurationToResources(Configuration config) {
+        synchronized (mPackages) {
+            applyConfigurationToResourcesLocked(config, null);
+        }
+    }
+
     final boolean applyConfigurationToResourcesLocked(Configuration config,
             CompatibilityInfo compat) {
         if (mResConfiguration == null) {
@@ -3518,8 +3529,7 @@
          * reflect configuration changes. The configuration object passed
          * in AppBindData can be safely assumed to be up to date
          */
-        Resources.getSystem().updateConfiguration(mConfiguration,
-                Resources.getSystem().getDisplayMetrics(), data.compatInfo);
+        applyConfigurationToResourcesLocked(data.config, data.compatInfo);
 
         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
 
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 5307696..6287d33 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -98,6 +98,12 @@
         return mApplication;
     }
 
+    /**
+     * Create information about a new .apk
+     *
+     * NOTE: This constructor is called with ActivityThread's lock held,
+     * so MUST NOT call back out to the activity manager.
+     */
     public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
             CompatibilityInfo compatInfo,
             ActivityThread mainThread, ClassLoader baseLoader,
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index e42caca..b7b6de6 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -243,11 +243,11 @@
     }
     
     public boolean neverSupportsScreen() {
-        return (mCompatibilityFlags&NEVER_NEEDS_COMPAT) != 0;
+        return (mCompatibilityFlags&ALWAYS_NEEDS_COMPAT) != 0;
     }
 
     public boolean alwaysSupportsScreen() {
-        return (mCompatibilityFlags&ALWAYS_NEEDS_COMPAT) != 0;
+        return (mCompatibilityFlags&NEVER_NEEDS_COMPAT) != 0;
     }
 
     /**
@@ -406,7 +406,7 @@
         if (!supportsScreen()) {
             // This is a larger screen device and the app is not
             // compatible with large screens, so diddle it.
-            CompatibilityInfo.updateCompatibleScreenFrame(inoutDm, null, inoutDm);
+            CompatibilityInfo.computeCompatibleScaling(inoutDm, inoutDm);
         } else {
             inoutDm.widthPixels = inoutDm.unscaledWidthPixels;
             inoutDm.heightPixels = inoutDm.unscaledHeightPixels;
@@ -443,8 +443,7 @@
      * @param outRect the output parameter which will contain the result.
      * @return Returns the scaling factor for the window.
      */
-    public static float updateCompatibleScreenFrame(DisplayMetrics dm,
-            Rect outRect, DisplayMetrics outDm) {
+    public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) {
         final int width = dm.unscaledWidthPixels;
         final int height = dm.unscaledHeightPixels;
         int shortSize, longSize;
@@ -477,12 +476,6 @@
             scale = 1;
         }
 
-        if (outRect != null) {
-            final int left = (int)((width-(newWidth*scale))/2);
-            final int top = (int)((height-(newHeight*scale))/2);
-            outRect.set(left, top, left+newWidth, top+newHeight);
-        }
-
         if (outDm != null) {
             outDm.widthPixels = newWidth;
             outDm.heightPixels = newHeight;
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index d476997..6409aac 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -330,17 +330,17 @@
         if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
             sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
         } else {
-            sb.append("?swdp");
+            sb.append(" ?swdp");
         }
         if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
             sb.append(" w"); sb.append(screenWidthDp); sb.append("dp");
         } else {
-            sb.append("?wdp");
+            sb.append(" ?wdp");
         }
         if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
             sb.append(" h"); sb.append(screenHeightDp); sb.append("dp");
         } else {
-            sb.append("?hdp");
+            sb.append(" ?hdp");
         }
         switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) {
             case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 81dc46a..70bf524 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -28,14 +28,13 @@
 import android.graphics.drawable.Drawable.ConstantState;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.LongSparseArray;
-import android.view.Display;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -1406,6 +1405,12 @@
     public void updateConfiguration(Configuration config,
             DisplayMetrics metrics, CompatibilityInfo compat) {
         synchronized (mTmpValue) {
+            if (false) {
+                Slog.i(TAG, "**** Updating config of " + this + ": old config is "
+                        + mConfiguration + " old compat is " + mCompatibilityInfo);
+                Slog.i(TAG, "**** Updating config of " + this + ": new config is "
+                        + config + " new compat is " + compat);
+            }
             if (compat != null) {
                 mCompatibilityInfo = compat;
             }
@@ -1471,6 +1476,11 @@
                     mConfiguration.screenLayout, mConfiguration.uiMode,
                     Build.VERSION.RESOURCES_SDK_INT);
 
+            if (false) {
+                Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration
+                        + " final compat is " + mCompatibilityInfo);
+            }
+
             clearDrawableCache(mDrawableCache, configChanges);
             clearDrawableCache(mColorDrawableCache, configChanges);
 
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index bdf04ab0..4427eb5 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -19,6 +19,7 @@
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Point;
@@ -88,7 +89,7 @@
     void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim);
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
-            CharSequence nonLocalizedLabel, int labelRes,
+            in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
             int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
     void setAppWillBeHidden(IBinder token);
     void setAppVisibility(IBinder token, boolean visible);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 82a4d2d..8a30c7b 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.content.Context;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.IBinder;
@@ -539,7 +540,7 @@
      * @see #removeStartingWindow
      */
     public View addStartingWindow(IBinder appToken, String packageName,
-            int theme, CharSequence nonLocalizedLabel,
+            int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel,
             int labelRes, int icon, int windowFlags);
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index d2c0709..09b0e87 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -30,6 +30,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -1126,9 +1127,9 @@
     }
     
     /** {@inheritDoc} */
-    public View addStartingWindow(IBinder appToken, String packageName,
-                                  int theme, CharSequence nonLocalizedLabel,
-                                  int labelRes, int icon, int windowFlags) {
+    public View addStartingWindow(IBinder appToken, String packageName, int theme,
+            CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
+            int icon, int windowFlags) {
         if (!SHOW_STARTING_ANIMATIONS) {
             return null;
         }
@@ -1174,8 +1175,12 @@
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
     
+            if (!compatInfo.supportsScreen()) {
+                win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
+            }
+
             win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
-                                WindowManager.LayoutParams.MATCH_PARENT);
+                    WindowManager.LayoutParams.MATCH_PARENT);
     
             final WindowManager.LayoutParams params = win.getAttributes();
             params.token = appToken;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index c03b994..fd502d8 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Locale;
 
+import org.apache.commons.logging.impl.SimpleLog;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 82e5e80..c2a8a1d 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -12398,6 +12398,15 @@
                     ac.updateConfiguration(mConfiguration);
                 }
 
+                // Make sure all resources in our process are updated
+                // right now, so that anyone who is going to retrieve
+                // resource values after we return will be sure to get
+                // the new ones.  This is especially important during
+                // boot, where the first config change needs to guarantee
+                // all resources have that config before following boot
+                // code is executed.
+                mSystemThread.applyConfigurationToResources(newConfig);
+
                 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
                     msg.obj = new Configuration(mConfiguration);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index f9be46f..2f9748b 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1455,6 +1455,8 @@
                     if (SHOW_APP_STARTING_PREVIEW && mMainStack) {
                         mService.mWindowManager.setAppStartingWindow(
                                 next, next.packageName, next.theme,
+                                mService.compatibilityInfoForPackageLocked(
+                                        next.info.applicationInfo),
                                 next.nonLocalizedLabel,
                                 next.labelRes, next.icon, next.windowFlags,
                                 null, true);
@@ -1491,6 +1493,8 @@
                 if (SHOW_APP_STARTING_PREVIEW) {
                     mService.mWindowManager.setAppStartingWindow(
                             next, next.packageName, next.theme,
+                            mService.compatibilityInfoForPackageLocked(
+                                    next.info.applicationInfo),
                             next.nonLocalizedLabel,
                             next.labelRes, next.icon, next.windowFlags,
                             null, true);
@@ -1615,7 +1619,9 @@
                     else if (prev.nowVisible) prev = null;
                 }
                 mService.mWindowManager.setAppStartingWindow(
-                        r, r.packageName, r.theme, r.nonLocalizedLabel,
+                        r, r.packageName, r.theme,
+                        mService.compatibilityInfoForPackageLocked(
+                                r.info.applicationInfo), r.nonLocalizedLabel,
                         r.labelRes, r.icon, r.windowFlags, prev, showStartingIcon);
             }
         } else {
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index 8949f48..1334bcd 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -150,9 +150,11 @@
     }
 
     public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
-        return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
+        CompatibilityInfo ci = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
                 mService.mConfiguration.smallestScreenWidthDp,
                 (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
+        //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
+        return ci;
     }
 
     public int computeCompatModeLocked(ApplicationInfo ai) {
diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java
index 625fcfe..46bb480 100644
--- a/services/java/com/android/server/wm/StartingData.java
+++ b/services/java/com/android/server/wm/StartingData.java
@@ -16,18 +16,23 @@
 
 package com.android.server.wm;
 
+import android.content.res.CompatibilityInfo;
+
 final class StartingData {
     final String pkg;
     final int theme;
+    final CompatibilityInfo compatInfo;
     final CharSequence nonLocalizedLabel;
     final int labelRes;
     final int icon;
     final int windowFlags;
 
-    StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
+    StartingData(String _pkg, int _theme, CompatibilityInfo _compatInfo,
+            CharSequence _nonLocalizedLabel,
             int _labelRes, int _icon, int _windowFlags) {
         pkg = _pkg;
         theme = _theme;
+        compatInfo = _compatInfo;
         nonLocalizedLabel = _nonLocalizedLabel;
         labelRes = _labelRes;
         icon = _icon;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 2aa53ec..080ba35 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -602,8 +602,7 @@
 
     final Configuration mTempConfiguration = new Configuration();
 
-    // The frame use to limit the size of the app running in compatibility mode.
-    Rect mCompatibleScreenFrame = new Rect();
+    // The desired scaling factor for compatible apps.
     float mCompatibleScreenScale;
 
     public static WindowManagerService main(Context context,
@@ -3526,7 +3525,8 @@
     }
 
     public void setAppStartingWindow(IBinder token, String pkg,
-            int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
+            int theme, CompatibilityInfo compatInfo,
+            CharSequence nonLocalizedLabel, int labelRes, int icon,
             int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppStartingIcon()")) {
@@ -3676,8 +3676,7 @@
             }
 
             mStartingIconInTransition = true;
-            wtoken.startingData = new StartingData(
-                    pkg, theme, nonLocalizedLabel,
+            wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                     labelRes, icon, windowFlags);
             Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
@@ -5566,8 +5565,7 @@
         dm.heightPixels = dm.unscaledHeightPixels = mAppDisplayHeight
                 = mPolicy.getNonDecorDisplayHeight(mRotation, dh);
 
-        mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame(
-                dm, mCompatibleScreenFrame, null);
+        mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, null);
 
         config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(mRotation, dw) / dm.density);
         config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(mRotation, dh) / dm.density);
@@ -6142,9 +6140,8 @@
                     View view = null;
                     try {
                         view = mPolicy.addStartingWindow(
-                            wtoken.token, sd.pkg,
-                            sd.theme, sd.nonLocalizedLabel, sd.labelRes,
-                            sd.icon, sd.windowFlags);
+                            wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
+                            sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
                     } catch (Exception e) {
                         Slog.w(TAG, "Exception when adding starting window", e);
                     }
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index e0f0f05..f015378 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -164,7 +164,7 @@
         }
         
         try {
-            mWm.setAppStartingWindow(null, "foo", 0, null, 0, 0, 0, null, false);
+            mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, null, false);
             fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {