Add attribute for specifying initial ScaleDrawable level

Bug: 19182305
Change-Id: Ic1f183db6183017352babc6dc190fdb9124c285a
diff --git a/api/current.txt b/api/current.txt
index 00b5ec0..a951656 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -779,6 +779,7 @@
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
+    field public static final int level = 16844031; // 0x10104ff
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
diff --git a/api/system-current.txt b/api/system-current.txt
index b2803b7..e2a6dcb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -871,6 +871,7 @@
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
+    field public static final int level = 16844031; // 0x10104ff
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 902d40d..dc96df4 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5550,6 +5550,8 @@
             <!-- Push object to the end of its container, not changing its size. -->
             <flag name="end" value="0x00800005" />
         </attr>
+        <!-- Specifies the initial drawable level in the range 0 to 10000. -->
+        <attr name="level" format="integer" />
         <!-- Reference to a drawable resource to draw with the specified scale. -->
         <attr name="drawable" />
         <!-- Use the drawable's intrinsic width and height as minimum size values.
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b6284c9..89d9bab 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2673,6 +2673,7 @@
     <public type="attr" name="maxButtonHeight" />
     <public type="attr" name="buttonGravity" />
     <public type="attr" name="collapseIcon" />
+    <public type="attr" name="level" />
 
     <public type="style" name="Theme.Material.DayNight" />
     <public type="style" name="Theme.Material.DayNight.DarkActionBar" />
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 0acbeda..f9206b7 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -35,19 +35,29 @@
 
 /**
  * A Drawable that changes the size of another Drawable based on its current
- * level value.  You can control how much the child Drawable changes in width
+ * level value. You can control how much the child Drawable changes in width
  * and height based on the level, as well as a gravity to control where it is
- * placed in its overall container.  Most often used to implement things like
+ * placed in its overall container. Most often used to implement things like
  * progress bars.
- *
- * <p>It can be defined in an XML file with the <code>&lt;scale></code> element. For more
- * information, see the guide to <a
- * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
+ * <p>
+ * The default level may be specified from XML using the
+ * {@link android.R.styleable#ScaleDrawable_level android:level} property. When
+ * this property is not specified, the default level is 0, which corresponds to
+ * zero height and/or width depending on the values specified for
+ * {@code android.R.styleable#ScaleDrawable_scaleWidth scaleWidth} and
+ * {@code android.R.styleable#ScaleDrawable_scaleHeight scaleHeight}. At run
+ * time, the level may be set via {@link #setLevel(int)}.
+ * <p>
+ * A scale drawable may be defined in an XML file with the {@code &lt;scale>}
+ * element. For more information, see the guide to
+ * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable
+ * Resources</a>.
  *
  * @attr ref android.R.styleable#ScaleDrawable_scaleWidth
  * @attr ref android.R.styleable#ScaleDrawable_scaleHeight
  * @attr ref android.R.styleable#ScaleDrawable_scaleGravity
  * @attr ref android.R.styleable#ScaleDrawable_drawable
+ * @attr ref android.R.styleable#ScaleDrawable_level
  */
 public class ScaleDrawable extends DrawableWrapper {
     private static final int MAX_LEVEL = 10000;
@@ -92,6 +102,8 @@
         inflateChildDrawable(r, parser, attrs, theme);
         verifyRequiredAttributes(a);
         a.recycle();
+
+        updateLocalState();
     }
 
     private void verifyRequiredAttributes(TypedArray a) throws XmlPullParserException {
@@ -117,6 +129,8 @@
                 R.styleable.ScaleDrawable_scaleGravity, state.mGravity);
         state.mUseIntrinsicSizeAsMin = a.getBoolean(
                 R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, state.mUseIntrinsicSizeAsMin);
+        state.mInitialLevel = a.getInt(
+                R.styleable.ScaleDrawable_level, state.mInitialLevel);
 
         final Drawable dr = a.getDrawable(R.styleable.ScaleDrawable_drawable);
         if (dr != null) {
@@ -165,6 +179,8 @@
         // The drawable may have changed as a result of applying the theme, so
         // apply the theme to the wrapped drawable last.
         super.applyTheme(t);
+
+        updateLocalState();
     }
 
     @Override
@@ -239,6 +255,7 @@
         float mScaleHeight = DO_NOT_SCALE;
         int mGravity = Gravity.LEFT;
         boolean mUseIntrinsicSizeAsMin = false;
+        int mInitialLevel = 0;
 
         ScaleState(ScaleState orig) {
             super(orig);
@@ -248,6 +265,7 @@
                 mScaleHeight = orig.mScaleHeight;
                 mGravity = orig.mGravity;
                 mUseIntrinsicSizeAsMin = orig.mUseIntrinsicSizeAsMin;
+                mInitialLevel = orig.mInitialLevel;
             }
         }
 
@@ -257,10 +275,23 @@
         }
     }
 
+    /**
+     * Creates a new ScaleDrawable based on the specified constant state.
+     * <p>
+     * The resulting drawable is guaranteed to have a new constant state.
+     *
+     * @param state constant state from which the drawable inherits
+     */
     private ScaleDrawable(ScaleState state, Resources res) {
         super(state, res);
 
         mState = state;
+
+        updateLocalState();
+    }
+
+    private void updateLocalState() {
+        setLevel(mState.mInitialLevel);
     }
 }