OSDN Git Service

This restores JB MR0 behavior where the framework throws an exception for improper...
authorJim Miller <jaggies@google.com>
Wed, 17 Oct 2012 02:01:32 +0000 (19:01 -0700)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 17 Oct 2012 02:01:32 +0000 (19:01 -0700)
Revert "Revert "Revert "Fix for bug 6050753."""

This reverts commit 6868d6f349610c15256471cc3d5fa708cbfd5f1d

Change-Id: I8843d92dba14c82f06d9ee59517cf11b2abbbf04

api/current.txt
core/java/android/content/res/TypedArray.java
core/java/android/view/LayoutInflater.java
core/java/android/view/ViewGroup.java
core/java/android/widget/FrameLayout.java
core/java/android/widget/RadioGroup.java
core/java/android/widget/TableLayout.java
core/java/android/widget/TableRow.java

index ee9a973..b5aa2c1 100644 (file)
@@ -7094,7 +7094,7 @@ package android.content.res {
     method public int getIndexCount();
     method public int getInt(int, int);
     method public int getInteger(int, int);
-    method public deprecated int getLayoutDimension(int, java.lang.String);
+    method public int getLayoutDimension(int, java.lang.String);
     method public int getLayoutDimension(int, int);
     method public java.lang.String getNonResourceString(int);
     method public java.lang.String getPositionDescription();
@@ -16149,7 +16149,7 @@ package android.os {
 
   public class Looper {
     method public void dump(android.util.Printer, java.lang.String);
-    method public static android.os.Looper getMainLooper();
+    method public static synchronized android.os.Looper getMainLooper();
     method public java.lang.Thread getThread();
     method public static void loop();
     method public static android.os.Looper myLooper();
index 7f3b6b9..2968fbb 100644 (file)
@@ -469,20 +469,13 @@ public class TypedArray {
      * {@link android.view.ViewGroup}'s layout_width and layout_height
      * attributes.  This is only here for performance reasons; applications
      * should use {@link #getDimensionPixelSize}.
-     *
+     * 
      * @param index Index of the attribute to retrieve.
      * @param name Textual name of attribute for error reporting.
      * 
      * @return Attribute dimension value multiplied by the appropriate 
      * metric and truncated to integer pixels.
-     *
-     * @throws RuntimeException
-     *             if this TypedArray does not contain an entry for <code>index</code>
-     *
-     * @deprecated Use {@link #getLayoutDimension(int, int)} instead.
-     *
      */
-    @Deprecated
     public int getLayoutDimension(int index, String name) {
         index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
index f692e05..26a5b26 100644 (file)
@@ -20,7 +20,6 @@ import android.graphics.Canvas;
 import android.os.Handler;
 import android.os.Message;
 import android.widget.FrameLayout;
-import com.android.internal.R;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -44,20 +43,20 @@ import java.util.HashMap;
  *
  * <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService
  *      (Context.LAYOUT_INFLATER_SERVICE);</pre>
- *
+ * 
  * <p>
  * To create a new LayoutInflater with an additional {@link Factory} for your
  * own views, you can use {@link #cloneInContext} to clone an existing
  * ViewFactory, and then call {@link #setFactory} on it to include your
  * Factory.
- *
+ * 
  * <p>
  * For performance reasons, view inflation relies heavily on pre-processing of
  * XML files that is done at build time. Therefore, it is not currently possible
  * to use LayoutInflater with an XmlPullParser over a plain XML file at runtime;
  * it only works with an XmlPullParser returned from a compiled resource
  * (R.<em>something</em> file.)
- *
+ * 
  * @see Context#getSystemService
  */
 public abstract class LayoutInflater {
@@ -83,7 +82,7 @@ public abstract class LayoutInflater {
 
     private static final HashMap<String, Constructor<? extends View>> sConstructorMap =
             new HashMap<String, Constructor<? extends View>>();
-
+    
     private HashMap<String, Boolean> mFilterMap;
 
     private static final String TAG_MERGE = "merge";
@@ -94,36 +93,36 @@ public abstract class LayoutInflater {
     /**
      * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
      * to be inflated.
-     *
+     * 
      */
     public interface Filter {
         /**
          * Hook to allow clients of the LayoutInflater to restrict the set of Views 
          * that are allowed to be inflated.
-         *
+         * 
          * @param clazz The class object for the View that is about to be inflated
-         *
+         * 
          * @return True if this class is allowed to be inflated, or false otherwise
          */
         @SuppressWarnings("unchecked")
         boolean onLoadClass(Class clazz);
     }
-
+    
     public interface Factory {
         /**
          * Hook you can supply that is called when inflating from a LayoutInflater.
          * You can use this to customize the tag names available in your XML
          * layout files.
-         *
+         * 
          * <p>
          * Note that it is good practice to prefix these custom names with your
          * package (i.e., com.coolcompany.apps) to avoid conflicts with system
          * names.
-         *
+         * 
          * @param name Tag name to be inflated.
          * @param context The context the view is being created in.
          * @param attrs Inflation attributes as specified in XML file.
-         *
+         * 
          * @return View Newly created view. Return null for the default
          *         behavior.
          */
@@ -151,14 +150,14 @@ public abstract class LayoutInflater {
     private static class FactoryMerger implements Factory2 {
         private final Factory mF1, mF2;
         private final Factory2 mF12, mF22;
-
+        
         FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) {
             mF1 = f1;
             mF2 = f2;
             mF12 = f12;
             mF22 = f22;
         }
-
+        
         public View onCreateView(String name, Context context, AttributeSet attrs) {
             View v = mF1.onCreateView(name, context, attrs);
             if (v != null) return v;
@@ -173,13 +172,13 @@ public abstract class LayoutInflater {
                     : mF2.onCreateView(name, context, attrs);
         }
     }
-
+    
     /**
      * Create a new LayoutInflater instance associated with a particular Context.
      * Applications will almost always want to use
      * {@link Context#getSystemService Context.getSystemService()} to retrieve
      * the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}.
-     *
+     * 
      * @param context The Context in which this LayoutInflater will create its
      * Views; most importantly, this supplies the theme from which the default
      * values for their attributes are retrieved.
@@ -192,7 +191,7 @@ public abstract class LayoutInflater {
      * Create a new LayoutInflater instance that is a copy of an existing
      * LayoutInflater, optionally with its Context changed.  For use in
      * implementing {@link #cloneInContext}.
-     *
+     * 
      * @param original The original LayoutInflater to copy.
      * @param newContext The new Context to use.
      */
@@ -203,7 +202,7 @@ public abstract class LayoutInflater {
         mPrivateFactory = original.mPrivateFactory;
         mFilter = original.mFilter;
     }
-
+    
     /**
      * Obtains the LayoutInflater from the given context.
      */
@@ -221,15 +220,15 @@ public abstract class LayoutInflater {
      * pointing to a different Context than the original.  This is used by
      * {@link ContextThemeWrapper} to create a new LayoutInflater to go along
      * with the new Context theme.
-     *
+     * 
      * @param newContext The new Context to associate with the new LayoutInflater.
      * May be the same as the original Context if desired.
-     *
+     * 
      * @return Returns a brand spanking new LayoutInflater object associated with
      * the given Context.
      */
     public abstract LayoutInflater cloneInContext(Context newContext);
-
+    
     /**
      * Return the context we are running in, for access to resources, class
      * loader, etc.
@@ -265,7 +264,7 @@ public abstract class LayoutInflater {
      * called on each element name as the xml is parsed. If the factory returns
      * a View, that is added to the hierarchy. If it returns null, the next
      * factory default {@link #onCreateView} method is called.
-     *
+     * 
      * <p>If you have an existing
      * LayoutInflater and want to add your own factory to it, use
      * {@link #cloneInContext} to clone the existing instance and then you
@@ -321,13 +320,13 @@ public abstract class LayoutInflater {
     public Filter getFilter() {
         return mFilter;
     }
-
+    
     /**
      * Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated
      * which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will
      * throw an {@link InflateException}. This filter will replace any previous filter set on this
      * LayoutInflater.
-     *
+     * 
      * @param filter The Filter which restricts the set of Views that are allowed to be inflated.
      *        This filter will replace any previous filter set on this LayoutInflater.
      */
@@ -341,7 +340,7 @@ public abstract class LayoutInflater {
     /**
      * Inflate a new view hierarchy from the specified xml resource. Throws
      * {@link InflateException} if there is an error.
-     *
+     * 
      * @param resource ID for an XML layout resource to load (e.g.,
      *        <code>R.layout.main_page</code>)
      * @param root Optional view to be the parent of the generated hierarchy.
@@ -361,7 +360,7 @@ public abstract class LayoutInflater {
      * reasons, view inflation relies heavily on pre-processing of XML files
      * that is done at build time. Therefore, it is not currently possible to
      * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
-     *
+     * 
      * @param parser XML dom node containing the description of the view
      *        hierarchy.
      * @param root Optional view to be the parent of the generated hierarchy.
@@ -376,7 +375,7 @@ public abstract class LayoutInflater {
     /**
      * Inflate a new view hierarchy from the specified xml resource. Throws
      * {@link InflateException} if there is an error.
-     *
+     * 
      * @param resource ID for an XML layout resource to load (e.g.,
      *        <code>R.layout.main_page</code>)
      * @param root Optional view to be the parent of the generated hierarchy (if
@@ -408,7 +407,7 @@ public abstract class LayoutInflater {
      * reasons, view inflation relies heavily on pre-processing of XML files
      * that is done at build time. Therefore, it is not currently possible to
      * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
-     *
+     * 
      * @param parser XML dom node containing the description of the view
      *        hierarchy.
      * @param root Optional view to be the parent of the generated hierarchy (if
@@ -443,7 +442,7 @@ public abstract class LayoutInflater {
                 }
 
                 final String name = parser.getName();
-
+                
                 if (DEBUG) {
                     System.out.println("**************************");
                     System.out.println("Creating root view: "
@@ -529,17 +528,17 @@ public abstract class LayoutInflater {
      * Low-level function for instantiating a view by name. This attempts to
      * instantiate a view class of the given <var>name</var> found in this
      * LayoutInflater's ClassLoader.
-     *
+     * 
      * <p>
      * There are two things that can happen in an error case: either the
      * exception describing the error will be thrown, or a null will be
      * returned. You must deal with both possibilities -- the former will happen
      * the first time createView() is called for a class of a particular name,
      * the latter every time there-after for that class name.
-     *
+     * 
      * @param name The full name of the class to be instantiated.
      * @param attrs The XML attributes supplied for this instance.
-     *
+     * 
      * @return View The newly instantiated view, or null.
      */
     public final View createView(String name, String prefix, AttributeSet attrs)
@@ -552,7 +551,7 @@ public abstract class LayoutInflater {
                 // Class not found in the cache, see if it's real, and try to add it
                 clazz = mContext.getClassLoader().loadClass(
                         prefix != null ? (prefix + name) : name).asSubclass(View.class);
-
+                
                 if (mFilter != null && clazz != null) {
                     boolean allowed = mFilter.onLoadClass(clazz);
                     if (!allowed) {
@@ -570,7 +569,7 @@ public abstract class LayoutInflater {
                         // New class -- remember whether it is allowed
                         clazz = mContext.getClassLoader().loadClass(
                                 prefix != null ? (prefix + name) : name).asSubclass(View.class);
-
+                        
                         boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
                         mFilterMap.put(name, allowed);
                         if (!allowed) {
@@ -633,10 +632,10 @@ public abstract class LayoutInflater {
      * given the xml element name. Override it to handle custom view objects. If
      * you override this in your subclass be sure to call through to
      * super.onCreateView(name) for names you do not recognize.
-     *
+     * 
      * @param name The fully qualified class name of the View to be create.
      * @param attrs An AttributeSet of attributes to apply to the View.
-     *
+     * 
      * @return View The View created.
      */
     protected View onCreateView(String name, AttributeSet attrs)
@@ -680,7 +679,7 @@ public abstract class LayoutInflater {
             if (view == null && mPrivateFactory != null) {
                 view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
             }
-
+            
             if (view == null) {
                 if (-1 == name.indexOf('.')) {
                     view = onCreateView(parent, name, attrs);
@@ -727,7 +726,7 @@ public abstract class LayoutInflater {
             }
 
             final String name = parser.getName();
-
+            
             if (TAG_REQUEST_FOCUS.equals(name)) {
                 parseRequestFocus(parser, parent);
             } else if (TAG_INCLUDE.equals(name)) {
@@ -742,7 +741,7 @@ public abstract class LayoutInflater {
                 final ViewGroup viewGroup = (ViewGroup) parent;
                 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
                 rInflate(parser, view, attrs, true);
-                viewGroup.addView(view, params);
+                viewGroup.addView(view, params);                
             } else {
                 final View view = createViewFromTag(parent, name, attrs);
                 final ViewGroup viewGroup = (ViewGroup) parent;
@@ -811,14 +810,21 @@ public abstract class LayoutInflater {
                         // We try to load the layout params set in the <include /> tag. If
                         // they don't exist, we will rely on the layout params set in the
                         // included XML file.
-                        TypedArray ta = getContext().obtainStyledAttributes(attrs,
-                                                            R.styleable.ViewGroup_Layout);
-                        boolean definesBothWidthAndHeight =
-                                ta.hasValue(R.styleable.ViewGroup_Layout_layout_width) &&
-                                ta.hasValue(R.styleable.ViewGroup_Layout_layout_height);
-                        AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs;
-                        view.setLayoutParams(group.generateLayoutParams(attributes));
-                        ta.recycle();
+                        // During a layoutparams generation, a runtime exception is thrown
+                        // if either layout_width or layout_height is missing. We catch
+                        // this exception and set localParams accordingly: true means we
+                        // successfully loaded layout params from the <include /> tag,
+                        // false means we need to rely on the included layout params.
+                        ViewGroup.LayoutParams params = null;
+                        try {
+                            params = group.generateLayoutParams(attrs);
+                        } catch (RuntimeException e) {
+                            params = group.generateLayoutParams(childAttrs);
+                        } finally {
+                            if (params != null) {
+                                view.setLayoutParams(params);
+                            }
+                        }
 
                         // Inflate all children.
                         rInflate(childParser, view, childAttrs, true);
index 9ce7df9..6c1049b 100644 (file)
@@ -5611,19 +5611,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
         }
 
         /**
-         * Extracts the <code>width</code> and <code>height</code> layout parameters
-         * from the supplied TypedArray, <code>a</code>, and assigns them
-         * to the appropriate fields. If, <code>a</code>, does not contain an
-         * entry for either attribute, the value, {@link ViewGroup.LayoutParams#WRAP_CONTENT},
-         * is used as a default.
+         * Extracts the layout parameters from the supplied attributes.
          *
          * @param a the style attributes to extract the parameters from
          * @param widthAttr the identifier of the width attribute
          * @param heightAttr the identifier of the height attribute
          */
         protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
-            width = a.getLayoutDimension(widthAttr, WRAP_CONTENT);
-            height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
+            width = a.getLayoutDimension(widthAttr, "layout_width");
+            height = a.getLayoutDimension(heightAttr, "layout_height");
         }
 
         /**
index 45f30df..e158776 100644 (file)
@@ -608,12 +608,6 @@ public class FrameLayout extends ViewGroup {
          */
         public int gravity = -1;
 
-        @Override
-        protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
-            width = a.getLayoutDimension(widthAttr, MATCH_PARENT);
-            height = a.getLayoutDimension(heightAttr, MATCH_PARENT);
-        }
-
         /**
          * {@inheritDoc}
          */
index 42d63b2..78d05b0 100644 (file)
@@ -297,6 +297,33 @@ public class RadioGroup extends LinearLayout {
         public LayoutParams(MarginLayoutParams source) {
             super(source);
         }
+
+        /**
+         * <p>Fixes the child's width to
+         * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the child's
+         * height to  {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+         * when not specified in the XML file.</p>
+         *
+         * @param a the styled attributes set
+         * @param widthAttr the width attribute to fetch
+         * @param heightAttr the height attribute to fetch
+         */
+        @Override
+        protected void setBaseAttributes(TypedArray a,
+                int widthAttr, int heightAttr) {
+
+            if (a.hasValue(widthAttr)) {
+                width = a.getLayoutDimension(widthAttr, "layout_width");
+            } else {
+                width = WRAP_CONTENT;
+            }
+            
+            if (a.hasValue(heightAttr)) {
+                height = a.getLayoutDimension(heightAttr, "layout_height");
+            } else {
+                height = WRAP_CONTENT;
+            }
+        }
     }
 
     /**
index 113299a..399b4fa 100644 (file)
@@ -741,9 +741,14 @@ public class TableLayout extends LinearLayout {
          * @param heightAttr the height attribute to fetch
          */
         @Override
-        protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
+        protected void setBaseAttributes(TypedArray a,
+                int widthAttr, int heightAttr) {
             this.width = MATCH_PARENT;
-            this.height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
+            if (a.hasValue(heightAttr)) {
+                this.height = a.getLayoutDimension(heightAttr, "layout_height");
+            } else {
+                this.height = WRAP_CONTENT;
+            }
         }
     }
 
index 3f8f9da..68ffd73 100644 (file)
@@ -505,8 +505,19 @@ public class TableRow extends LinearLayout {
 
         @Override
         protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
-            width = a.getLayoutDimension(widthAttr, MATCH_PARENT);
-            height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
+            // We don't want to force users to specify a layout_width
+            if (a.hasValue(widthAttr)) {
+                width = a.getLayoutDimension(widthAttr, "layout_width");
+            } else {
+                width = MATCH_PARENT;
+            }
+
+            // We don't want to force users to specify a layout_height
+            if (a.hasValue(heightAttr)) {
+                height = a.getLayoutDimension(heightAttr, "layout_height");
+            } else {
+                height = WRAP_CONTENT;
+            }
         }
     }