Drawable.java revision bd5afc71864181c549bf3c620eedf8fc8c0cd531
165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2006 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.graphics.drawable;
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.annotation.NonNull;
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.content.res.ColorStateList;
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.content.res.Resources;
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.content.res.Resources.Theme;
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.content.res.TypedArray;
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Bitmap;
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.BitmapFactory;
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Canvas;
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Color;
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.ColorFilter;
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Insets;
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.NinePatch;
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Outline;
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.PixelFormat;
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.PorterDuff;
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.PorterDuff.Mode;
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.PorterDuffColorFilter;
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Rect;
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Region;
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.graphics.Xfermode;
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.os.Trace;
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.AttributeSet;
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.DisplayMetrics;
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.StateSet;
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.TypedValue;
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.Xml;
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.view.View;
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport org.xmlpull.v1.XmlPullParser;
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport org.xmlpull.v1.XmlPullParserException;
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.IOException;
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.InputStream;
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.ref.WeakReference;
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Arrays;
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * A Drawable is a general abstraction for "something that can be drawn."  Most
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * often you will deal with Drawable as the type of resource retrieved for
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * drawing things to the screen; the Drawable class provides a generic API for
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * dealing with an underlying visual resource that may take a variety of forms.
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unlike a {@link android.view.View}, a Drawable does not have any facility to
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * receive events or otherwise interact with the user.
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * <p>In addition to simple drawing, Drawable provides a number of generic
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * mechanisms for its client to interact with what is being drawn:
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * <ul>
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     <li> The {@link #setBounds} method <var>must</var> be called to tell the
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     Drawable where it is drawn and how large it should be.  All Drawables
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     should respect the requested size, often simply by scaling their
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     imagery.  A client can find the preferred size for some Drawables with
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     the {@link #getIntrinsicHeight} and {@link #getIntrinsicWidth} methods.
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     <li> The {@link #getPadding} method can return from some Drawables
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     information about how to frame content that is placed inside of them.
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     For example, a Drawable that is intended to be the frame for a button
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     widget would need to return padding that correctly places the label
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     inside of itself.
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     <li> The {@link #setState} method allows the client to tell the Drawable
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     in which state it is to be drawn, such as "focused", "selected", etc.
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     Some drawables may modify their imagery based on the selected state.
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     <li> The {@link #setLevel} method allows the client to supply a single
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     continuous controller that can modify the Drawable is displayed, such as
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *     a battery level or progress level.  Some drawables may modify their
86 *     imagery based on the current level.
87 *
88 *     <li> A Drawable can perform animations by calling back to its client
89 *     through the {@link Callback} interface.  All clients should support this
90 *     interface (via {@link #setCallback}) so that animations will work.  A
91 *     simple way to do this is through the system facilities such as
92 *     {@link android.view.View#setBackground(Drawable)} and
93 *     {@link android.widget.ImageView}.
94 * </ul>
95 *
96 * Though usually not visible to the application, Drawables may take a variety
97 * of forms:
98 *
99 * <ul>
100 *     <li> <b>Bitmap</b>: the simplest Drawable, a PNG or JPEG image.
101 *     <li> <b>Nine Patch</b>: an extension to the PNG format allows it to
102 *     specify information about how to stretch it and place things inside of
103 *     it.
104 *     <li> <b>Shape</b>: contains simple drawing commands instead of a raw
105 *     bitmap, allowing it to resize better in some cases.
106 *     <li> <b>Layers</b>: a compound drawable, which draws multiple underlying
107 *     drawables on top of each other.
108 *     <li> <b>States</b>: a compound drawable that selects one of a set of
109 *     drawables based on its state.
110 *     <li> <b>Levels</b>: a compound drawable that selects one of a set of
111 *     drawables based on its level.
112 *     <li> <b>Scale</b>: a compound drawable with a single child drawable,
113 *     whose overall size is modified based on the current level.
114 * </ul>
115 *
116 * <div class="special reference">
117 * <h3>Developer Guides</h3>
118 * <p>For more information about how to use drawables, read the
119 * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and Drawables</a> developer
120 * guide. For information and examples of creating drawable resources (XML or bitmap files that
121 * can be loaded in code), read the
122 * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>
123 * document.</p></div>
124 */
125public abstract class Drawable {
126    private static final Rect ZERO_BOUNDS_RECT = new Rect();
127
128    private int[] mStateSet = StateSet.WILD_CARD;
129    private int mLevel = 0;
130    private int mChangingConfigurations = 0;
131    private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
132    private WeakReference<Callback> mCallback = null;
133    private boolean mVisible = true;
134
135    private int mLayoutDirection;
136
137    /**
138     * Draw in its bounds (set via setBounds) respecting optional effects such
139     * as alpha (set via setAlpha) and color filter (set via setColorFilter).
140     *
141     * @param canvas The canvas to draw into
142     */
143    public abstract void draw(Canvas canvas);
144
145    /**
146     * Specify a bounding rectangle for the Drawable. This is where the drawable
147     * will draw when its draw() method is called.
148     */
149    public void setBounds(int left, int top, int right, int bottom) {
150        Rect oldBounds = mBounds;
151
152        if (oldBounds == ZERO_BOUNDS_RECT) {
153            oldBounds = mBounds = new Rect();
154        }
155
156        if (oldBounds.left != left || oldBounds.top != top ||
157                oldBounds.right != right || oldBounds.bottom != bottom) {
158            if (!oldBounds.isEmpty()) {
159                // first invalidate the previous bounds
160                invalidateSelf();
161            }
162            mBounds.set(left, top, right, bottom);
163            onBoundsChange(mBounds);
164        }
165    }
166
167    /**
168     * Specify a bounding rectangle for the Drawable. This is where the drawable
169     * will draw when its draw() method is called.
170     */
171    public void setBounds(Rect bounds) {
172        setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
173    }
174
175    /**
176     * Return a copy of the drawable's bounds in the specified Rect (allocated
177     * by the caller). The bounds specify where this will draw when its draw()
178     * method is called.
179     *
180     * @param bounds Rect to receive the drawable's bounds (allocated by the
181     *               caller).
182     */
183    public final void copyBounds(Rect bounds) {
184        bounds.set(mBounds);
185    }
186
187    /**
188     * Return a copy of the drawable's bounds in a new Rect. This returns the
189     * same values as getBounds(), but the returned object is guaranteed to not
190     * be changed later by the drawable (i.e. it retains no reference to this
191     * rect). If the caller already has a Rect allocated, call copyBounds(rect).
192     *
193     * @return A copy of the drawable's bounds
194     */
195    public final Rect copyBounds() {
196        return new Rect(mBounds);
197    }
198
199    /**
200     * Return the drawable's bounds Rect. Note: for efficiency, the returned
201     * object may be the same object stored in the drawable (though this is not
202     * guaranteed), so if a persistent copy of the bounds is needed, call
203     * copyBounds(rect) instead.
204     * You should also not change the object returned by this method as it may
205     * be the same object stored in the drawable.
206     *
207     * @return The bounds of the drawable (which may change later, so caller
208     *         beware). DO NOT ALTER the returned object as it may change the
209     *         stored bounds of this drawable.
210     *
211     * @see #copyBounds()
212     * @see #copyBounds(android.graphics.Rect)
213     */
214    public final Rect getBounds() {
215        if (mBounds == ZERO_BOUNDS_RECT) {
216            mBounds = new Rect();
217        }
218
219        return mBounds;
220    }
221
222    /**
223     * Return the drawable's dirty bounds Rect. Note: for efficiency, the
224     * returned object may be the same object stored in the drawable (though
225     * this is not guaranteed).
226     * <p>
227     * By default, this returns the full drawable bounds. Custom drawables may
228     * override this method to perform more precise invalidation.
229     *
230     * @return The dirty bounds of this drawable
231     */
232    public Rect getDirtyBounds() {
233        return getBounds();
234    }
235
236    /**
237     * Set a mask of the configuration parameters for which this drawable
238     * may change, requiring that it be re-created.
239     *
240     * @param configs A mask of the changing configuration parameters, as
241     * defined by {@link android.content.pm.ActivityInfo}.
242     *
243     * @see android.content.pm.ActivityInfo
244     */
245    public void setChangingConfigurations(int configs) {
246        mChangingConfigurations = configs;
247    }
248
249    /**
250     * Return a mask of the configuration parameters for which this drawable
251     * may change, requiring that it be re-created.  The default implementation
252     * returns whatever was provided through
253     * {@link #setChangingConfigurations(int)} or 0 by default.  Subclasses
254     * may extend this to or in the changing configurations of any other
255     * drawables they hold.
256     *
257     * @return Returns a mask of the changing configuration parameters, as
258     * defined by {@link android.content.pm.ActivityInfo}.
259     *
260     * @see android.content.pm.ActivityInfo
261     */
262    public int getChangingConfigurations() {
263        return mChangingConfigurations;
264    }
265
266    /**
267     * Set to true to have the drawable dither its colors when drawn to a device
268     * with fewer than 8-bits per color component. This can improve the look on
269     * those devices, but can also slow down the drawing a little.
270     */
271    public void setDither(boolean dither) {}
272
273    /**
274     * Set to true to have the drawable filter its bitmap when scaled or rotated
275     * (for drawables that use bitmaps). If the drawable does not use bitmaps,
276     * this call is ignored. This can improve the look when scaled or rotated,
277     * but also slows down the drawing.
278     */
279    public void setFilterBitmap(boolean filter) {}
280
281    /**
282     * Implement this interface if you want to create an animated drawable that
283     * extends {@link android.graphics.drawable.Drawable Drawable}.
284     * Upon retrieving a drawable, use
285     * {@link Drawable#setCallback(android.graphics.drawable.Drawable.Callback)}
286     * to supply your implementation of the interface to the drawable; it uses
287     * this interface to schedule and execute animation changes.
288     */
289    public static interface Callback {
290        /**
291         * Called when the drawable needs to be redrawn.  A view at this point
292         * should invalidate itself (or at least the part of itself where the
293         * drawable appears).
294         *
295         * @param who The drawable that is requesting the update.
296         */
297        public void invalidateDrawable(Drawable who);
298
299        /**
300         * A Drawable can call this to schedule the next frame of its
301         * animation.  An implementation can generally simply call
302         * {@link android.os.Handler#postAtTime(Runnable, Object, long)} with
303         * the parameters <var>(what, who, when)</var> to perform the
304         * scheduling.
305         *
306         * @param who The drawable being scheduled.
307         * @param what The action to execute.
308         * @param when The time (in milliseconds) to run.  The timebase is
309         *             {@link android.os.SystemClock#uptimeMillis}
310         */
311        public void scheduleDrawable(Drawable who, Runnable what, long when);
312
313        /**
314         * A Drawable can call this to unschedule an action previously
315         * scheduled with {@link #scheduleDrawable}.  An implementation can
316         * generally simply call
317         * {@link android.os.Handler#removeCallbacks(Runnable, Object)} with
318         * the parameters <var>(what, who)</var> to unschedule the drawable.
319         *
320         * @param who The drawable being unscheduled.
321         * @param what The action being unscheduled.
322         */
323        public void unscheduleDrawable(Drawable who, Runnable what);
324    }
325
326    /**
327     * Bind a {@link Callback} object to this Drawable.  Required for clients
328     * that want to support animated drawables.
329     *
330     * @param cb The client's Callback implementation.
331     *
332     * @see #getCallback()
333     */
334    public final void setCallback(Callback cb) {
335        mCallback = new WeakReference<Callback>(cb);
336    }
337
338    /**
339     * Return the current {@link Callback} implementation attached to this
340     * Drawable.
341     *
342     * @return A {@link Callback} instance or null if no callback was set.
343     *
344     * @see #setCallback(android.graphics.drawable.Drawable.Callback)
345     */
346    public Callback getCallback() {
347        if (mCallback != null) {
348            return mCallback.get();
349        }
350        return null;
351    }
352
353    /**
354     * Use the current {@link Callback} implementation to have this Drawable
355     * redrawn.  Does nothing if there is no Callback attached to the
356     * Drawable.
357     *
358     * @see Callback#invalidateDrawable
359     * @see #getCallback()
360     * @see #setCallback(android.graphics.drawable.Drawable.Callback)
361     */
362    public void invalidateSelf() {
363        final Callback callback = getCallback();
364        if (callback != null) {
365            callback.invalidateDrawable(this);
366        }
367    }
368
369    /**
370     * Use the current {@link Callback} implementation to have this Drawable
371     * scheduled.  Does nothing if there is no Callback attached to the
372     * Drawable.
373     *
374     * @param what The action being scheduled.
375     * @param when The time (in milliseconds) to run.
376     *
377     * @see Callback#scheduleDrawable
378     */
379    public void scheduleSelf(Runnable what, long when) {
380        final Callback callback = getCallback();
381        if (callback != null) {
382            callback.scheduleDrawable(this, what, when);
383        }
384    }
385
386    /**
387     * Use the current {@link Callback} implementation to have this Drawable
388     * unscheduled.  Does nothing if there is no Callback attached to the
389     * Drawable.
390     *
391     * @param what The runnable that you no longer want called.
392     *
393     * @see Callback#unscheduleDrawable
394     */
395    public void unscheduleSelf(Runnable what) {
396        final Callback callback = getCallback();
397        if (callback != null) {
398            callback.unscheduleDrawable(this, what);
399        }
400    }
401
402    /**
403     * Returns the resolved layout direction for this Drawable.
404     *
405     * @return One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
406     *   {@link android.view.View#LAYOUT_DIRECTION_RTL}
407     *
408     * @hide
409     */
410    public int getLayoutDirection() {
411        return mLayoutDirection;
412    }
413
414    /**
415     * Set the layout direction for this drawable. Should be a resolved direction as the
416     * Drawable as no capacity to do the resolution on his own.
417     *
418     * @param layoutDirection One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
419     *   {@link android.view.View#LAYOUT_DIRECTION_RTL}
420     *
421     * @hide
422     */
423    public void setLayoutDirection(@View.ResolvedLayoutDir int layoutDirection) {
424        if (getLayoutDirection() != layoutDirection) {
425            mLayoutDirection = layoutDirection;
426        }
427    }
428
429    /**
430     * Specify an alpha value for the drawable. 0 means fully transparent, and
431     * 255 means fully opaque.
432     */
433    public abstract void setAlpha(int alpha);
434
435    /**
436     * Gets the current alpha value for the drawable. 0 means fully transparent,
437     * 255 means fully opaque. This method is implemented by
438     * Drawable subclasses and the value returned is specific to how that class treats alpha.
439     * The default return value is 255 if the class does not override this method to return a value
440     * specific to its use of alpha.
441     */
442    public int getAlpha() {
443        return 0xFF;
444    }
445
446    /**
447     * @hide Consider for future API inclusion
448     */
449    public void setXfermode(Xfermode mode) {
450        // Base implementation drops it on the floor for compatibility. Whee!
451        // TODO: For this to be included in the API proper, all framework drawables need impls.
452        // For right now only BitmapDrawable has it.
453    }
454
455    /**
456     * Specify an optional color filter for the drawable. Pass {@code null} to
457     * remove any existing color filter.
458     *
459     * @param cf the color filter to apply, or {@code null} to remove the
460     *            existing color filter
461     */
462    public abstract void setColorFilter(ColorFilter cf);
463
464    /**
465     * Specify a color and Porter-Duff mode to be the color filter for this
466     * drawable.
467     */
468    public void setColorFilter(int color, PorterDuff.Mode mode) {
469        setColorFilter(new PorterDuffColorFilter(color, mode));
470    }
471
472    /**
473     * Specifies a tint for this drawable.
474     * <p>
475     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
476     * tint.
477     *
478     * @param tint Color to use for tinting this drawable
479     * @see #setTintMode(PorterDuff.Mode)
480     */
481    public void setTint(int tint) {
482        setTintList(ColorStateList.valueOf(tint));
483    }
484
485    /**
486     * Specifies a tint for this drawable as a color state list.
487     * <p>
488     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
489     * tint.
490     *
491     * @param tint Color state list to use for tinting this drawable, or null to
492     *            clear the tint
493     * @see #setTintMode(PorterDuff.Mode)
494     */
495    public void setTintList(ColorStateList tint) {}
496
497    /**
498     * Specifies a tint blending mode for this drawable.
499     * <p>
500     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
501     * tint.
502     *
503     * @param tintMode Color state list to use for tinting this drawable, or null to
504     *            clear the tint
505     * @param tintMode A Porter-Duff blending mode
506     */
507    public void setTintMode(PorterDuff.Mode tintMode) {}
508
509    /**
510     * Returns the current color filter, or {@code null} if none set.
511     *
512     * @return the current color filter, or {@code null} if none set
513     */
514    public ColorFilter getColorFilter() {
515        return null;
516    }
517
518    /**
519     * Removes the color filter for this drawable.
520     */
521    public void clearColorFilter() {
522        setColorFilter(null);
523    }
524
525    /**
526     * Specifies the hotspot's location within the drawable.
527     *
528     * @param x The X coordinate of the center of the hotspot
529     * @param y The Y coordinate of the center of the hotspot
530     */
531    public void setHotspot(float x, float y) {}
532
533    /**
534     * Sets the bounds to which the hotspot is constrained, if they should be
535     * different from the drawable bounds.
536     *
537     * @param left
538     * @param top
539     * @param right
540     * @param bottom
541     */
542    public void setHotspotBounds(int left, int top, int right, int bottom) {}
543
544    /** @hide For internal use only. Individual results may vary. */
545    public void getHotspotBounds(Rect outRect) {
546        outRect.set(getBounds());
547    }
548
549    /**
550     * Whether this drawable requests projection.
551     *
552     * @hide magic!
553     */
554    public boolean isProjected() {
555        return false;
556    }
557
558    /**
559     * Indicates whether this drawable will change its appearance based on
560     * state. Clients can use this to determine whether it is necessary to
561     * calculate their state and call setState.
562     *
563     * @return True if this drawable changes its appearance based on state,
564     *         false otherwise.
565     * @see #setState(int[])
566     */
567    public boolean isStateful() {
568        return false;
569    }
570
571    /**
572     * Specify a set of states for the drawable. These are use-case specific,
573     * so see the relevant documentation. As an example, the background for
574     * widgets like Button understand the following states:
575     * [{@link android.R.attr#state_focused},
576     *  {@link android.R.attr#state_pressed}].
577     *
578     * <p>If the new state you are supplying causes the appearance of the
579     * Drawable to change, then it is responsible for calling
580     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
581     * true will be returned from this function.
582     *
583     * <p>Note: The Drawable holds a reference on to <var>stateSet</var>
584     * until a new state array is given to it, so you must not modify this
585     * array during that time.</p>
586     *
587     * @param stateSet The new set of states to be displayed.
588     *
589     * @return Returns true if this change in state has caused the appearance
590     * of the Drawable to change (hence requiring an invalidate), otherwise
591     * returns false.
592     */
593    public boolean setState(final int[] stateSet) {
594        if (!Arrays.equals(mStateSet, stateSet)) {
595            mStateSet = stateSet;
596            return onStateChange(stateSet);
597        }
598        return false;
599    }
600
601    /**
602     * Describes the current state, as a union of primitve states, such as
603     * {@link android.R.attr#state_focused},
604     * {@link android.R.attr#state_selected}, etc.
605     * Some drawables may modify their imagery based on the selected state.
606     * @return An array of resource Ids describing the current state.
607     */
608    public int[] getState() {
609        return mStateSet;
610    }
611
612    /**
613     * If this Drawable does transition animations between states, ask that
614     * it immediately jump to the current state and skip any active animations.
615     */
616    public void jumpToCurrentState() {
617    }
618
619    /**
620     * @return The current drawable that will be used by this drawable. For simple drawables, this
621     *         is just the drawable itself. For drawables that change state like
622     *         {@link StateListDrawable} and {@link LevelListDrawable} this will be the child drawable
623     *         currently in use.
624     */
625    public Drawable getCurrent() {
626        return this;
627    }
628
629    /**
630     * Specify the level for the drawable.  This allows a drawable to vary its
631     * imagery based on a continuous controller, for example to show progress
632     * or volume level.
633     *
634     * <p>If the new level you are supplying causes the appearance of the
635     * Drawable to change, then it is responsible for calling
636     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
637     * true will be returned from this function.
638     *
639     * @param level The new level, from 0 (minimum) to 10000 (maximum).
640     *
641     * @return Returns true if this change in level has caused the appearance
642     * of the Drawable to change (hence requiring an invalidate), otherwise
643     * returns false.
644     */
645    public final boolean setLevel(int level) {
646        if (mLevel != level) {
647            mLevel = level;
648            return onLevelChange(level);
649        }
650        return false;
651    }
652
653    /**
654     * Retrieve the current level.
655     *
656     * @return int Current level, from 0 (minimum) to 10000 (maximum).
657     */
658    public final int getLevel() {
659        return mLevel;
660    }
661
662    /**
663     * Set whether this Drawable is visible.  This generally does not impact
664     * the Drawable's behavior, but is a hint that can be used by some
665     * Drawables, for example, to decide whether run animations.
666     *
667     * @param visible Set to true if visible, false if not.
668     * @param restart You can supply true here to force the drawable to behave
669     *                as if it has just become visible, even if it had last
670     *                been set visible.  Used for example to force animations
671     *                to restart.
672     *
673     * @return boolean Returns true if the new visibility is different than
674     *         its previous state.
675     */
676    public boolean setVisible(boolean visible, boolean restart) {
677        boolean changed = mVisible != visible;
678        if (changed) {
679            mVisible = visible;
680            invalidateSelf();
681        }
682        return changed;
683    }
684
685    public final boolean isVisible() {
686        return mVisible;
687    }
688
689    /**
690     * Set whether this Drawable is automatically mirrored when its layout direction is RTL
691     * (right-to left). See {@link android.util.LayoutDirection}.
692     *
693     * @param mirrored Set to true if the Drawable should be mirrored, false if not.
694     */
695    public void setAutoMirrored(boolean mirrored) {
696    }
697
698    /**
699     * Tells if this Drawable will be automatically mirrored  when its layout direction is RTL
700     * right-to-left. See {@link android.util.LayoutDirection}.
701     *
702     * @return boolean Returns true if this Drawable will be automatically mirrored.
703     */
704    public boolean isAutoMirrored() {
705        return false;
706    }
707
708    /**
709     * Applies the specified theme to this Drawable and its children.
710     */
711    public void applyTheme(@SuppressWarnings("unused") Theme t) {
712    }
713
714    public boolean canApplyTheme() {
715        return false;
716    }
717
718    /**
719     * Return the opacity/transparency of this Drawable.  The returned value is
720     * one of the abstract format constants in
721     * {@link android.graphics.PixelFormat}:
722     * {@link android.graphics.PixelFormat#UNKNOWN},
723     * {@link android.graphics.PixelFormat#TRANSLUCENT},
724     * {@link android.graphics.PixelFormat#TRANSPARENT}, or
725     * {@link android.graphics.PixelFormat#OPAQUE}.
726     *
727     * <p>Generally a Drawable should be as conservative as possible with the
728     * value it returns.  For example, if it contains multiple child drawables
729     * and only shows one of them at a time, if only one of the children is
730     * TRANSLUCENT and the others are OPAQUE then TRANSLUCENT should be
731     * returned.  You can use the method {@link #resolveOpacity} to perform a
732     * standard reduction of two opacities to the appropriate single output.
733     *
734     * <p>Note that the returned value does <em>not</em> take into account a
735     * custom alpha or color filter that has been applied by the client through
736     * the {@link #setAlpha} or {@link #setColorFilter} methods.
737     *
738     * @return int The opacity class of the Drawable.
739     *
740     * @see android.graphics.PixelFormat
741     */
742    public abstract int getOpacity();
743
744    /**
745     * Return the appropriate opacity value for two source opacities.  If
746     * either is UNKNOWN, that is returned; else, if either is TRANSLUCENT,
747     * that is returned; else, if either is TRANSPARENT, that is returned;
748     * else, OPAQUE is returned.
749     *
750     * <p>This is to help in implementing {@link #getOpacity}.
751     *
752     * @param op1 One opacity value.
753     * @param op2 Another opacity value.
754     *
755     * @return int The combined opacity value.
756     *
757     * @see #getOpacity
758     */
759    public static int resolveOpacity(int op1, int op2) {
760        if (op1 == op2) {
761            return op1;
762        }
763        if (op1 == PixelFormat.UNKNOWN || op2 == PixelFormat.UNKNOWN) {
764            return PixelFormat.UNKNOWN;
765        }
766        if (op1 == PixelFormat.TRANSLUCENT || op2 == PixelFormat.TRANSLUCENT) {
767            return PixelFormat.TRANSLUCENT;
768        }
769        if (op1 == PixelFormat.TRANSPARENT || op2 == PixelFormat.TRANSPARENT) {
770            return PixelFormat.TRANSPARENT;
771        }
772        return PixelFormat.OPAQUE;
773    }
774
775    /**
776     * Returns a Region representing the part of the Drawable that is completely
777     * transparent.  This can be used to perform drawing operations, identifying
778     * which parts of the target will not change when rendering the Drawable.
779     * The default implementation returns null, indicating no transparent
780     * region; subclasses can optionally override this to return an actual
781     * Region if they want to supply this optimization information, but it is
782     * not required that they do so.
783     *
784     * @return Returns null if the Drawables has no transparent region to
785     * report, else a Region holding the parts of the Drawable's bounds that
786     * are transparent.
787     */
788    public Region getTransparentRegion() {
789        return null;
790    }
791
792    /**
793     * Override this in your subclass to change appearance if you recognize the
794     * specified state.
795     *
796     * @return Returns true if the state change has caused the appearance of
797     * the Drawable to change (that is, it needs to be drawn), else false
798     * if it looks the same and there is no need to redraw it since its
799     * last state.
800     */
801    protected boolean onStateChange(int[] state) { return false; }
802    /** Override this in your subclass to change appearance if you vary based
803     *  on level.
804     * @return Returns true if the level change has caused the appearance of
805     * the Drawable to change (that is, it needs to be drawn), else false
806     * if it looks the same and there is no need to redraw it since its
807     * last level.
808     */
809    protected boolean onLevelChange(int level) { return false; }
810    /**
811     * Override this in your subclass to change appearance if you vary based on
812     * the bounds.
813     */
814    protected void onBoundsChange(Rect bounds) {}
815
816    /**
817     * Return the intrinsic width of the underlying drawable object.  Returns
818     * -1 if it has no intrinsic width, such as with a solid color.
819     */
820    public int getIntrinsicWidth() {
821        return -1;
822    }
823
824    /**
825     * Return the intrinsic height of the underlying drawable object. Returns
826     * -1 if it has no intrinsic height, such as with a solid color.
827     */
828    public int getIntrinsicHeight() {
829        return -1;
830    }
831
832    /**
833     * Returns the minimum width suggested by this Drawable. If a View uses this
834     * Drawable as a background, it is suggested that the View use at least this
835     * value for its width. (There will be some scenarios where this will not be
836     * possible.) This value should INCLUDE any padding.
837     *
838     * @return The minimum width suggested by this Drawable. If this Drawable
839     *         doesn't have a suggested minimum width, 0 is returned.
840     */
841    public int getMinimumWidth() {
842        final int intrinsicWidth = getIntrinsicWidth();
843        return intrinsicWidth > 0 ? intrinsicWidth : 0;
844    }
845
846    /**
847     * Returns the minimum height suggested by this Drawable. If a View uses this
848     * Drawable as a background, it is suggested that the View use at least this
849     * value for its height. (There will be some scenarios where this will not be
850     * possible.) This value should INCLUDE any padding.
851     *
852     * @return The minimum height suggested by this Drawable. If this Drawable
853     *         doesn't have a suggested minimum height, 0 is returned.
854     */
855    public int getMinimumHeight() {
856        final int intrinsicHeight = getIntrinsicHeight();
857        return intrinsicHeight > 0 ? intrinsicHeight : 0;
858    }
859
860    /**
861     * Return in padding the insets suggested by this Drawable for placing
862     * content inside the drawable's bounds. Positive values move toward the
863     * center of the Drawable (set Rect.inset).
864     *
865     * @return true if this drawable actually has a padding, else false. When false is returned,
866     * the padding is always set to 0.
867     */
868    public boolean getPadding(@NonNull Rect padding) {
869        padding.set(0, 0, 0, 0);
870        return false;
871    }
872
873    /**
874     * Return in insets the layout insets suggested by this Drawable for use with alignment
875     * operations during layout.
876     *
877     * @hide
878     */
879    public Insets getOpticalInsets() {
880        return Insets.NONE;
881    }
882
883    /**
884     * Called to get the drawable to populate the Outline that defines its drawing area.
885     * <p>
886     * This method is called by the default {@link android.view.ViewOutlineProvider} to define
887     * the outline of the View.
888     * <p>
889     * The default behavior defines the outline to be the bounding rectangle of 0 alpha.
890     * Subclasses that wish to convey a different shape or alpha value must override this method.
891     *
892     * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
893     */
894    public void getOutline(@NonNull Outline outline) {
895        outline.setRect(getBounds());
896        outline.setAlpha(getAlpha() / 255.0f);
897    }
898
899    /**
900     * Make this drawable mutable. This operation cannot be reversed. A mutable
901     * drawable is guaranteed to not share its state with any other drawable.
902     * This is especially useful when you need to modify properties of drawables
903     * loaded from resources. By default, all drawables instances loaded from
904     * the same resource share a common state; if you modify the state of one
905     * instance, all the other instances will receive the same modification.
906     *
907     * Calling this method on a mutable Drawable will have no effect.
908     *
909     * @return This drawable.
910     * @see ConstantState
911     * @see #getConstantState()
912     */
913    public Drawable mutate() {
914        return this;
915    }
916
917    /**
918     * Create a drawable from an inputstream
919     */
920    public static Drawable createFromStream(InputStream is, String srcName) {
921        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
922        try {
923            return createFromResourceStream(null, null, is, srcName);
924        } finally {
925            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
926        }
927    }
928
929    /**
930     * Create a drawable from an inputstream, using the given resources and
931     * value to determine density information.
932     */
933    public static Drawable createFromResourceStream(Resources res, TypedValue value,
934            InputStream is, String srcName) {
935        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
936        try {
937            return createFromResourceStream(res, value, is, srcName, null);
938        } finally {
939            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
940        }
941    }
942
943    /**
944     * Create a drawable from an inputstream, using the given resources and
945     * value to determine density information.
946     */
947    public static Drawable createFromResourceStream(Resources res, TypedValue value,
948            InputStream is, String srcName, BitmapFactory.Options opts) {
949        if (is == null) {
950            return null;
951        }
952
953        /*  ugh. The decodeStream contract is that we have already allocated
954            the pad rect, but if the bitmap does not had a ninepatch chunk,
955            then the pad will be ignored. If we could change this to lazily
956            alloc/assign the rect, we could avoid the GC churn of making new
957            Rects only to drop them on the floor.
958        */
959        Rect pad = new Rect();
960
961        // Special stuff for compatibility mode: if the target density is not
962        // the same as the display density, but the resource -is- the same as
963        // the display density, then don't scale it down to the target density.
964        // This allows us to load the system's density-correct resources into
965        // an application in compatibility mode, without scaling those down
966        // to the compatibility density only to have them scaled back up when
967        // drawn to the screen.
968        if (opts == null) opts = new BitmapFactory.Options();
969        opts.inScreenDensity = res != null
970                ? res.getDisplayMetrics().noncompatDensityDpi : DisplayMetrics.DENSITY_DEVICE;
971        Bitmap  bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
972        if (bm != null) {
973            byte[] np = bm.getNinePatchChunk();
974            if (np == null || !NinePatch.isNinePatchChunk(np)) {
975                np = null;
976                pad = null;
977            }
978
979            final Rect opticalInsets = new Rect();
980            bm.getOpticalInsets(opticalInsets);
981            return drawableFromBitmap(res, bm, np, pad, opticalInsets, srcName);
982        }
983        return null;
984    }
985
986    /**
987     * Create a drawable from an XML document. For more information on how to
988     * create resources in XML, see
989     * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
990     */
991    public static Drawable createFromXml(Resources r, XmlPullParser parser)
992            throws XmlPullParserException, IOException {
993        return createFromXml(r, parser, null);
994    }
995
996    /**
997     * Create a drawable from an XML document using an optional {@link Theme}.
998     * For more information on how to create resources in XML, see
999     * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
1000     */
1001    public static Drawable createFromXml(Resources r, XmlPullParser parser, Theme theme)
1002            throws XmlPullParserException, IOException {
1003        AttributeSet attrs = Xml.asAttributeSet(parser);
1004
1005        int type;
1006        while ((type=parser.next()) != XmlPullParser.START_TAG &&
1007                type != XmlPullParser.END_DOCUMENT) {
1008            // Empty loop
1009        }
1010
1011        if (type != XmlPullParser.START_TAG) {
1012            throw new XmlPullParserException("No start tag found");
1013        }
1014
1015        Drawable drawable = createFromXmlInner(r, parser, attrs, theme);
1016
1017        if (drawable == null) {
1018            throw new RuntimeException("Unknown initial tag: " + parser.getName());
1019        }
1020
1021        return drawable;
1022    }
1023
1024    /**
1025     * Create from inside an XML document.  Called on a parser positioned at
1026     * a tag in an XML document, tries to create a Drawable from that tag.
1027     * Returns null if the tag is not a valid drawable.
1028     */
1029    public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs)
1030            throws XmlPullParserException, IOException {
1031        return createFromXmlInner(r, parser, attrs, null);
1032    }
1033
1034    /**
1035     * Create a drawable from inside an XML document using an optional
1036     * {@link Theme}. Called on a parser positioned at a tag in an XML
1037     * document, tries to create a Drawable from that tag. Returns {@code null}
1038     * if the tag is not a valid drawable.
1039     */
1040    public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs,
1041            Theme theme) throws XmlPullParserException, IOException {
1042        final Drawable drawable;
1043
1044        final String name = parser.getName();
1045        if (name.equals("selector")) {
1046            drawable = new StateListDrawable();
1047        } else if (name.equals("animated-selector")) {
1048            drawable = new AnimatedStateListDrawable();
1049        } else if (name.equals("level-list")) {
1050            drawable = new LevelListDrawable();
1051        } else if (name.equals("layer-list")) {
1052            drawable = new LayerDrawable();
1053        } else if (name.equals("transition")) {
1054            drawable = new TransitionDrawable();
1055        } else if (name.equals("ripple")) {
1056            drawable = new RippleDrawable();
1057        } else if (name.equals("color")) {
1058            drawable = new ColorDrawable();
1059        } else if (name.equals("shape")) {
1060            drawable = new GradientDrawable();
1061        } else if (name.equals("vector")) {
1062            drawable = new VectorDrawable();
1063        } else if (name.equals("animated-vector")) {
1064            drawable = new AnimatedVectorDrawable();
1065        } else if (name.equals("scale")) {
1066            drawable = new ScaleDrawable();
1067        } else if (name.equals("clip")) {
1068            drawable = new ClipDrawable();
1069        } else if (name.equals("rotate")) {
1070            drawable = new RotateDrawable();
1071        } else if (name.equals("animated-rotate")) {
1072            drawable = new AnimatedRotateDrawable();
1073        } else if (name.equals("animation-list")) {
1074            drawable = new AnimationDrawable();
1075        } else if (name.equals("inset")) {
1076            drawable = new InsetDrawable();
1077        } else if (name.equals("bitmap")) {
1078            //noinspection deprecation
1079            drawable = new BitmapDrawable(r);
1080            if (r != null) {
1081               ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
1082            }
1083        } else if (name.equals("nine-patch")) {
1084            drawable = new NinePatchDrawable();
1085            if (r != null) {
1086                ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
1087             }
1088        } else {
1089            throw new XmlPullParserException(parser.getPositionDescription() +
1090                    ": invalid drawable tag " + name);
1091        }
1092
1093        drawable.inflate(r, parser, attrs, theme);
1094        return drawable;
1095    }
1096
1097
1098    /**
1099     * Create a drawable from file path name.
1100     */
1101    public static Drawable createFromPath(String pathName) {
1102        if (pathName == null) {
1103            return null;
1104        }
1105
1106        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, pathName);
1107        try {
1108            Bitmap bm = BitmapFactory.decodeFile(pathName);
1109            if (bm != null) {
1110                return drawableFromBitmap(null, bm, null, null, null, pathName);
1111            }
1112        } finally {
1113            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
1114        }
1115
1116        return null;
1117    }
1118
1119    /**
1120     * Inflate this Drawable from an XML resource. Does not apply a theme.
1121     *
1122     * @see #inflate(Resources, XmlPullParser, AttributeSet, Theme)
1123     */
1124    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
1125            throws XmlPullParserException, IOException {
1126        inflate(r, parser, attrs, null);
1127    }
1128
1129    /**
1130     * Inflate this Drawable from an XML resource optionally styled by a theme.
1131     *
1132     * @param r Resources used to resolve attribute values
1133     * @param parser XML parser from which to inflate this Drawable
1134     * @param attrs Base set of attribute values
1135     * @param theme Theme to apply, may be null
1136     * @throws XmlPullParserException
1137     * @throws IOException
1138     */
1139    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
1140            throws XmlPullParserException, IOException {
1141        final TypedArray a;
1142        if (theme != null) {
1143            a = theme.obtainStyledAttributes(
1144                    attrs, com.android.internal.R.styleable.Drawable, 0, 0);
1145        } else {
1146            a = r.obtainAttributes(attrs, com.android.internal.R.styleable.Drawable);
1147        }
1148
1149        inflateWithAttributes(r, parser, a, com.android.internal.R.styleable.Drawable_visible);
1150        a.recycle();
1151    }
1152
1153    /**
1154     * Inflate a Drawable from an XML resource.
1155     *
1156     * @throws XmlPullParserException
1157     * @throws IOException
1158     */
1159    void inflateWithAttributes(Resources r, XmlPullParser parser, TypedArray attrs, int visibleAttr)
1160            throws XmlPullParserException, IOException {
1161        mVisible = attrs.getBoolean(visibleAttr, mVisible);
1162    }
1163
1164    /**
1165     * This abstract class is used by {@link Drawable}s to store shared constant state and data
1166     * between Drawables. {@link BitmapDrawable}s created from the same resource will for instance
1167     * share a unique bitmap stored in their ConstantState.
1168     *
1169     * <p>
1170     * {@link #newDrawable(Resources)} can be used as a factory to create new Drawable instances
1171     * from this ConstantState.
1172     * </p>
1173     *
1174     * Use {@link Drawable#getConstantState()} to retrieve the ConstantState of a Drawable. Calling
1175     * {@link Drawable#mutate()} on a Drawable should typically create a new ConstantState for that
1176     * Drawable.
1177     */
1178    public static abstract class ConstantState {
1179        /**
1180         * Create a new drawable without supplying resources the caller
1181         * is running in.  Note that using this means the density-dependent
1182         * drawables (like bitmaps) will not be able to update their target
1183         * density correctly. One should use {@link #newDrawable(Resources)}
1184         * instead to provide a resource.
1185         */
1186        public abstract Drawable newDrawable();
1187
1188        /**
1189         * Create a new Drawable instance from its constant state.  This
1190         * must be implemented for drawables that change based on the target
1191         * density of their caller (that is depending on whether it is
1192         * in compatibility mode).
1193         */
1194        public Drawable newDrawable(Resources res) {
1195            return newDrawable();
1196        }
1197
1198        /**
1199         * Create a new Drawable instance from its constant state. This must be
1200         * implemented for drawables that can have a theme applied.
1201         */
1202        public Drawable newDrawable(Resources res, Theme theme) {
1203            return newDrawable();
1204        }
1205
1206        /**
1207         * Return a bit mask of configuration changes that will impact
1208         * this drawable (and thus require completely reloading it).
1209         */
1210        public abstract int getChangingConfigurations();
1211
1212        /**
1213         * @hide
1214         */
1215        public Bitmap getBitmap() {
1216            return null;
1217        }
1218
1219        /**
1220         * Return whether this constant state can have a theme applied.
1221         */
1222        public boolean canApplyTheme() {
1223            return false;
1224        }
1225    }
1226
1227    /**
1228     * Return a {@link ConstantState} instance that holds the shared state of this Drawable.
1229     *
1230     * @return The ConstantState associated to that Drawable.
1231     * @see ConstantState
1232     * @see Drawable#mutate()
1233     */
1234    public ConstantState getConstantState() {
1235        return null;
1236    }
1237
1238    private static Drawable drawableFromBitmap(Resources res, Bitmap bm, byte[] np,
1239            Rect pad, Rect layoutBounds, String srcName) {
1240
1241        if (np != null) {
1242            return new NinePatchDrawable(res, bm, np, pad, layoutBounds, srcName);
1243        }
1244
1245        return new BitmapDrawable(res, bm);
1246    }
1247
1248    /**
1249     * Ensures the tint filter is consistent with the current tint color and
1250     * mode.
1251     */
1252    PorterDuffColorFilter updateTintFilter(PorterDuffColorFilter tintFilter, ColorStateList tint,
1253            PorterDuff.Mode tintMode) {
1254        if (tint == null || tintMode == null) {
1255            return null;
1256        }
1257
1258        final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
1259        if (tintFilter == null) {
1260            return new PorterDuffColorFilter(color, tintMode);
1261        }
1262
1263        tintFilter.setColor(color);
1264        tintFilter.setMode(tintMode);
1265        return tintFilter;
1266    }
1267
1268    /**
1269     * Obtains styled attributes from the theme, if available, or unstyled
1270     * resources if the theme is null.
1271     */
1272    static TypedArray obtainAttributes(
1273            Resources res, Theme theme, AttributeSet set, int[] attrs) {
1274        if (theme == null) {
1275            return res.obtainAttributes(set, attrs);
1276        }
1277        return theme.obtainStyledAttributes(set, attrs, 0, 0);
1278    }
1279
1280    /**
1281     * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode
1282     * attribute's enum value.
1283     *
1284     * @hide
1285     */
1286    public static PorterDuff.Mode parseTintMode(int value, Mode defaultMode) {
1287        switch (value) {
1288            case 3: return Mode.SRC_OVER;
1289            case 5: return Mode.SRC_IN;
1290            case 9: return Mode.SRC_ATOP;
1291            case 14: return Mode.MULTIPLY;
1292            case 15: return Mode.SCREEN;
1293            case 16: return Mode.ADD;
1294            default: return defaultMode;
1295        }
1296    }
1297}
1298
1299